summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Vlad <marius.vlad@collabora.com>2021-02-01 13:23:20 +0200
committerDaniel Stone <daniels@collabora.com>2021-06-22 11:16:04 +0000
commit67e911977fbe1f444045f59028c149a04ba29566 (patch)
tree2860b6a815e93c49977fa35ea9186501d2e6b9df
parentf287d1990b859602b0cbe50f0b903343c3b67d1a (diff)
xf86drm: Add a human readable representation for format modifiers
Introduces two new methods to retrieve a human readable representation of a format modifier: drmGetFormatModifierName() - returns a format modifier as a string, from a token modifier drmGetFormatModifierVendor() - returns the vendor as a string, from a token modifier and the fourcc_mod_get_vendor macro that returns the vendor. New format modifiers added in drm_fourcc.h uapi kernel header should be sync'ed up with libdrm and should include a human readable representation for that format modifier, in order to display it correctly as a string. That happens with the help of a python script that reads up drm_fourcc header file and outputs a static table comprised of token modifiers alongside a vendor table (Suggested-by Simon Ser <contact@emersion.fr>). The reason for doing it in libdrm is to have a unified place instead of each user of libdrm having a way to keep track of the format modifiers. With this patch, modetest has also been modified to make use of it. Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--.gitlab-ci/debian-install.sh2
-rw-r--r--core-symbols.txt2
-rw-r--r--gen_table_fourcc.py84
-rw-r--r--meson.build9
-rw-r--r--tests/modetest/modetest.c75
-rw-r--r--xf86drm.c80
-rw-r--r--xf86drm.h11
8 files changed, 216 insertions, 49 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7cd6d0f1..26eaf83b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -14,7 +14,7 @@
# repository's registry will be used there as well.
variables:
UPSTREAM_REPO: mesa/drm
- DEBIAN_TAG: "2020-11-15"
+ DEBIAN_TAG: "2021-02-11"
DEBIAN_VERSION: buster-slim
DEBIAN_IMAGE: "$CI_REGISTRY_IMAGE/debian/$DEBIAN_VERSION:$DEBIAN_TAG"
diff --git a/.gitlab-ci/debian-install.sh b/.gitlab-ci/debian-install.sh
index 886e808f..ab901360 100644
--- a/.gitlab-ci/debian-install.sh
+++ b/.gitlab-ci/debian-install.sh
@@ -63,4 +63,4 @@ done
# Test that the oldest Meson version we claim to support is still supported
-pip3 install meson==0.43
+pip3 install meson==0.46
diff --git a/core-symbols.txt b/core-symbols.txt
index 410054b3..a79e6260 100644
--- a/core-symbols.txt
+++ b/core-symbols.txt
@@ -196,3 +196,5 @@ drmUnmap
drmUnmapBufs
drmUpdateDrawableInfo
drmWaitVBlank
+drmGetFormatModifierName
+drmGetFormatModifierVendor
diff --git a/gen_table_fourcc.py b/gen_table_fourcc.py
new file mode 100644
index 00000000..4e8bc409
--- /dev/null
+++ b/gen_table_fourcc.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+
+# Copyright 2021 Collabora, Ltd.
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice (including the
+# next paragraph) shall be included in all copies or substantial
+# portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+# Helper script that reads drm_fourcc.h and writes a static table with the
+# simpler format token modifiers
+
+import sys
+import re
+
+filename = sys.argv[1]
+towrite = sys.argv[2]
+
+fm_re = {
+ 'intel': r'^#define I915_FORMAT_MOD_(\w+)',
+ 'others': r'^#define DRM_FORMAT_MOD_((?:ARM|SAMSUNG|QCOM|VIVANTE|NVIDIA|BROADCOM|ALLWINNER)\w+)\s',
+ 'vendors': r'^#define DRM_FORMAT_MOD_VENDOR_(\w+)'
+}
+
+def print_fm_intel(f, f_mod):
+ f.write(' {{ DRM_MODIFIER_INTEL({}, {}) }},\n'.format(f_mod, f_mod))
+
+# generic write func
+def print_fm(f, vendor, mod, f_name):
+ f.write(' {{ DRM_MODIFIER({}, {}, {}) }},\n'.format(vendor, mod, f_name))
+
+with open(filename, "r") as f:
+ data = f.read()
+ for k, v in fm_re.items():
+ fm_re[k] = re.findall(v, data, flags=re.M)
+
+with open(towrite, "w") as f:
+ f.write('''\
+/* AUTOMATICALLY GENERATED by gen_table_fourcc.py. You should modify
+ that script instead of adding here entries manually! */
+static const struct drmFormatModifierInfo drm_format_modifier_table[] = {
+''')
+ f.write(' { DRM_MODIFIER_INVALID(NONE, INVALID_MODIFIER) },\n')
+ f.write(' { DRM_MODIFIER_LINEAR(NONE, LINEAR) },\n')
+
+ for entry in fm_re['intel']:
+ print_fm_intel(f, entry)
+
+ for entry in fm_re['others']:
+ (vendor, mod) = entry.split('_', 1)
+ if vendor == 'ARM' and (mod == 'TYPE_AFBC' or mod == 'TYPE_MISC'):
+ continue
+ print_fm(f, vendor, mod, mod)
+
+ f.write('''\
+};
+''')
+
+ f.write('''\
+static const struct drmFormatModifierVendorInfo drm_format_modifier_vendor_table[] = {
+''')
+
+ for entry in fm_re['vendors']:
+ f.write(" {{ DRM_FORMAT_MOD_VENDOR_{}, \"{}\" }},\n".format(entry, entry))
+
+ f.write('''\
+};
+''')
diff --git a/meson.build b/meson.build
index fd59c4b3..2bbb485b 100644
--- a/meson.build
+++ b/meson.build
@@ -23,7 +23,7 @@ project(
['c'],
version : '2.4.106',
license : 'MIT',
- meson_version : '>= 0.43',
+ meson_version : '>= 0.46',
default_options : ['buildtype=debugoptimized', 'c_std=gnu99'],
)
@@ -51,6 +51,11 @@ prog_nm = find_program('nm')
intel_atomics = false
lib_atomics = false
+python3 = import('python').find_installation()
+format_mod_static_table = custom_target('format_mod_static_table',
+ output : 'generated_static_table_fourcc.h', input: 'include/drm/drm_fourcc.h',
+ command : [python3, files('gen_table_fourcc.py'), '@INPUT@', '@OUTPUT@'])
+
dep_atomic_ops = dependency('atomic_ops', required : false)
if cc.links('''
int atomic_add(int *i) { return __sync_add_and_fetch (i, 1); }
@@ -300,7 +305,7 @@ libdrm = library(
'xf86drm.c', 'xf86drmHash.c', 'xf86drmRandom.c', 'xf86drmSL.c',
'xf86drmMode.c'
),
- config_file,
+ config_file, format_mod_static_table
],
c_args : libdrm_c_args,
dependencies : [dep_valgrind, dep_rt, dep_m],
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index fc75383a..2c83bd03 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -265,52 +265,37 @@ static void dump_blob(struct device *dev, uint32_t blob_id)
static const char *modifier_to_string(uint64_t modifier)
{
- switch (modifier) {
- case DRM_FORMAT_MOD_INVALID:
- return "INVALID";
- case DRM_FORMAT_MOD_LINEAR:
- return "LINEAR";
- case I915_FORMAT_MOD_X_TILED:
- return "X_TILED";
- case I915_FORMAT_MOD_Y_TILED:
- return "Y_TILED";
- case I915_FORMAT_MOD_Yf_TILED:
- return "Yf_TILED";
- case I915_FORMAT_MOD_Y_TILED_CCS:
- return "Y_TILED_CCS";
- case I915_FORMAT_MOD_Yf_TILED_CCS:
- return "Yf_TILED_CCS";
- case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:
- return "SAMSUNG_64_32_TILE";
- case DRM_FORMAT_MOD_VIVANTE_TILED:
- return "VIVANTE_TILED";
- case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
- return "VIVANTE_SUPER_TILED";
- case DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED:
- return "VIVANTE_SPLIT_TILED";
- case DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED:
- return "VIVANTE_SPLIT_SUPER_TILED";
- case DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED:
- return "NVIDIA_TEGRA_TILED";
- case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0):
- return "NVIDIA_16BX2_BLOCK(0)";
- case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1):
- return "NVIDIA_16BX2_BLOCK(1)";
- case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2):
- return "NVIDIA_16BX2_BLOCK(2)";
- case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3):
- return "NVIDIA_16BX2_BLOCK(3)";
- case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4):
- return "NVIDIA_16BX2_BLOCK(4)";
- case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5):
- return "NVIDIA_16BX2_BLOCK(5)";
- case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
- return "MOD_BROADCOM_VC4_T_TILED";
- case DRM_FORMAT_MOD_QCOM_COMPRESSED:
- return "QCOM_COMPRESSED";
- default:
- return "(UNKNOWN MODIFIER)";
+ static char mod_string[4096];
+
+ char *modifier_name = drmGetFormatModifierName(modifier);
+ char *vendor_name = drmGetFormatModifierVendor(modifier);
+ memset(mod_string, 0x00, sizeof(mod_string));
+
+ if (!modifier_name) {
+ if (vendor_name)
+ snprintf(mod_string, sizeof(mod_string), "%s_%s",
+ vendor_name, "UNKNOWN_MODIFIER");
+ else
+ snprintf(mod_string, sizeof(mod_string), "%s_%s",
+ "UNKNOWN_VENDOR", "UNKNOWN_MODIFIER");
+ /* safe, as free is no-op for NULL */
+ free(vendor_name);
+ return mod_string;
}
+
+ if (modifier == DRM_FORMAT_MOD_LINEAR) {
+ snprintf(mod_string, sizeof(mod_string), "%s", modifier_name);
+ free(modifier_name);
+ free(vendor_name);
+ return mod_string;
+ }
+
+ snprintf(mod_string, sizeof(mod_string), "%s_%s",
+ vendor_name, modifier_name);
+
+ free(modifier_name);
+ free(vendor_name);
+ return mod_string;
}
static void dump_in_formats(struct device *dev, uint32_t blob_id)
diff --git a/xf86drm.c b/xf86drm.c
index edfeb347..24163665 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -76,6 +76,7 @@
#include "xf86drm.h"
#include "libdrm_macros.h"
+#include "drm_fourcc.h"
#include "util_math.h"
@@ -124,6 +125,33 @@ static drmServerInfoPtr drm_server_info;
static bool drmNodeIsDRM(int maj, int min);
static char *drmGetMinorNameForFD(int fd, int type);
+#define DRM_MODIFIER(v, f, f_name) \
+ .modifier = DRM_FORMAT_MOD_##v ## _ ##f, \
+ .modifier_name = #f_name
+
+#define DRM_MODIFIER_INVALID(v, f_name) \
+ .modifier = DRM_FORMAT_MOD_INVALID, .modifier_name = #f_name
+
+#define DRM_MODIFIER_LINEAR(v, f_name) \
+ .modifier = DRM_FORMAT_MOD_LINEAR, .modifier_name = #f_name
+
+/* Intel is abit special as the format doesn't follow other vendors naming
+ * scheme */
+#define DRM_MODIFIER_INTEL(f, f_name) \
+ .modifier = I915_FORMAT_MOD_##f, .modifier_name = #f_name
+
+struct drmFormatModifierInfo {
+ uint64_t modifier;
+ const char *modifier_name;
+};
+
+struct drmFormatModifierVendorInfo {
+ uint8_t vendor;
+ const char *vendor_name;
+};
+
+#include "generated_static_table_fourcc.h"
+
static unsigned log2_int(unsigned x)
{
unsigned l;
@@ -4585,3 +4613,55 @@ drm_public int drmSyncobjTransfer(int fd,
return ret;
}
+
+static char *
+drmGetFormatModifierFromSimpleTokens(uint64_t modifier)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(drm_format_modifier_table); i++) {
+ if (drm_format_modifier_table[i].modifier == modifier)
+ return strdup(drm_format_modifier_table[i].modifier_name);
+ }
+
+ return NULL;
+}
+
+/** Retrieves a human-readable representation of a vendor (as a string) from
+ * the format token modifier
+ *
+ * \param modifier the format modifier token
+ * \return a char pointer to the human-readable form of the vendor. Caller is
+ * responsible for freeing it.
+ */
+drm_public char *
+drmGetFormatModifierVendor(uint64_t modifier)
+{
+ unsigned int i;
+ uint8_t vendor = fourcc_mod_get_vendor(modifier);
+
+ for (i = 0; i < ARRAY_SIZE(drm_format_modifier_vendor_table); i++) {
+ if (drm_format_modifier_vendor_table[i].vendor == vendor)
+ return strdup(drm_format_modifier_vendor_table[i].vendor_name);
+ }
+
+ return NULL;
+}
+
+/** Retrieves a human-readable representation string from a format token
+ * modifier
+ *
+ * If the format modifier was not in the table, this function would return
+ * NULL.
+ *
+ * \param modifier the token format
+ * \return a malloc'ed string representation of the modifier. Caller is
+ * responsible for freeing the string returned.
+ *
+ */
+drm_public char *
+drmGetFormatModifierName(uint64_t modifier)
+{
+ char *modifier_found = drmGetFormatModifierFromSimpleTokens(modifier);
+ return modifier_found;
+}
diff --git a/xf86drm.h b/xf86drm.h
index 9fc06ab8..930d2f40 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -944,6 +944,17 @@ extern int drmSyncobjTransfer(int fd,
uint32_t src_handle, uint64_t src_point,
uint32_t flags);
+extern char *
+drmGetFormatModifierVendor(uint64_t modifier);
+
+extern char *
+drmGetFormatModifierName(uint64_t modifier);
+
+#ifndef fourcc_mod_get_vendor
+#define fourcc_mod_get_vendor(modifier) \
+ (((modifier) >> 56) & 0xff)
+#endif
+
#if defined(__cplusplus)
}
#endif