aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Anderson <scott@anderso.nz>2019-12-19 14:08:24 +1300
committerSimon Ser <contact@emersion.fr>2019-12-20 10:56:15 +0100
commit5e083729ed0423e24f734bec1d9a91c77b21d31f (patch)
tree712c1c1916b0360d6fcf43c048e968ce87cc0606
parente2063b276bc1e9556adc09d42b87e63848389710 (diff)
downloadexternal_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-xfourcc.py77
-rw-r--r--meson.build6
-rw-r--r--tables.h11
3 files changed, 65 insertions, 29 deletions
diff --git a/fourcc.py b/fourcc.py
index 3613cce..8e95436 100755
--- a/fourcc.py
+++ b/fourcc.py
@@ -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