New Upstream Release - drm-info

Ready changes

Summary

Merged new upstream version: 2.5.0 (was: 2.4.0).

Diff

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..02861b8
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1 @@
+include: https://git.sr.ht/~emersion/dalligi/blob/master/templates/single.yml
diff --git a/debian/changelog b/debian/changelog
index b6a4672..7864f50 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+drm-info (2.5.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Tue, 13 Jun 2023 03:27:40 -0000
+
 drm-info (2.4.0-1) unstable; urgency=medium
 
   * Update d/watch to new upstream repository at freedesktop.org
diff --git a/debian/patches/0000-drm-info-fourcc_py.patch b/debian/patches/0000-drm-info-fourcc_py.patch
index cced25b..ba96e51 100644
--- a/debian/patches/0000-drm-info-fourcc_py.patch
+++ b/debian/patches/0000-drm-info-fourcc_py.patch
@@ -4,9 +4,11 @@ Description: Add list deduplication for unique case labels
 Author: Dennis Filder <d.filder@web.de>
 Bug-Debian: https://bugs.debian.org/982696
 Last-Update: 2021-02-16
---- drm-info-2.2.0/fourcc.py	2021-02-16 18:05:00.000000000 +0100
-+++ drm-info-2.2.0/fourcc.py	2021-02-16 18:05:00.000000000 +0100
-@@ -46,8 +46,11 @@ const char *basic_modifier_str(uint64_t modifier)
+Index: drm-info.git/fourcc.py
+===================================================================
+--- drm-info.git.orig/fourcc.py
++++ drm-info.git/fourcc.py
+@@ -46,8 +46,11 @@ const char *basic_modifier_str(uint64_t
  	switch (modifier) {
  ''')
  
diff --git a/drm_info.h b/drm_info.h
index 654440a..db8f838 100644
--- a/drm_info.h
+++ b/drm_info.h
@@ -6,4 +6,16 @@ struct json_object;
 struct json_object *drm_info(char *paths[]);
 void print_drm(struct json_object *obj);
 
+/* according to CTA 861.G */
+enum {
+	HDMI_STATIC_METADATA_TYPE1 = 0
+};
+
+enum {
+	CTA_EOTF_TRADITIONAL_SDR = 0,
+	CTA_EOTF_TRADITIONAL_HDR,
+	CTA_EOTF_SMPTE_2084,
+	CTA_EOTF_HLG
+};
+
 #endif
diff --git a/fourcc.py b/fourcc.py
index 02768c0..0f43b90 100755
--- a/fourcc.py
+++ b/fourcc.py
@@ -37,7 +37,7 @@ const char *format_str(uint32_t format)
 
 	f.write('''\
 	default:
-		return "Unknown";
+		return "unknown";
 	}
 }
 
@@ -51,7 +51,7 @@ const char *basic_modifier_str(uint64_t modifier)
 
 	f.write('''\
 	default:
-		return "Unknown";
+		return "unknown";
 	}
 }
 ''')
diff --git a/json.c b/json.c
index 038ba10..3bf2657 100644
--- a/json.c
+++ b/json.c
@@ -15,6 +15,7 @@
 #include <xf86drmMode.h>
 
 #include "drm_info.h"
+#include "tables.h"
 
 static const struct {
 	const char *name;
@@ -129,39 +130,66 @@ static struct json_object *device_info(int fd)
 	json_object_object_add(obj, "bus_type",
 		json_object_new_uint64(dev->bustype));
 
-	struct json_object *device_data_obj = NULL;
+	struct json_object *device_data_obj = NULL, *bus_data_obj = NULL;
 	switch (dev->bustype) {
 	case DRM_BUS_PCI:;
-		drmPciDeviceInfo *pci = dev->deviceinfo.pci;
+		drmPciDeviceInfo *pci_dev = dev->deviceinfo.pci;
+		drmPciBusInfo *pci_bus = dev->businfo.pci;
+
 		device_data_obj = json_object_new_object();
 		json_object_object_add(device_data_obj, "vendor",
-			json_object_new_uint64(pci->vendor_id));
+			json_object_new_uint64(pci_dev->vendor_id));
 		json_object_object_add(device_data_obj, "device",
-			json_object_new_uint64(pci->device_id));
+			json_object_new_uint64(pci_dev->device_id));
 		json_object_object_add(device_data_obj, "subsystem_vendor",
-			json_object_new_uint64(pci->subvendor_id));
+			json_object_new_uint64(pci_dev->subvendor_id));
 		json_object_object_add(device_data_obj, "subsystem_device",
-			json_object_new_uint64(pci->subdevice_id));
+			json_object_new_uint64(pci_dev->subdevice_id));
+
+		bus_data_obj = json_object_new_object();
+		json_object_object_add(bus_data_obj, "domain",
+			json_object_new_uint64(pci_bus->domain));
+		json_object_object_add(bus_data_obj, "bus",
+			json_object_new_uint64(pci_bus->bus));
+		json_object_object_add(bus_data_obj, "slot",
+			json_object_new_uint64(pci_bus->dev));
+		json_object_object_add(bus_data_obj, "function",
+			json_object_new_uint64(pci_bus->func));
 		break;
 	case DRM_BUS_USB:;
-		drmUsbDeviceInfo *usb = dev->deviceinfo.usb;
+		drmUsbDeviceInfo *usb_dev = dev->deviceinfo.usb;
+		drmUsbBusInfo *usb_bus = dev->businfo.usb;
+
 		device_data_obj = json_object_new_object();
 		json_object_object_add(device_data_obj, "vendor",
-			json_object_new_uint64(usb->vendor));
+			json_object_new_uint64(usb_dev->vendor));
 		json_object_object_add(device_data_obj, "product",
-			json_object_new_uint64(usb->product));
+			json_object_new_uint64(usb_dev->product));
+
+		bus_data_obj = json_object_new_object();
+		json_object_object_add(bus_data_obj, "bus",
+			json_object_new_uint64(usb_bus->bus));
+		json_object_object_add(bus_data_obj, "device",
+			json_object_new_uint64(usb_bus->dev));
 		break;
 	case DRM_BUS_PLATFORM:;
-		drmPlatformDeviceInfo *platform = dev->deviceinfo.platform;
+		drmPlatformDeviceInfo *platform_dev = dev->deviceinfo.platform;
+		drmPlatformBusInfo *platform_bus = dev->businfo.platform;
+
 		device_data_obj = json_object_new_object();
 		struct json_object *compatible_arr = json_object_new_array();
-		for (size_t i = 0; platform->compatible[i]; ++i)
+		for (size_t i = 0; platform_dev->compatible[i]; ++i)
 			json_object_array_add(compatible_arr,
-				json_object_new_string(platform->compatible[i]));
+				json_object_new_string(platform_dev->compatible[i]));
 		json_object_object_add(device_data_obj, "compatible", compatible_arr);
+
+		bus_data_obj = json_object_new_object();
+		json_object_object_add(bus_data_obj, "fullname",
+			json_object_new_string(platform_bus->fullname));
 		break;
 	}
 	json_object_object_add(obj, "device_data", device_data_obj);
+	json_object_object_add(obj, "bus_data", bus_data_obj);
 
 	drmFreeDevice(&dev);
 
@@ -288,6 +316,69 @@ static struct json_object *path_info(int fd, uint32_t blob_id)
 	return obj;
 }
 
+static struct json_object *hdr_output_metadata_info(int fd, uint32_t blob_id)
+{
+	drmModePropertyBlobRes *blob = drmModeGetPropertyBlob(fd, blob_id);
+	if (!blob) {
+		perror("drmModeGetPropertyBlob");
+		return NULL;
+	}
+
+	struct json_object *obj = NULL;
+
+	// The type field in the struct comes first and is an u32
+	if (blob->length < sizeof(uint32_t)) {
+		fprintf(stderr, "HDR output metadata blob too short\n");
+		goto exit;
+	}
+
+	const struct hdr_output_metadata *meta = blob->data;
+
+	obj = json_object_new_object();
+	json_object_object_add(obj, "type", json_object_new_uint64(meta->metadata_type));
+
+	if (meta->metadata_type == HDMI_STATIC_METADATA_TYPE1) {
+		const size_t min_size = offsetof(struct hdr_output_metadata, hdmi_metadata_type1)
+			+ sizeof(struct hdr_metadata_infoframe);
+		if (blob->length < min_size) {
+			fprintf(stderr, "HDR output metadata blob too short\n");
+			goto exit;
+		}
+
+		const struct hdr_metadata_infoframe *info = &meta->hdmi_metadata_type1;
+		json_object_object_add(obj, "eotf", json_object_new_int(info->eotf));
+		// TODO: maybe add info->metadata_type, but seems to be the same as
+		// meta->metadata_type?
+		struct json_object *dp_obj = json_object_new_object();
+		static const char *dp_keys[] = {"r", "g", "b"};
+		for (size_t i = 0; i < 3; i++) {
+			struct json_object *coord_obj = json_object_new_object();
+			json_object_object_add(coord_obj, "x",
+				json_object_new_double(info->display_primaries[i].x / 50000.0));
+			json_object_object_add(coord_obj, "y",
+				json_object_new_double(info->display_primaries[i].y / 50000.0));
+			json_object_object_add(dp_obj, dp_keys[i], coord_obj);
+		}
+		json_object_object_add(obj, "display_primaries", dp_obj);
+		struct json_object *coord_obj = json_object_new_object();
+		json_object_object_add(coord_obj, "x",
+			json_object_new_double(info->white_point.x / 50000.0));
+		json_object_object_add(coord_obj, "y",
+			json_object_new_double(info->white_point.y / 50000.0));
+		json_object_object_add(obj, "white_point", coord_obj);
+		json_object_object_add(obj, "max_display_mastering_luminance",
+			json_object_new_int(info->max_display_mastering_luminance));
+		json_object_object_add(obj, "min_display_mastering_luminance",
+			json_object_new_double(info->min_display_mastering_luminance / 10000.0));
+		json_object_object_add(obj, "max_cll", json_object_new_int(info->max_cll));
+		json_object_object_add(obj, "max_fall", json_object_new_int(info->max_fall));
+	}
+
+exit:
+	drmModeFreePropertyBlob(blob);
+	return obj;
+}
+
 static struct json_object *fb_info(int fd, uint32_t id)
 {
 #ifdef HAVE_GETFB2
@@ -456,6 +547,8 @@ static struct json_object *properties_info(int fd, uint32_t id, uint32_t type)
 				data_obj = writeback_pixel_formats_info(fd, value);
 			} else if (strcmp(prop->name, "PATH") == 0) {
 				data_obj = path_info(fd, value);
+			} else if (strcmp(prop->name, "HDR_OUTPUT_METADATA") == 0) {
+				data_obj = hdr_output_metadata_info(fd, value);
 			}
 			break;
 		case DRM_MODE_PROP_RANGE:
diff --git a/meson.build b/meson.build
index 6245dbc..1943e4c 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
 project('drm_info', 'c',
-  version: '2.4.0',
+  version: '2.5.0',
   license: 'MIT',
   meson_version: '>=0.49.0',
   default_options: [
@@ -34,14 +34,13 @@ libdrm = dependency('libdrm',
   ],
 )
 
-inc = []
 # libdrm pretty consistently pulls in the linux userspace API headers.
 # We want a new libdrm to get all of the #defines in those headers, but
 # we don't actually need to link against a new version of libdrm itself.
 #
 # We need to make sure we don't use any new libdrm functions, but those
 # are added very infrequently, so this is unlikely to be an issue.
-if libdrm.version().version_compare('<2.4.113')
+if libdrm.version().version_compare('<2.4.115')
   if libdrm.type_name() == 'internal'
     error('libdrm subproject out of date. Run `meson subprojects update`.')
   endif
@@ -55,13 +54,15 @@ if libdrm.version().version_compare('<2.4.113')
     warning(s)
   endforeach
 
+  # Sadly we need to circumvent Meson's sandbox here. There is no other way to
+  # link to the system libdrm *and* use drm_fourcc.h from the subproject.
   fourcc_h = meson.current_source_dir() / 'subprojects/libdrm/include/drm/drm_fourcc.h'
-  inc += include_directories('subprojects/libdrm/include/drm')
+  add_project_arguments('-I' + meson.current_source_dir() / 'subprojects/libdrm/include/drm', language: 'c')
   libdrm = libdrm.partial_dependency(link_args: true)
 elif libdrm.type_name() == 'internal'
   fourcc_h = meson.current_source_dir() / 'subprojects/libdrm/include/drm/drm_fourcc.h'
 else
-  fourcc_h = libdrm.get_pkgconfig_variable('includedir') / 'libdrm/drm_fourcc.h'
+  fourcc_h = libdrm.get_pkgconfig_variable('pc_sysrootdir') + libdrm.get_pkgconfig_variable('includedir') / 'libdrm/drm_fourcc.h'
 endif
 
 if libpci.found()
@@ -80,7 +81,6 @@ tables_c = custom_target('tables_c',
 
 executable('drm_info',
   ['main.c', 'modifiers.c', 'json.c', 'pretty.c', tables_c],
-  include_directories: inc,
   dependencies: [libdrm, libpci, jsonc],
   install: true,
 )
diff --git a/modifiers.c b/modifiers.c
index dab1fac..8cede2a 100644
--- a/modifiers.c
+++ b/modifiers.c
@@ -30,12 +30,16 @@ static const char *amd_tile_version_str(uint64_t tile_version) {
 		return "GFX10";
 	case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
 		return "GFX10_RBPLUS";
+	case AMD_FMT_MOD_TILE_VER_GFX11:
+		return "GFX11";
 	}
-	return "Unknown";
+	return "unknown";
 }
 
 static const char *amd_tile_str(uint64_t tile, uint64_t tile_version) {
 	switch (tile_version) {
+	case AMD_FMT_MOD_TILE_VER_GFX11:
+		/* fallthrough */
 	case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
 		/* fallthrough */
 	case AMD_FMT_MOD_TILE_VER_GFX10:
@@ -52,9 +56,11 @@ static const char *amd_tile_str(uint64_t tile, uint64_t tile_version) {
 			return "GFX9_64K_D_X";
 		case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
 			return "GFX9_64K_R_X";
+		case AMD_FMT_MOD_TILE_GFX11_256K_R_X:
+			return "GFX11_256K_R_X";
 		}
 	}
-	return "Unknown";
+	return "unknown";
 }
 
 static const char *amd_dcc_block_size_str(uint64_t size) {
@@ -66,7 +72,7 @@ static const char *amd_dcc_block_size_str(uint64_t size) {
 	case AMD_FMT_MOD_DCC_BLOCK_256B:
 		return "256B";
 	}
-	return "Unknown";
+	return "unknown";
 }
 
 static bool amd_gfx9_tile_is_x_t(uint64_t tile) {
@@ -142,7 +148,7 @@ static const char *arm_afbc_block_size_str(uint64_t block_size) {
 	case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
 		return "32x8_64x4";
 	}
-	return "Unknown";
+	return "unknown";
 }
 
 static const char *arm_afrc_cu_size_str(uint64_t cu_size) {
@@ -154,7 +160,7 @@ static const char *arm_afrc_cu_size_str(uint64_t cu_size) {
 	case AFRC_FORMAT_MOD_CU_SIZE_32:
 		return "32";
 	}
-	return "Unknown";
+	return "unknown";
 }
 
 static void print_arm_modifier(uint64_t mod) {
@@ -227,7 +233,7 @@ static const char *amlogic_layout_str(uint64_t layout) {
 	case AMLOGIC_FBC_LAYOUT_SCATTER:
 		return "SCATTER";
 	}
-	return "Unknown";
+	return "unknown";
 }
 
 static void print_amlogic_modifier(uint64_t mod) {
@@ -239,6 +245,59 @@ static void print_amlogic_modifier(uint64_t mod) {
 		(options & AMLOGIC_FBC_OPTION_MEM_SAVING) ? "MEM_SAVING" : "0");
 }
 
+static const char *vivante_color_tiling_str(uint64_t tiling) {
+	switch (tiling) {
+	case 0:
+		return "LINEAR";
+	case DRM_FORMAT_MOD_VIVANTE_TILED:
+		return "TILED";
+	case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
+		return "SUPER_TILED";
+	case DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED:
+		return "SPLIT_TILED";
+	case DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED:
+		return "SPLIT_SUPER_TILED";
+	}
+	return "Unknown";
+}
+
+static const char *vivante_tile_status_str(uint64_t ts) {
+	switch (ts) {
+	case VIVANTE_MOD_TS_64_4:
+		return "64_4";
+	case VIVANTE_MOD_TS_64_2:
+		return "64_2";
+	case VIVANTE_MOD_TS_128_4:
+		return "128_4";
+	case VIVANTE_MOD_TS_256_4:
+		return "256_4";
+	}
+	return "Unknown";
+}
+
+static const char *vivante_compression_str(uint64_t comp) {
+	switch (comp) {
+	case VIVANTE_MOD_COMP_DEC400:
+		return "DEC400";
+	}
+	return "Unknown";
+}
+
+static void print_vivante_modifier(uint64_t mod) {
+	uint64_t ts = mod & VIVANTE_MOD_TS_MASK;
+	uint64_t comp = mod & VIVANTE_MOD_COMP_MASK;
+	uint64_t tiling = mod & ~VIVANTE_MOD_EXT_MASK;
+
+	printf("VIVANTE(tiling = %s", vivante_color_tiling_str(tiling));
+	if (ts != 0) {
+		printf(", ts = %s", vivante_tile_status_str(ts));
+	}
+	if (comp != 0) {
+		printf(", comp = %s", vivante_compression_str(comp));
+	}
+	printf(")");
+}
+
 static uint8_t mod_vendor(uint64_t mod) {
 	return (uint8_t)(mod >> 56);
 }
@@ -257,6 +316,9 @@ void print_modifier(uint64_t mod) {
 	case DRM_FORMAT_MOD_VENDOR_AMLOGIC:
 		print_amlogic_modifier(mod);
 		break;
+	case DRM_FORMAT_MOD_VENDOR_VIVANTE:
+		print_vivante_modifier(mod);
+		break;
 	default:
 		printf("%s", basic_modifier_str(mod));
 	}
diff --git a/pretty.c b/pretty.c
index b344ae5..4c7a5af 100644
--- a/pretty.c
+++ b/pretty.c
@@ -40,6 +40,16 @@ static uint64_t get_object_object_uint64(struct json_object *obj,
 	return json_object_get_uint64(uint64_obj);
 }
 
+static double get_object_object_double(struct json_object *obj,
+		const char *key)
+{
+	struct json_object *double_obj = json_object_object_get(obj, key);
+	if (!double_obj) {
+		return 0;
+	}
+	return json_object_get_double(double_obj);
+}
+
 static void print_driver(struct json_object *obj)
 {
 	const char *name = get_object_object_string(obj, "name");
@@ -367,6 +377,66 @@ static void print_path(struct json_object *obj, const char *prefix)
 	printf("%s" L_LAST "%s\n", prefix, json_object_get_string(obj));
 }
 
+static void print_hdr_output_metadata(struct json_object *obj,
+		const char *prefix)
+{
+	int type = get_object_object_uint64(obj, "type");
+
+	if (type != HDMI_STATIC_METADATA_TYPE1) {
+		printf("%s" L_LAST "Type: Reserved (%d)\n", prefix, type);
+		return;
+	}
+	printf("%s" L_VAL "Type: Static Metadata Type 1\n", prefix);
+
+	int eotf = get_object_object_uint64(obj, "eotf");
+	printf("%s" L_VAL "EOTF: ", prefix);
+	switch (eotf) {
+	case CTA_EOTF_TRADITIONAL_SDR:
+		printf("Traditional gamma - SDR");
+		break;
+	case CTA_EOTF_TRADITIONAL_HDR:
+		printf("Traditional gamma - HDR");
+		break;
+	case CTA_EOTF_SMPTE_2084:
+		printf("SMPTE ST 2084 (PQ)");
+		break;
+	case CTA_EOTF_HLG:
+		printf("HLG");
+		break;
+	default:
+		printf("Reserved (%d)", eotf);
+		break;
+	}
+	printf("\n");
+
+	struct json_object *dp_obj = json_object_object_get(obj, "display_primaries");
+	static const char *dp_keys[] = {"r", "g", "b"};
+	static const char *dp_names[] = {"Red", "Green", "Blue"};
+	printf("%s" L_VAL "Display primaries:\n", prefix);
+	for (size_t i = 0; i < 3; i++) {
+		struct json_object *coord_obj = json_object_object_get(dp_obj, dp_keys[i]);
+		printf("%s" L_LINE "%s%s: ", prefix, i == 2 ? L_LAST : L_VAL, dp_names[i]);
+		printf("(%.4f, %.4f)\n",
+			get_object_object_double(coord_obj, "x"),
+			get_object_object_double(coord_obj, "y"));
+	}
+
+	struct json_object *wp_obj = json_object_object_get(obj, "white_point");
+	printf("%s" L_VAL "White point: ", prefix);
+	printf("(%.4f, %.4f)\n",
+		get_object_object_double(wp_obj, "x"),
+		get_object_object_double(wp_obj, "y"));
+
+	printf("%s" L_VAL "Max display mastering luminance: %d cd/m²\n", prefix,
+		(int) get_object_object_uint64(obj, "max_display_mastering_luminance"));
+	printf("%s" L_VAL "Min display mastering luminance: %.4f cd/m²\n", prefix,
+		get_object_object_double(obj, "min_display_mastering_luminance"));
+	printf("%s" L_VAL "Max content light level: %d cd/m²\n", prefix,
+		(int) get_object_object_uint64(obj, "max_cll"));
+	printf("%s" L_LAST "Max frame average light level: %d cd/m²\n", prefix,
+		(int) get_object_object_uint64(obj, "max_fall"));
+}
+
 static void print_fb(struct json_object *obj, const char *prefix)
 {
 	uint32_t id = get_object_object_uint64(obj, "id");
@@ -517,6 +587,8 @@ static void print_properties(struct json_object *obj, const char *prefix)
 				print_writeback_pixel_formats(data_obj, sub_prefix);
 			else if (strcmp(prop_name, "PATH") == 0)
 				print_path(data_obj, sub_prefix);
+			else if (strcmp(prop_name, "HDR_OUTPUT_METADATA") == 0)
+				print_hdr_output_metadata(data_obj, sub_prefix);
 			break;
 		case DRM_MODE_PROP_BITMASK:
 			printf("bitmask {");
diff --git a/subprojects/libdrm.wrap b/subprojects/libdrm.wrap
index bea08f2..5b42d38 100644
--- a/subprojects/libdrm.wrap
+++ b/subprojects/libdrm.wrap
@@ -1,4 +1,4 @@
 [wrap-git]
 url = https://gitlab.freedesktop.org/mesa/drm.git
-revision = libdrm-2.4.113
+revision = libdrm-2.4.115
 depth = 1

More details

Full run details

Historical runs