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>main
parent
f287d1990b
commit
67e911977f
|
@ -14,7 +14,7 @@
|
||||||
# repository's registry will be used there as well.
|
# repository's registry will be used there as well.
|
||||||
variables:
|
variables:
|
||||||
UPSTREAM_REPO: mesa/drm
|
UPSTREAM_REPO: mesa/drm
|
||||||
DEBIAN_TAG: "2020-11-15"
|
DEBIAN_TAG: "2021-02-11"
|
||||||
DEBIAN_VERSION: buster-slim
|
DEBIAN_VERSION: buster-slim
|
||||||
DEBIAN_IMAGE: "$CI_REGISTRY_IMAGE/debian/$DEBIAN_VERSION:$DEBIAN_TAG"
|
DEBIAN_IMAGE: "$CI_REGISTRY_IMAGE/debian/$DEBIAN_VERSION:$DEBIAN_TAG"
|
||||||
|
|
||||||
|
|
|
@ -63,4 +63,4 @@ done
|
||||||
|
|
||||||
|
|
||||||
# Test that the oldest Meson version we claim to support is still supported
|
# Test that the oldest Meson version we claim to support is still supported
|
||||||
pip3 install meson==0.43
|
pip3 install meson==0.46
|
||||||
|
|
|
@ -196,3 +196,5 @@ drmUnmap
|
||||||
drmUnmapBufs
|
drmUnmapBufs
|
||||||
drmUpdateDrawableInfo
|
drmUpdateDrawableInfo
|
||||||
drmWaitVBlank
|
drmWaitVBlank
|
||||||
|
drmGetFormatModifierName
|
||||||
|
drmGetFormatModifierVendor
|
||||||
|
|
|
@ -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('''\
|
||||||
|
};
|
||||||
|
''')
|
|
@ -23,7 +23,7 @@ project(
|
||||||
['c'],
|
['c'],
|
||||||
version : '2.4.106',
|
version : '2.4.106',
|
||||||
license : 'MIT',
|
license : 'MIT',
|
||||||
meson_version : '>= 0.43',
|
meson_version : '>= 0.46',
|
||||||
default_options : ['buildtype=debugoptimized', 'c_std=gnu99'],
|
default_options : ['buildtype=debugoptimized', 'c_std=gnu99'],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,6 +51,11 @@ prog_nm = find_program('nm')
|
||||||
intel_atomics = false
|
intel_atomics = false
|
||||||
lib_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)
|
dep_atomic_ops = dependency('atomic_ops', required : false)
|
||||||
if cc.links('''
|
if cc.links('''
|
||||||
int atomic_add(int *i) { return __sync_add_and_fetch (i, 1); }
|
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',
|
'xf86drm.c', 'xf86drmHash.c', 'xf86drmRandom.c', 'xf86drmSL.c',
|
||||||
'xf86drmMode.c'
|
'xf86drmMode.c'
|
||||||
),
|
),
|
||||||
config_file,
|
config_file, format_mod_static_table
|
||||||
],
|
],
|
||||||
c_args : libdrm_c_args,
|
c_args : libdrm_c_args,
|
||||||
dependencies : [dep_valgrind, dep_rt, dep_m],
|
dependencies : [dep_valgrind, dep_rt, dep_m],
|
||||||
|
|
|
@ -265,52 +265,37 @@ static void dump_blob(struct device *dev, uint32_t blob_id)
|
||||||
|
|
||||||
static const char *modifier_to_string(uint64_t modifier)
|
static const char *modifier_to_string(uint64_t modifier)
|
||||||
{
|
{
|
||||||
switch (modifier) {
|
static char mod_string[4096];
|
||||||
case DRM_FORMAT_MOD_INVALID:
|
|
||||||
return "INVALID";
|
char *modifier_name = drmGetFormatModifierName(modifier);
|
||||||
case DRM_FORMAT_MOD_LINEAR:
|
char *vendor_name = drmGetFormatModifierVendor(modifier);
|
||||||
return "LINEAR";
|
memset(mod_string, 0x00, sizeof(mod_string));
|
||||||
case I915_FORMAT_MOD_X_TILED:
|
|
||||||
return "X_TILED";
|
if (!modifier_name) {
|
||||||
case I915_FORMAT_MOD_Y_TILED:
|
if (vendor_name)
|
||||||
return "Y_TILED";
|
snprintf(mod_string, sizeof(mod_string), "%s_%s",
|
||||||
case I915_FORMAT_MOD_Yf_TILED:
|
vendor_name, "UNKNOWN_MODIFIER");
|
||||||
return "Yf_TILED";
|
else
|
||||||
case I915_FORMAT_MOD_Y_TILED_CCS:
|
snprintf(mod_string, sizeof(mod_string), "%s_%s",
|
||||||
return "Y_TILED_CCS";
|
"UNKNOWN_VENDOR", "UNKNOWN_MODIFIER");
|
||||||
case I915_FORMAT_MOD_Yf_TILED_CCS:
|
/* safe, as free is no-op for NULL */
|
||||||
return "Yf_TILED_CCS";
|
free(vendor_name);
|
||||||
case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:
|
return mod_string;
|
||||||
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)";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
static void dump_in_formats(struct device *dev, uint32_t blob_id)
|
||||||
|
|
80
xf86drm.c
80
xf86drm.c
|
@ -76,6 +76,7 @@
|
||||||
|
|
||||||
#include "xf86drm.h"
|
#include "xf86drm.h"
|
||||||
#include "libdrm_macros.h"
|
#include "libdrm_macros.h"
|
||||||
|
#include "drm_fourcc.h"
|
||||||
|
|
||||||
#include "util_math.h"
|
#include "util_math.h"
|
||||||
|
|
||||||
|
@ -124,6 +125,33 @@ static drmServerInfoPtr drm_server_info;
|
||||||
static bool drmNodeIsDRM(int maj, int min);
|
static bool drmNodeIsDRM(int maj, int min);
|
||||||
static char *drmGetMinorNameForFD(int fd, int type);
|
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)
|
static unsigned log2_int(unsigned x)
|
||||||
{
|
{
|
||||||
unsigned l;
|
unsigned l;
|
||||||
|
@ -4585,3 +4613,55 @@ drm_public int drmSyncobjTransfer(int fd,
|
||||||
|
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
|
11
xf86drm.h
11
xf86drm.h
|
@ -944,6 +944,17 @@ extern int drmSyncobjTransfer(int fd,
|
||||||
uint32_t src_handle, uint64_t src_point,
|
uint32_t src_handle, uint64_t src_point,
|
||||||
uint32_t flags);
|
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)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue