[igt-dev] [RFC PATCH v2 3/8] lib/igt_kms: Introduce drm_colorop object

Harry Wentland harry.wentland at amd.com
Thu Oct 19 21:22:56 UTC 2023


We've introduced a new drm_colorop object in DRM. These are
used to make up a color pipeline. Introduce the concept of
this new DRM core object to IGT, including:
 - discovery of drm_colorop objects during init
 - various helper functions for deaing with drm_colorops
 - handling drm_colorops in atomic commit

v2:
 - Iterate through all next drm_colorop objects

Signed-off-by: Harry Wentland <harry.wentland at amd.com>
Cc: Ville Syrjala <ville.syrjala at linux.intel.com>
Cc: Pekka Paalanen <pekka.paalanen at collabora.com>
Cc: Simon Ser <contact at emersion.fr>
Cc: Harry Wentland <harry.wentland at amd.com>
Cc: Melissa Wen <mwen at igalia.com>
Cc: Jonas Ådahl <jadahl at redhat.com>
Cc: Sebastian Wick <sebastian.wick at redhat.com>
Cc: Shashank Sharma <shashank.sharma at amd.com>
Cc: Alexander Goins <agoins at nvidia.com>
Cc: Joshua Ashton <joshua at froggi.es>
Cc: Michel Dänzer <mdaenzer at redhat.com>
Cc: Aleix Pol <aleixpol at kde.org>
Cc: Xaver Hugl <xaver.hugl at gmail.com>
Cc: Victoria Brekenfeld <victoria at system76.com>
Cc: Sima <daniel at ffwll.ch>
Cc: Uma Shankar <uma.shankar at intel.com>
Cc: Naseer Ahmed <quic_naseer at quicinc.com>
Cc: Christopher Braga <quic_cbraga at quicinc.com>
Cc: Abhinav Kumar <quic_abhinavk at quicinc.com>
Cc: Arthur Grillo <arthurgrillo at riseup.net>
Cc: Hector Martin <marcan at marcan.st>
Cc: Liviu Dudau <Liviu.Dudau at arm.com>
Cc: Sasha McIntosh <sashamcintosh at google.com>
---
 lib/igt_kms.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++++-
 lib/igt_kms.h |  91 ++++++++++++++++++++++++
 2 files changed, 278 insertions(+), 2 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 53f9ff19ff95..cd36e778bae7 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -618,6 +618,13 @@ const char * const igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
 	[IGT_PLANE_SCALING_FILTER] = "SCALING_FILTER",
 };
 
+const char * const igt_colorop_prop_names[IGT_NUM_COLOROP_PROPS] = {
+	[IGT_COLOROP_TYPE] = "TYPE",
+	[IGT_COLOROP_BYPASS] = "BYPASS",
+	[IGT_COLOROP_CURVE_1D_TYPE] = "CURVE_1D_TYPE",
+	[IGT_COLOROP_NEXT] = "NEXT",
+};
+
 const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
 	[IGT_CRTC_CTM] = "CTM",
 	[IGT_CRTC_GAMMA_LUT] = "GAMMA_LUT",
@@ -683,6 +690,21 @@ igt_plane_rotations(igt_display_t *display, igt_plane_t *plane,
 	return rotations;
 }
 
+igt_colorop_t *igt_find_colorop(igt_display_t *display, uint32_t id)
+{
+	int i;
+
+	/* find corresponding igt_colorop */
+	for (i = 0; i < display->n_colorops; ++i) {
+		igt_colorop_t *colorop = &display->colorops[i];
+
+		if (colorop->drm_colorop->colorop_id == id)
+			return colorop;
+	}
+
+	return NULL;
+}
+
 /*
  * Retrieve all the properies specified in props_name and store them into
  * plane->props.
@@ -723,6 +745,40 @@ igt_fill_plane_props(igt_display_t *display, igt_plane_t *plane,
 	drmModeFreeObjectProperties(props);
 }
 
+/*
+ * Retrieve all the properies specified in props_name and store them into
+ * colorop->props.
+ */
+static void
+igt_fill_colorop_props(igt_display_t *display, igt_colorop_t *colorop,
+		       int num_props, const char * const prop_names[])
+{
+	drmModeObjectPropertiesPtr props;
+	int i, j, fd;
+
+	fd = display->drm_fd;
+
+	props = drmModeObjectGetProperties(fd, colorop->drm_colorop->colorop_id, DRM_MODE_OBJECT_COLOROP);
+	igt_assert(props);
+
+	for (i = 0; i < props->count_props; i++) {
+		drmModePropertyPtr prop =
+			drmModeGetProperty(fd, props->props[i]);
+
+		for (j = 0; j < num_props; j++) {
+			if (strcmp(prop->name, prop_names[j]) != 0)
+				continue;
+
+			colorop->props[j] = props->props[i];
+			break;
+		}
+
+		drmModeFreeProperty(prop);
+	}
+
+	drmModeFreeObjectProperties(props);
+}
+
 /*
  * Retrieve all the properies specified in props_name and store them into
  * config->atomic_props_crtc and config->atomic_props_connector.
@@ -2627,7 +2683,8 @@ void igt_display_require(igt_display_t *display, int drm_fd)
 {
 	drmModeRes *resources;
 	drmModePlaneRes *plane_resources;
-	int i;
+	drmModeColoropRes *colorop_resources;
+	int i, j;
 	bool is_intel_dev;
 
 	memset(display, 0, sizeof(igt_display_t));
@@ -2712,17 +2769,47 @@ void igt_display_require(igt_display_t *display, int drm_fd)
 
 	drmModeFreePlaneResources(plane_resources);
 
+	/* get all colorop resources */
+	colorop_resources = drmModeGetColoropResources(display->drm_fd);
+
+	if (colorop_resources) {
+		display->n_colorops = colorop_resources->count_colorops;
+		display->colorops = calloc(sizeof(igt_colorop_t), display->n_colorops);
+		igt_assert_f(display->colorops, "Failed to allocate memory for %d colorops\n", display->n_colorops);
+
+		for (i = 0; i < colorop_resources->count_colorops; ++i) {
+			igt_colorop_t *colorop = &display->colorops[i];
+			uint32_t id = colorop_resources->colorops[i];
+
+			colorop->drm_colorop = drmModeGetColorop(display->drm_fd, id);
+			igt_assert(colorop->drm_colorop);
+
+			igt_fill_colorop_props(display, colorop, IGT_NUM_COLOROP_PROPS, igt_colorop_prop_names);
+
+			for (j = 0; j < display->n_planes; ++j)
+				if (display->planes[j].drm_plane->plane_id == colorop->drm_colorop->plane_id)
+					colorop->plane = &display->planes[j];
+
+		}
+
+
+
+		drmModeFreeColoropResources(colorop_resources);
+	}
+
+
 	for_each_pipe(display, i) {
 		igt_pipe_t *pipe = &display->pipes[i];
 		igt_plane_t *plane;
 		int p = 1, crtc_mask = 0;
-		int j, type;
+		int type;
 		uint8_t last_plane = 0, n_planes = 0;
 
 		pipe->display = display;
 		pipe->plane_cursor = -1;
 		pipe->plane_primary = -1;
 		pipe->planes = NULL;
+		pipe->colorops = NULL;
 		pipe->num_primary_planes = 0;
 
 		igt_fill_pipe_props(display, pipe, IGT_NUM_CRTC_PROPS, igt_crtc_prop_names);
@@ -3000,6 +3087,15 @@ void igt_display_fini(igt_display_t *display)
 {
 	int i;
 
+	for (i = 0; i < display->n_colorops; ++i) {
+		igt_colorop_t *colorop = &display->colorops[i];
+
+		if (colorop->drm_colorop) {
+			drmModeFreeColorop(colorop->drm_colorop);
+			colorop->drm_colorop = NULL;
+		}
+	}
+
 	for (i = 0; i < display->n_planes; ++i) {
 		igt_plane_t *plane = &display->planes[i];
 
@@ -3335,6 +3431,48 @@ igt_atomic_prepare_plane_commit(igt_plane_t *plane, igt_pipe_t *pipe,
 	}
 }
 
+
+/*
+ * Add colorop properties
+ */
+static void
+igt_atomic_prepare_colorop_commit(igt_colorop_t *colorop, igt_pipe_t *pipe,
+	drmModeAtomicReq *req)
+{
+	igt_display_t *display = pipe->display;
+	int i, next_val;
+
+	while (colorop) {
+		igt_assert(colorop->drm_colorop);
+
+		LOG(display,
+		    "populating colorop data: %s.%d\n",
+		    kmstest_pipe_name(pipe->pipe),
+		    colorop->drm_colorop->colorop_id);
+
+		for (i = 0; i < IGT_NUM_COLOROP_PROPS; i++) {
+			if (!igt_colorop_is_prop_changed(colorop, i))
+				continue;
+
+			/* it's an error to try an unsupported feature */
+			igt_assert(colorop->props[i]);
+
+			igt_debug("colorop %s.%d: Setting property \"%s\" to 0x%"PRIx64"/%"PRIi64"\n",
+				kmstest_pipe_name(pipe->pipe), colorop->drm_colorop->colorop_id, igt_colorop_prop_names[i],
+				colorop->values[i], colorop->values[i]);
+
+			igt_assert_lt(0, drmModeAtomicAddProperty(req, colorop->drm_colorop->colorop_id,
+							colorop->props[i],
+							colorop->values[i]));
+		}
+
+		/* get next colorop */
+		next_val = igt_colorop_get_prop(display, colorop,
+						IGT_COLOROP_NEXT);
+		colorop = igt_find_colorop(display, next_val);
+	}
+}
+
 /*
  * Properties that can be changed through legacy SetProperty:
  * - Obviously not the XYWH SRC/CRTC coordinates.
@@ -3782,6 +3920,25 @@ uint64_t igt_plane_get_prop(igt_plane_t *plane, enum igt_atomic_plane_properties
 					plane->drm_plane->plane_id, plane->props[prop]);
 }
 
+/**
+ * igt_colorop_get_prop:
+ * @colorop: Target colorop.
+ * @prop: Property to check.
+ *
+ * Return current value on a colorop for a given property.
+ *
+ * Returns: The value the property is set to, if this
+ * is a blob, the blob id is returned. This can be passed
+ * to drmModeGetPropertyBlob() to get the contents of the blob.
+ */
+uint64_t igt_colorop_get_prop(igt_display_t *display, igt_colorop_t *colorop, enum igt_atomic_colorop_properties prop)
+{
+	igt_assert(igt_colorop_has_prop(colorop, prop));
+
+	return igt_mode_object_get_prop(display, DRM_MODE_OBJECT_COLOROP,
+					colorop->drm_colorop->colorop_id, colorop->props[prop]);
+}
+
 static bool igt_mode_object_get_prop_enum_value(int drm_fd, uint32_t id, const char *str, uint64_t *val)
 {
 	drmModePropertyPtr prop = drmModeGetProperty(drm_fd, id);
@@ -3824,6 +3981,34 @@ void igt_plane_set_prop_enum(igt_plane_t *plane,
 	igt_assert(igt_plane_try_prop_enum(plane, prop, val));
 }
 
+bool igt_colorop_try_prop_enum(igt_display_t *display,
+			       igt_colorop_t *colorop,
+			       enum igt_atomic_colorop_properties prop,
+			       const char *val)
+{
+	uint64_t uval;
+
+	igt_assert(colorop->props[prop]);
+
+	if (!igt_mode_object_get_prop_enum_value(display->drm_fd,
+						 colorop->props[prop], val, &uval))
+		return false;
+
+	igt_colorop_set_prop_value(colorop, prop, uval);
+	return true;
+}
+
+void igt_colorop_set_prop_enum(igt_display_t *display,
+			       igt_colorop_t *colorop,
+			       enum igt_atomic_colorop_properties prop,
+			       const char *val)
+{
+	bool result = false;
+	result = igt_colorop_try_prop_enum(display, colorop, prop, val);
+	igt_assert(result);
+}
+
+
 /**
  * igt_plane_replace_prop_blob:
  * @plane: plane to set property on.
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 356620dc688f..c6402979d10f 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -329,6 +329,19 @@ enum igt_atomic_plane_properties {
        IGT_NUM_PLANE_PROPS
 };
 
+enum igt_atomic_colorop_properties {
+	IGT_COLOROP_TYPE,
+	IGT_COLOROP_BYPASS,
+	IGT_COLOROP_CURVE_1D_TYPE,
+	IGT_COLOROP_NEXT,
+	IGT_NUM_COLOROP_PROPS
+};
+
+/* TODO move to libdrm header?? */
+enum drm_colorop_type {
+	DRM_COLOROP_1D_CURVE
+};
+
 /**
  * igt_plane_prop_names
  *
@@ -337,6 +350,14 @@ enum igt_atomic_plane_properties {
  */
 extern const char * const igt_plane_prop_names[];
 
+/**
+ * igt_colorop_prop_names
+ *
+ * igt_colorop_prop_names contains a list of colorop property names,
+ * as indexed by the igt_atomic_colorop_properties enum.
+ */
+extern const char * const igt_colorop_prop_names[];
+
 typedef struct igt_display igt_display_t;
 typedef struct igt_pipe igt_pipe_t;
 typedef uint32_t igt_fixed_t;			/* 16.16 fixed point */
@@ -359,6 +380,24 @@ static inline bool igt_rotation_90_or_270(igt_rotation_t rotation)
 	return rotation & (IGT_ROTATION_90 | IGT_ROTATION_270);
 }
 
+typedef struct igt_plane igt_plane_t;
+
+typedef struct igt_colorop {
+	/*< private >*/
+	igt_pipe_t *pipe;
+
+	drmModeColorop *drm_colorop;
+
+	igt_plane_t *plane;
+
+	char name[DRM_PROP_NAME_LEN];
+
+	uint64_t changed;
+	uint32_t props[IGT_NUM_COLOROP_PROPS];
+	uint64_t values[IGT_NUM_COLOROP_PROPS];
+
+} igt_colorop_t;
+
 typedef struct igt_plane {
 	/*< private >*/
 	igt_pipe_t *pipe;
@@ -412,6 +451,7 @@ struct igt_pipe {
 	int plane_cursor;
 	int plane_primary;
 	igt_plane_t *planes;
+	igt_colorop_t *colorops;
 
 	uint64_t changed;
 	uint32_t props[IGT_NUM_CRTC_PROPS];
@@ -450,9 +490,11 @@ struct igt_display {
 	int log_shift;
 	int n_pipes;
 	int n_planes;
+	int n_colorops;
 	int n_outputs;
 	igt_output_t *outputs;
 	igt_plane_t *planes;
+	igt_colorop_t *colorops;
 	igt_pipe_t *pipes;
 	bool has_cursor_plane;
 	bool is_atomic;
@@ -731,6 +773,53 @@ extern void igt_plane_set_prop_enum(igt_plane_t *plane,
 				    enum igt_atomic_plane_properties prop,
 				    const char *val);
 
+
+
+extern bool igt_plane_is_valid_colorop(igt_plane_t *plane, igt_colorop_t *colorop);
+
+/**
+ * igt_colorop_has_prop:
+ * @colorop: colorop to check.
+ * @prop: Property to check.
+ *
+ * Check whether colorop supports a given property.
+ *
+ * Returns: True if the property is supported, otherwise false.
+ */
+static inline bool
+igt_colorop_has_prop(igt_colorop_t *colorop, enum igt_atomic_colorop_properties prop)
+{
+	return colorop->props[prop];
+}
+
+uint64_t igt_colorop_get_prop(igt_display_t *display, igt_colorop_t *colorop, enum igt_atomic_colorop_properties prop);
+
+#define igt_colorop_is_prop_changed(colorop, prop) \
+	(!!((colorop)->changed & (1 << (prop))))
+
+#define igt_colorop_set_prop_changed(colorop, prop) \
+	(colorop)->changed |= 1 << (prop)
+
+#define igt_colorop_clear_prop_changed(colorop, prop) \
+	(colorop)->changed &= ~(1 << (prop))
+
+#define igt_colorop_set_prop_value(colorop, prop, value) \
+	do { \
+		colorop->values[prop] = value; \
+		igt_colorop_set_prop_changed(colorop, prop); \
+	} while (0)
+
+
+extern bool igt_colorop_try_prop_enum(igt_display_t *display,
+				      igt_colorop_t *colorop,
+				      enum igt_atomic_colorop_properties prop,
+				      const char *val);
+
+extern void igt_colorop_set_prop_enum(igt_display_t *display,
+				      igt_colorop_t *colorop,
+				      enum igt_atomic_colorop_properties prop,
+				      const char *val);
+
 extern void igt_plane_replace_prop_blob(igt_plane_t *plane,
 					enum igt_atomic_plane_properties prop,
 					const void *ptr, size_t length);
@@ -1018,4 +1107,6 @@ bool igt_check_output_is_dp_mst(igt_output_t *output);
 int igt_get_dp_mst_connector_id(igt_output_t *output);
 int get_num_scalers(int drm_fd, enum pipe pipe);
 
+igt_colorop_t *igt_find_colorop(igt_display_t *display, uint32_t id);
+
 #endif /* __IGT_KMS_H__ */
-- 
2.42.0



More information about the igt-dev mailing list