diff options
author | Scott Anderson <scott@anderso.nz> | 2019-12-19 14:08:24 +1300 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2019-12-20 10:56:15 +0100 |
commit | 5e083729ed0423e24f734bec1d9a91c77b21d31f (patch) | |
tree | 712c1c1916b0360d6fcf43c048e968ce87cc0606 | |
parent | e2063b276bc1e9556adc09d42b87e63848389710 (diff) | |
download | external_drm_info-5e083729ed0423e24f734bec1d9a91c77b21d31f.tar.gz external_drm_info-5e083729ed0423e24f734bec1d9a91c77b21d31f.tar.bz2 external_drm_info-5e083729ed0423e24f734bec1d9a91c77b21d31f.zip |
fourcc.py: Handle AFBC modifiers
ARM Framebuffer Compression is a structured modifier that we just gave
up on parsing before. This adds the code to generate all of the possible
combinations of arguments for printing.
There are 8 bits that can be set, plus 5 possible block sizes (including
not specified). This adds over 2000 lines of C code to tables.h, so it
has been split out into a C file instead of an inline function inside of
the header.
This also makes our matching a bit more strict, so future complex
modifers should not be matched, and require to be added explicitly.
-rwxr-xr-x | fourcc.py | 77 | ||||
-rw-r--r-- | meson.build | 6 | ||||
-rw-r--r-- | tables.h | 11 |
3 files changed, 65 insertions, 29 deletions
@@ -2,57 +2,82 @@ import sys import re +from itertools import chain, combinations -fourcc_include = sys.argv[1] +def powerset(s): + return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1)) -fmt_list = [] -mod_list = [] +def case_print(f, c, s): + f.write('\tcase {}:\n'.format(c)) + f.write('\t\treturn "{}";\n'.format(s)) -fmt = re.compile(r'^#define (\w+)\s*(?:\\$\s*)?fourcc_code', flags=re.M) -mod = re.compile(r'^#define (\w+)\s*(?:\\$\s*)?fourcc_mod_code', flags=re.M) -mod_broadcom = re.compile(r'^#define (DRM_FORMAT_MOD_BROADCOM\w+(?=\s))', flags=re.M) +def afbc_print(f, l): + fmt = 'DRM_FORMAT_MOD_ARM_AFBC({})' + if l: + # Strip prefix to stop string being stupidly long + short = [s[len('AFBC_FORMAT_MOD_'):] for s in l] + case_print(f, fmt.format('|'.join(l)), fmt.format('|'.join(short))) + else: + case_print(f, fmt.format(0), fmt.format(0)) -f = open(fourcc_include).read() -fmt_list = fmt.findall(f) -mod_list = set(mod.findall(f) + mod_broadcom.findall(f)) +info = { + 'fmt': r'^#define (\w+)\s*(?:\\$\s*)?fourcc_code', + 'basic_pre': r'\bI915_FORMAT_MOD_\w+\b', + 'basic_post': r'\b(DRM_FORMAT_MOD_(?:INVALID|LINEAR|SAMSUNG|QCOM|VIVANTE|NVIDIA|BROADCOM|ALLWINNER)\w*)\s', + 'afbc_block': r'\bAFBC_FORMAT_MOD_BLOCK_SIZE(?:_\d+x\d+)+\b', + 'afbc_bitmask': r'\bAFBC_FORMAT_MOD_[A-Z]+\b', +} -f_name = sys.argv[2] +with open(sys.argv[1], 'r') as f: + data = f.read() + for k, v in info.items(): + info[k] = re.findall(v, data, flags=re.M) -with open(f_name, 'w') as f: +with open(sys.argv[2], 'w') as f: f.write('''\ #include <stdint.h> #include <drm_fourcc.h> -static inline const char *format_str(uint32_t format) +#include "tables.h" + +const char *format_str(uint32_t format) { switch (format) { case DRM_FORMAT_INVALID: return "INVALID"; ''') - for ident in fmt_list: - f.write('\tcase {}:\n\t\treturn "{}";\n'.format(ident, ident[len('DRM_FORMAT_'):])) + + for ident in info['fmt']: + case_print(f, ident, ident[len('DRM_FORMAT_'):]) + f.write('''\ default: - return "unknown"; + return "Unknown"; } } -static inline const char *modifier_str(uint64_t modifier) +const char *modifier_str(uint64_t modifier) { - /* - * ARM has a complex format which we can't be bothered to parse. - */ - if ((modifier >> 56) == DRM_FORMAT_MOD_VENDOR_ARM) { - return "DRM_FORMAT_MOD_ARM_AFBC()"; - } - switch (modifier) { ''') - for ident in mod_list: - f.write('\tcase {}:\n\t\treturn "{}";\n'.format(ident, ident)) + + for ident in info['basic_pre'] + info['basic_post']: + case_print(f, ident, ident) + + # ARM framebuffer compression + # Not all of the combintations we generate will be valid modifers exposed + # by the driver + + for bits in powerset(info['afbc_bitmask']): + bits = list(bits) + bits.sort() + afbc_print(f, bits) + for block in info['afbc_block']: + afbc_print(f, bits + [block]) + f.write('''\ default: - return "unknown"; + return "Unknown"; } } ''') diff --git a/meson.build b/meson.build index a58bc4a..8279c06 100644 --- a/meson.build +++ b/meson.build @@ -64,12 +64,12 @@ endif python3 = import('python').find_installation() -tables_h = custom_target('tables_h', - output : 'tables.h', +tables_c = custom_target('tables_c', + output : 'tables.c', command : [python3, files('fourcc.py'), fourcc_h, '@OUTPUT@']) executable('drm_info', - [files('main.c', 'json.c', 'pretty.c'), tables_h], + [files('main.c', 'json.c', 'pretty.c'), tables_c], include_directories: inc, dependencies: [libdrm, jsonc], install: true, diff --git a/tables.h b/tables.h new file mode 100644 index 0000000..8510f18 --- /dev/null +++ b/tables.h @@ -0,0 +1,11 @@ +#ifndef TABLES_H +#define TABLES_H + +#include <stdint.h> + +/* The implementation of these functions are generated by fourcc.py */ + +const char *format_str(uint32_t format); +const char *modifier_str(uint64_t modifier); + +#endif |