* [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