public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH i-g-t v2 0/2] RFC: Add modifier helper and temporary test
@ 2026-04-01 15:25 Jeevan B
  0 siblings, 0 replies; 4+ messages in thread
From: Jeevan B @ 2026-04-01 15:25 UTC (permalink / raw)
  To: igt-dev; +Cc: uma.shankar, jani.nikula, Jeevan B

This series adds a new helper for querying driver-supported format
modifiers and a temporary test to verify that the helper outputs the
expected modifier list.

Jeevan B (2):
  lib: Add modifier helper for querying driver-supported modifiers
  DONT_MERGE: Add kms_modifier_list test to verify new modifier helper

 lib/igt_modifier.c        | 242 ++++++++++++++++++++++++++++++++++++++
 lib/igt_modifier.h        |  18 +++
 lib/meson.build           |   1 +
 tests/kms_modifier_list.c | 127 ++++++++++++++++++++
 tests/meson.build         |   1 +
 5 files changed, 389 insertions(+)
 create mode 100644 lib/igt_modifier.c
 create mode 100644 lib/igt_modifier.h
 create mode 100644 tests/kms_modifier_list.c

-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH i-g-t v2 0/2] RFC: Add modifier helper and temporary test
@ 2026-04-01 15:31 Jeevan B
  2026-04-01 15:31 ` [PATCH i-g-t v2 1/2] lib: Add modifier helper for querying driver-supported modifiers Jeevan B
  2026-04-01 15:31 ` [PATCH i-g-t v2 2/2] DONT_MERGE: Add kms_modifier_list test to verify new modifier helper Jeevan B
  0 siblings, 2 replies; 4+ messages in thread
From: Jeevan B @ 2026-04-01 15:31 UTC (permalink / raw)
  To: igt-dev; +Cc: uma.shankar, jani.nikula, Jeevan B

This series adds a new helper for querying driver-supported format
modifiers and a temporary test to verify that the helper outputs the
expected modifier list.

Jeevan B (2):
  lib: Add modifier helper for querying driver-supported modifiers
  DONT_MERGE: Add kms_modifier_list test to verify new modifier helper

 lib/igt_modifier.c        | 242 ++++++++++++++++++++++++++++++++++++++
 lib/igt_modifier.h        |  18 +++
 lib/meson.build           |   1 +
 tests/kms_modifier_list.c | 127 ++++++++++++++++++++
 tests/meson.build         |   1 +
 5 files changed, 389 insertions(+)
 create mode 100644 lib/igt_modifier.c
 create mode 100644 lib/igt_modifier.h
 create mode 100644 tests/kms_modifier_list.c

-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH i-g-t v2 1/2] lib: Add modifier helper for querying driver-supported modifiers
  2026-04-01 15:31 [PATCH i-g-t v2 0/2] RFC: Add modifier helper and temporary test Jeevan B
@ 2026-04-01 15:31 ` Jeevan B
  2026-04-01 15:31 ` [PATCH i-g-t v2 2/2] DONT_MERGE: Add kms_modifier_list test to verify new modifier helper Jeevan B
  1 sibling, 0 replies; 4+ messages in thread
From: Jeevan B @ 2026-04-01 15:31 UTC (permalink / raw)
  To: igt-dev; +Cc: uma.shankar, jani.nikula, Jeevan B

Introduce a new helper library that collects DRM format modifiers
reported by KMS planes via the IN_FORMATS property. Two functions are
added:

 - igt_get_all_supported_modifiers()
 - igt_get_basic_tiling_modifiers()

These helpers return unique modifier lists for a given format and will
be used by modifier-related tests.

v2: Update license headers, removes unnecessary inline usage,
    standardizes loops to use int, drops unused casts, introduces
    a small struct to manage modifier lists more cleanly, improves
    allocation handling, simplifies the basic modifier selection
    logic, and update coding‑style improvements.

Signed-off-by: Jeevan B <jeevan.b@intel.com>
---
 lib/igt_modifier.c | 242 +++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_modifier.h |  18 ++++
 lib/meson.build    |   1 +
 3 files changed, 261 insertions(+)
 create mode 100644 lib/igt_modifier.c
 create mode 100644 lib/igt_modifier.h

diff --git a/lib/igt_modifier.c b/lib/igt_modifier.c
new file mode 100644
index 000000000..02f3f6ce3
--- /dev/null
+++ b/lib/igt_modifier.c
@@ -0,0 +1,242 @@
+/* SPDX-License-Identifier: MIT */
+
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <drm_fourcc.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include "igt_modifier.h"
+#include "igt_core.h"
+#include "drmtest.h"
+
+/*
+ * Modifier array with dynamic allocation.
+ */
+struct modifiers {
+	uint64_t *array;
+	int nelems;
+	int alloc;
+};
+
+static void modifiers_init(struct modifiers *m)
+{
+	m->array = NULL;
+	m->nelems = 0;
+	m->alloc = 0;
+}
+
+static bool modifiers_contains(const struct modifiers *m, uint64_t val)
+{
+	for (int i = 0; i < m->nelems; i++)
+		if (m->array[i] == val)
+			return true;
+	return false;
+}
+
+static void modifiers_append_unique(struct modifiers *m, uint64_t val)
+{
+	if (modifiers_contains(m, val))
+		return;
+
+	if (m->nelems == m->alloc) {
+		int new_alloc = m->alloc ? m->alloc * 2 : 8;
+		m->array = realloc(m->array, new_alloc * sizeof(uint64_t));
+		igt_assert(m->array);
+
+		m->alloc = new_alloc;
+	}
+
+	m->array[m->nelems++] = val;
+}
+
+static void modifiers_finalize(struct modifiers *m, uint64_t **out, int *count)
+{
+	*out = m->array;
+	*count = m->nelems;
+}
+
+
+static const uint32_t *
+blob_formats_ptr(const struct drm_format_modifier_blob *blob)
+{
+	return (const uint32_t *)((const char *)blob + blob->formats_offset);
+}
+
+static const struct drm_format_modifier *
+blob_modifiers_ptr(const struct drm_format_modifier_blob *blob)
+{
+	return (const struct drm_format_modifier *)
+		((const char *)blob + blob->modifiers_offset);
+}
+
+static void collect_modifiers_from_blob(struct modifiers *m,
+		const struct drm_format_modifier_blob *blob,
+		uint32_t format)
+{
+	const uint32_t *formats = blob_formats_ptr(blob);
+	const struct drm_format_modifier *mods = blob_modifiers_ptr(blob);
+
+	int fmt_idx = -1, i;
+
+	for (i = 0; i < blob->count_formats; i++) {
+		if (formats[i] == format) {
+			fmt_idx = i;
+			break;
+		}
+	}
+
+	if (fmt_idx < 0)
+		return;
+
+	for (i = 0; i < blob->count_modifiers; i++) {
+		const struct drm_format_modifier *entry = &mods[i];
+		int rel = fmt_idx - entry->offset;
+
+		if (rel < 0 || rel >= 64)
+			continue;
+
+		if (entry->formats & (1ULL << rel))
+			modifiers_append_unique(m, entry->modifier);
+	}
+}
+
+static int query_plane_modifiers(int drm_fd, uint32_t format,
+				 uint64_t **out)
+{
+	struct modifiers mods;
+	drmModePlaneResPtr pres;
+
+	modifiers_init(&mods);
+
+	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+
+	pres = drmModeGetPlaneResources(drm_fd);
+	if (!pres)
+		goto fallback;
+
+	for (int i = 0; i < pres->count_planes; i++) {
+		drmModePlanePtr p;
+		drmModeObjectPropertiesPtr props;
+		drmModePropertyBlobPtr blob;
+		bool supported;
+		int f, j;
+
+		p = drmModeGetPlane(drm_fd, pres->planes[i]);
+		if (!p)
+			continue;
+
+		supported = false;
+
+		for (f = 0; f < p->count_formats; f++) {
+			if (p->formats[f] == format) {
+				supported = true;
+				break;
+			}
+		}
+
+		if (!supported) {
+			drmModeFreePlane(p);
+			continue;
+		}
+
+		props =	drmModeObjectGetProperties(drm_fd, p->plane_id,
+						   DRM_MODE_OBJECT_PLANE);
+
+		blob = NULL;
+
+		if (props) {
+			for ( j = 0; j < props->count_props; j++) {
+				drmModePropertyPtr prop =
+					drmModeGetProperty(drm_fd, props->props[j]);
+				if (!prop)
+					continue;
+
+				if (!strcmp(prop->name, "IN_FORMATS") &&
+				    drm_property_type_is(prop, DRM_MODE_PROP_BLOB) &&
+				    props->prop_values[j] != 0) {
+					blob = drmModeGetPropertyBlob(
+							drm_fd, props->prop_values[j]);
+				}
+
+				drmModeFreeProperty(prop);
+
+				if (blob)
+					break;
+			}
+			drmModeFreeObjectProperties(props);
+		}
+
+		if (blob) {
+			const struct drm_format_modifier_blob *b =
+				(const struct drm_format_modifier_blob *)blob->data;
+
+			collect_modifiers_from_blob(&mods, b, format);
+			drmModeFreePropertyBlob(blob);
+		} else {
+			modifiers_append_unique(&mods, DRM_FORMAT_MOD_LINEAR);
+		}
+
+		drmModeFreePlane(p);
+	}
+
+	drmModeFreePlaneResources(pres);
+
+fallback:
+	int count;
+
+	if (mods.nelems == 0)
+		modifiers_append_unique(&mods, DRM_FORMAT_MOD_LINEAR);
+
+	modifiers_finalize(&mods, out, &count);
+	return count;
+}
+
+int igt_get_all_supported_modifiers(int drm_fd, uint32_t format,
+				    uint64_t **modifiers_out)
+{
+	igt_assert(modifiers_out);
+	return query_plane_modifiers(drm_fd, format, modifiers_out);
+}
+
+static const uint64_t basic_mods[] = {
+	DRM_FORMAT_MOD_LINEAR,
+	I915_FORMAT_MOD_X_TILED,
+	I915_FORMAT_MOD_Y_TILED,
+	I915_FORMAT_MOD_4_TILED,
+};
+
+int igt_get_basic_tiling_modifiers(int drm_fd, uint32_t format,
+				   uint64_t **modifiers_out)
+{
+	uint64_t *all = NULL;
+	int all_count = query_plane_modifiers(drm_fd, format, &all);
+	int count;
+
+	struct modifiers out;
+	modifiers_init(&out);
+
+	for (int i = 0; i < all_count; i++) {
+		for (int j = 0; j < (sizeof(basic_mods)/sizeof(basic_mods[0])); j++) {
+			if (all[i] == basic_mods[j]) {
+				modifiers_append_unique(&out, all[i]);
+				break;
+			}
+		}
+	}
+
+	free(all);
+
+	if (out.nelems == 0)
+		modifiers_append_unique(&out, DRM_FORMAT_MOD_LINEAR);
+
+	modifiers_finalize(&out, modifiers_out, &count);
+	return count;
+}
diff --git a/lib/igt_modifier.h b/lib/igt_modifier.h
new file mode 100644
index 000000000..069ea334a
--- /dev/null
+++ b/lib/igt_modifier.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: MIT */
+
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#ifndef __IGT_MODIFIER_H__
+#define __IGT_MODIFIER_H__
+
+#include <stdint.h>
+
+int igt_get_all_supported_modifiers(int drm_fd, uint32_t format,
+				    uint64_t **modifiers_out);
+
+int igt_get_basic_tiling_modifiers(int drm_fd, uint32_t format,
+				   uint64_t **modifiers_out);
+
+#endif /* __IGT_MODIFIER_H__ */
diff --git a/lib/meson.build b/lib/meson.build
index 5c4829345..ca2867eed 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -99,6 +99,7 @@ lib_sources = [
 	'igt_draw.c',
 	'igt_list.c',
 	'igt_map.c',
+        'igt_modifier.c',
 	'igt_panel.c',
 	'igt_pm.c',
 	'igt_dummyload.c',
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH i-g-t v2 2/2] DONT_MERGE: Add kms_modifier_list test to verify new modifier helper
  2026-04-01 15:31 [PATCH i-g-t v2 0/2] RFC: Add modifier helper and temporary test Jeevan B
  2026-04-01 15:31 ` [PATCH i-g-t v2 1/2] lib: Add modifier helper for querying driver-supported modifiers Jeevan B
@ 2026-04-01 15:31 ` Jeevan B
  1 sibling, 0 replies; 4+ messages in thread
From: Jeevan B @ 2026-04-01 15:31 UTC (permalink / raw)
  To: igt-dev; +Cc: uma.shankar, jani.nikula, Jeevan B

Temporary test to check that the new lib modifier functions work and
print all supported modifiers.

Signed-off-by: Jeevan B <jeevan.b@intel.com>
---
 tests/kms_modifier_list.c | 127 ++++++++++++++++++++++++++++++++++++++
 tests/meson.build         |   1 +
 2 files changed, 128 insertions(+)
 create mode 100644 tests/kms_modifier_list.c

diff --git a/tests/kms_modifier_list.c b/tests/kms_modifier_list.c
new file mode 100644
index 000000000..2e203855c
--- /dev/null
+++ b/tests/kms_modifier_list.c
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: MIT */
+
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#include "igt.h"
+#include "igt_modifier.h"
+#include <drm_fourcc.h>
+#include <inttypes.h>
+
+IGT_TEST_DESCRIPTION("Validate igt_get_basic_tiling_modifiers() and "
+                     "igt_get_all_supported_modifiers().");
+
+/**
+ * TEST: kms modifier list
+ * Category: Display
+ * Description: Validate the igt_get_basic_tiling_modifiers() and
+ *              igt_get_all_supported_modifiers() helper functions.
+ * Driver requirement: i915, xe
+ * Mega feature: General Display Features
+ */
+
+/**
+ * SUBTEST: basic-modifiers-nonempty
+ * Description: Verify that igt_get_basic_tiling_modifiers() returns a
+ *              non-empty list for DRM_FORMAT_XRGB8888.
+ *
+ * SUBTEST: all-modifiers-nonempty
+ * Description: Verify that igt_get_all_supported_modifiers() returns a
+ *              non-empty list for DRM_FORMAT_XRGB8888.
+ *
+ * SUBTEST: basic-subset-of-all
+ * Description: Verify that every modifier in the basic list is also present
+ *              in the all-modifiers list.
+ */
+
+static int drm_fd;
+static igt_display_t display;
+
+int igt_main()
+{
+	igt_fixture() {
+		drm_fd = drm_open_driver_master(DRIVER_ANY);
+		igt_display_require(&display, drm_fd);
+	}
+
+	igt_subtest("basic-modifiers-nonempty") {
+		uint64_t *mods = NULL;
+		int count;
+
+		count = igt_get_basic_tiling_modifiers(drm_fd,
+						       DRM_FORMAT_XRGB8888,
+						       &mods);
+		igt_assert_f(count > 0,
+			     "igt_get_basic_tiling_modifiers() returned empty list\n");
+
+		igt_info("Basic modifiers (%d):\n", count);
+		for (int i = 0; i < count; i++) {
+			const char *name = igt_fb_modifier_name(mods[i]);
+			igt_info("  [basic] 0x%" PRIx64 " (%s)\n", mods[i], name);
+		}
+		free(mods);
+	}
+
+	igt_subtest("all-modifiers-nonempty") {
+		uint64_t *mods = NULL;
+		int count;
+
+		count = igt_get_all_supported_modifiers(drm_fd,
+							DRM_FORMAT_XRGB8888,
+							&mods);
+		igt_assert_f(count > 0,
+			     "igt_get_all_supported_modifiers() returned empty list\n");
+
+		igt_info("All supported modifiers (%d):\n", count);
+		for (int i = 0; i < count; i++) {
+			const char *name = igt_fb_modifier_name(mods[i]);
+			igt_info("  [all] 0x%" PRIx64 " (%s)\n", mods[i], name);
+		}
+
+		free(mods);
+	}
+
+	igt_subtest("basic-subset-of-all") {
+		uint64_t *basic = NULL, *all = NULL;
+		int basic_count, all_count;
+
+		basic_count = igt_get_basic_tiling_modifiers(drm_fd,
+							     DRM_FORMAT_XRGB8888,
+							     &basic);
+		all_count = igt_get_all_supported_modifiers(drm_fd,
+							    DRM_FORMAT_XRGB8888,
+							    &all);
+
+		igt_assert(basic_count > 0);
+		igt_assert(all_count > 0);
+
+		igt_info("Checking: basic-subset-of-all\n");
+		for (int i = 0; i < basic_count; i++) {
+			bool found = false;
+			const char *name = igt_fb_modifier_name(basic[i]);
+
+			for (int j = 0; j < all_count; j++) {
+				if (basic[i] == all[j]) {
+					found = true;
+					break;
+				}
+			}
+
+			igt_info("  [basic] 0x%" PRIx64 " (%s) -> %s\n",
+				 basic[i], name, found ? "FOUND" : "NOT FOUND");
+
+			igt_assert_f(found,
+				     "basic modifier 0x%"PRIx64" not in all-modifiers list\n",
+				     basic[i]);
+		}
+
+		free(basic);
+		free(all);
+	}
+
+	igt_fixture() {
+		igt_display_fini(&display);
+		drm_close_driver(drm_fd);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index cecb4a8ae..348cb9c74 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -46,6 +46,7 @@ test_progs = [
 	'kms_hdr',
 	'kms_invalid_mode',
 	'kms_lease',
+        'kms_modifier_list',
 	'kms_multipipe_modeset',
 	'kms_panel_fitting',
 	'kms_pipe_crc_basic',
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-04-01 15:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-01 15:31 [PATCH i-g-t v2 0/2] RFC: Add modifier helper and temporary test Jeevan B
2026-04-01 15:31 ` [PATCH i-g-t v2 1/2] lib: Add modifier helper for querying driver-supported modifiers Jeevan B
2026-04-01 15:31 ` [PATCH i-g-t v2 2/2] DONT_MERGE: Add kms_modifier_list test to verify new modifier helper Jeevan B
  -- strict thread matches above, loose matches on Subject: below --
2026-04-01 15:25 [PATCH i-g-t v2 0/2] RFC: Add modifier helper and temporary test Jeevan B

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox