All of lore.kernel.org
 help / color / mirror / Atom feed
* [i-g-t 00/14] Add IGT support for plane color management
@ 2021-11-15  9:47 ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Bhanuprakash Modem

From the Plane Color Management feature design, userspace can
take the smart blending decisions based on hardware supported
plane color features to obtain an accurate color profile.

These IGT patches extend the existing pipe color management
tests to the plane level.

Kernel implementation:
https://patchwork.freedesktop.org/series/90825/

Bhanuprakash Modem (11):
  HAX: Get uapi headers to compile the IGT
  lib/igt_kms: Add plane color mgmt properties
  kms_color_helper: Add helper functions for plane color mgmt
  tests/kms_color: New subtests for Plane gamma
  tests/kms_color: New subtests for Plane degamma
  tests/kms_color: New subtests for Plane CTM
  tests/kms_color: New negative tests for plane level color mgmt
  tests/kms_color_chamelium: New subtests for Plane gamma
  tests/kms_color_chamelium: New subtests for Plane degamma
  tests/kms_color_chamelium: New subtests for Plane CTM
  tests/kms_color_chamelium: Extended IGT tests to support logarithmic
    gamma mode

Mukunda Pramodh Kumar (3):
  lib/igt_kms: Add pipe color mgmt properties
  kms_color_helper: Add helper functions to support logarithmic gamma
    mode
  tests/kms_color: Extended IGT tests to support logarithmic gamma mode

 include/drm-uapi/drm.h      |  10 +
 include/drm-uapi/drm_mode.h |  28 ++
 lib/igt_kms.c               |   6 +
 lib/igt_kms.h               |   6 +
 tests/kms_color.c           | 674 +++++++++++++++++++++++++++++++++++-
 tests/kms_color_chamelium.c | 588 ++++++++++++++++++++++++++++++-
 tests/kms_color_helper.c    | 300 ++++++++++++++++
 tests/kms_color_helper.h    |  45 +++
 8 files changed, 1648 insertions(+), 9 deletions(-)

--
2.32.0


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

* [igt-dev] [i-g-t 00/14] Add IGT support for plane color management
@ 2021-11-15  9:47 ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel

From the Plane Color Management feature design, userspace can
take the smart blending decisions based on hardware supported
plane color features to obtain an accurate color profile.

These IGT patches extend the existing pipe color management
tests to the plane level.

Kernel implementation:
https://patchwork.freedesktop.org/series/90825/

Bhanuprakash Modem (11):
  HAX: Get uapi headers to compile the IGT
  lib/igt_kms: Add plane color mgmt properties
  kms_color_helper: Add helper functions for plane color mgmt
  tests/kms_color: New subtests for Plane gamma
  tests/kms_color: New subtests for Plane degamma
  tests/kms_color: New subtests for Plane CTM
  tests/kms_color: New negative tests for plane level color mgmt
  tests/kms_color_chamelium: New subtests for Plane gamma
  tests/kms_color_chamelium: New subtests for Plane degamma
  tests/kms_color_chamelium: New subtests for Plane CTM
  tests/kms_color_chamelium: Extended IGT tests to support logarithmic
    gamma mode

Mukunda Pramodh Kumar (3):
  lib/igt_kms: Add pipe color mgmt properties
  kms_color_helper: Add helper functions to support logarithmic gamma
    mode
  tests/kms_color: Extended IGT tests to support logarithmic gamma mode

 include/drm-uapi/drm.h      |  10 +
 include/drm-uapi/drm_mode.h |  28 ++
 lib/igt_kms.c               |   6 +
 lib/igt_kms.h               |   6 +
 tests/kms_color.c           | 674 +++++++++++++++++++++++++++++++++++-
 tests/kms_color_chamelium.c | 588 ++++++++++++++++++++++++++++++-
 tests/kms_color_helper.c    | 300 ++++++++++++++++
 tests/kms_color_helper.h    |  45 +++
 8 files changed, 1648 insertions(+), 9 deletions(-)

--
2.32.0

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

* [i-g-t 01/14] HAX: Get uapi headers to compile the IGT
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
  (?)
@ 2021-11-15  9:47 ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Bhanuprakash Modem

Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 include/drm-uapi/drm.h      | 10 ++++++++++
 include/drm-uapi/drm_mode.h | 28 ++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/include/drm-uapi/drm.h b/include/drm-uapi/drm.h
index 5e54c3aa4c..9ca3dbe8e5 100644
--- a/include/drm-uapi/drm.h
+++ b/include/drm-uapi/drm.h
@@ -830,6 +830,16 @@ struct drm_get_cap {
  */
 #define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS	5
 
+/**
+ * DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES
+ *
+ * Add support for advance gamma mode UAPI
+ * If set to 1, DRM will enable advance gamma mode
+ * UAPI to process the gamma mode based on extended
+ * range and segments.
+ */
+#define DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES     6
+
 /* DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
 struct drm_set_client_cap {
 	__u64 capability;
diff --git a/include/drm-uapi/drm_mode.h b/include/drm-uapi/drm_mode.h
index e4a2570a60..97198609a5 100644
--- a/include/drm-uapi/drm_mode.h
+++ b/include/drm-uapi/drm_mode.h
@@ -817,6 +817,34 @@ struct drm_color_lut {
 	__u16 reserved;
 };
 
+/*
+ * Creating 64 bit palette entries for better data
+ * precision. This will be required for HDR and
+ * similar color processing usecases.
+ */
+struct drm_color_lut_ext {
+    /*
+     * Data is U32.32 fixed point format.
+     */
+    __u64 red;
+    __u64 green;
+    __u64 blue;
+    __u64 reserved;
+};
+
+struct drm_color_lut_range {
+    /* DRM_MODE_LUT_* */
+    __u32 flags;
+    /* number of points on the curve */
+    __u16 count;
+    /* input/output bits per component */
+    __u8 input_bpc, output_bpc;
+    /* input start/end values */
+    __s32 start, end;
+    /* output min/max values */
+    __s32 min, max;
+};
+
 /**
  * struct hdr_metadata_infoframe - HDR Metadata Infoframe Data.
  *
-- 
2.32.0


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

* [i-g-t 02/14] lib/igt_kms: Add plane color mgmt properties
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Juha-Pekka Heikkila, Uma Shankar, Bhanuprakash Modem

Add support for Plane color management properties.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 lib/igt_kms.c | 5 +++++
 lib/igt_kms.h | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 34a2aa00ea..fdb83e0f91 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -581,6 +581,11 @@ const char * const igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
 	[IGT_PLANE_ALPHA] = "alpha",
 	[IGT_PLANE_ZPOS] = "zpos",
 	[IGT_PLANE_FB_DAMAGE_CLIPS] = "FB_DAMAGE_CLIPS",
+	[IGT_PLANE_CTM] = "PLANE_CTM",
+	[IGT_PLANE_GAMMA_MODE] = "PLANE_GAMMA_MODE",
+	[IGT_PLANE_GAMMA_LUT] = "PLANE_GAMMA_LUT",
+	[IGT_PLANE_DEGAMMA_MODE] = "PLANE_DEGAMMA_MODE",
+	[IGT_PLANE_DEGAMMA_LUT] = "PLANE_DEGAMMA_LUT",
 };
 
 const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index e9ecd21e98..3a1f7243ad 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -301,6 +301,11 @@ enum igt_atomic_plane_properties {
        IGT_PLANE_ALPHA,
        IGT_PLANE_ZPOS,
        IGT_PLANE_FB_DAMAGE_CLIPS,
+       IGT_PLANE_CTM,
+       IGT_PLANE_GAMMA_MODE,
+       IGT_PLANE_GAMMA_LUT,
+       IGT_PLANE_DEGAMMA_MODE,
+       IGT_PLANE_DEGAMMA_LUT,
        IGT_NUM_PLANE_PROPS
 };
 
-- 
2.32.0


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

* [igt-dev] [i-g-t 02/14] lib/igt_kms: Add plane color mgmt properties
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel

Add support for Plane color management properties.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 lib/igt_kms.c | 5 +++++
 lib/igt_kms.h | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 34a2aa00ea..fdb83e0f91 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -581,6 +581,11 @@ const char * const igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
 	[IGT_PLANE_ALPHA] = "alpha",
 	[IGT_PLANE_ZPOS] = "zpos",
 	[IGT_PLANE_FB_DAMAGE_CLIPS] = "FB_DAMAGE_CLIPS",
+	[IGT_PLANE_CTM] = "PLANE_CTM",
+	[IGT_PLANE_GAMMA_MODE] = "PLANE_GAMMA_MODE",
+	[IGT_PLANE_GAMMA_LUT] = "PLANE_GAMMA_LUT",
+	[IGT_PLANE_DEGAMMA_MODE] = "PLANE_DEGAMMA_MODE",
+	[IGT_PLANE_DEGAMMA_LUT] = "PLANE_DEGAMMA_LUT",
 };
 
 const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index e9ecd21e98..3a1f7243ad 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -301,6 +301,11 @@ enum igt_atomic_plane_properties {
        IGT_PLANE_ALPHA,
        IGT_PLANE_ZPOS,
        IGT_PLANE_FB_DAMAGE_CLIPS,
+       IGT_PLANE_CTM,
+       IGT_PLANE_GAMMA_MODE,
+       IGT_PLANE_GAMMA_LUT,
+       IGT_PLANE_DEGAMMA_MODE,
+       IGT_PLANE_DEGAMMA_LUT,
        IGT_NUM_PLANE_PROPS
 };
 
-- 
2.32.0

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

* [i-g-t 03/14] kms_color_helper: Add helper functions for plane color mgmt
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Juha-Pekka Heikkila, Uma Shankar, Bhanuprakash Modem

Add helper functions to support Plane color management properties.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_helper.c | 173 +++++++++++++++++++++++++++++++++++++++
 tests/kms_color_helper.h |  29 +++++++
 2 files changed, 202 insertions(+)

diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
index d71e7bb2e6..c65b7a0f50 100644
--- a/tests/kms_color_helper.c
+++ b/tests/kms_color_helper.c
@@ -241,6 +241,150 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
 		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
 }
 
+drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
+				enum igt_atomic_plane_properties prop)
+{
+	igt_display_t *display = plane->pipe->display;
+	uint32_t prop_id = plane->props[prop];
+	drmModePropertyPtr drmProp;
+
+	igt_assert(prop_id);
+
+	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
+
+	igt_assert(drmProp);
+	igt_assert(drmProp->count_enums);
+
+	return drmProp;
+}
+
+struct drm_color_lut_ext *create_linear_lut(segment_data_t *info)
+{
+	uint32_t val, segment, entry, index = 0;
+	uint32_t max_val = 0xffffffff;
+	struct drm_color_lut_ext *lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
+	igt_assert(lut);
+
+	for (segment = 0; segment < info->segment_count; segment++) {
+		uint32_t entry_count = info->segment_data[segment].count;
+		uint32_t start = info->segment_data[segment].start;
+		uint32_t end = info->segment_data[segment].end;
+
+		for (entry = 1; entry <= entry_count; entry++) {
+			val = (index == 0) ? /* First entry is Zero. */
+				0 : start + entry * ((end - start) * 1.0 / entry_count);
+
+			lut[index].red = lut[index].green = lut[index].blue = MIN(val, max_val);
+
+			index++;
+		}
+	}
+
+	return lut;
+}
+
+struct drm_color_lut_ext *create_max_lut(segment_data_t *info)
+{
+	int i;
+	struct drm_color_lut_ext *lut;
+	uint32_t max_val = 0xffffffff;
+
+	lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
+	igt_assert(lut);
+
+	lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is Zero. */
+
+	for (i = 1; i < info->entries_count; i++)
+		lut[i].red = lut[i].green = lut[i].blue = max_val;
+
+	return lut;
+}
+
+void clear_segment_data(segment_data_t *info)
+{
+	if (!info)
+		return;
+
+	free(info->segment_data);
+	free(info);
+}
+
+segment_data_t *get_segment_data(data_t *data,
+				uint64_t blob_id, char *mode)
+{
+	drmModePropertyBlobPtr blob;
+	struct drm_color_lut_range *lut_range = NULL;
+	segment_data_t *info = NULL;
+	uint32_t i;
+
+	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
+	igt_assert(blob);
+	igt_assert(blob->length);
+
+	info = malloc(sizeof(segment_data_t));
+	igt_assert(info);
+
+	lut_range = (struct drm_color_lut_range *) blob->data;
+	info->segment_count = blob->length / sizeof(lut_range[0]);
+	igt_assert(info->segment_count);
+
+	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
+	igt_assert(info->segment_data);
+
+	for (i = 0; i < info->segment_count; i++) {
+		info->entries_count += lut_range[i].count;
+		info->segment_data[i] = lut_range[i];
+	}
+
+	drmModeFreePropertyBlob(blob);
+
+	return info;
+}
+
+void set_plane_gamma(igt_plane_t *plane,
+		char *mode,
+		struct drm_color_lut_ext *lut,
+		uint32_t size)
+{
+	igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, mode);
+	igt_plane_replace_prop_blob(plane, IGT_PLANE_GAMMA_LUT, lut, size);
+}
+
+void set_plane_degamma(igt_plane_t *plane,
+		char *mode,
+		struct drm_color_lut_ext *lut,
+		uint32_t size)
+{
+	igt_plane_set_prop_enum(plane, IGT_PLANE_DEGAMMA_MODE, mode);
+	igt_plane_replace_prop_blob(plane, IGT_PLANE_DEGAMMA_LUT, lut, size);
+}
+
+void set_plane_ctm(igt_plane_t *plane, const double *coefficients)
+{
+	struct drm_color_ctm ctm;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
+		if (coefficients[i] < 0) {
+			ctm.matrix[i] =
+				(int64_t) (-coefficients[i] *
+				((int64_t) 1L << 32));
+			ctm.matrix[i] |= 1ULL << 63;
+		} else
+			ctm.matrix[i] =
+				(int64_t) (coefficients[i] *
+				((int64_t) 1L << 32));
+	}
+
+	igt_plane_replace_prop_blob(plane, IGT_PLANE_CTM, &ctm, sizeof(ctm));
+}
+
+void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
+{
+	if (igt_plane_has_prop(plane, prop))
+		igt_plane_replace_prop_blob(plane, prop, NULL, 0);
+}
+
 drmModePropertyBlobPtr
 get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
 {
@@ -274,6 +418,19 @@ pipe_set_property_blob_id(igt_pipe_t *pipe,
 	return ret;
 }
 
+static int
+plane_set_property_blob(igt_display_t *display,
+			igt_plane_t *plane,
+			enum igt_atomic_plane_properties prop,
+			void *ptr, size_t length)
+{
+	igt_plane_replace_prop_blob(plane, prop, ptr, length);
+
+	return igt_display_try_commit2(display,
+				       display->is_atomic ?
+				       COMMIT_ATOMIC : COMMIT_LEGACY);
+}
+
 int
 pipe_set_property_blob(igt_pipe_t *pipe,
 		       enum igt_atomic_crtc_properties prop,
@@ -319,6 +476,22 @@ invalid_lut_sizes(data_t *data, enum pipe p,
 	free(lut);
 }
 
+void
+invalid_plane_lut_sizes(igt_display_t *display,
+			igt_plane_t *plane,
+			enum igt_atomic_plane_properties prop,
+			size_t lut_size)
+{
+	void *lut = malloc(lut_size * 2);
+	igt_assert(lut);
+
+	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, 1), -EINVAL);
+	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size + 1), -EINVAL);
+	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size - 1), -EINVAL);
+
+	free(lut);
+}
+
 void
 invalid_gamma_lut_sizes(data_t *data, enum pipe p)
 {
diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
index bb6f0054f3..5a35dcaac1 100644
--- a/tests/kms_color_helper.h
+++ b/tests/kms_color_helper.h
@@ -64,6 +64,14 @@ typedef struct {
 	color_t coeffs[];
 } gamma_lut_t;
 
+typedef struct {
+	uint32_t segment_count;
+	struct drm_color_lut_range *segment_data;
+	uint32_t entries_count;
+} segment_data_t;
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
 void paint_gradient_rectangles(data_t *data,
 			       drmModeModeInfo *mode,
 			       color_t *colors,
@@ -90,10 +98,31 @@ void set_gamma(data_t *data,
 void set_ctm(igt_pipe_t *pipe, const double *coefficients);
 void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
 
+drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
+	enum igt_atomic_plane_properties prop);
+void clear_segment_data(segment_data_t *info);
+struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
+struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
+segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
+void set_plane_gamma(igt_plane_t *plane,
+	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
+void set_plane_degamma(igt_plane_t *plane,
+	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
+void set_plane_ctm(igt_plane_t *plane, const double *coefficients);
+void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop);
+void invalid_plane_lut_sizes(igt_display_t *display,
+			   igt_plane_t *plane,
+			   enum igt_atomic_plane_properties prop,
+			   size_t lut_size);
+
 #define disable_degamma(pipe) disable_prop(pipe, IGT_CRTC_DEGAMMA_LUT)
 #define disable_gamma(pipe) disable_prop(pipe, IGT_CRTC_GAMMA_LUT)
 #define disable_ctm(pipe) disable_prop(pipe, IGT_CRTC_CTM)
 
+#define disable_plane_degamma(plane) disable_plane_prop(plane, IGT_PLANE_DEGAMMA_LUT)
+#define disable_plane_gamma(plane) disable_plane_prop(plane, IGT_PLANE_GAMMA_LUT)
+#define disable_plane_ctm(plane) disable_plane_prop(plane, IGT_PLANE_CTM)
+
 drmModePropertyBlobPtr get_blob(data_t *data, igt_pipe_t *pipe,
 				enum igt_atomic_crtc_properties prop);
 bool crc_equal(igt_crc_t *a, igt_crc_t *b);
-- 
2.32.0


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

* [igt-dev] [i-g-t 03/14] kms_color_helper: Add helper functions for plane color mgmt
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel

Add helper functions to support Plane color management properties.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_helper.c | 173 +++++++++++++++++++++++++++++++++++++++
 tests/kms_color_helper.h |  29 +++++++
 2 files changed, 202 insertions(+)

diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
index d71e7bb2e6..c65b7a0f50 100644
--- a/tests/kms_color_helper.c
+++ b/tests/kms_color_helper.c
@@ -241,6 +241,150 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
 		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
 }
 
+drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
+				enum igt_atomic_plane_properties prop)
+{
+	igt_display_t *display = plane->pipe->display;
+	uint32_t prop_id = plane->props[prop];
+	drmModePropertyPtr drmProp;
+
+	igt_assert(prop_id);
+
+	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
+
+	igt_assert(drmProp);
+	igt_assert(drmProp->count_enums);
+
+	return drmProp;
+}
+
+struct drm_color_lut_ext *create_linear_lut(segment_data_t *info)
+{
+	uint32_t val, segment, entry, index = 0;
+	uint32_t max_val = 0xffffffff;
+	struct drm_color_lut_ext *lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
+	igt_assert(lut);
+
+	for (segment = 0; segment < info->segment_count; segment++) {
+		uint32_t entry_count = info->segment_data[segment].count;
+		uint32_t start = info->segment_data[segment].start;
+		uint32_t end = info->segment_data[segment].end;
+
+		for (entry = 1; entry <= entry_count; entry++) {
+			val = (index == 0) ? /* First entry is Zero. */
+				0 : start + entry * ((end - start) * 1.0 / entry_count);
+
+			lut[index].red = lut[index].green = lut[index].blue = MIN(val, max_val);
+
+			index++;
+		}
+	}
+
+	return lut;
+}
+
+struct drm_color_lut_ext *create_max_lut(segment_data_t *info)
+{
+	int i;
+	struct drm_color_lut_ext *lut;
+	uint32_t max_val = 0xffffffff;
+
+	lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
+	igt_assert(lut);
+
+	lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is Zero. */
+
+	for (i = 1; i < info->entries_count; i++)
+		lut[i].red = lut[i].green = lut[i].blue = max_val;
+
+	return lut;
+}
+
+void clear_segment_data(segment_data_t *info)
+{
+	if (!info)
+		return;
+
+	free(info->segment_data);
+	free(info);
+}
+
+segment_data_t *get_segment_data(data_t *data,
+				uint64_t blob_id, char *mode)
+{
+	drmModePropertyBlobPtr blob;
+	struct drm_color_lut_range *lut_range = NULL;
+	segment_data_t *info = NULL;
+	uint32_t i;
+
+	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
+	igt_assert(blob);
+	igt_assert(blob->length);
+
+	info = malloc(sizeof(segment_data_t));
+	igt_assert(info);
+
+	lut_range = (struct drm_color_lut_range *) blob->data;
+	info->segment_count = blob->length / sizeof(lut_range[0]);
+	igt_assert(info->segment_count);
+
+	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
+	igt_assert(info->segment_data);
+
+	for (i = 0; i < info->segment_count; i++) {
+		info->entries_count += lut_range[i].count;
+		info->segment_data[i] = lut_range[i];
+	}
+
+	drmModeFreePropertyBlob(blob);
+
+	return info;
+}
+
+void set_plane_gamma(igt_plane_t *plane,
+		char *mode,
+		struct drm_color_lut_ext *lut,
+		uint32_t size)
+{
+	igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, mode);
+	igt_plane_replace_prop_blob(plane, IGT_PLANE_GAMMA_LUT, lut, size);
+}
+
+void set_plane_degamma(igt_plane_t *plane,
+		char *mode,
+		struct drm_color_lut_ext *lut,
+		uint32_t size)
+{
+	igt_plane_set_prop_enum(plane, IGT_PLANE_DEGAMMA_MODE, mode);
+	igt_plane_replace_prop_blob(plane, IGT_PLANE_DEGAMMA_LUT, lut, size);
+}
+
+void set_plane_ctm(igt_plane_t *plane, const double *coefficients)
+{
+	struct drm_color_ctm ctm;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
+		if (coefficients[i] < 0) {
+			ctm.matrix[i] =
+				(int64_t) (-coefficients[i] *
+				((int64_t) 1L << 32));
+			ctm.matrix[i] |= 1ULL << 63;
+		} else
+			ctm.matrix[i] =
+				(int64_t) (coefficients[i] *
+				((int64_t) 1L << 32));
+	}
+
+	igt_plane_replace_prop_blob(plane, IGT_PLANE_CTM, &ctm, sizeof(ctm));
+}
+
+void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
+{
+	if (igt_plane_has_prop(plane, prop))
+		igt_plane_replace_prop_blob(plane, prop, NULL, 0);
+}
+
 drmModePropertyBlobPtr
 get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
 {
@@ -274,6 +418,19 @@ pipe_set_property_blob_id(igt_pipe_t *pipe,
 	return ret;
 }
 
+static int
+plane_set_property_blob(igt_display_t *display,
+			igt_plane_t *plane,
+			enum igt_atomic_plane_properties prop,
+			void *ptr, size_t length)
+{
+	igt_plane_replace_prop_blob(plane, prop, ptr, length);
+
+	return igt_display_try_commit2(display,
+				       display->is_atomic ?
+				       COMMIT_ATOMIC : COMMIT_LEGACY);
+}
+
 int
 pipe_set_property_blob(igt_pipe_t *pipe,
 		       enum igt_atomic_crtc_properties prop,
@@ -319,6 +476,22 @@ invalid_lut_sizes(data_t *data, enum pipe p,
 	free(lut);
 }
 
+void
+invalid_plane_lut_sizes(igt_display_t *display,
+			igt_plane_t *plane,
+			enum igt_atomic_plane_properties prop,
+			size_t lut_size)
+{
+	void *lut = malloc(lut_size * 2);
+	igt_assert(lut);
+
+	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, 1), -EINVAL);
+	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size + 1), -EINVAL);
+	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size - 1), -EINVAL);
+
+	free(lut);
+}
+
 void
 invalid_gamma_lut_sizes(data_t *data, enum pipe p)
 {
diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
index bb6f0054f3..5a35dcaac1 100644
--- a/tests/kms_color_helper.h
+++ b/tests/kms_color_helper.h
@@ -64,6 +64,14 @@ typedef struct {
 	color_t coeffs[];
 } gamma_lut_t;
 
+typedef struct {
+	uint32_t segment_count;
+	struct drm_color_lut_range *segment_data;
+	uint32_t entries_count;
+} segment_data_t;
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
 void paint_gradient_rectangles(data_t *data,
 			       drmModeModeInfo *mode,
 			       color_t *colors,
@@ -90,10 +98,31 @@ void set_gamma(data_t *data,
 void set_ctm(igt_pipe_t *pipe, const double *coefficients);
 void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
 
+drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
+	enum igt_atomic_plane_properties prop);
+void clear_segment_data(segment_data_t *info);
+struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
+struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
+segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
+void set_plane_gamma(igt_plane_t *plane,
+	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
+void set_plane_degamma(igt_plane_t *plane,
+	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
+void set_plane_ctm(igt_plane_t *plane, const double *coefficients);
+void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop);
+void invalid_plane_lut_sizes(igt_display_t *display,
+			   igt_plane_t *plane,
+			   enum igt_atomic_plane_properties prop,
+			   size_t lut_size);
+
 #define disable_degamma(pipe) disable_prop(pipe, IGT_CRTC_DEGAMMA_LUT)
 #define disable_gamma(pipe) disable_prop(pipe, IGT_CRTC_GAMMA_LUT)
 #define disable_ctm(pipe) disable_prop(pipe, IGT_CRTC_CTM)
 
+#define disable_plane_degamma(plane) disable_plane_prop(plane, IGT_PLANE_DEGAMMA_LUT)
+#define disable_plane_gamma(plane) disable_plane_prop(plane, IGT_PLANE_GAMMA_LUT)
+#define disable_plane_ctm(plane) disable_plane_prop(plane, IGT_PLANE_CTM)
+
 drmModePropertyBlobPtr get_blob(data_t *data, igt_pipe_t *pipe,
 				enum igt_atomic_crtc_properties prop);
 bool crc_equal(igt_crc_t *a, igt_crc_t *b);
-- 
2.32.0

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

* [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Juha-Pekka Heikkila, Uma Shankar, Bhanuprakash Modem

To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out gamma LUT and verify we have the same CRC as drawing solid
color rectangles.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 178 insertions(+), 1 deletion(-)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index 775f35964f..b45d66762f 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -24,7 +24,34 @@
 
 #include "kms_color_helper.h"
 
-IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
+IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
+
+#define MAX_SUPPORTED_PLANES 7
+#define SDR_PLANE_BASE 3
+
+typedef bool (*test_t)(data_t*, igt_plane_t*);
+
+static bool is_hdr_plane(const igt_plane_t *plane)
+{
+	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
+}
+
+static bool is_valid_plane(igt_plane_t *plane)
+{
+	int index = plane->index;
+
+	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+		return false;
+
+	/*
+	 * Test 1 HDR plane, 1 SDR plane.
+	 *
+	 * 0,1,2 HDR planes
+	 * 3,4,5,6 SDR planes
+	 *
+	 */
+	return index >= 0 && index < MAX_SUPPORTED_PLANES;
+}
 
 static void test_pipe_degamma(data_t *data,
 			      igt_plane_t *primary)
@@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t *data,
 }
 #endif
 
+static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb;
+	drmModePropertyPtr gamma_mode = NULL;
+	uint32_t i;
+	bool ret = true;
+	igt_pipe_crc_t *pipe_crc = NULL;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd,
+				  plane->pipe->pipe,
+				  INTEL_PIPE_CRC_SOURCE_AUTO);
+
+	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+	igt_plane_set_fb(plane, &fb);
+
+	/* Disable Pipe color props. */
+	disable_ctm(plane->pipe);
+	disable_degamma(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_ctm(plane);
+	disable_plane_degamma(plane);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
+
+	/* Iterate all supported gamma modes. */
+	for (i = 0; i < gamma_mode->count_enums; i++) {
+		igt_crc_t crc_gamma, crc_fullcolors;
+		segment_data_t *segment_info = NULL;
+		struct drm_color_lut_ext *lut = NULL;
+		uint32_t lut_size = 0;
+
+		/* Ignore 'no gamma' from enum list. */
+		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
+			continue;
+
+		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
+
+		/* Draw solid colors with no gamma transformation. */
+		disable_plane_gamma(plane);
+		paint_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
+
+		/* Draw gradient colors with gamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
+				gamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
+		lut = create_max_lut(segment_info);
+		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
+
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
+
+		/* Verify that the CRC of the software computed output is
+		 * equal to the CRC of the gamma LUT transformation output.
+		 */
+		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
+
+		free(lut);
+		clear_segment_data(segment_info);
+	}
+
+	disable_plane_gamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	igt_pipe_crc_free(pipe_crc);
+	drmModeFreeProperty(gamma_mode);
+
+	return ret;
+}
+
 static void
 prep_pipe(data_t *data, enum pipe p)
 {
@@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
 		invalid_ctm_matrix_sizes(data, p);
 }
 
+static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
+{
+	igt_plane_t *plane;
+	int count = 0;
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!is_valid_plane(plane))
+			continue;
+
+		igt_assert(test(data, plane));
+
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
+static void run_tests_for_plane(data_t *data, enum pipe pipe)
+{
+	igt_fixture {
+		igt_require_pipe(&data->display, pipe);
+		igt_require_pipe_crc(data->drm_fd);
+		igt_require(data->display.pipes[pipe].n_planes > 0);
+		igt_display_require_output_on_pipe(&data->display, pipe);
+	}
+
+	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_gamma_test);
+}
+
 igt_main
 {
 	data_t data = {};
@@ -910,6 +1084,9 @@ igt_main
 
 		igt_subtest_group
 			run_invalid_tests_for_pipe(&data, pipe);
+
+		igt_subtest_group
+			run_tests_for_plane(&data, pipe);
 	}
 
 	igt_fixture {
-- 
2.32.0


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

* [igt-dev] [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel

To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out gamma LUT and verify we have the same CRC as drawing solid
color rectangles.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 178 insertions(+), 1 deletion(-)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index 775f35964f..b45d66762f 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -24,7 +24,34 @@
 
 #include "kms_color_helper.h"
 
-IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
+IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
+
+#define MAX_SUPPORTED_PLANES 7
+#define SDR_PLANE_BASE 3
+
+typedef bool (*test_t)(data_t*, igt_plane_t*);
+
+static bool is_hdr_plane(const igt_plane_t *plane)
+{
+	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
+}
+
+static bool is_valid_plane(igt_plane_t *plane)
+{
+	int index = plane->index;
+
+	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+		return false;
+
+	/*
+	 * Test 1 HDR plane, 1 SDR plane.
+	 *
+	 * 0,1,2 HDR planes
+	 * 3,4,5,6 SDR planes
+	 *
+	 */
+	return index >= 0 && index < MAX_SUPPORTED_PLANES;
+}
 
 static void test_pipe_degamma(data_t *data,
 			      igt_plane_t *primary)
@@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t *data,
 }
 #endif
 
+static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb;
+	drmModePropertyPtr gamma_mode = NULL;
+	uint32_t i;
+	bool ret = true;
+	igt_pipe_crc_t *pipe_crc = NULL;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd,
+				  plane->pipe->pipe,
+				  INTEL_PIPE_CRC_SOURCE_AUTO);
+
+	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+	igt_plane_set_fb(plane, &fb);
+
+	/* Disable Pipe color props. */
+	disable_ctm(plane->pipe);
+	disable_degamma(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_ctm(plane);
+	disable_plane_degamma(plane);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
+
+	/* Iterate all supported gamma modes. */
+	for (i = 0; i < gamma_mode->count_enums; i++) {
+		igt_crc_t crc_gamma, crc_fullcolors;
+		segment_data_t *segment_info = NULL;
+		struct drm_color_lut_ext *lut = NULL;
+		uint32_t lut_size = 0;
+
+		/* Ignore 'no gamma' from enum list. */
+		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
+			continue;
+
+		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
+
+		/* Draw solid colors with no gamma transformation. */
+		disable_plane_gamma(plane);
+		paint_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
+
+		/* Draw gradient colors with gamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
+				gamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
+		lut = create_max_lut(segment_info);
+		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
+
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
+
+		/* Verify that the CRC of the software computed output is
+		 * equal to the CRC of the gamma LUT transformation output.
+		 */
+		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
+
+		free(lut);
+		clear_segment_data(segment_info);
+	}
+
+	disable_plane_gamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	igt_pipe_crc_free(pipe_crc);
+	drmModeFreeProperty(gamma_mode);
+
+	return ret;
+}
+
 static void
 prep_pipe(data_t *data, enum pipe p)
 {
@@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
 		invalid_ctm_matrix_sizes(data, p);
 }
 
+static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
+{
+	igt_plane_t *plane;
+	int count = 0;
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!is_valid_plane(plane))
+			continue;
+
+		igt_assert(test(data, plane));
+
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
+static void run_tests_for_plane(data_t *data, enum pipe pipe)
+{
+	igt_fixture {
+		igt_require_pipe(&data->display, pipe);
+		igt_require_pipe_crc(data->drm_fd);
+		igt_require(data->display.pipes[pipe].n_planes > 0);
+		igt_display_require_output_on_pipe(&data->display, pipe);
+	}
+
+	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_gamma_test);
+}
+
 igt_main
 {
 	data_t data = {};
@@ -910,6 +1084,9 @@ igt_main
 
 		igt_subtest_group
 			run_invalid_tests_for_pipe(&data, pipe);
+
+		igt_subtest_group
+			run_tests_for_plane(&data, pipe);
 	}
 
 	igt_fixture {
-- 
2.32.0

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

* [i-g-t 05/14] tests/kms_color: New subtests for Plane degamma
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Juha-Pekka Heikkila, Uma Shankar, Bhanuprakash Modem

To verify Plane degamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out degamma LUT and verify we have the same CRC as drawing solid
color rectangles without degamma.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index b45d66762f..920a5eaadd 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -781,6 +781,125 @@ static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	drmModePropertyPtr degamma_mode;
+	struct igt_fb fb;
+	uint32_t i;
+	bool ret = true;
+	igt_pipe_crc_t *pipe_crc = NULL;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane degamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd,
+				    plane->pipe->pipe,
+				    INTEL_PIPE_CRC_SOURCE_AUTO);
+
+	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_plane_set_fb(plane, &fb);
+
+	/* Disable Pipe color props. */
+	disable_ctm(plane->pipe);
+	disable_degamma(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
+
+	/* Iterate all supported degamma modes. */
+	for (i = 0; i < degamma_mode->count_enums; i++) {
+		igt_crc_t crc_degamma, crc_fullcolors;
+		segment_data_t *degamma_segment_info = NULL;
+		struct drm_color_lut_ext *degamma_lut = NULL;
+		uint32_t degamma_lut_size = 0;
+
+		/* Ignore 'no degamma' from enum list. */
+		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
+			continue;
+
+		degamma_segment_info = get_segment_data(data, degamma_mode->enums[i].value,
+						degamma_mode->enums[i].name);
+		degamma_lut_size = sizeof(struct drm_color_lut_ext) * degamma_segment_info->entries_count;
+		degamma_lut = create_max_lut(degamma_segment_info);
+
+		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
+
+		/* Draw solid colors with no degamma. */
+		disable_plane_degamma(plane);
+		paint_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+				display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
+
+		/* Draw gradient colors with degamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		set_plane_degamma(plane, degamma_mode->enums[i].name,
+				  degamma_lut, degamma_lut_size);
+		igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+				display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_degamma);
+
+		/* Verify that the CRC of the software computed output
+		 * is equal to the CRC of the degamma LUT transformation
+		 * output.
+		 */
+		ret &= igt_check_crc_equal(&crc_degamma, &crc_fullcolors);
+
+		free(degamma_lut);
+		clear_segment_data(degamma_segment_info);
+	}
+
+	disable_plane_degamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	igt_pipe_crc_free(pipe_crc);
+	drmModeFreeProperty(degamma_mode);
+
+	return ret;
+}
+
 static void
 prep_pipe(data_t *data, enum pipe p)
 {
@@ -1062,6 +1181,11 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");
 	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_gamma_test);
+
+	igt_describe("Compare maxed out plane degamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-degamma",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_degamma_test);
 }
 
 igt_main
-- 
2.32.0


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

* [igt-dev] [i-g-t 05/14] tests/kms_color: New subtests for Plane degamma
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel

To verify Plane degamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out degamma LUT and verify we have the same CRC as drawing solid
color rectangles without degamma.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index b45d66762f..920a5eaadd 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -781,6 +781,125 @@ static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	drmModePropertyPtr degamma_mode;
+	struct igt_fb fb;
+	uint32_t i;
+	bool ret = true;
+	igt_pipe_crc_t *pipe_crc = NULL;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane degamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd,
+				    plane->pipe->pipe,
+				    INTEL_PIPE_CRC_SOURCE_AUTO);
+
+	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_plane_set_fb(plane, &fb);
+
+	/* Disable Pipe color props. */
+	disable_ctm(plane->pipe);
+	disable_degamma(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
+
+	/* Iterate all supported degamma modes. */
+	for (i = 0; i < degamma_mode->count_enums; i++) {
+		igt_crc_t crc_degamma, crc_fullcolors;
+		segment_data_t *degamma_segment_info = NULL;
+		struct drm_color_lut_ext *degamma_lut = NULL;
+		uint32_t degamma_lut_size = 0;
+
+		/* Ignore 'no degamma' from enum list. */
+		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
+			continue;
+
+		degamma_segment_info = get_segment_data(data, degamma_mode->enums[i].value,
+						degamma_mode->enums[i].name);
+		degamma_lut_size = sizeof(struct drm_color_lut_ext) * degamma_segment_info->entries_count;
+		degamma_lut = create_max_lut(degamma_segment_info);
+
+		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
+
+		/* Draw solid colors with no degamma. */
+		disable_plane_degamma(plane);
+		paint_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+				display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
+
+		/* Draw gradient colors with degamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		set_plane_degamma(plane, degamma_mode->enums[i].name,
+				  degamma_lut, degamma_lut_size);
+		igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+				display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_degamma);
+
+		/* Verify that the CRC of the software computed output
+		 * is equal to the CRC of the degamma LUT transformation
+		 * output.
+		 */
+		ret &= igt_check_crc_equal(&crc_degamma, &crc_fullcolors);
+
+		free(degamma_lut);
+		clear_segment_data(degamma_segment_info);
+	}
+
+	disable_plane_degamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	igt_pipe_crc_free(pipe_crc);
+	drmModeFreeProperty(degamma_mode);
+
+	return ret;
+}
+
 static void
 prep_pipe(data_t *data, enum pipe p)
 {
@@ -1062,6 +1181,11 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");
 	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_gamma_test);
+
+	igt_describe("Compare maxed out plane degamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-degamma",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_degamma_test);
 }
 
 igt_main
-- 
2.32.0

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

* [i-g-t 06/14] tests/kms_color: New subtests for Plane CTM
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Juha-Pekka Heikkila, Uma Shankar, Bhanuprakash Modem

To verify plane CTM, draw 3 rectangles using before colors with the
ctm matrix applied and verify the CRC is equal to using after colors
with an identify ctm matrix.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 225 insertions(+)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index 920a5eaadd..e14b37cb6f 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -53,6 +53,77 @@ static bool is_valid_plane(igt_plane_t *plane)
 	return index >= 0 && index < MAX_SUPPORTED_PLANES;
 }
 
+struct {
+	const char *test_name;
+	int iter;
+	color_t expected_colors[3];
+	double ctm[9];
+} ctm_tests[] = {
+	{"plane-ctm-red-to-blue", 0,
+					{{ 0.0, 0.0, 1.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 0.0, 0.0, 0.0,
+		  0.0, 1.0, 0.0,
+		  1.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-green-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 1.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 1.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0,
+		  0.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-blue-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 1.0, 0.0, 0.0 }},
+		{ 1.0, 0.0, 1.0,
+		  0.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0 },
+	},
+	{"plane-ctm-max", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 100.0, 0.0, 0.0,
+		  0.0, 100.0, 0.0,
+		  0.0, 0.0, 100.0 },
+	},
+	{"plane-ctm-negative", 0,
+					{{ 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 }},
+		{ -1.0, 0.0, 0.0,
+		   0.0, -1.0, 0.0,
+		   0.0, 0.0, -1.0 },
+	},
+	/* We tests a few values around the expected result because
+	 * it depends on the hardware we're dealing with, we can
+	 * either get clamped or rounded values and we also need to
+	 * account for odd number of items in the LUTs.
+	 */
+	{"plane-ctm-0-25", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.25, 0.0,  0.0,
+		  0.0,  0.25, 0.0,
+		  0.0,  0.0,  0.25 },
+	},
+	{"plane-ctm-0-50", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.5,  0.0,  0.0,
+		  0.0,  0.5,  0.0,
+		  0.0,  0.0,  0.5 },
+	},
+	{"plane-ctm-0-75", 7,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.75, 0.0,  0.0,
+		  0.0,  0.75, 0.0,
+		  0.0,  0.0,  0.75 },
+	},
+};
+
 static void test_pipe_degamma(data_t *data,
 			      igt_plane_t *primary)
 {
@@ -900,6 +971,99 @@ static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool test_plane_ctm(data_t *data,
+			  igt_plane_t *plane,
+			  color_t *before,
+			  color_t *after,
+			  double *ctm_matrix)
+{
+	const double ctm_identity[] = {
+		1.0, 0.0, 0.0,
+		0.0, 1.0, 0.0,
+		0.0, 0.0, 1.0
+	};
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb;
+	igt_crc_t crc_software, crc_hardware;
+	igt_pipe_crc_t *pipe_crc = NULL;
+	bool ret = true;
+
+	igt_info("Plane CTM test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd,
+				  plane->pipe->pipe,
+				  INTEL_PIPE_CRC_SOURCE_AUTO);
+
+	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_plane_set_fb(plane, &fb);
+
+	/* Disable Pipe color props. */
+	disable_degamma(plane->pipe);
+	disable_gamma(plane->pipe);
+	disable_ctm(plane->pipe);
+
+	disable_plane_gamma(plane);
+	disable_plane_degamma(plane);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Without CTM transformation. */
+	paint_rectangles(data, mode, after, &fb);
+	igt_plane_set_fb(plane, &fb);
+	set_plane_ctm(plane, ctm_identity);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+	igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+	igt_pipe_crc_collect_crc(pipe_crc, &crc_software);
+
+	/* With CTM transformation. */
+	paint_rectangles(data, mode, before, &fb);
+	igt_plane_set_fb(plane, &fb);
+	set_plane_ctm(plane, ctm_matrix);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+	igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+	igt_pipe_crc_collect_crc(pipe_crc, &crc_hardware);
+
+	/* Verify that the CRC of the software computed ouutput
+	 * is equal to the CRC of the CTM matrix transformation
+	 * output.
+	 */
+	ret = igt_check_crc_equal(&crc_software, &crc_hardware);
+
+	disable_plane_ctm(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	igt_pipe_crc_free(pipe_crc);
+
+	return ret;
+}
+
 static void
 prep_pipe(data_t *data, enum pipe p)
 {
@@ -1169,8 +1333,57 @@ static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 	igt_require_f(count, "No valid planes found.\n");
 }
 
+static void run_plane_ctm_test(data_t *data,
+				enum pipe pipe,
+				color_t *expected,
+				double *ctm,
+				int iter)
+{
+	igt_plane_t *plane;
+	bool result;
+	int i, count = 0;
+	double delta = 1.0 / (1 << 8);
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!is_valid_plane(plane))
+			continue;
+
+		result = false;
+
+		if (!iter)
+			result |= test_plane_ctm(data, plane,
+					red_green_blue, expected,
+					ctm);
+
+		for (i = 0; i < iter; i++) {
+			expected[0].r =
+			expected[1].g =
+			expected[2].b =
+				ctm[0] + delta * (i - (iter/2));
+
+			result |= test_plane_ctm(data, plane,
+					red_green_blue,	expected,
+					ctm);
+			if (result)
+				break;
+		}
+
+		igt_assert(result);
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
 static void run_tests_for_plane(data_t *data, enum pipe pipe)
 {
+	int i;
+
 	igt_fixture {
 		igt_require_pipe(&data->display, pipe);
 		igt_require_pipe_crc(data->drm_fd);
@@ -1186,6 +1399,18 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_subtest_f("pipe-%s-plane-degamma",
 			kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_degamma_test);
+
+	for (i = 0; i < ARRAY_SIZE(ctm_tests); i++) {
+		igt_describe("Compare after applying ctm matrix & identity matrix");
+		igt_subtest_f("pipe-%s-%s",
+				kmstest_pipe_name(pipe),
+				ctm_tests[i].test_name) {
+			run_plane_ctm_test(data, pipe,
+					ctm_tests[i].expected_colors,
+					ctm_tests[i].ctm,
+					ctm_tests[i].iter);
+		}
+	}
 }
 
 igt_main
-- 
2.32.0


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

* [igt-dev] [i-g-t 06/14] tests/kms_color: New subtests for Plane CTM
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel

To verify plane CTM, draw 3 rectangles using before colors with the
ctm matrix applied and verify the CRC is equal to using after colors
with an identify ctm matrix.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 225 insertions(+)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index 920a5eaadd..e14b37cb6f 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -53,6 +53,77 @@ static bool is_valid_plane(igt_plane_t *plane)
 	return index >= 0 && index < MAX_SUPPORTED_PLANES;
 }
 
+struct {
+	const char *test_name;
+	int iter;
+	color_t expected_colors[3];
+	double ctm[9];
+} ctm_tests[] = {
+	{"plane-ctm-red-to-blue", 0,
+					{{ 0.0, 0.0, 1.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 0.0, 0.0, 0.0,
+		  0.0, 1.0, 0.0,
+		  1.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-green-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 1.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 1.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0,
+		  0.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-blue-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 1.0, 0.0, 0.0 }},
+		{ 1.0, 0.0, 1.0,
+		  0.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0 },
+	},
+	{"plane-ctm-max", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 100.0, 0.0, 0.0,
+		  0.0, 100.0, 0.0,
+		  0.0, 0.0, 100.0 },
+	},
+	{"plane-ctm-negative", 0,
+					{{ 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 }},
+		{ -1.0, 0.0, 0.0,
+		   0.0, -1.0, 0.0,
+		   0.0, 0.0, -1.0 },
+	},
+	/* We tests a few values around the expected result because
+	 * it depends on the hardware we're dealing with, we can
+	 * either get clamped or rounded values and we also need to
+	 * account for odd number of items in the LUTs.
+	 */
+	{"plane-ctm-0-25", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.25, 0.0,  0.0,
+		  0.0,  0.25, 0.0,
+		  0.0,  0.0,  0.25 },
+	},
+	{"plane-ctm-0-50", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.5,  0.0,  0.0,
+		  0.0,  0.5,  0.0,
+		  0.0,  0.0,  0.5 },
+	},
+	{"plane-ctm-0-75", 7,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.75, 0.0,  0.0,
+		  0.0,  0.75, 0.0,
+		  0.0,  0.0,  0.75 },
+	},
+};
+
 static void test_pipe_degamma(data_t *data,
 			      igt_plane_t *primary)
 {
@@ -900,6 +971,99 @@ static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool test_plane_ctm(data_t *data,
+			  igt_plane_t *plane,
+			  color_t *before,
+			  color_t *after,
+			  double *ctm_matrix)
+{
+	const double ctm_identity[] = {
+		1.0, 0.0, 0.0,
+		0.0, 1.0, 0.0,
+		0.0, 0.0, 1.0
+	};
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb;
+	igt_crc_t crc_software, crc_hardware;
+	igt_pipe_crc_t *pipe_crc = NULL;
+	bool ret = true;
+
+	igt_info("Plane CTM test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd,
+				  plane->pipe->pipe,
+				  INTEL_PIPE_CRC_SOURCE_AUTO);
+
+	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_plane_set_fb(plane, &fb);
+
+	/* Disable Pipe color props. */
+	disable_degamma(plane->pipe);
+	disable_gamma(plane->pipe);
+	disable_ctm(plane->pipe);
+
+	disable_plane_gamma(plane);
+	disable_plane_degamma(plane);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Without CTM transformation. */
+	paint_rectangles(data, mode, after, &fb);
+	igt_plane_set_fb(plane, &fb);
+	set_plane_ctm(plane, ctm_identity);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+	igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+	igt_pipe_crc_collect_crc(pipe_crc, &crc_software);
+
+	/* With CTM transformation. */
+	paint_rectangles(data, mode, before, &fb);
+	igt_plane_set_fb(plane, &fb);
+	set_plane_ctm(plane, ctm_matrix);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+	igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+	igt_pipe_crc_collect_crc(pipe_crc, &crc_hardware);
+
+	/* Verify that the CRC of the software computed ouutput
+	 * is equal to the CRC of the CTM matrix transformation
+	 * output.
+	 */
+	ret = igt_check_crc_equal(&crc_software, &crc_hardware);
+
+	disable_plane_ctm(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	igt_pipe_crc_free(pipe_crc);
+
+	return ret;
+}
+
 static void
 prep_pipe(data_t *data, enum pipe p)
 {
@@ -1169,8 +1333,57 @@ static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 	igt_require_f(count, "No valid planes found.\n");
 }
 
+static void run_plane_ctm_test(data_t *data,
+				enum pipe pipe,
+				color_t *expected,
+				double *ctm,
+				int iter)
+{
+	igt_plane_t *plane;
+	bool result;
+	int i, count = 0;
+	double delta = 1.0 / (1 << 8);
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!is_valid_plane(plane))
+			continue;
+
+		result = false;
+
+		if (!iter)
+			result |= test_plane_ctm(data, plane,
+					red_green_blue, expected,
+					ctm);
+
+		for (i = 0; i < iter; i++) {
+			expected[0].r =
+			expected[1].g =
+			expected[2].b =
+				ctm[0] + delta * (i - (iter/2));
+
+			result |= test_plane_ctm(data, plane,
+					red_green_blue,	expected,
+					ctm);
+			if (result)
+				break;
+		}
+
+		igt_assert(result);
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
 static void run_tests_for_plane(data_t *data, enum pipe pipe)
 {
+	int i;
+
 	igt_fixture {
 		igt_require_pipe(&data->display, pipe);
 		igt_require_pipe_crc(data->drm_fd);
@@ -1186,6 +1399,18 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_subtest_f("pipe-%s-plane-degamma",
 			kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_degamma_test);
+
+	for (i = 0; i < ARRAY_SIZE(ctm_tests); i++) {
+		igt_describe("Compare after applying ctm matrix & identity matrix");
+		igt_subtest_f("pipe-%s-%s",
+				kmstest_pipe_name(pipe),
+				ctm_tests[i].test_name) {
+			run_plane_ctm_test(data, pipe,
+					ctm_tests[i].expected_colors,
+					ctm_tests[i].ctm,
+					ctm_tests[i].iter);
+		}
+	}
 }
 
 igt_main
-- 
2.32.0

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

* [i-g-t 07/14] tests/kms_color: New negative tests for plane level color mgmt
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Juha-Pekka Heikkila, Uma Shankar, Bhanuprakash Modem

Negative check for:
 * plane gamma lut sizes
 * plane degamma lut sizes
 * plane ctm matrix sizes

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 127 insertions(+)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index e14b37cb6f..d9fe417ba9 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -736,6 +736,118 @@ static void test_pipe_limited_range_ctm(data_t *data,
 }
 #endif
 
+static bool invalid_plane_gamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_display_t *display = &data->display;
+	drmModePropertyPtr gamma_mode = NULL;
+	uint32_t i;
+
+	igt_info("Plane invalid gamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
+
+	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
+
+	/* Iterate all supported gamma modes. */
+	for (i = 0; i < gamma_mode->count_enums; i++) {
+		segment_data_t *segment_info = NULL;
+		size_t lut_size = 0;
+
+		/* Ignore 'no gamma' from enum list. */
+		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
+			continue;
+
+		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
+
+		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
+				gamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
+
+		igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, gamma_mode->enums[i].name);
+		invalid_plane_lut_sizes(display, plane,
+					IGT_PLANE_GAMMA_LUT,
+					lut_size);
+
+		clear_segment_data(segment_info);
+
+		/* One enum is enough. */
+		break;
+	}
+
+	drmModeFreeProperty(gamma_mode);
+
+	return true;
+}
+
+static bool invalid_plane_degamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_display_t *display = &data->display;
+	drmModePropertyPtr degamma_mode = NULL;
+	uint32_t i;
+
+	igt_info("Plane invalid degamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
+
+	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
+
+	/* Iterate all supported degamma modes. */
+	for (i = 0; i < degamma_mode->count_enums; i++) {
+		segment_data_t *segment_info = NULL;
+		size_t lut_size = 0;
+
+		/* Ignore 'no degamma' from enum list. */
+		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
+			continue;
+
+		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
+
+		segment_info = get_segment_data(data,
+						degamma_mode->enums[i].value,
+						degamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count * 2;
+
+		igt_plane_set_prop_enum(plane,
+					IGT_PLANE_DEGAMMA_MODE,
+					degamma_mode->enums[i].name);
+		invalid_plane_lut_sizes(display, plane,
+					IGT_PLANE_DEGAMMA_LUT,
+					lut_size);
+
+		clear_segment_data(segment_info);
+
+		/* One enum is enough. */
+		break;
+	}
+
+	drmModeFreeProperty(degamma_mode);
+
+	return true;
+}
+
+static bool invalid_plane_ctm_test(data_t *data, igt_plane_t *plane)
+{
+	igt_info("Plane invalid CTM test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
+	invalid_plane_lut_sizes(&data->display, plane,
+				IGT_PLANE_CTM,
+				sizeof(struct drm_color_ctm));
+
+	return true;
+}
+
 static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
 {
 	igt_output_t *output;
@@ -1411,6 +1523,21 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 					ctm_tests[i].iter);
 		}
 	}
+
+	igt_describe("Negative check for invalid plane gamma lut sizes");
+	igt_subtest_f("pipe-%s-invalid-plane-gamma-lut-sizes",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, invalid_plane_gamma_test);
+
+	igt_describe("Negative check for invalid plane degamma lut sizes");
+	igt_subtest_f("pipe-%s-invalid-plane-degamma-lut-sizes",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, invalid_plane_degamma_test);
+
+	igt_describe("Negative check for invalid plane ctm matrix sizes");
+	igt_subtest_f("pipe-%s-invalid-plane-ctm-matrix-sizes",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, invalid_plane_ctm_test);
 }
 
 igt_main
-- 
2.32.0


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

* [igt-dev] [i-g-t 07/14] tests/kms_color: New negative tests for plane level color mgmt
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel

Negative check for:
 * plane gamma lut sizes
 * plane degamma lut sizes
 * plane ctm matrix sizes

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 127 insertions(+)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index e14b37cb6f..d9fe417ba9 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -736,6 +736,118 @@ static void test_pipe_limited_range_ctm(data_t *data,
 }
 #endif
 
+static bool invalid_plane_gamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_display_t *display = &data->display;
+	drmModePropertyPtr gamma_mode = NULL;
+	uint32_t i;
+
+	igt_info("Plane invalid gamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
+
+	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
+
+	/* Iterate all supported gamma modes. */
+	for (i = 0; i < gamma_mode->count_enums; i++) {
+		segment_data_t *segment_info = NULL;
+		size_t lut_size = 0;
+
+		/* Ignore 'no gamma' from enum list. */
+		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
+			continue;
+
+		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
+
+		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
+				gamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
+
+		igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, gamma_mode->enums[i].name);
+		invalid_plane_lut_sizes(display, plane,
+					IGT_PLANE_GAMMA_LUT,
+					lut_size);
+
+		clear_segment_data(segment_info);
+
+		/* One enum is enough. */
+		break;
+	}
+
+	drmModeFreeProperty(gamma_mode);
+
+	return true;
+}
+
+static bool invalid_plane_degamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_display_t *display = &data->display;
+	drmModePropertyPtr degamma_mode = NULL;
+	uint32_t i;
+
+	igt_info("Plane invalid degamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
+
+	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
+
+	/* Iterate all supported degamma modes. */
+	for (i = 0; i < degamma_mode->count_enums; i++) {
+		segment_data_t *segment_info = NULL;
+		size_t lut_size = 0;
+
+		/* Ignore 'no degamma' from enum list. */
+		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
+			continue;
+
+		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
+
+		segment_info = get_segment_data(data,
+						degamma_mode->enums[i].value,
+						degamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count * 2;
+
+		igt_plane_set_prop_enum(plane,
+					IGT_PLANE_DEGAMMA_MODE,
+					degamma_mode->enums[i].name);
+		invalid_plane_lut_sizes(display, plane,
+					IGT_PLANE_DEGAMMA_LUT,
+					lut_size);
+
+		clear_segment_data(segment_info);
+
+		/* One enum is enough. */
+		break;
+	}
+
+	drmModeFreeProperty(degamma_mode);
+
+	return true;
+}
+
+static bool invalid_plane_ctm_test(data_t *data, igt_plane_t *plane)
+{
+	igt_info("Plane invalid CTM test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
+	invalid_plane_lut_sizes(&data->display, plane,
+				IGT_PLANE_CTM,
+				sizeof(struct drm_color_ctm));
+
+	return true;
+}
+
 static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
 {
 	igt_output_t *output;
@@ -1411,6 +1523,21 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 					ctm_tests[i].iter);
 		}
 	}
+
+	igt_describe("Negative check for invalid plane gamma lut sizes");
+	igt_subtest_f("pipe-%s-invalid-plane-gamma-lut-sizes",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, invalid_plane_gamma_test);
+
+	igt_describe("Negative check for invalid plane degamma lut sizes");
+	igt_subtest_f("pipe-%s-invalid-plane-degamma-lut-sizes",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, invalid_plane_degamma_test);
+
+	igt_describe("Negative check for invalid plane ctm matrix sizes");
+	igt_subtest_f("pipe-%s-invalid-plane-ctm-matrix-sizes",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, invalid_plane_ctm_test);
 }
 
 igt_main
-- 
2.32.0

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

* [i-g-t 08/14] tests/kms_color_chamelium: New subtests for Plane gamma
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel
  Cc: Kunal Joshi, Juha-Pekka Heikkila, Uma Shankar, Bhanuprakash Modem

To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out gamma LUT and verify we have the same frame dump as
drawing solid color rectangles.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 188 +++++++++++++++++++++++++++++++++++-
 1 file changed, 187 insertions(+), 1 deletion(-)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index 76f82d6d35..b506109271 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -24,7 +24,34 @@
 
 #include "kms_color_helper.h"
 
-IGT_TEST_DESCRIPTION("Test Color Features at Pipe level using Chamelium to verify instead of CRC");
+IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level using Chamelium to verify instead of CRC");
+
+#define MAX_SUPPORTED_PLANES 7
+#define SDR_PLANE_BASE 3
+
+typedef bool (*test_t)(data_t*, igt_plane_t*);
+
+static bool is_hdr_plane(const igt_plane_t *plane)
+{
+	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
+}
+
+static bool is_valid_plane(igt_plane_t *plane)
+{
+	int index = plane->index;
+
+	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+		return false;
+
+	/*
+	 * Test 1 HDR plane, 1 SDR plane.
+	 *
+	 * 0,1,2 HDR planes
+	 * 3,4,5,6 SDR planes
+	 *
+	 */
+	return index >= 0 && index < MAX_SUPPORTED_PLANES;
+}
 
 /*
  * Draw 3 gradient rectangles in red, green and blue, with a maxed out
@@ -723,6 +750,161 @@ run_tests_for_pipe(data_t *data, enum pipe p)
 	}
 }
 
+static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb, fbref;
+	drmModePropertyPtr gamma_mode = NULL;
+	uint32_t i;
+	bool ret = true;
+	struct chamelium_port *port = NULL;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
+
+	for_each_valid_output_on_pipe(display, plane->pipe->pipe, output) {
+		for (i = 0; i < data->port_count; i++)
+			if (strcmp(output->name, chamelium_port_get_name(data->ports[i])) == 0) {
+				port = data->ports[i];
+				break;
+			}
+
+		if (port)
+			break;
+	}
+	igt_require(port);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fbref));
+
+	disable_degamma(plane->pipe);
+	disable_ctm(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_degamma(plane);
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+
+	igt_plane_set_fb(plane, &fbref);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Draw solid colors with no gamma transformation. */
+	paint_rectangles(data, mode, red_green_blue, &fbref);
+
+	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
+	/* Iterate all supported gamma modes. */
+	for (i = 0; i < gamma_mode->count_enums; i++) {
+		struct chamelium_frame_dump *frame_fullcolors;
+		segment_data_t *segment_info = NULL;
+		struct drm_color_lut_ext *lut = NULL;
+		uint32_t lut_size = 0;
+
+		/* Ignore 'no gamma' from enum list. */
+		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
+			continue;
+
+		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
+
+		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
+				gamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
+		lut = create_max_lut(segment_info);
+		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
+
+		/* Draw a gradient with gamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+		chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 1);
+		frame_fullcolors =
+			chamelium_read_captured_frame(data->chamelium, 0);
+
+		/* Verify that the framebuffer reference of the software computed
+		 * output is equal to the frame dump of the gamma LUT
+		 * transformation output.
+		 */
+		ret &= chamelium_frame_match_or_dump(data->chamelium, port,
+					      frame_fullcolors, &fbref,
+					      CHAMELIUM_CHECK_ANALOG);
+		free(lut);
+		clear_segment_data(segment_info);
+	}
+
+	disable_plane_gamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	drmModeFreeProperty(gamma_mode);
+
+	return ret;
+}
+
+static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
+{
+	igt_plane_t *plane;
+	int count = 0;
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!is_valid_plane(plane))
+			continue;
+
+		igt_assert(test(data, plane));
+
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
+static void run_tests_for_plane(data_t *data, enum pipe pipe)
+{
+	igt_fixture {
+		igt_require_pipe(&data->display, pipe);
+		igt_require(data->display.pipes[pipe].n_planes > 0);
+		igt_display_require_output_on_pipe(&data->display, pipe);
+	}
+
+	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-gamma",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_gamma_test);
+}
+
 igt_main
 {
 	data_t data = {};
@@ -755,6 +937,10 @@ igt_main
 		igt_subtest_group
 			run_tests_for_pipe(&data, pipe);
 
+	for_each_pipe_static(pipe)
+		igt_subtest_group
+			run_tests_for_plane(&data, pipe);
+
 	igt_fixture {
 		igt_display_fini(&data.display);
 	}
-- 
2.32.0


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

* [igt-dev] [i-g-t 08/14] tests/kms_color_chamelium: New subtests for Plane gamma
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Kunal Joshi

To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out gamma LUT and verify we have the same frame dump as
drawing solid color rectangles.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 188 +++++++++++++++++++++++++++++++++++-
 1 file changed, 187 insertions(+), 1 deletion(-)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index 76f82d6d35..b506109271 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -24,7 +24,34 @@
 
 #include "kms_color_helper.h"
 
-IGT_TEST_DESCRIPTION("Test Color Features at Pipe level using Chamelium to verify instead of CRC");
+IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level using Chamelium to verify instead of CRC");
+
+#define MAX_SUPPORTED_PLANES 7
+#define SDR_PLANE_BASE 3
+
+typedef bool (*test_t)(data_t*, igt_plane_t*);
+
+static bool is_hdr_plane(const igt_plane_t *plane)
+{
+	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
+}
+
+static bool is_valid_plane(igt_plane_t *plane)
+{
+	int index = plane->index;
+
+	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+		return false;
+
+	/*
+	 * Test 1 HDR plane, 1 SDR plane.
+	 *
+	 * 0,1,2 HDR planes
+	 * 3,4,5,6 SDR planes
+	 *
+	 */
+	return index >= 0 && index < MAX_SUPPORTED_PLANES;
+}
 
 /*
  * Draw 3 gradient rectangles in red, green and blue, with a maxed out
@@ -723,6 +750,161 @@ run_tests_for_pipe(data_t *data, enum pipe p)
 	}
 }
 
+static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb, fbref;
+	drmModePropertyPtr gamma_mode = NULL;
+	uint32_t i;
+	bool ret = true;
+	struct chamelium_port *port = NULL;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
+
+	for_each_valid_output_on_pipe(display, plane->pipe->pipe, output) {
+		for (i = 0; i < data->port_count; i++)
+			if (strcmp(output->name, chamelium_port_get_name(data->ports[i])) == 0) {
+				port = data->ports[i];
+				break;
+			}
+
+		if (port)
+			break;
+	}
+	igt_require(port);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fbref));
+
+	disable_degamma(plane->pipe);
+	disable_ctm(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_degamma(plane);
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+
+	igt_plane_set_fb(plane, &fbref);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Draw solid colors with no gamma transformation. */
+	paint_rectangles(data, mode, red_green_blue, &fbref);
+
+	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
+	/* Iterate all supported gamma modes. */
+	for (i = 0; i < gamma_mode->count_enums; i++) {
+		struct chamelium_frame_dump *frame_fullcolors;
+		segment_data_t *segment_info = NULL;
+		struct drm_color_lut_ext *lut = NULL;
+		uint32_t lut_size = 0;
+
+		/* Ignore 'no gamma' from enum list. */
+		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
+			continue;
+
+		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
+
+		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
+				gamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
+		lut = create_max_lut(segment_info);
+		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
+
+		/* Draw a gradient with gamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+		chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 1);
+		frame_fullcolors =
+			chamelium_read_captured_frame(data->chamelium, 0);
+
+		/* Verify that the framebuffer reference of the software computed
+		 * output is equal to the frame dump of the gamma LUT
+		 * transformation output.
+		 */
+		ret &= chamelium_frame_match_or_dump(data->chamelium, port,
+					      frame_fullcolors, &fbref,
+					      CHAMELIUM_CHECK_ANALOG);
+		free(lut);
+		clear_segment_data(segment_info);
+	}
+
+	disable_plane_gamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	drmModeFreeProperty(gamma_mode);
+
+	return ret;
+}
+
+static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
+{
+	igt_plane_t *plane;
+	int count = 0;
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!is_valid_plane(plane))
+			continue;
+
+		igt_assert(test(data, plane));
+
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
+static void run_tests_for_plane(data_t *data, enum pipe pipe)
+{
+	igt_fixture {
+		igt_require_pipe(&data->display, pipe);
+		igt_require(data->display.pipes[pipe].n_planes > 0);
+		igt_display_require_output_on_pipe(&data->display, pipe);
+	}
+
+	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-gamma",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_gamma_test);
+}
+
 igt_main
 {
 	data_t data = {};
@@ -755,6 +937,10 @@ igt_main
 		igt_subtest_group
 			run_tests_for_pipe(&data, pipe);
 
+	for_each_pipe_static(pipe)
+		igt_subtest_group
+			run_tests_for_plane(&data, pipe);
+
 	igt_fixture {
 		igt_display_fini(&data.display);
 	}
-- 
2.32.0

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

* [i-g-t 09/14] tests/kms_color_chamelium: New subtests for Plane degamma
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel
  Cc: Kunal Joshi, Juha-Pekka Heikkila, Uma Shankar, Bhanuprakash Modem

To verify Plane degamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out degamma LUT and verify we have the same frame dump as
drawing solid color rectangles with linear gamma LUT.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 131 ++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index b506109271..3bcb3ac043 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -874,6 +874,132 @@ static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	drmModePropertyPtr degamma_mode;
+	struct igt_fb fb, fbref;
+	struct chamelium_port *port;
+	uint32_t i;
+	bool ret = true;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane degamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
+
+	for_each_valid_output_on_pipe(display, plane->pipe->pipe, output) {
+		for (i = 0; i < data->port_count; i++)
+			if (strcmp(output->name, chamelium_port_get_name(data->ports[i])) == 0) {
+				port = data->ports[i];
+				break;
+			}
+
+		if (port)
+			break;
+	}
+	igt_require(port);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fbref));
+
+	disable_degamma(plane->pipe);
+	disable_ctm(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_degamma(plane);
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+
+	igt_plane_set_fb(plane, &fbref);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Draw solid colors with no degamma. */
+	paint_rectangles(data, mode, red_green_blue, &fbref);
+
+	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
+	/* Iterate all supported degamma modes. */
+	for (i = 0; i < degamma_mode->count_enums; i++) {
+		struct chamelium_frame_dump *frame_fullcolors;
+		segment_data_t *degamma_segment_info = NULL;
+		struct drm_color_lut_ext *degamma_lut = NULL;
+		uint32_t degamma_lut_size = 0;
+
+		/* Ignore 'no degamma' from enum list. */
+		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
+			continue;
+
+		degamma_segment_info = get_segment_data(data, degamma_mode->enums[i].value,
+						degamma_mode->enums[i].name);
+		degamma_lut_size = sizeof(struct drm_color_lut_ext) * degamma_segment_info->entries_count;
+		degamma_lut = create_max_lut(degamma_segment_info);
+
+		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
+
+		/* Draw a gradient with degamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		set_plane_degamma(plane, degamma_mode->enums[i].name,
+				degamma_lut, degamma_lut_size);
+		igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+		chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 1);
+		frame_fullcolors =
+			chamelium_read_captured_frame(data->chamelium, 0);
+
+		/* Verify that the framebuffer reference of the software computed
+		 * output is equal to the frame dump of the gamma LUT
+		 * transformation output.
+		 */
+		ret &= chamelium_frame_match_or_dump(data->chamelium, port,
+				frame_fullcolors, &fbref,
+				CHAMELIUM_CHECK_ANALOG);
+
+		free(degamma_lut);
+		clear_segment_data(degamma_segment_info);
+	}
+
+	disable_plane_degamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	drmModeFreeProperty(degamma_mode);
+
+	return ret;
+}
+
 static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 {
 	igt_plane_t *plane;
@@ -903,6 +1029,11 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_subtest_f("pipe-%s-plane-gamma",
 			kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_gamma_test);
+
+	igt_describe("Compare maxed out plane degamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-degamma",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_degamma_test);
 }
 
 igt_main
-- 
2.32.0


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

* [igt-dev] [i-g-t 09/14] tests/kms_color_chamelium: New subtests for Plane degamma
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Kunal Joshi

To verify Plane degamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out degamma LUT and verify we have the same frame dump as
drawing solid color rectangles with linear gamma LUT.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 131 ++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index b506109271..3bcb3ac043 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -874,6 +874,132 @@ static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	drmModePropertyPtr degamma_mode;
+	struct igt_fb fb, fbref;
+	struct chamelium_port *port;
+	uint32_t i;
+	bool ret = true;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane degamma test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
+
+	for_each_valid_output_on_pipe(display, plane->pipe->pipe, output) {
+		for (i = 0; i < data->port_count; i++)
+			if (strcmp(output->name, chamelium_port_get_name(data->ports[i])) == 0) {
+				port = data->ports[i];
+				break;
+			}
+
+		if (port)
+			break;
+	}
+	igt_require(port);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fbref));
+
+	disable_degamma(plane->pipe);
+	disable_ctm(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_degamma(plane);
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+
+	igt_plane_set_fb(plane, &fbref);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Draw solid colors with no degamma. */
+	paint_rectangles(data, mode, red_green_blue, &fbref);
+
+	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
+	/* Iterate all supported degamma modes. */
+	for (i = 0; i < degamma_mode->count_enums; i++) {
+		struct chamelium_frame_dump *frame_fullcolors;
+		segment_data_t *degamma_segment_info = NULL;
+		struct drm_color_lut_ext *degamma_lut = NULL;
+		uint32_t degamma_lut_size = 0;
+
+		/* Ignore 'no degamma' from enum list. */
+		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
+			continue;
+
+		degamma_segment_info = get_segment_data(data, degamma_mode->enums[i].value,
+						degamma_mode->enums[i].name);
+		degamma_lut_size = sizeof(struct drm_color_lut_ext) * degamma_segment_info->entries_count;
+		degamma_lut = create_max_lut(degamma_segment_info);
+
+		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
+
+		/* Draw a gradient with degamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		set_plane_degamma(plane, degamma_mode->enums[i].name,
+				degamma_lut, degamma_lut_size);
+		igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+		chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 1);
+		frame_fullcolors =
+			chamelium_read_captured_frame(data->chamelium, 0);
+
+		/* Verify that the framebuffer reference of the software computed
+		 * output is equal to the frame dump of the gamma LUT
+		 * transformation output.
+		 */
+		ret &= chamelium_frame_match_or_dump(data->chamelium, port,
+				frame_fullcolors, &fbref,
+				CHAMELIUM_CHECK_ANALOG);
+
+		free(degamma_lut);
+		clear_segment_data(degamma_segment_info);
+	}
+
+	disable_plane_degamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	drmModeFreeProperty(degamma_mode);
+
+	return ret;
+}
+
 static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 {
 	igt_plane_t *plane;
@@ -903,6 +1029,11 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_subtest_f("pipe-%s-plane-gamma",
 			kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_gamma_test);
+
+	igt_describe("Compare maxed out plane degamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-degamma",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_degamma_test);
 }
 
 igt_main
-- 
2.32.0

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

* [i-g-t 10/14] tests/kms_color_chamelium: New subtests for Plane CTM
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel
  Cc: Kunal Joshi, Juha-Pekka Heikkila, Uma Shankar, Bhanuprakash Modem

To verify plane CTM, draw 3 rectangles using before colors with the
ctm matrix applied and verify the frame dump is equal to using after
colors with an identify ctm matrix.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 229 ++++++++++++++++++++++++++++++++++++
 1 file changed, 229 insertions(+)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index 3bcb3ac043..af820565d3 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -53,6 +53,77 @@ static bool is_valid_plane(igt_plane_t *plane)
 	return index >= 0 && index < MAX_SUPPORTED_PLANES;
 }
 
+struct {
+	const char *test_name;
+	int iter;
+	color_t expected_colors[3];
+	double ctm[9];
+} ctm_tests[] = {
+	{"plane-ctm-red-to-blue", 0,
+					{{ 0.0, 0.0, 1.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 0.0, 0.0, 0.0,
+		  0.0, 1.0, 0.0,
+		  1.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-green-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 1.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 1.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0,
+		  0.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-blue-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 1.0, 0.0, 0.0 }},
+		{ 1.0, 0.0, 1.0,
+		  0.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0 },
+	},
+	{"plane-ctm-max", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 100.0, 0.0, 0.0,
+		  0.0, 100.0, 0.0,
+		  0.0, 0.0, 100.0 },
+	},
+	{"plane-ctm-negative", 0,
+					{{ 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 }},
+		{ -1.0, 0.0, 0.0,
+		   0.0, -1.0, 0.0,
+		   0.0, 0.0, -1.0 },
+	},
+	/* We tests a few values around the expected result because
+	 * it depends on the hardware we're dealing with, we can
+	 * either get clamped or rounded values and we also need to
+	 * account for odd number of items in the LUTs.
+	 */
+	{"plane-ctm-0-25", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.25, 0.0,  0.0,
+		  0.0,  0.25, 0.0,
+		  0.0,  0.0,  0.25 },
+	},
+	{"plane-ctm-0-50", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.5,  0.0,  0.0,
+		  0.0,  0.5,  0.0,
+		  0.0,  0.0,  0.5 },
+	},
+	{"plane-ctm-0-75", 7,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.75, 0.0,  0.0,
+		  0.0,  0.75, 0.0,
+		  0.0,  0.0,  0.75 },
+	},
+};
+
 /*
  * Draw 3 gradient rectangles in red, green and blue, with a maxed out
  * degamma LUT and verify we have the same frame dump as drawing solid color
@@ -1000,6 +1071,103 @@ static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool test_plane_ctm(data_t *data,
+			  igt_plane_t *plane,
+			  color_t *before,
+			  color_t *after,
+			  double *ctm_matrix)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb, fbref;
+	struct chamelium_port *port;
+	struct chamelium_frame_dump *frame_hardware;
+	uint32_t i;
+	bool ret = true;
+
+	igt_info("Plane CTM test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
+
+	for_each_valid_output_on_pipe(display, plane->pipe->pipe, output) {
+		for (i = 0; i < data->port_count; i++)
+			if (strcmp(output->name, chamelium_port_get_name(data->ports[i])) == 0) {
+				port = data->ports[i];
+				break;
+			}
+
+		if (port)
+			break;
+	}
+	igt_require(port);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fbref));
+
+	disable_degamma(plane->pipe);
+	disable_ctm(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_degamma(plane);
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+
+	igt_plane_set_fb(plane, &fbref);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Without CTM transformation. */
+	paint_rectangles(data, mode, after, &fbref);
+
+	/* With CTM transformation. */
+	paint_rectangles(data, mode, before, &fb);
+	igt_plane_set_fb(plane, &fb);
+	set_plane_ctm(plane, ctm_matrix);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 1);
+	frame_hardware =
+		chamelium_read_captured_frame(data->chamelium, 0);
+
+	/* Verify that the framebuffer reference of the software
+	 * computed output is equal to the frame dump of the CTM
+	 * matrix transformation output.
+	 */
+	ret = chamelium_frame_match_or_dump(data->chamelium, port,
+					     frame_hardware,
+					     &fbref,
+					     CHAMELIUM_CHECK_ANALOG);
+
+	disable_plane_ctm(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	return ret;
+}
+
 static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 {
 	igt_plane_t *plane;
@@ -1017,8 +1185,57 @@ static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 	igt_require_f(count, "No valid planes found.\n");
 }
 
+static void run_plane_ctm_test(data_t *data,
+				enum pipe pipe,
+				color_t *expected,
+				double *ctm,
+				int iter)
+{
+	igt_plane_t *plane;
+	bool result;
+	int i, count = 0;
+	double delta = 1.0 / (1 << 8);
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!is_valid_plane(plane))
+			continue;
+
+		result = false;
+
+		if (!iter)
+			result |= test_plane_ctm(data, plane,
+					red_green_blue, expected,
+					ctm);
+
+		for (i = 0; i < iter; i++) {
+			expected[0].r =
+			expected[1].g =
+			expected[2].b =
+				ctm[0] + delta * (i - (iter/2));
+
+			result |= test_plane_ctm(data, plane,
+					red_green_blue,	expected,
+					ctm);
+			if (result)
+				break;
+		}
+
+		igt_assert(result);
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
 static void run_tests_for_plane(data_t *data, enum pipe pipe)
 {
+	int i;
+
 	igt_fixture {
 		igt_require_pipe(&data->display, pipe);
 		igt_require(data->display.pipes[pipe].n_planes > 0);
@@ -1034,6 +1251,18 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_subtest_f("pipe-%s-plane-degamma",
 			kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_degamma_test);
+
+	for (i = 0; i < ARRAY_SIZE(ctm_tests); i++) {
+		igt_describe("Compare after applying ctm matrix & identity matrix");
+		igt_subtest_f("pipe-%s-%s",
+				kmstest_pipe_name(pipe),
+				ctm_tests[i].test_name) {
+			run_plane_ctm_test(data, pipe,
+					ctm_tests[i].expected_colors,
+					ctm_tests[i].ctm,
+					ctm_tests[i].iter);
+		}
+	}
 }
 
 igt_main
-- 
2.32.0


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

* [igt-dev] [i-g-t 10/14] tests/kms_color_chamelium: New subtests for Plane CTM
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Kunal Joshi

To verify plane CTM, draw 3 rectangles using before colors with the
ctm matrix applied and verify the frame dump is equal to using after
colors with an identify ctm matrix.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 229 ++++++++++++++++++++++++++++++++++++
 1 file changed, 229 insertions(+)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index 3bcb3ac043..af820565d3 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -53,6 +53,77 @@ static bool is_valid_plane(igt_plane_t *plane)
 	return index >= 0 && index < MAX_SUPPORTED_PLANES;
 }
 
+struct {
+	const char *test_name;
+	int iter;
+	color_t expected_colors[3];
+	double ctm[9];
+} ctm_tests[] = {
+	{"plane-ctm-red-to-blue", 0,
+					{{ 0.0, 0.0, 1.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 0.0, 0.0, 0.0,
+		  0.0, 1.0, 0.0,
+		  1.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-green-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 1.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 1.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0,
+		  0.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-blue-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 1.0, 0.0, 0.0 }},
+		{ 1.0, 0.0, 1.0,
+		  0.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0 },
+	},
+	{"plane-ctm-max", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 100.0, 0.0, 0.0,
+		  0.0, 100.0, 0.0,
+		  0.0, 0.0, 100.0 },
+	},
+	{"plane-ctm-negative", 0,
+					{{ 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 }},
+		{ -1.0, 0.0, 0.0,
+		   0.0, -1.0, 0.0,
+		   0.0, 0.0, -1.0 },
+	},
+	/* We tests a few values around the expected result because
+	 * it depends on the hardware we're dealing with, we can
+	 * either get clamped or rounded values and we also need to
+	 * account for odd number of items in the LUTs.
+	 */
+	{"plane-ctm-0-25", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.25, 0.0,  0.0,
+		  0.0,  0.25, 0.0,
+		  0.0,  0.0,  0.25 },
+	},
+	{"plane-ctm-0-50", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.5,  0.0,  0.0,
+		  0.0,  0.5,  0.0,
+		  0.0,  0.0,  0.5 },
+	},
+	{"plane-ctm-0-75", 7,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.75, 0.0,  0.0,
+		  0.0,  0.75, 0.0,
+		  0.0,  0.0,  0.75 },
+	},
+};
+
 /*
  * Draw 3 gradient rectangles in red, green and blue, with a maxed out
  * degamma LUT and verify we have the same frame dump as drawing solid color
@@ -1000,6 +1071,103 @@ static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool test_plane_ctm(data_t *data,
+			  igt_plane_t *plane,
+			  color_t *before,
+			  color_t *after,
+			  double *ctm_matrix)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb, fbref;
+	struct chamelium_port *port;
+	struct chamelium_frame_dump *frame_hardware;
+	uint32_t i;
+	bool ret = true;
+
+	igt_info("Plane CTM test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
+
+	for_each_valid_output_on_pipe(display, plane->pipe->pipe, output) {
+		for (i = 0; i < data->port_count; i++)
+			if (strcmp(output->name, chamelium_port_get_name(data->ports[i])) == 0) {
+				port = data->ports[i];
+				break;
+			}
+
+		if (port)
+			break;
+	}
+	igt_require(port);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fbref));
+
+	disable_degamma(plane->pipe);
+	disable_ctm(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_degamma(plane);
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+
+	igt_plane_set_fb(plane, &fbref);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Without CTM transformation. */
+	paint_rectangles(data, mode, after, &fbref);
+
+	/* With CTM transformation. */
+	paint_rectangles(data, mode, before, &fb);
+	igt_plane_set_fb(plane, &fb);
+	set_plane_ctm(plane, ctm_matrix);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 1);
+	frame_hardware =
+		chamelium_read_captured_frame(data->chamelium, 0);
+
+	/* Verify that the framebuffer reference of the software
+	 * computed output is equal to the frame dump of the CTM
+	 * matrix transformation output.
+	 */
+	ret = chamelium_frame_match_or_dump(data->chamelium, port,
+					     frame_hardware,
+					     &fbref,
+					     CHAMELIUM_CHECK_ANALOG);
+
+	disable_plane_ctm(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	return ret;
+}
+
 static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 {
 	igt_plane_t *plane;
@@ -1017,8 +1185,57 @@ static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 	igt_require_f(count, "No valid planes found.\n");
 }
 
+static void run_plane_ctm_test(data_t *data,
+				enum pipe pipe,
+				color_t *expected,
+				double *ctm,
+				int iter)
+{
+	igt_plane_t *plane;
+	bool result;
+	int i, count = 0;
+	double delta = 1.0 / (1 << 8);
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!is_valid_plane(plane))
+			continue;
+
+		result = false;
+
+		if (!iter)
+			result |= test_plane_ctm(data, plane,
+					red_green_blue, expected,
+					ctm);
+
+		for (i = 0; i < iter; i++) {
+			expected[0].r =
+			expected[1].g =
+			expected[2].b =
+				ctm[0] + delta * (i - (iter/2));
+
+			result |= test_plane_ctm(data, plane,
+					red_green_blue,	expected,
+					ctm);
+			if (result)
+				break;
+		}
+
+		igt_assert(result);
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
 static void run_tests_for_plane(data_t *data, enum pipe pipe)
 {
+	int i;
+
 	igt_fixture {
 		igt_require_pipe(&data->display, pipe);
 		igt_require(data->display.pipes[pipe].n_planes > 0);
@@ -1034,6 +1251,18 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_subtest_f("pipe-%s-plane-degamma",
 			kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_degamma_test);
+
+	for (i = 0; i < ARRAY_SIZE(ctm_tests); i++) {
+		igt_describe("Compare after applying ctm matrix & identity matrix");
+		igt_subtest_f("pipe-%s-%s",
+				kmstest_pipe_name(pipe),
+				ctm_tests[i].test_name) {
+			run_plane_ctm_test(data, pipe,
+					ctm_tests[i].expected_colors,
+					ctm_tests[i].ctm,
+					ctm_tests[i].iter);
+		}
+	}
 }
 
 igt_main
-- 
2.32.0

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

* [i-g-t 11/14] lib/igt_kms: Add pipe color mgmt properties
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel
  Cc: Mukunda Pramodh Kumar, Juha-Pekka Heikkila, Uma Shankar,
	Bhanuprakash Modem

From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>

Add support for Pipe color management properties.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 lib/igt_kms.c | 1 +
 lib/igt_kms.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index fdb83e0f91..677d26fedb 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -592,6 +592,7 @@ const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
 	[IGT_CRTC_CTM] = "CTM",
 	[IGT_CRTC_GAMMA_LUT] = "GAMMA_LUT",
 	[IGT_CRTC_GAMMA_LUT_SIZE] = "GAMMA_LUT_SIZE",
+	[IGT_CRTC_GAMMA_MODE] = "GAMMA_MODE",
 	[IGT_CRTC_DEGAMMA_LUT] = "DEGAMMA_LUT",
 	[IGT_CRTC_DEGAMMA_LUT_SIZE] = "DEGAMMA_LUT_SIZE",
 	[IGT_CRTC_MODE_ID] = "MODE_ID",
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 3a1f7243ad..5fac651fa3 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -119,6 +119,7 @@ enum igt_atomic_crtc_properties {
        IGT_CRTC_CTM = 0,
        IGT_CRTC_GAMMA_LUT,
        IGT_CRTC_GAMMA_LUT_SIZE,
+       IGT_CRTC_GAMMA_MODE,
        IGT_CRTC_DEGAMMA_LUT,
        IGT_CRTC_DEGAMMA_LUT_SIZE,
        IGT_CRTC_MODE_ID,
-- 
2.32.0


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

* [igt-dev] [i-g-t 11/14] lib/igt_kms: Add pipe color mgmt properties
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Mukunda Pramodh Kumar

From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>

Add support for Pipe color management properties.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 lib/igt_kms.c | 1 +
 lib/igt_kms.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index fdb83e0f91..677d26fedb 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -592,6 +592,7 @@ const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
 	[IGT_CRTC_CTM] = "CTM",
 	[IGT_CRTC_GAMMA_LUT] = "GAMMA_LUT",
 	[IGT_CRTC_GAMMA_LUT_SIZE] = "GAMMA_LUT_SIZE",
+	[IGT_CRTC_GAMMA_MODE] = "GAMMA_MODE",
 	[IGT_CRTC_DEGAMMA_LUT] = "DEGAMMA_LUT",
 	[IGT_CRTC_DEGAMMA_LUT_SIZE] = "DEGAMMA_LUT_SIZE",
 	[IGT_CRTC_MODE_ID] = "MODE_ID",
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 3a1f7243ad..5fac651fa3 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -119,6 +119,7 @@ enum igt_atomic_crtc_properties {
        IGT_CRTC_CTM = 0,
        IGT_CRTC_GAMMA_LUT,
        IGT_CRTC_GAMMA_LUT_SIZE,
+       IGT_CRTC_GAMMA_MODE,
        IGT_CRTC_DEGAMMA_LUT,
        IGT_CRTC_DEGAMMA_LUT_SIZE,
        IGT_CRTC_MODE_ID,
-- 
2.32.0

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

* [i-g-t 12/14] kms_color_helper: Add helper functions to support logarithmic gamma mode
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel
  Cc: Mukunda Pramodh Kumar, Juha-Pekka Heikkila, Uma Shankar,
	Bhanuprakash Modem

From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>

Add helper functions to support logarithmic gamma mode

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_helper.c | 127 +++++++++++++++++++++++++++++++++++++++
 tests/kms_color_helper.h |  16 +++++
 2 files changed, 143 insertions(+)

diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
index c65b7a0f50..7ea8282df3 100644
--- a/tests/kms_color_helper.c
+++ b/tests/kms_color_helper.c
@@ -190,6 +190,33 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
 	return lut;
 }
 
+struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
+						const gamma_lut_t *gamma,
+						uint32_t color_depth,
+						int off)
+{
+	struct drm_color_lut *lut;
+	int i, lut_size = gamma->size;
+	/* This is the maximum value due to 16 bit precision in hardware. */
+	uint32_t max_hw_value = (1 << 16) - 1;
+	unsigned int max_segment_value = 1 << 24;
+
+	lut = malloc(sizeof(struct drm_color_lut) * lut_size);
+
+	for (i = 0; i < lut_size; i++) {
+		double scaling_factor = (double)max_hw_value / (double)max_segment_value;
+		uint32_t r = MIN((gamma->coeffs[i].r * scaling_factor), max_hw_value);
+		uint32_t g = MIN((gamma->coeffs[i].g * scaling_factor), max_hw_value);
+		uint32_t b = MIN((gamma->coeffs[i].b * scaling_factor), max_hw_value);
+
+		lut[i].red = r;
+		lut[i].green = g;
+		lut[i].blue = b;
+	}
+
+	return lut;
+}
+
 void set_degamma(data_t *data,
 		 igt_pipe_t *pipe,
 		 const gamma_lut_t *gamma)
@@ -203,6 +230,15 @@ void set_degamma(data_t *data,
 	free(lut);
 }
 
+void set_pipe_gamma(igt_pipe_t *pipe,
+		    uint64_t value,
+		    struct drm_color_lut *lut,
+		    uint32_t size)
+{
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_MODE, value);
+	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
+}
+
 void set_gamma(data_t *data,
 	       igt_pipe_t *pipe, const gamma_lut_t *gamma)
 {
@@ -241,6 +277,51 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
 		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
 }
 
+drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
+					       enum igt_atomic_crtc_properties prop)
+{
+	igt_display_t *display = pipe->display;
+	uint32_t prop_id = pipe->props[prop];
+	drmModePropertyPtr drmProp;
+
+	igt_assert(prop_id);
+
+	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
+
+	igt_assert(drmProp);
+	igt_assert(drmProp->count_enums);
+
+	return drmProp;
+}
+
+gamma_lut_t *pipe_create_linear_lut(segment_data_t *info)
+{
+	uint32_t segment, entry, index = 0;
+	double val;
+	int i = 0;
+	gamma_lut_t *gamma = alloc_lut(info->entries_count);
+
+	igt_assert(gamma);
+
+	gamma->size = info->entries_count;
+	for (segment = 0; segment < info->segment_count; segment++) {
+		uint32_t entry_count = info->segment_data[segment].count;
+		uint32_t start = (segment == 0) ? 0 : (1 << (segment - 1));
+		uint32_t end = 1 << segment;
+
+		for (entry = 0; entry < entry_count; entry++) {
+			val = (index == 0) ? /* First entry is Zero. */
+				0 : start + entry *
+				((end - start) * 1.0 / entry_count);
+
+			set_rgb(&gamma->coeffs[i++], val);
+			index++;
+		}
+	}
+
+	return gamma;
+}
+
 drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
 				enum igt_atomic_plane_properties prop)
 {
@@ -331,6 +412,7 @@ segment_data_t *get_segment_data(data_t *data,
 	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
 	igt_assert(info->segment_data);
 
+	info->entries_count = 0;
 	for (i = 0; i < info->segment_count; i++) {
 		info->entries_count += lut_range[i].count;
 		info->segment_data[i] = lut_range[i];
@@ -341,6 +423,51 @@ segment_data_t *get_segment_data(data_t *data,
 	return info;
 }
 
+void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type)
+{
+	igt_display_t *display = &data->display;
+	gamma_lut_t *gamma_log;
+	drmModePropertyPtr gamma_mode = NULL;
+	segment_data_t *segment_info = NULL;
+	struct drm_color_lut *lut = NULL;
+	int lut_size = 0;
+
+	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
+	gamma_mode = get_pipe_gamma_degamma_mode(pipe, IGT_CRTC_GAMMA_MODE);
+
+	for (int i = 0; i < gamma_mode->count_enums; i++) {
+		if (!strcmp(gamma_mode->enums[i].name, "logarithmic gamma")) {
+			segment_info = get_segment_data(data,
+							gamma_mode->enums[i].value,
+							gamma_mode->enums[i].name);
+			lut_size = sizeof(struct drm_color_lut) *
+					  segment_info->entries_count;
+			if (type == LINEAR_GAMMA) {
+				gamma_log = pipe_create_linear_lut(segment_info);
+				lut = coeffs_to_logarithmic_lut(data,
+								gamma_log,
+								data->color_depth,
+								0);
+			} else if (type == MAX_GAMMA) {
+				gamma_log = generate_table_max(segment_info->entries_count);
+				gamma_log->size = segment_info->entries_count;
+				lut = coeffs_to_lut(data, gamma_log,
+						    data->color_depth, 0);
+			}
+			set_pipe_gamma(pipe, gamma_mode->enums[i].value,
+				       lut, lut_size);
+			igt_display_commit2(display, display->is_atomic
+					    ? COMMIT_ATOMIC : COMMIT_LEGACY);
+			break;
+		}
+	}
+	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
+	free(gamma_log);
+	free(lut);
+	clear_segment_data(segment_info);
+	drmModeFreeProperty(gamma_mode);
+}
+
 void set_plane_gamma(igt_plane_t *plane,
 		char *mode,
 		struct drm_color_lut_ext *lut,
diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
index 5a35dcaac1..c863874f0c 100644
--- a/tests/kms_color_helper.h
+++ b/tests/kms_color_helper.h
@@ -70,6 +70,11 @@ typedef struct {
 	uint32_t entries_count;
 } segment_data_t;
 
+enum gamma_type {
+	LINEAR_GAMMA,
+	MAX_GAMMA
+};
+
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 
 void paint_gradient_rectangles(data_t *data,
@@ -89,6 +94,10 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
 				    const gamma_lut_t *gamma,
 				    uint32_t color_depth,
 				    int off);
+struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
+						const gamma_lut_t *gamma,
+						uint32_t color_depth,
+						int off);
 void set_degamma(data_t *data,
 		 igt_pipe_t *pipe,
 		 const gamma_lut_t *gamma);
@@ -98,12 +107,19 @@ void set_gamma(data_t *data,
 void set_ctm(igt_pipe_t *pipe, const double *coefficients);
 void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
 
+drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
+					       enum igt_atomic_crtc_properties
+					       prop);
 drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
 	enum igt_atomic_plane_properties prop);
 void clear_segment_data(segment_data_t *info);
+gamma_lut_t *pipe_create_linear_lut(segment_data_t *info);
 struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
 struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
 segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
+void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
+		    struct drm_color_lut *lut, uint32_t size);
+void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type);
 void set_plane_gamma(igt_plane_t *plane,
 	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
 void set_plane_degamma(igt_plane_t *plane,
-- 
2.32.0


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

* [igt-dev] [i-g-t 12/14] kms_color_helper: Add helper functions to support logarithmic gamma mode
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Mukunda Pramodh Kumar

From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>

Add helper functions to support logarithmic gamma mode

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_helper.c | 127 +++++++++++++++++++++++++++++++++++++++
 tests/kms_color_helper.h |  16 +++++
 2 files changed, 143 insertions(+)

diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
index c65b7a0f50..7ea8282df3 100644
--- a/tests/kms_color_helper.c
+++ b/tests/kms_color_helper.c
@@ -190,6 +190,33 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
 	return lut;
 }
 
+struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
+						const gamma_lut_t *gamma,
+						uint32_t color_depth,
+						int off)
+{
+	struct drm_color_lut *lut;
+	int i, lut_size = gamma->size;
+	/* This is the maximum value due to 16 bit precision in hardware. */
+	uint32_t max_hw_value = (1 << 16) - 1;
+	unsigned int max_segment_value = 1 << 24;
+
+	lut = malloc(sizeof(struct drm_color_lut) * lut_size);
+
+	for (i = 0; i < lut_size; i++) {
+		double scaling_factor = (double)max_hw_value / (double)max_segment_value;
+		uint32_t r = MIN((gamma->coeffs[i].r * scaling_factor), max_hw_value);
+		uint32_t g = MIN((gamma->coeffs[i].g * scaling_factor), max_hw_value);
+		uint32_t b = MIN((gamma->coeffs[i].b * scaling_factor), max_hw_value);
+
+		lut[i].red = r;
+		lut[i].green = g;
+		lut[i].blue = b;
+	}
+
+	return lut;
+}
+
 void set_degamma(data_t *data,
 		 igt_pipe_t *pipe,
 		 const gamma_lut_t *gamma)
@@ -203,6 +230,15 @@ void set_degamma(data_t *data,
 	free(lut);
 }
 
+void set_pipe_gamma(igt_pipe_t *pipe,
+		    uint64_t value,
+		    struct drm_color_lut *lut,
+		    uint32_t size)
+{
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_MODE, value);
+	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
+}
+
 void set_gamma(data_t *data,
 	       igt_pipe_t *pipe, const gamma_lut_t *gamma)
 {
@@ -241,6 +277,51 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
 		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
 }
 
+drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
+					       enum igt_atomic_crtc_properties prop)
+{
+	igt_display_t *display = pipe->display;
+	uint32_t prop_id = pipe->props[prop];
+	drmModePropertyPtr drmProp;
+
+	igt_assert(prop_id);
+
+	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
+
+	igt_assert(drmProp);
+	igt_assert(drmProp->count_enums);
+
+	return drmProp;
+}
+
+gamma_lut_t *pipe_create_linear_lut(segment_data_t *info)
+{
+	uint32_t segment, entry, index = 0;
+	double val;
+	int i = 0;
+	gamma_lut_t *gamma = alloc_lut(info->entries_count);
+
+	igt_assert(gamma);
+
+	gamma->size = info->entries_count;
+	for (segment = 0; segment < info->segment_count; segment++) {
+		uint32_t entry_count = info->segment_data[segment].count;
+		uint32_t start = (segment == 0) ? 0 : (1 << (segment - 1));
+		uint32_t end = 1 << segment;
+
+		for (entry = 0; entry < entry_count; entry++) {
+			val = (index == 0) ? /* First entry is Zero. */
+				0 : start + entry *
+				((end - start) * 1.0 / entry_count);
+
+			set_rgb(&gamma->coeffs[i++], val);
+			index++;
+		}
+	}
+
+	return gamma;
+}
+
 drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
 				enum igt_atomic_plane_properties prop)
 {
@@ -331,6 +412,7 @@ segment_data_t *get_segment_data(data_t *data,
 	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
 	igt_assert(info->segment_data);
 
+	info->entries_count = 0;
 	for (i = 0; i < info->segment_count; i++) {
 		info->entries_count += lut_range[i].count;
 		info->segment_data[i] = lut_range[i];
@@ -341,6 +423,51 @@ segment_data_t *get_segment_data(data_t *data,
 	return info;
 }
 
+void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type)
+{
+	igt_display_t *display = &data->display;
+	gamma_lut_t *gamma_log;
+	drmModePropertyPtr gamma_mode = NULL;
+	segment_data_t *segment_info = NULL;
+	struct drm_color_lut *lut = NULL;
+	int lut_size = 0;
+
+	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
+	gamma_mode = get_pipe_gamma_degamma_mode(pipe, IGT_CRTC_GAMMA_MODE);
+
+	for (int i = 0; i < gamma_mode->count_enums; i++) {
+		if (!strcmp(gamma_mode->enums[i].name, "logarithmic gamma")) {
+			segment_info = get_segment_data(data,
+							gamma_mode->enums[i].value,
+							gamma_mode->enums[i].name);
+			lut_size = sizeof(struct drm_color_lut) *
+					  segment_info->entries_count;
+			if (type == LINEAR_GAMMA) {
+				gamma_log = pipe_create_linear_lut(segment_info);
+				lut = coeffs_to_logarithmic_lut(data,
+								gamma_log,
+								data->color_depth,
+								0);
+			} else if (type == MAX_GAMMA) {
+				gamma_log = generate_table_max(segment_info->entries_count);
+				gamma_log->size = segment_info->entries_count;
+				lut = coeffs_to_lut(data, gamma_log,
+						    data->color_depth, 0);
+			}
+			set_pipe_gamma(pipe, gamma_mode->enums[i].value,
+				       lut, lut_size);
+			igt_display_commit2(display, display->is_atomic
+					    ? COMMIT_ATOMIC : COMMIT_LEGACY);
+			break;
+		}
+	}
+	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
+	free(gamma_log);
+	free(lut);
+	clear_segment_data(segment_info);
+	drmModeFreeProperty(gamma_mode);
+}
+
 void set_plane_gamma(igt_plane_t *plane,
 		char *mode,
 		struct drm_color_lut_ext *lut,
diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
index 5a35dcaac1..c863874f0c 100644
--- a/tests/kms_color_helper.h
+++ b/tests/kms_color_helper.h
@@ -70,6 +70,11 @@ typedef struct {
 	uint32_t entries_count;
 } segment_data_t;
 
+enum gamma_type {
+	LINEAR_GAMMA,
+	MAX_GAMMA
+};
+
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 
 void paint_gradient_rectangles(data_t *data,
@@ -89,6 +94,10 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
 				    const gamma_lut_t *gamma,
 				    uint32_t color_depth,
 				    int off);
+struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
+						const gamma_lut_t *gamma,
+						uint32_t color_depth,
+						int off);
 void set_degamma(data_t *data,
 		 igt_pipe_t *pipe,
 		 const gamma_lut_t *gamma);
@@ -98,12 +107,19 @@ void set_gamma(data_t *data,
 void set_ctm(igt_pipe_t *pipe, const double *coefficients);
 void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
 
+drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
+					       enum igt_atomic_crtc_properties
+					       prop);
 drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
 	enum igt_atomic_plane_properties prop);
 void clear_segment_data(segment_data_t *info);
+gamma_lut_t *pipe_create_linear_lut(segment_data_t *info);
 struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
 struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
 segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
+void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
+		    struct drm_color_lut *lut, uint32_t size);
+void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type);
 void set_plane_gamma(igt_plane_t *plane,
 	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
 void set_plane_degamma(igt_plane_t *plane,
-- 
2.32.0

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

* [i-g-t 13/14] tests/kms_color: Extended IGT tests to support logarithmic gamma mode
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel
  Cc: Mukunda Pramodh Kumar, Juha-Pekka Heikkila, Uma Shankar,
	Bhanuprakash Modem

From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>

Extended IGT tests to support logarithmic gamma mode on pipe

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index d9fe417ba9..00742afaaf 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -232,8 +232,6 @@ static void test_pipe_gamma(data_t *data,
 
 	igt_require(igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_LUT));
 
-	gamma_full = generate_table_max(data->gamma_lut_size);
-
 	output = igt_get_single_output_for_pipe(&data->display, primary->pipe->pipe);
 	igt_require(output);
 
@@ -258,10 +256,13 @@ static void test_pipe_gamma(data_t *data,
 	igt_assert(fb_modeset_id);
 
 	igt_plane_set_fb(primary, &fb_modeset);
+	/* Reset Color properties */
 	disable_ctm(primary->pipe);
 	disable_degamma(primary->pipe);
-	set_gamma(data, primary->pipe, gamma_full);
+	disable_gamma(primary->pipe);
 	igt_display_commit(&data->display);
+	igt_wait_for_vblank(data->drm_fd,
+			    display->pipes[primary->pipe->pipe].crtc_offset);
 
 	/* Draw solid colors with no gamma transformation. */
 	paint_rectangles(data, mode, red_green_blue, &fb);
@@ -274,6 +275,13 @@ static void test_pipe_gamma(data_t *data,
 	/* Draw a gradient with gamma LUT to remap all values
 	 * to max red/green/blue.
 	 */
+	if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE)) {
+		set_advance_gamma(data, primary->pipe, MAX_GAMMA);
+	} else {
+		gamma_full = generate_table_max(data->gamma_lut_size);
+		set_gamma(data, primary->pipe, gamma_full);
+		igt_display_commit(&data->display);
+	}
 	paint_gradient_rectangles(data, mode, red_green_blue, &fb);
 	igt_plane_set_fb(primary, &fb);
 	igt_display_commit(&data->display);
@@ -581,7 +589,10 @@ static bool test_pipe_ctm(data_t *data,
 	 */
 	if (memcmp(before, after, sizeof(color_t))) {
 		set_degamma(data, primary->pipe, degamma_linear);
-		set_gamma(data, primary->pipe, gamma_linear);
+		if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE))
+			disable_gamma(primary->pipe);
+		else
+			set_gamma(data, primary->pipe, gamma_linear);
 	} else {
 		/* Disable Degamma and Gamma for ctm max test */
 		disable_degamma(primary->pipe);
-- 
2.32.0


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

* [igt-dev] [i-g-t 13/14] tests/kms_color: Extended IGT tests to support logarithmic gamma mode
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Mukunda Pramodh Kumar

From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>

Extended IGT tests to support logarithmic gamma mode on pipe

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index d9fe417ba9..00742afaaf 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -232,8 +232,6 @@ static void test_pipe_gamma(data_t *data,
 
 	igt_require(igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_LUT));
 
-	gamma_full = generate_table_max(data->gamma_lut_size);
-
 	output = igt_get_single_output_for_pipe(&data->display, primary->pipe->pipe);
 	igt_require(output);
 
@@ -258,10 +256,13 @@ static void test_pipe_gamma(data_t *data,
 	igt_assert(fb_modeset_id);
 
 	igt_plane_set_fb(primary, &fb_modeset);
+	/* Reset Color properties */
 	disable_ctm(primary->pipe);
 	disable_degamma(primary->pipe);
-	set_gamma(data, primary->pipe, gamma_full);
+	disable_gamma(primary->pipe);
 	igt_display_commit(&data->display);
+	igt_wait_for_vblank(data->drm_fd,
+			    display->pipes[primary->pipe->pipe].crtc_offset);
 
 	/* Draw solid colors with no gamma transformation. */
 	paint_rectangles(data, mode, red_green_blue, &fb);
@@ -274,6 +275,13 @@ static void test_pipe_gamma(data_t *data,
 	/* Draw a gradient with gamma LUT to remap all values
 	 * to max red/green/blue.
 	 */
+	if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE)) {
+		set_advance_gamma(data, primary->pipe, MAX_GAMMA);
+	} else {
+		gamma_full = generate_table_max(data->gamma_lut_size);
+		set_gamma(data, primary->pipe, gamma_full);
+		igt_display_commit(&data->display);
+	}
 	paint_gradient_rectangles(data, mode, red_green_blue, &fb);
 	igt_plane_set_fb(primary, &fb);
 	igt_display_commit(&data->display);
@@ -581,7 +589,10 @@ static bool test_pipe_ctm(data_t *data,
 	 */
 	if (memcmp(before, after, sizeof(color_t))) {
 		set_degamma(data, primary->pipe, degamma_linear);
-		set_gamma(data, primary->pipe, gamma_linear);
+		if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE))
+			disable_gamma(primary->pipe);
+		else
+			set_gamma(data, primary->pipe, gamma_linear);
 	} else {
 		/* Disable Degamma and Gamma for ctm max test */
 		disable_degamma(primary->pipe);
-- 
2.32.0

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

* [i-g-t 14/14] tests/kms_color_chamelium: Extended IGT tests to support logarithmic gamma mode
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  -1 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel
  Cc: Kunal Joshi, Mukunda Pramodh Kumar, Juha-Pekka Heikkila,
	Uma Shankar, Bhanuprakash Modem

Extended IGT tests to support logarithmic gamma mode on pipe

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 40 ++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index af820565d3..26e940f4c1 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -317,10 +317,21 @@ static void test_pipe_gamma(data_t *data,
 		igt_assert(fbref_id);
 
 		igt_plane_set_fb(primary, &fb_modeset);
+
+		/* Reset the color properties */
 		disable_ctm(primary->pipe);
 		disable_degamma(primary->pipe);
-		set_gamma(data, primary->pipe, gamma_full);
+		disable_gamma(primary->pipe);
 		igt_display_commit(&data->display);
+		igt_wait_for_vblank(data->drm_fd,
+				    data->display.pipes[primary->pipe->pipe].crtc_offset);
+
+		if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE)) {
+			set_advance_gamma(data, primary->pipe, MAX_GAMMA);
+		} else {
+			set_gamma(data, primary->pipe, gamma_full);
+			igt_display_commit(&data->display);
+		}
 
 		/* Draw solid colors with no gamma transformation. */
 		paint_rectangles(data, mode, red_green_blue, &fbref);
@@ -343,6 +354,7 @@ static void test_pipe_gamma(data_t *data,
 					      frame_fullcolors, &fbref,
 					      CHAMELIUM_CHECK_ANALOG);
 
+		/* Cleanup */
 		disable_gamma(primary->pipe);
 		igt_plane_set_fb(primary, NULL);
 		igt_output_set_pipe(output, PIPE_NONE);
@@ -431,7 +443,10 @@ static bool test_pipe_ctm(data_t *data,
 
 		if (memcmp(before, after, sizeof(color_t))) {
 			set_degamma(data, primary->pipe, degamma_linear);
-			set_gamma(data, primary->pipe, gamma_linear);
+			if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE))
+				disable_gamma(primary->pipe);
+			else
+				set_gamma(data, primary->pipe, gamma_linear);
 		} else {
 			/* Disable Degamma and Gamma for ctm max test */
 			disable_degamma(primary->pipe);
@@ -465,6 +480,12 @@ static bool test_pipe_ctm(data_t *data,
 		igt_output_set_pipe(output, PIPE_NONE);
 	}
 
+	/* Cleanup */
+	disable_gamma(primary->pipe);
+	disable_degamma(primary->pipe);
+	disable_ctm(primary->pipe);
+	igt_display_commit(&data->display);
+
 	free_lut(degamma_linear);
 	free_lut(gamma_linear);
 
@@ -561,7 +582,14 @@ static void test_pipe_limited_range_ctm(data_t *data,
 		igt_plane_set_fb(primary, &fb_modeset);
 
 		set_degamma(data, primary->pipe, degamma_linear);
-		set_gamma(data, primary->pipe, gamma_linear);
+		/*
+		 * No need of linear gamma for limited range ctm test
+		 * Not extending for new API interface.
+		 */
+		if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE))
+			disable_gamma(primary->pipe);
+		else
+			set_gamma(data, primary->pipe, gamma_linear);
 		set_ctm(primary->pipe, ctm);
 
 		igt_output_set_prop_value(output,
@@ -598,6 +626,12 @@ static void test_pipe_limited_range_ctm(data_t *data,
 
 	}
 
+	/* Cleanup */
+	disable_gamma(primary->pipe);
+	disable_degamma(primary->pipe);
+	disable_ctm(primary->pipe);
+	igt_display_commit(&data->display);
+
 	free_lut(gamma_linear);
 	free_lut(degamma_linear);
 
-- 
2.32.0


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

* [igt-dev] [i-g-t 14/14] tests/kms_color_chamelium: Extended IGT tests to support logarithmic gamma mode
@ 2021-11-15  9:47   ` Bhanuprakash Modem
  0 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2021-11-15  9:47 UTC (permalink / raw)
  To: igt-dev, dri-devel; +Cc: Kunal Joshi, Mukunda Pramodh Kumar

Extended IGT tests to support logarithmic gamma mode on pipe

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 40 ++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index af820565d3..26e940f4c1 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -317,10 +317,21 @@ static void test_pipe_gamma(data_t *data,
 		igt_assert(fbref_id);
 
 		igt_plane_set_fb(primary, &fb_modeset);
+
+		/* Reset the color properties */
 		disable_ctm(primary->pipe);
 		disable_degamma(primary->pipe);
-		set_gamma(data, primary->pipe, gamma_full);
+		disable_gamma(primary->pipe);
 		igt_display_commit(&data->display);
+		igt_wait_for_vblank(data->drm_fd,
+				    data->display.pipes[primary->pipe->pipe].crtc_offset);
+
+		if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE)) {
+			set_advance_gamma(data, primary->pipe, MAX_GAMMA);
+		} else {
+			set_gamma(data, primary->pipe, gamma_full);
+			igt_display_commit(&data->display);
+		}
 
 		/* Draw solid colors with no gamma transformation. */
 		paint_rectangles(data, mode, red_green_blue, &fbref);
@@ -343,6 +354,7 @@ static void test_pipe_gamma(data_t *data,
 					      frame_fullcolors, &fbref,
 					      CHAMELIUM_CHECK_ANALOG);
 
+		/* Cleanup */
 		disable_gamma(primary->pipe);
 		igt_plane_set_fb(primary, NULL);
 		igt_output_set_pipe(output, PIPE_NONE);
@@ -431,7 +443,10 @@ static bool test_pipe_ctm(data_t *data,
 
 		if (memcmp(before, after, sizeof(color_t))) {
 			set_degamma(data, primary->pipe, degamma_linear);
-			set_gamma(data, primary->pipe, gamma_linear);
+			if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE))
+				disable_gamma(primary->pipe);
+			else
+				set_gamma(data, primary->pipe, gamma_linear);
 		} else {
 			/* Disable Degamma and Gamma for ctm max test */
 			disable_degamma(primary->pipe);
@@ -465,6 +480,12 @@ static bool test_pipe_ctm(data_t *data,
 		igt_output_set_pipe(output, PIPE_NONE);
 	}
 
+	/* Cleanup */
+	disable_gamma(primary->pipe);
+	disable_degamma(primary->pipe);
+	disable_ctm(primary->pipe);
+	igt_display_commit(&data->display);
+
 	free_lut(degamma_linear);
 	free_lut(gamma_linear);
 
@@ -561,7 +582,14 @@ static void test_pipe_limited_range_ctm(data_t *data,
 		igt_plane_set_fb(primary, &fb_modeset);
 
 		set_degamma(data, primary->pipe, degamma_linear);
-		set_gamma(data, primary->pipe, gamma_linear);
+		/*
+		 * No need of linear gamma for limited range ctm test
+		 * Not extending for new API interface.
+		 */
+		if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE))
+			disable_gamma(primary->pipe);
+		else
+			set_gamma(data, primary->pipe, gamma_linear);
 		set_ctm(primary->pipe, ctm);
 
 		igt_output_set_prop_value(output,
@@ -598,6 +626,12 @@ static void test_pipe_limited_range_ctm(data_t *data,
 
 	}
 
+	/* Cleanup */
+	disable_gamma(primary->pipe);
+	disable_degamma(primary->pipe);
+	disable_ctm(primary->pipe);
+	igt_display_commit(&data->display);
+
 	free_lut(gamma_linear);
 	free_lut(degamma_linear);
 
-- 
2.32.0

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

* [igt-dev] ✓ Fi.CI.BAT: success for Add IGT support for plane color management
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
                   ` (14 preceding siblings ...)
  (?)
@ 2021-11-15 11:14 ` Patchwork
  -1 siblings, 0 replies; 96+ messages in thread
From: Patchwork @ 2021-11-15 11:14 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 2546 bytes --]

== Series Details ==

Series: Add IGT support for plane color management
URL   : https://patchwork.freedesktop.org/series/96895/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_10881 -> IGTPW_6398
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/index.html

Participating hosts (40 -> 35)
------------------------------

  Additional (1): fi-snb-2520m 
  Missing    (6): fi-kbl-soraka bat-dg1-6 fi-tgl-u2 bat-dg1-5 fi-icl-u2 fi-bdw-samus 

Known issues
------------

  Here are the changes found in IGTPW_6398 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_chamelium@dp-crc-fast:
    - fi-bsw-nick:        NOTRUN -> [SKIP][1] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/fi-bsw-nick/igt@kms_chamelium@dp-crc-fast.html

  * igt@prime_vgem@basic-fence-flip:
    - fi-bsw-nick:        NOTRUN -> [SKIP][2] ([fdo#109271]) +55 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/fi-bsw-nick/igt@prime_vgem@basic-fence-flip.html

  * igt@runner@aborted:
    - fi-snb-2520m:       NOTRUN -> [FAIL][3] ([i915#2426])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/fi-snb-2520m/igt@runner@aborted.html

  
#### Possible fixes ####

  * igt@gem_ringfill@basic-all:
    - fi-bsw-nick:        [DMESG-WARN][4] ([i915#3428]) -> [PASS][5]
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/fi-bsw-nick/igt@gem_ringfill@basic-all.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/fi-bsw-nick/igt@gem_ringfill@basic-all.html

  
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#2426]: https://gitlab.freedesktop.org/drm/intel/issues/2426
  [i915#3428]: https://gitlab.freedesktop.org/drm/intel/issues/3428


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_6280 -> IGTPW_6398

  CI-20190529: 20190529
  CI_DRM_10881: ec2cf62da73ea8fd5f28c1a20468296bcae41d4a @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_6398: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/index.html
  IGT_6280: 246bfd31dba6bf184b26b170d91d72c90a54be6b @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git



== Testlist changes ==

+++ 138 lines
--- 0 lines

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/index.html

[-- Attachment #2: Type: text/html, Size: 3305 bytes --]

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

* [igt-dev] ✗ Fi.CI.IGT: failure for Add IGT support for plane color management
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
                   ` (15 preceding siblings ...)
  (?)
@ 2021-11-15 13:36 ` Patchwork
  -1 siblings, 0 replies; 96+ messages in thread
From: Patchwork @ 2021-11-15 13:36 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 30260 bytes --]

== Series Details ==

Series: Add IGT support for plane color management
URL   : https://patchwork.freedesktop.org/series/96895/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_10881_full -> IGTPW_6398_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_6398_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_6398_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/index.html

Participating hosts (11 -> 7)
------------------------------

  Missing    (4): pig-skl-6260u pig-kbl-iris shard-rkl pig-glk-j5005 

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_6398_full:

### IGT changes ###

#### Possible regressions ####

  * igt@kms_color@pipe-b-gamma:
    - shard-kbl:          [PASS][1] -> [FAIL][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-kbl6/igt@kms_color@pipe-b-gamma.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-kbl1/igt@kms_color@pipe-b-gamma.html

  * {igt@kms_color@pipe-b-plane-ctm-red-to-blue} (NEW):
    - shard-tglb:         NOTRUN -> [SKIP][3] +40 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb5/igt@kms_color@pipe-b-plane-ctm-red-to-blue.html

  * igt@kms_color@pipe-c-gamma:
    - shard-glk:          [PASS][4] -> [FAIL][5] +1 similar issue
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-glk3/igt@kms_color@pipe-c-gamma.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-glk6/igt@kms_color@pipe-c-gamma.html
    - shard-apl:          [PASS][6] -> [FAIL][7] +1 similar issue
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-apl8/igt@kms_color@pipe-c-gamma.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-apl4/igt@kms_color@pipe-c-gamma.html
    - shard-kbl:          NOTRUN -> [FAIL][8]
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-kbl7/igt@kms_color@pipe-c-gamma.html

  
#### Warnings ####

  * igt@gem_pread@exhaustion:
    - shard-tglb:         [WARN][9] ([i915#2658]) -> [DMESG-WARN][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-tglb5/igt@gem_pread@exhaustion.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb2/igt@gem_pread@exhaustion.html

  
New tests
---------

  New tests have been introduced between CI_DRM_10881_full and IGTPW_6398_full:

### New IGT tests (92) ###

  * igt@kms_color@pipe-a-invalid-plane-ctm-matrix-sizes:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-a-invalid-plane-degamma-lut-sizes:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-a-invalid-plane-gamma-lut-sizes:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-a-plane-ctm-0-25:
    - Statuses : 3 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-a-plane-ctm-0-50:
    - Statuses :
    - Exec time: [None] s

  * igt@kms_color@pipe-a-plane-ctm-0-75:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-a-plane-ctm-blue-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-a-plane-ctm-green-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-a-plane-ctm-max:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-a-plane-ctm-negative:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-a-plane-ctm-red-to-blue:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-a-plane-degamma:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-a-plane-gamma:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-invalid-plane-ctm-matrix-sizes:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-invalid-plane-degamma-lut-sizes:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-invalid-plane-gamma-lut-sizes:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-plane-ctm-0-25:
    - Statuses :
    - Exec time: [None] s

  * igt@kms_color@pipe-b-plane-ctm-0-50:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-plane-ctm-0-75:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-plane-ctm-blue-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-plane-ctm-green-to-red:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-plane-ctm-max:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-plane-ctm-negative:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-plane-ctm-red-to-blue:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-plane-degamma:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-b-plane-gamma:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-invalid-plane-ctm-matrix-sizes:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-invalid-plane-degamma-lut-sizes:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-invalid-plane-gamma-lut-sizes:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-plane-ctm-0-25:
    - Statuses : 1 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-plane-ctm-0-50:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-plane-ctm-0-75:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-plane-ctm-blue-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-plane-ctm-green-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@kms_color@pipe-c-plane-ctm-max:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-plane-ctm-negative:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-plane-ctm-red-to-blue:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-plane-degamma:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-c-plane-gamma:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-invalid-plane-ctm-matrix-sizes:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-invalid-plane-degamma-lut-sizes:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-invalid-plane-gamma-lut-sizes:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-plane-ctm-0-25:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-plane-ctm-0-50:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-plane-ctm-0-75:
    - Statuses : 3 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-plane-ctm-blue-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-plane-ctm-green-to-red:
    - Statuses : 3 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-plane-ctm-max:
    - Statuses : 1 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-plane-ctm-negative:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-plane-ctm-red-to-blue:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color@pipe-d-plane-degamma:
    - Statuses :
    - Exec time: [None] s

  * igt@kms_color@pipe-d-plane-gamma:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-a-plane-ctm-0-25:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-a-plane-ctm-0-50:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-a-plane-ctm-0-75:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-a-plane-ctm-blue-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-a-plane-ctm-green-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-a-plane-ctm-max:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-a-plane-ctm-negative:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-a-plane-ctm-red-to-blue:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-a-plane-degamma:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-a-plane-gamma:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-b-plane-ctm-0-25:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-b-plane-ctm-0-50:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-b-plane-ctm-0-75:
    - Statuses : 1 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-b-plane-ctm-blue-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-b-plane-ctm-green-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-b-plane-ctm-max:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-b-plane-ctm-negative:
    - Statuses :
    - Exec time: [None] s

  * igt@kms_color_chamelium@pipe-b-plane-ctm-red-to-blue:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-b-plane-degamma:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-b-plane-gamma:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-c-plane-ctm-0-25:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-c-plane-ctm-0-50:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-c-plane-ctm-0-75:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-c-plane-ctm-blue-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-c-plane-ctm-green-to-red:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-c-plane-ctm-max:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-c-plane-ctm-negative:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-c-plane-ctm-red-to-blue:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-c-plane-degamma:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-c-plane-gamma:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-d-plane-ctm-0-25:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-d-plane-ctm-0-50:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-d-plane-ctm-0-75:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-d-plane-ctm-blue-to-red:
    - Statuses : 2 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-d-plane-ctm-green-to-red:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-d-plane-ctm-max:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-d-plane-ctm-negative:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-d-plane-ctm-red-to-blue:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-d-plane-degamma:
    - Statuses : 1 skip(s)
    - Exec time: [0.0] s

  * igt@kms_color_chamelium@pipe-d-plane-gamma:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  

Known issues
------------

  Here are the changes found in IGTPW_6398_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_create@create-massive:
    - shard-tglb:         NOTRUN -> [DMESG-WARN][11] ([i915#3002])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb1/igt@gem_create@create-massive.html
    - shard-apl:          NOTRUN -> [DMESG-WARN][12] ([i915#3002])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-apl1/igt@gem_create@create-massive.html

  * igt@gem_ctx_isolation@preservation-s3@rcs0:
    - shard-apl:          NOTRUN -> [DMESG-WARN][13] ([i915#180])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-apl1/igt@gem_ctx_isolation@preservation-s3@rcs0.html

  * igt@gem_ctx_param@set-priority-not-supported:
    - shard-tglb:         NOTRUN -> [SKIP][14] ([fdo#109314])
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb8/igt@gem_ctx_param@set-priority-not-supported.html

  * igt@gem_ctx_sseu@mmap-args:
    - shard-tglb:         NOTRUN -> [SKIP][15] ([i915#280])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb6/igt@gem_ctx_sseu@mmap-args.html

  * igt@gem_exec_balancer@parallel-keep-submit-fence:
    - shard-tglb:         NOTRUN -> [SKIP][16] ([i915#4525])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb1/igt@gem_exec_balancer@parallel-keep-submit-fence.html

  * igt@gem_exec_fair@basic-none-share@rcs0:
    - shard-apl:          [PASS][17] -> [SKIP][18] ([fdo#109271])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-apl2/igt@gem_exec_fair@basic-none-share@rcs0.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-apl2/igt@gem_exec_fair@basic-none-share@rcs0.html

  * igt@gem_exec_fair@basic-none@vcs1:
    - shard-iclb:         NOTRUN -> [FAIL][19] ([i915#2842])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-iclb1/igt@gem_exec_fair@basic-none@vcs1.html

  * igt@gem_exec_fair@basic-pace-solo@rcs0:
    - shard-kbl:          [PASS][20] -> [FAIL][21] ([i915#2842])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-kbl6/igt@gem_exec_fair@basic-pace-solo@rcs0.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-kbl2/igt@gem_exec_fair@basic-pace-solo@rcs0.html

  * igt@gem_exec_fair@basic-pace@vcs0:
    - shard-iclb:         [PASS][22] -> [FAIL][23] ([i915#2842])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-iclb4/igt@gem_exec_fair@basic-pace@vcs0.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-iclb4/igt@gem_exec_fair@basic-pace@vcs0.html
    - shard-tglb:         [PASS][24] -> [FAIL][25] ([i915#2842])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-tglb1/igt@gem_exec_fair@basic-pace@vcs0.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb6/igt@gem_exec_fair@basic-pace@vcs0.html

  * igt@gem_exec_flush@basic-batch-kernel-default-cmd:
    - shard-tglb:         NOTRUN -> [SKIP][26] ([fdo#109313])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb3/igt@gem_exec_flush@basic-batch-kernel-default-cmd.html

  * igt@gem_exec_whisper@basic-contexts-forked-all:
    - shard-glk:          [PASS][27] -> [DMESG-WARN][28] ([i915#118])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-glk5/igt@gem_exec_whisper@basic-contexts-forked-all.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-glk7/igt@gem_exec_whisper@basic-contexts-forked-all.html

  * igt@gem_mmap_gtt@coherency:
    - shard-tglb:         NOTRUN -> [SKIP][29] ([fdo#111656])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb5/igt@gem_mmap_gtt@coherency.html

  * igt@gem_pxp@dmabuf-shared-protected-dst-is-context-refcounted:
    - shard-tglb:         NOTRUN -> [SKIP][30] ([i915#4270]) +1 similar issue
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb1/igt@gem_pxp@dmabuf-shared-protected-dst-is-context-refcounted.html

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-kbl:          [PASS][31] -> [DMESG-WARN][32] ([i915#180]) +1 similar issue
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-kbl2/igt@gem_workarounds@suspend-resume-fd.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-kbl3/igt@gem_workarounds@suspend-resume-fd.html

  * igt@gen3_render_linear_blits:
    - shard-tglb:         NOTRUN -> [SKIP][33] ([fdo#109289]) +2 similar issues
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb1/igt@gen3_render_linear_blits.html

  * igt@gen9_exec_parse@bb-start-far:
    - shard-tglb:         NOTRUN -> [SKIP][34] ([i915#2856])
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb3/igt@gen9_exec_parse@bb-start-far.html

  * igt@i915_pm_lpsp@screens-disabled:
    - shard-tglb:         NOTRUN -> [SKIP][35] ([i915#1902])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb7/igt@i915_pm_lpsp@screens-disabled.html

  * igt@i915_pm_rpm@modeset-pc8-residency-stress:
    - shard-tglb:         NOTRUN -> [SKIP][36] ([fdo#109506] / [i915#2411])
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb1/igt@i915_pm_rpm@modeset-pc8-residency-stress.html

  * igt@i915_pm_rpm@system-suspend:
    - shard-kbl:          [PASS][37] -> [INCOMPLETE][38] ([i915#151])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-kbl7/igt@i915_pm_rpm@system-suspend.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-kbl2/igt@i915_pm_rpm@system-suspend.html

  * igt@kms_big_fb@linear-32bpp-rotate-180:
    - shard-glk:          NOTRUN -> [DMESG-WARN][39] ([i915#118]) +1 similar issue
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-glk4/igt@kms_big_fb@linear-32bpp-rotate-180.html

  * igt@kms_big_fb@x-tiled-16bpp-rotate-270:
    - shard-tglb:         NOTRUN -> [SKIP][40] ([fdo#111614]) +1 similar issue
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb3/igt@kms_big_fb@x-tiled-16bpp-rotate-270.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-0-hflip:
    - shard-apl:          NOTRUN -> [SKIP][41] ([fdo#109271] / [i915#3777])
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-apl7/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-0-hflip.html

  * igt@kms_ccs@pipe-a-random-ccs-data-y_tiled_gen12_mc_ccs:
    - shard-kbl:          NOTRUN -> [SKIP][42] ([fdo#109271] / [i915#3886]) +3 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-kbl2/igt@kms_ccs@pipe-a-random-ccs-data-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-b-bad-pixel-format-y_tiled_gen12_mc_ccs:
    - shard-apl:          NOTRUN -> [SKIP][43] ([fdo#109271] / [i915#3886]) +5 similar issues
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-apl4/igt@kms_ccs@pipe-b-bad-pixel-format-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-b-bad-pixel-format-y_tiled_gen12_rc_ccs_cc:
    - shard-iclb:         NOTRUN -> [SKIP][44] ([fdo#109278] / [i915#3886]) +1 similar issue
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-iclb2/igt@kms_ccs@pipe-b-bad-pixel-format-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-b-bad-rotation-90-y_tiled_gen12_mc_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][45] ([i915#3689] / [i915#3886]) +3 similar issues
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb3/igt@kms_ccs@pipe-b-bad-rotation-90-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-c-crc-primary-rotation-180-y_tiled_gen12_rc_ccs_cc:
    - shard-glk:          NOTRUN -> [SKIP][46] ([fdo#109271] / [i915#3886]) +2 similar issues
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-glk4/igt@kms_ccs@pipe-c-crc-primary-rotation-180-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-d-bad-rotation-90-yf_tiled_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][47] ([i915#3689]) +11 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb6/igt@kms_ccs@pipe-d-bad-rotation-90-yf_tiled_ccs.html

  * igt@kms_chamelium@dp-hpd-storm-disable:
    - shard-glk:          NOTRUN -> [SKIP][48] ([fdo#109271] / [fdo#111827]) +1 similar issue
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-glk9/igt@kms_chamelium@dp-hpd-storm-disable.html

  * igt@kms_chamelium@hdmi-audio-edid:
    - shard-kbl:          NOTRUN -> [SKIP][49] ([fdo#109271] / [fdo#111827]) +4 similar issues
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-kbl4/igt@kms_chamelium@hdmi-audio-edid.html

  * igt@kms_chamelium@vga-hpd-fast:
    - shard-tglb:         NOTRUN -> [SKIP][50] ([fdo#109284] / [fdo#111827]) +16 similar issues
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb7/igt@kms_chamelium@vga-hpd-fast.html

  * {igt@kms_color@pipe-a-invalid-plane-gamma-lut-sizes} (NEW):
    - shard-apl:          NOTRUN -> [SKIP][51] ([fdo#109271]) +160 similar issues
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-apl7/igt@kms_color@pipe-a-invalid-plane-gamma-lut-sizes.html

  * {igt@kms_color@pipe-a-plane-ctm-0-25} (NEW):
    - shard-glk:          NOTRUN -> [SKIP][52] ([fdo#109271]) +114 similar issues
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-glk8/igt@kms_color@pipe-a-plane-ctm-0-25.html

  * igt@kms_color@pipe-b-gamma:
    - shard-iclb:         [PASS][53] -> [FAIL][54] ([i915#1149]) +1 similar issue
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-iclb5/igt@kms_color@pipe-b-gamma.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-iclb3/igt@kms_color@pipe-b-gamma.html

  * {igt@kms_color@pipe-c-invalid-plane-degamma-lut-sizes} (NEW):
    - shard-iclb:         NOTRUN -> [SKIP][55] ([fdo#109278]) +51 similar issues
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-iclb2/igt@kms_color@pipe-c-invalid-plane-degamma-lut-sizes.html

  * igt@kms_color@pipe-d-gamma:
    - shard-tglb:         [PASS][56] -> [FAIL][57] ([i915#1149]) +2 similar issues
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-tglb8/igt@kms_color@pipe-d-gamma.html
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb6/igt@kms_color@pipe-d-gamma.html

  * {igt@kms_color_chamelium@pipe-a-plane-ctm-blue-to-red} (NEW):
    - shard-iclb:         NOTRUN -> [SKIP][58] ([fdo#109284]) +28 similar issues
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-iclb4/igt@kms_color_chamelium@pipe-a-plane-ctm-blue-to-red.html

  * igt@kms_color_chamelium@pipe-c-ctm-0-25:
    - shard-apl:          NOTRUN -> [SKIP][59] ([fdo#109271] / [fdo#111827]) +7 similar issues
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-apl2/igt@kms_color_chamelium@pipe-c-ctm-0-25.html

  * {igt@kms_color_chamelium@pipe-c-plane-ctm-negative} (NEW):
    - shard-kbl:          NOTRUN -> [SKIP][60] ([fdo#109271]) +124 similar issues
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-kbl3/igt@kms_color_chamelium@pipe-c-plane-ctm-negative.html

  * {igt@kms_color_chamelium@pipe-d-plane-ctm-green-to-red} (NEW):
    - shard-tglb:         NOTRUN -> [SKIP][61] ([fdo#109284]) +34 similar issues
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb3/igt@kms_color_chamelium@pipe-d-plane-ctm-green-to-red.html

  * {igt@kms_color_chamelium@pipe-d-plane-degamma} (NEW):
    - shard-iclb:         NOTRUN -> [SKIP][62] ([fdo#109278] / [fdo#109284]) +8 similar issues
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-iclb3/igt@kms_color_chamelium@pipe-d-plane-degamma.html

  * igt@kms_content_protection@dp-mst-lic-type-1:
    - shard-tglb:         NOTRUN -> [SKIP][63] ([i915#3116])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb8/igt@kms_content_protection@dp-mst-lic-type-1.html

  * igt@kms_cursor_crc@pipe-b-cursor-32x10-onscreen:
    - shard-tglb:         NOTRUN -> [SKIP][64] ([i915#3359]) +3 similar issues
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb6/igt@kms_cursor_crc@pipe-b-cursor-32x10-onscreen.html

  * igt@kms_cursor_crc@pipe-b-cursor-32x32-sliding:
    - shard-tglb:         NOTRUN -> [SKIP][65] ([i915#3319]) +1 similar issue
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb7/igt@kms_cursor_crc@pipe-b-cursor-32x32-sliding.html

  * igt@kms_cursor_crc@pipe-c-cursor-suspend:
    - shard-apl:          [PASS][66] -> [DMESG-WARN][67] ([i915#180]) +2 similar issues
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-apl3/igt@kms_cursor_crc@pipe-c-cursor-suspend.html
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-apl8/igt@kms_cursor_crc@pipe-c-cursor-suspend.html

  * igt@kms_cursor_crc@pipe-d-cursor-512x512-rapid-movement:
    - shard-tglb:         NOTRUN -> [SKIP][68] ([fdo#109279] / [i915#3359]) +1 similar issue
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb5/igt@kms_cursor_crc@pipe-d-cursor-512x512-rapid-movement.html

  * igt@kms_cursor_legacy@cursora-vs-flipb-atomic:
    - shard-tglb:         NOTRUN -> [SKIP][69] ([fdo#111825]) +30 similar issues
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb8/igt@kms_cursor_legacy@cursora-vs-flipb-atomic.html

  * igt@kms_cursor_legacy@cursorb-vs-flipb-toggle:
    - shard-iclb:         NOTRUN -> [SKIP][70] ([fdo#109274] / [fdo#109278])
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-iclb6/igt@kms_cursor_legacy@cursorb-vs-flipb-toggle.html

  * igt@kms_cursor_legacy@flip-vs-cursor-toggle:
    - shard-iclb:         [PASS][71] -> [FAIL][72] ([i915#2346])
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-iclb5/igt@kms_cursor_legacy@flip-vs-cursor-toggle.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-iclb7/igt@kms_cursor_legacy@flip-vs-cursor-toggle.html

  * igt@kms_dsc@xrgb8888-dsc-compression:
    - shard-tglb:         NOTRUN -> [SKIP][73] ([i915#3828])
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb6/igt@kms_dsc@xrgb8888-dsc-compression.html

  * igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@ac-hdmi-a1-hdmi-a2:
    - shard-glk:          [PASS][74] -> [FAIL][75] ([i915#79])
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-glk2/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@ac-hdmi-a1-hdmi-a2.html
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-glk8/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@ac-hdmi-a1-hdmi-a2.html

  * igt@kms_flip@flip-vs-suspend@a-edp1:
    - shard-tglb:         [PASS][76] -> [INCOMPLETE][77] ([i915#2411] / [i915#456])
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-tglb3/igt@kms_flip@flip-vs-suspend@a-edp1.html
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb7/igt@kms_flip@flip-vs-suspend@a-edp1.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile:
    - shard-iclb:         [PASS][78] -> [SKIP][79] ([i915#3701])
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-iclb6/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile.html
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-iclb2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-indfb-draw-mmap-gtt:
    - shard-iclb:         NOTRUN -> [SKIP][80] ([fdo#109280])
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-iclb4/igt@kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-indfb-draw-mmap-gtt.html

  * igt@kms_hdr@static-toggle-suspend:
    - shard-tglb:         NOTRUN -> [SKIP][81] ([i915#1187])
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb1/igt@kms_hdr@static-toggle-suspend.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - shard-tglb:         [PASS][82] -> [INCOMPLETE][83] ([i915#456])
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-tglb2/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb7/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  * igt@kms_plane_alpha_blend@pipe-b-alpha-7efc:
    - shard-apl:          NOTRUN -> [FAIL][84] ([fdo#108145] / [i915#265])
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-apl7/igt@kms_plane_alpha_blend@pipe-b-alpha-7efc.html

  * igt@kms_plane_alpha_blend@pipe-c-alpha-opaque-fb:
    - shard-kbl:          NOTRUN -> [FAIL][85] ([fdo#108145] / [i915#265])
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-kbl7/igt@kms_plane_alpha_blend@pipe-c-alpha-opaque-fb.html

  * igt@kms_plane_multiple@atomic-pipe-d-tiling-yf:
    - shard-tglb:         NOTRUN -> [SKIP][86] ([fdo#112054])
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb8/igt@kms_plane_multiple@atomic-pipe-d-tiling-yf.html

  * igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-3:
    - shard-apl:          NOTRUN -> [SKIP][87] ([fdo#109271] / [i915#658])
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-apl7/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-3.html

  * igt@kms_psr2_su@frontbuffer:
    - shard-glk:          NOTRUN -> [SKIP][88] ([fdo#109271] / [i915#658])
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-glk6/igt@kms_psr2_su@frontbuffer.html

  * igt@kms_psr@psr2_sprite_mmap_gtt:
    - shard-tglb:         NOTRUN -> [FAIL][89] ([i915#132] / [i915#3467]) +1 similar issue
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/shard-tglb6/igt@kms_psr@psr2_sprite_mmap_gtt.html

  * igt@kms_psr@psr2_suspend:
    - shard-iclb:         [PASS][90] -> [SKIP][91] ([fdo#109441]) +1 similar issue
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10881/shard-iclb2/igt@kms_psr@psr2_suspend.html
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/IG

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6398/index.html

[-- Attachment #2: Type: text/html, Size: 35596 bytes --]

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

* Re: [i-g-t 03/14] kms_color_helper: Add helper functions for plane color mgmt
  2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-18  8:41     ` Pekka Paalanen
  -1 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  8:41 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev, Uma Shankar, dri-devel, Juha-Pekka Heikkila

[-- Attachment #1: Type: text/plain, Size: 10250 bytes --]

On Mon, 15 Nov 2021 15:17:48 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> Add helper functions to support Plane color management properties.
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color_helper.c | 173 +++++++++++++++++++++++++++++++++++++++
>  tests/kms_color_helper.h |  29 +++++++
>  2 files changed, 202 insertions(+)
> 
> diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> index d71e7bb2e6..c65b7a0f50 100644
> --- a/tests/kms_color_helper.c
> +++ b/tests/kms_color_helper.c
> @@ -241,6 +241,150 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
>  }
>  
> +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> +				enum igt_atomic_plane_properties prop)
> +{
> +	igt_display_t *display = plane->pipe->display;
> +	uint32_t prop_id = plane->props[prop];
> +	drmModePropertyPtr drmProp;
> +
> +	igt_assert(prop_id);
> +
> +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> +
> +	igt_assert(drmProp);
> +	igt_assert(drmProp->count_enums);
> +
> +	return drmProp;
> +}
> +
> +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info)

Hi,

this actually creates an identity transformation as a LUT, does it not?
If so, it should be named that way. A linear transformation
represented by a LUT may not be identity transformation.

Identity is quite a bad case to test with, because it is a no-op, and
simply accidentally disabling the whole LUT will pass a writeback test.

> +{
> +	uint32_t val, segment, entry, index = 0;
> +	uint32_t max_val = 0xffffffff;
> +	struct drm_color_lut_ext *lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> +	igt_assert(lut);
> +
> +	for (segment = 0; segment < info->segment_count; segment++) {
> +		uint32_t entry_count = info->segment_data[segment].count;
> +		uint32_t start = info->segment_data[segment].start;
> +		uint32_t end = info->segment_data[segment].end;
> +
> +		for (entry = 1; entry <= entry_count; entry++) {
> +			val = (index == 0) ? /* First entry is Zero. */
> +				0 : start + entry * ((end - start) * 1.0 / entry_count);

Having to explicitly special-case index zero feels odd to me. Why does
it need explicit special-casing?

To me it's a hint that the definitions of .start and .end are somehow
inconsistent.

> +
> +			lut[index].red = lut[index].green = lut[index].blue = MIN(val, max_val);

There are tests that use different curves for each of red, green and
blue and check that they also work, right?

> +
> +			index++;
> +		}
> +	}
> +
> +	return lut;
> +}
> +
> +struct drm_color_lut_ext *create_max_lut(segment_data_t *info)

What is the point of testing this pathological case?

> +{
> +	int i;
> +	struct drm_color_lut_ext *lut;
> +	uint32_t max_val = 0xffffffff;
> +
> +	lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> +	igt_assert(lut);
> +
> +	lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is Zero. */

It's not a max LUT, if the first entry is zero.

> +
> +	for (i = 1; i < info->entries_count; i++)
> +		lut[i].red = lut[i].green = lut[i].blue = max_val;
> +
> +	return lut;
> +}
> +
> +void clear_segment_data(segment_data_t *info)
> +{
> +	if (!info)
> +		return;
> +
> +	free(info->segment_data);
> +	free(info);
> +}
> +
> +segment_data_t *get_segment_data(data_t *data,
> +				uint64_t blob_id, char *mode)
> +{
> +	drmModePropertyBlobPtr blob;
> +	struct drm_color_lut_range *lut_range = NULL;
> +	segment_data_t *info = NULL;
> +	uint32_t i;
> +
> +	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
> +	igt_assert(blob);
> +	igt_assert(blob->length);
> +
> +	info = malloc(sizeof(segment_data_t));
> +	igt_assert(info);
> +
> +	lut_range = (struct drm_color_lut_range *) blob->data;
> +	info->segment_count = blob->length / sizeof(lut_range[0]);
> +	igt_assert(info->segment_count);
> +
> +	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
> +	igt_assert(info->segment_data);
> +
> +	for (i = 0; i < info->segment_count; i++) {
> +		info->entries_count += lut_range[i].count;
> +		info->segment_data[i] = lut_range[i];
> +	}
> +
> +	drmModeFreePropertyBlob(blob);
> +
> +	return info;
> +}
> +
> +void set_plane_gamma(igt_plane_t *plane,
> +		char *mode,
> +		struct drm_color_lut_ext *lut,
> +		uint32_t size)
> +{
> +	igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, mode);
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_GAMMA_LUT, lut, size);
> +}
> +
> +void set_plane_degamma(igt_plane_t *plane,
> +		char *mode,
> +		struct drm_color_lut_ext *lut,
> +		uint32_t size)
> +{
> +	igt_plane_set_prop_enum(plane, IGT_PLANE_DEGAMMA_MODE, mode);
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_DEGAMMA_LUT, lut, size);
> +}
> +
> +void set_plane_ctm(igt_plane_t *plane, const double *coefficients)
> +{
> +	struct drm_color_ctm ctm;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
> +		if (coefficients[i] < 0) {
> +			ctm.matrix[i] =
> +				(int64_t) (-coefficients[i] *
> +				((int64_t) 1L << 32));
> +			ctm.matrix[i] |= 1ULL << 63;
> +		} else
> +			ctm.matrix[i] =
> +				(int64_t) (coefficients[i] *
> +				((int64_t) 1L << 32));
> +	}

Is this literally the only function that converts double to the KMS
matrix element type? If not, I think the value conversion should be a
separate function that just converts a single value, and be called from
all sites that need the same conversion.

> +
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_CTM, &ctm, sizeof(ctm));
> +}
> +
> +void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
> +{
> +	if (igt_plane_has_prop(plane, prop))
> +		igt_plane_replace_prop_blob(plane, prop, NULL, 0);
> +}
> +
>  drmModePropertyBlobPtr
>  get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  {
> @@ -274,6 +418,19 @@ pipe_set_property_blob_id(igt_pipe_t *pipe,
>  	return ret;
>  }
>  
> +static int
> +plane_set_property_blob(igt_display_t *display,
> +			igt_plane_t *plane,
> +			enum igt_atomic_plane_properties prop,
> +			void *ptr, size_t length)
> +{
> +	igt_plane_replace_prop_blob(plane, prop, ptr, length);
> +
> +	return igt_display_try_commit2(display,
> +				       display->is_atomic ?
> +				       COMMIT_ATOMIC : COMMIT_LEGACY);
> +}
> +
>  int
>  pipe_set_property_blob(igt_pipe_t *pipe,
>  		       enum igt_atomic_crtc_properties prop,
> @@ -319,6 +476,22 @@ invalid_lut_sizes(data_t *data, enum pipe p,
>  	free(lut);
>  }
>  
> +void
> +invalid_plane_lut_sizes(igt_display_t *display,
> +			igt_plane_t *plane,
> +			enum igt_atomic_plane_properties prop,
> +			size_t lut_size)
> +{
> +	void *lut = malloc(lut_size * 2);

Feeding garbage data does not seem like a good idea. Maybe it can lead
to EINVAL even when the driver misses the size check because the values
are illegal?

I think this needs to craft a real and good lut data blob, with the
only problem that it is of the wrong size.

> +	igt_assert(lut);
> +
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, 1), -EINVAL);
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size + 1), -EINVAL);
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size - 1), -EINVAL);
> +
> +	free(lut);
> +}

Thanks,
pq


> +
>  void
>  invalid_gamma_lut_sizes(data_t *data, enum pipe p)
>  {
> diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> index bb6f0054f3..5a35dcaac1 100644
> --- a/tests/kms_color_helper.h
> +++ b/tests/kms_color_helper.h
> @@ -64,6 +64,14 @@ typedef struct {
>  	color_t coeffs[];
>  } gamma_lut_t;
>  
> +typedef struct {
> +	uint32_t segment_count;
> +	struct drm_color_lut_range *segment_data;
> +	uint32_t entries_count;
> +} segment_data_t;
> +
> +#define MIN(a, b) ((a) < (b) ? (a) : (b))
> +
>  void paint_gradient_rectangles(data_t *data,
>  			       drmModeModeInfo *mode,
>  			       color_t *colors,
> @@ -90,10 +98,31 @@ void set_gamma(data_t *data,
>  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
>  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
>  
> +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> +	enum igt_atomic_plane_properties prop);
> +void clear_segment_data(segment_data_t *info);
> +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> +struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> +segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
> +void set_plane_gamma(igt_plane_t *plane,
> +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> +void set_plane_degamma(igt_plane_t *plane,
> +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> +void set_plane_ctm(igt_plane_t *plane, const double *coefficients);
> +void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop);
> +void invalid_plane_lut_sizes(igt_display_t *display,
> +			   igt_plane_t *plane,
> +			   enum igt_atomic_plane_properties prop,
> +			   size_t lut_size);
> +
>  #define disable_degamma(pipe) disable_prop(pipe, IGT_CRTC_DEGAMMA_LUT)
>  #define disable_gamma(pipe) disable_prop(pipe, IGT_CRTC_GAMMA_LUT)
>  #define disable_ctm(pipe) disable_prop(pipe, IGT_CRTC_CTM)
>  
> +#define disable_plane_degamma(plane) disable_plane_prop(plane, IGT_PLANE_DEGAMMA_LUT)
> +#define disable_plane_gamma(plane) disable_plane_prop(plane, IGT_PLANE_GAMMA_LUT)
> +#define disable_plane_ctm(plane) disable_plane_prop(plane, IGT_PLANE_CTM)
> +
>  drmModePropertyBlobPtr get_blob(data_t *data, igt_pipe_t *pipe,
>  				enum igt_atomic_crtc_properties prop);
>  bool crc_equal(igt_crc_t *a, igt_crc_t *b);


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [igt-dev] [i-g-t 03/14] kms_color_helper: Add helper functions for plane color mgmt
@ 2021-11-18  8:41     ` Pekka Paalanen
  0 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  8:41 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev, dri-devel

[-- Attachment #1: Type: text/plain, Size: 10250 bytes --]

On Mon, 15 Nov 2021 15:17:48 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> Add helper functions to support Plane color management properties.
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color_helper.c | 173 +++++++++++++++++++++++++++++++++++++++
>  tests/kms_color_helper.h |  29 +++++++
>  2 files changed, 202 insertions(+)
> 
> diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> index d71e7bb2e6..c65b7a0f50 100644
> --- a/tests/kms_color_helper.c
> +++ b/tests/kms_color_helper.c
> @@ -241,6 +241,150 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
>  }
>  
> +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> +				enum igt_atomic_plane_properties prop)
> +{
> +	igt_display_t *display = plane->pipe->display;
> +	uint32_t prop_id = plane->props[prop];
> +	drmModePropertyPtr drmProp;
> +
> +	igt_assert(prop_id);
> +
> +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> +
> +	igt_assert(drmProp);
> +	igt_assert(drmProp->count_enums);
> +
> +	return drmProp;
> +}
> +
> +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info)

Hi,

this actually creates an identity transformation as a LUT, does it not?
If so, it should be named that way. A linear transformation
represented by a LUT may not be identity transformation.

Identity is quite a bad case to test with, because it is a no-op, and
simply accidentally disabling the whole LUT will pass a writeback test.

> +{
> +	uint32_t val, segment, entry, index = 0;
> +	uint32_t max_val = 0xffffffff;
> +	struct drm_color_lut_ext *lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> +	igt_assert(lut);
> +
> +	for (segment = 0; segment < info->segment_count; segment++) {
> +		uint32_t entry_count = info->segment_data[segment].count;
> +		uint32_t start = info->segment_data[segment].start;
> +		uint32_t end = info->segment_data[segment].end;
> +
> +		for (entry = 1; entry <= entry_count; entry++) {
> +			val = (index == 0) ? /* First entry is Zero. */
> +				0 : start + entry * ((end - start) * 1.0 / entry_count);

Having to explicitly special-case index zero feels odd to me. Why does
it need explicit special-casing?

To me it's a hint that the definitions of .start and .end are somehow
inconsistent.

> +
> +			lut[index].red = lut[index].green = lut[index].blue = MIN(val, max_val);

There are tests that use different curves for each of red, green and
blue and check that they also work, right?

> +
> +			index++;
> +		}
> +	}
> +
> +	return lut;
> +}
> +
> +struct drm_color_lut_ext *create_max_lut(segment_data_t *info)

What is the point of testing this pathological case?

> +{
> +	int i;
> +	struct drm_color_lut_ext *lut;
> +	uint32_t max_val = 0xffffffff;
> +
> +	lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> +	igt_assert(lut);
> +
> +	lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is Zero. */

It's not a max LUT, if the first entry is zero.

> +
> +	for (i = 1; i < info->entries_count; i++)
> +		lut[i].red = lut[i].green = lut[i].blue = max_val;
> +
> +	return lut;
> +}
> +
> +void clear_segment_data(segment_data_t *info)
> +{
> +	if (!info)
> +		return;
> +
> +	free(info->segment_data);
> +	free(info);
> +}
> +
> +segment_data_t *get_segment_data(data_t *data,
> +				uint64_t blob_id, char *mode)
> +{
> +	drmModePropertyBlobPtr blob;
> +	struct drm_color_lut_range *lut_range = NULL;
> +	segment_data_t *info = NULL;
> +	uint32_t i;
> +
> +	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
> +	igt_assert(blob);
> +	igt_assert(blob->length);
> +
> +	info = malloc(sizeof(segment_data_t));
> +	igt_assert(info);
> +
> +	lut_range = (struct drm_color_lut_range *) blob->data;
> +	info->segment_count = blob->length / sizeof(lut_range[0]);
> +	igt_assert(info->segment_count);
> +
> +	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
> +	igt_assert(info->segment_data);
> +
> +	for (i = 0; i < info->segment_count; i++) {
> +		info->entries_count += lut_range[i].count;
> +		info->segment_data[i] = lut_range[i];
> +	}
> +
> +	drmModeFreePropertyBlob(blob);
> +
> +	return info;
> +}
> +
> +void set_plane_gamma(igt_plane_t *plane,
> +		char *mode,
> +		struct drm_color_lut_ext *lut,
> +		uint32_t size)
> +{
> +	igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, mode);
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_GAMMA_LUT, lut, size);
> +}
> +
> +void set_plane_degamma(igt_plane_t *plane,
> +		char *mode,
> +		struct drm_color_lut_ext *lut,
> +		uint32_t size)
> +{
> +	igt_plane_set_prop_enum(plane, IGT_PLANE_DEGAMMA_MODE, mode);
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_DEGAMMA_LUT, lut, size);
> +}
> +
> +void set_plane_ctm(igt_plane_t *plane, const double *coefficients)
> +{
> +	struct drm_color_ctm ctm;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
> +		if (coefficients[i] < 0) {
> +			ctm.matrix[i] =
> +				(int64_t) (-coefficients[i] *
> +				((int64_t) 1L << 32));
> +			ctm.matrix[i] |= 1ULL << 63;
> +		} else
> +			ctm.matrix[i] =
> +				(int64_t) (coefficients[i] *
> +				((int64_t) 1L << 32));
> +	}

Is this literally the only function that converts double to the KMS
matrix element type? If not, I think the value conversion should be a
separate function that just converts a single value, and be called from
all sites that need the same conversion.

> +
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_CTM, &ctm, sizeof(ctm));
> +}
> +
> +void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
> +{
> +	if (igt_plane_has_prop(plane, prop))
> +		igt_plane_replace_prop_blob(plane, prop, NULL, 0);
> +}
> +
>  drmModePropertyBlobPtr
>  get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  {
> @@ -274,6 +418,19 @@ pipe_set_property_blob_id(igt_pipe_t *pipe,
>  	return ret;
>  }
>  
> +static int
> +plane_set_property_blob(igt_display_t *display,
> +			igt_plane_t *plane,
> +			enum igt_atomic_plane_properties prop,
> +			void *ptr, size_t length)
> +{
> +	igt_plane_replace_prop_blob(plane, prop, ptr, length);
> +
> +	return igt_display_try_commit2(display,
> +				       display->is_atomic ?
> +				       COMMIT_ATOMIC : COMMIT_LEGACY);
> +}
> +
>  int
>  pipe_set_property_blob(igt_pipe_t *pipe,
>  		       enum igt_atomic_crtc_properties prop,
> @@ -319,6 +476,22 @@ invalid_lut_sizes(data_t *data, enum pipe p,
>  	free(lut);
>  }
>  
> +void
> +invalid_plane_lut_sizes(igt_display_t *display,
> +			igt_plane_t *plane,
> +			enum igt_atomic_plane_properties prop,
> +			size_t lut_size)
> +{
> +	void *lut = malloc(lut_size * 2);

Feeding garbage data does not seem like a good idea. Maybe it can lead
to EINVAL even when the driver misses the size check because the values
are illegal?

I think this needs to craft a real and good lut data blob, with the
only problem that it is of the wrong size.

> +	igt_assert(lut);
> +
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, 1), -EINVAL);
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size + 1), -EINVAL);
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size - 1), -EINVAL);
> +
> +	free(lut);
> +}

Thanks,
pq


> +
>  void
>  invalid_gamma_lut_sizes(data_t *data, enum pipe p)
>  {
> diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> index bb6f0054f3..5a35dcaac1 100644
> --- a/tests/kms_color_helper.h
> +++ b/tests/kms_color_helper.h
> @@ -64,6 +64,14 @@ typedef struct {
>  	color_t coeffs[];
>  } gamma_lut_t;
>  
> +typedef struct {
> +	uint32_t segment_count;
> +	struct drm_color_lut_range *segment_data;
> +	uint32_t entries_count;
> +} segment_data_t;
> +
> +#define MIN(a, b) ((a) < (b) ? (a) : (b))
> +
>  void paint_gradient_rectangles(data_t *data,
>  			       drmModeModeInfo *mode,
>  			       color_t *colors,
> @@ -90,10 +98,31 @@ void set_gamma(data_t *data,
>  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
>  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
>  
> +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> +	enum igt_atomic_plane_properties prop);
> +void clear_segment_data(segment_data_t *info);
> +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> +struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> +segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
> +void set_plane_gamma(igt_plane_t *plane,
> +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> +void set_plane_degamma(igt_plane_t *plane,
> +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> +void set_plane_ctm(igt_plane_t *plane, const double *coefficients);
> +void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop);
> +void invalid_plane_lut_sizes(igt_display_t *display,
> +			   igt_plane_t *plane,
> +			   enum igt_atomic_plane_properties prop,
> +			   size_t lut_size);
> +
>  #define disable_degamma(pipe) disable_prop(pipe, IGT_CRTC_DEGAMMA_LUT)
>  #define disable_gamma(pipe) disable_prop(pipe, IGT_CRTC_GAMMA_LUT)
>  #define disable_ctm(pipe) disable_prop(pipe, IGT_CRTC_CTM)
>  
> +#define disable_plane_degamma(plane) disable_plane_prop(plane, IGT_PLANE_DEGAMMA_LUT)
> +#define disable_plane_gamma(plane) disable_plane_prop(plane, IGT_PLANE_GAMMA_LUT)
> +#define disable_plane_ctm(plane) disable_plane_prop(plane, IGT_PLANE_CTM)
> +
>  drmModePropertyBlobPtr get_blob(data_t *data, igt_pipe_t *pipe,
>  				enum igt_atomic_crtc_properties prop);
>  bool crc_equal(igt_crc_t *a, igt_crc_t *b);


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
  2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-18  9:02     ` Pekka Paalanen
  -1 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:02 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev, Uma Shankar, dri-devel, Juha-Pekka Heikkila

[-- Attachment #1: Type: text/plain, Size: 7632 bytes --]

On Mon, 15 Nov 2021 15:17:49 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> with a maxed out gamma LUT and verify we have the same CRC as drawing solid
> color rectangles.
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 178 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/kms_color.c b/tests/kms_color.c
> index 775f35964f..b45d66762f 100644
> --- a/tests/kms_color.c
> +++ b/tests/kms_color.c
> @@ -24,7 +24,34 @@
>  
>  #include "kms_color_helper.h"
>  
> -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
> +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
> +
> +#define MAX_SUPPORTED_PLANES 7
> +#define SDR_PLANE_BASE 3
> +
> +typedef bool (*test_t)(data_t*, igt_plane_t*);
> +
> +static bool is_hdr_plane(const igt_plane_t *plane)
> +{
> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;

How can this be right for all KMS drivers?

What is a HDR plane?

> +}
> +
> +static bool is_valid_plane(igt_plane_t *plane)
> +{
> +	int index = plane->index;
> +
> +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> +		return false;
> +
> +	/*
> +	 * Test 1 HDR plane, 1 SDR plane.
> +	 *
> +	 * 0,1,2 HDR planes
> +	 * 3,4,5,6 SDR planes

As above, where does this come from? Is this your hardware?

> +	 *
> +	 */
> +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> +}
>  
>  static void test_pipe_degamma(data_t *data,
>  			      igt_plane_t *primary)
> @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t *data,
>  }
>  #endif
>  
> +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> +{
> +	igt_output_t *output;
> +	igt_display_t *display = &data->display;
> +	drmModeModeInfo *mode;
> +	struct igt_fb fb;
> +	drmModePropertyPtr gamma_mode = NULL;
> +	uint32_t i;
> +	bool ret = true;
> +	igt_pipe_crc_t *pipe_crc = NULL;
> +	color_t red_green_blue[] = {
> +		{ 1.0, 0.0, 0.0 },
> +		{ 0.0, 1.0, 0.0 },
> +		{ 0.0, 0.0, 1.0 }
> +	};
> +
> +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
> +			kmstest_pipe_name(plane->pipe->pipe),
> +			kmstest_plane_type_name(plane->type),
> +			is_hdr_plane(plane) ? "hdr":"sdr");
> +
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> +
> +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
> +				  plane->pipe->pipe,
> +				  INTEL_PIPE_CRC_SOURCE_AUTO);
> +
> +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
> +	igt_assert(output);
> +
> +	igt_output_set_pipe(output, plane->pipe->pipe);
> +	mode = igt_output_get_mode(output);
> +
> +	/* Create a framebuffer at the size of the output. */
> +	igt_assert(igt_create_fb(data->drm_fd,
> +			      mode->hdisplay,
> +			      mode->vdisplay,
> +			      DRM_FORMAT_XRGB8888,
> +			      DRM_FORMAT_MOD_LINEAR,
> +			      &fb));
> +	igt_plane_set_fb(plane, &fb);
> +
> +	/* Disable Pipe color props. */
> +	disable_ctm(plane->pipe);
> +	disable_degamma(plane->pipe);
> +	disable_gamma(plane->pipe);
> +
> +	disable_plane_ctm(plane);
> +	disable_plane_degamma(plane);
> +	igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +
> +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> +
> +	/* Iterate all supported gamma modes. */
> +	for (i = 0; i < gamma_mode->count_enums; i++) {
> +		igt_crc_t crc_gamma, crc_fullcolors;
> +		segment_data_t *segment_info = NULL;
> +		struct drm_color_lut_ext *lut = NULL;
> +		uint32_t lut_size = 0;
> +
> +		/* Ignore 'no gamma' from enum list. */
> +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> +			continue;
> +
> +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
> +
> +		/* Draw solid colors with no gamma transformation. */
> +		disable_plane_gamma(plane);
> +		paint_rectangles(data, mode, red_green_blue, &fb);
> +		igt_plane_set_fb(plane, &fb);
> +		igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +		igt_wait_for_vblank(data->drm_fd,
> +			display->pipes[plane->pipe->pipe].crtc_offset);
> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
> +
> +		/* Draw gradient colors with gamma LUT to remap all
> +		 * values to max red/green/blue.
> +		 */
> +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> +				gamma_mode->enums[i].name);
> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
> +		lut = create_max_lut(segment_info);

Using max LUT seems like a weak test. I recall seeing problem reports
related to alpha blending where trying to display an alpha gradient
essentially resulted in what max LUT would produce.


Thanks,
pq

> +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
> +
> +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
> +		igt_plane_set_fb(plane, &fb);
> +		igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +		igt_wait_for_vblank(data->drm_fd,
> +			display->pipes[plane->pipe->pipe].crtc_offset);
> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
> +
> +		/* Verify that the CRC of the software computed output is
> +		 * equal to the CRC of the gamma LUT transformation output.
> +		 */
> +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
> +
> +		free(lut);
> +		clear_segment_data(segment_info);
> +	}
> +
> +	disable_plane_gamma(plane);
> +	igt_plane_set_fb(plane, NULL);
> +	igt_output_set_pipe(output, PIPE_NONE);
> +	igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +
> +	igt_pipe_crc_free(pipe_crc);
> +	drmModeFreeProperty(gamma_mode);
> +
> +	return ret;
> +}
> +
>  static void
>  prep_pipe(data_t *data, enum pipe p)
>  {
> @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
>  		invalid_ctm_matrix_sizes(data, p);
>  }
>  
> +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
> +{
> +	igt_plane_t *plane;
> +	int count = 0;
> +
> +	for_each_plane_on_pipe(&data->display, pipe, plane) {
> +		if (!is_valid_plane(plane))
> +			continue;
> +
> +		igt_assert(test(data, plane));
> +
> +		count++;
> +	}
> +
> +	igt_require_f(count, "No valid planes found.\n");
> +}
> +
> +static void run_tests_for_plane(data_t *data, enum pipe pipe)
> +{
> +	igt_fixture {
> +		igt_require_pipe(&data->display, pipe);
> +		igt_require_pipe_crc(data->drm_fd);
> +		igt_require(data->display.pipes[pipe].n_planes > 0);
> +		igt_display_require_output_on_pipe(&data->display, pipe);
> +	}
> +
> +	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");
> +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
> +		run_plane_color_test(data, pipe, plane_gamma_test);
> +}
> +
>  igt_main
>  {
>  	data_t data = {};
> @@ -910,6 +1084,9 @@ igt_main
>  
>  		igt_subtest_group
>  			run_invalid_tests_for_pipe(&data, pipe);
> +
> +		igt_subtest_group
> +			run_tests_for_plane(&data, pipe);
>  	}
>  
>  	igt_fixture {


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [igt-dev] [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
@ 2021-11-18  9:02     ` Pekka Paalanen
  0 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:02 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev, dri-devel

[-- Attachment #1: Type: text/plain, Size: 7632 bytes --]

On Mon, 15 Nov 2021 15:17:49 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> with a maxed out gamma LUT and verify we have the same CRC as drawing solid
> color rectangles.
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 178 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/kms_color.c b/tests/kms_color.c
> index 775f35964f..b45d66762f 100644
> --- a/tests/kms_color.c
> +++ b/tests/kms_color.c
> @@ -24,7 +24,34 @@
>  
>  #include "kms_color_helper.h"
>  
> -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
> +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
> +
> +#define MAX_SUPPORTED_PLANES 7
> +#define SDR_PLANE_BASE 3
> +
> +typedef bool (*test_t)(data_t*, igt_plane_t*);
> +
> +static bool is_hdr_plane(const igt_plane_t *plane)
> +{
> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;

How can this be right for all KMS drivers?

What is a HDR plane?

> +}
> +
> +static bool is_valid_plane(igt_plane_t *plane)
> +{
> +	int index = plane->index;
> +
> +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> +		return false;
> +
> +	/*
> +	 * Test 1 HDR plane, 1 SDR plane.
> +	 *
> +	 * 0,1,2 HDR planes
> +	 * 3,4,5,6 SDR planes

As above, where does this come from? Is this your hardware?

> +	 *
> +	 */
> +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> +}
>  
>  static void test_pipe_degamma(data_t *data,
>  			      igt_plane_t *primary)
> @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t *data,
>  }
>  #endif
>  
> +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> +{
> +	igt_output_t *output;
> +	igt_display_t *display = &data->display;
> +	drmModeModeInfo *mode;
> +	struct igt_fb fb;
> +	drmModePropertyPtr gamma_mode = NULL;
> +	uint32_t i;
> +	bool ret = true;
> +	igt_pipe_crc_t *pipe_crc = NULL;
> +	color_t red_green_blue[] = {
> +		{ 1.0, 0.0, 0.0 },
> +		{ 0.0, 1.0, 0.0 },
> +		{ 0.0, 0.0, 1.0 }
> +	};
> +
> +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
> +			kmstest_pipe_name(plane->pipe->pipe),
> +			kmstest_plane_type_name(plane->type),
> +			is_hdr_plane(plane) ? "hdr":"sdr");
> +
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> +
> +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
> +				  plane->pipe->pipe,
> +				  INTEL_PIPE_CRC_SOURCE_AUTO);
> +
> +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
> +	igt_assert(output);
> +
> +	igt_output_set_pipe(output, plane->pipe->pipe);
> +	mode = igt_output_get_mode(output);
> +
> +	/* Create a framebuffer at the size of the output. */
> +	igt_assert(igt_create_fb(data->drm_fd,
> +			      mode->hdisplay,
> +			      mode->vdisplay,
> +			      DRM_FORMAT_XRGB8888,
> +			      DRM_FORMAT_MOD_LINEAR,
> +			      &fb));
> +	igt_plane_set_fb(plane, &fb);
> +
> +	/* Disable Pipe color props. */
> +	disable_ctm(plane->pipe);
> +	disable_degamma(plane->pipe);
> +	disable_gamma(plane->pipe);
> +
> +	disable_plane_ctm(plane);
> +	disable_plane_degamma(plane);
> +	igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +
> +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> +
> +	/* Iterate all supported gamma modes. */
> +	for (i = 0; i < gamma_mode->count_enums; i++) {
> +		igt_crc_t crc_gamma, crc_fullcolors;
> +		segment_data_t *segment_info = NULL;
> +		struct drm_color_lut_ext *lut = NULL;
> +		uint32_t lut_size = 0;
> +
> +		/* Ignore 'no gamma' from enum list. */
> +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> +			continue;
> +
> +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
> +
> +		/* Draw solid colors with no gamma transformation. */
> +		disable_plane_gamma(plane);
> +		paint_rectangles(data, mode, red_green_blue, &fb);
> +		igt_plane_set_fb(plane, &fb);
> +		igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +		igt_wait_for_vblank(data->drm_fd,
> +			display->pipes[plane->pipe->pipe].crtc_offset);
> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
> +
> +		/* Draw gradient colors with gamma LUT to remap all
> +		 * values to max red/green/blue.
> +		 */
> +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> +				gamma_mode->enums[i].name);
> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
> +		lut = create_max_lut(segment_info);

Using max LUT seems like a weak test. I recall seeing problem reports
related to alpha blending where trying to display an alpha gradient
essentially resulted in what max LUT would produce.


Thanks,
pq

> +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
> +
> +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
> +		igt_plane_set_fb(plane, &fb);
> +		igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +		igt_wait_for_vblank(data->drm_fd,
> +			display->pipes[plane->pipe->pipe].crtc_offset);
> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
> +
> +		/* Verify that the CRC of the software computed output is
> +		 * equal to the CRC of the gamma LUT transformation output.
> +		 */
> +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
> +
> +		free(lut);
> +		clear_segment_data(segment_info);
> +	}
> +
> +	disable_plane_gamma(plane);
> +	igt_plane_set_fb(plane, NULL);
> +	igt_output_set_pipe(output, PIPE_NONE);
> +	igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +
> +	igt_pipe_crc_free(pipe_crc);
> +	drmModeFreeProperty(gamma_mode);
> +
> +	return ret;
> +}
> +
>  static void
>  prep_pipe(data_t *data, enum pipe p)
>  {
> @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
>  		invalid_ctm_matrix_sizes(data, p);
>  }
>  
> +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
> +{
> +	igt_plane_t *plane;
> +	int count = 0;
> +
> +	for_each_plane_on_pipe(&data->display, pipe, plane) {
> +		if (!is_valid_plane(plane))
> +			continue;
> +
> +		igt_assert(test(data, plane));
> +
> +		count++;
> +	}
> +
> +	igt_require_f(count, "No valid planes found.\n");
> +}
> +
> +static void run_tests_for_plane(data_t *data, enum pipe pipe)
> +{
> +	igt_fixture {
> +		igt_require_pipe(&data->display, pipe);
> +		igt_require_pipe_crc(data->drm_fd);
> +		igt_require(data->display.pipes[pipe].n_planes > 0);
> +		igt_display_require_output_on_pipe(&data->display, pipe);
> +	}
> +
> +	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");
> +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
> +		run_plane_color_test(data, pipe, plane_gamma_test);
> +}
> +
>  igt_main
>  {
>  	data_t data = {};
> @@ -910,6 +1084,9 @@ igt_main
>  
>  		igt_subtest_group
>  			run_invalid_tests_for_pipe(&data, pipe);
> +
> +		igt_subtest_group
> +			run_tests_for_plane(&data, pipe);
>  	}
>  
>  	igt_fixture {


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [i-g-t 07/14] tests/kms_color: New negative tests for plane level color mgmt
  2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-18  9:19     ` Pekka Paalanen
  -1 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:19 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev, Uma Shankar, dri-devel, Juha-Pekka Heikkila

[-- Attachment #1: Type: text/plain, Size: 6193 bytes --]

On Mon, 15 Nov 2021 15:17:52 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> Negative check for:
>  * plane gamma lut sizes
>  * plane degamma lut sizes
>  * plane ctm matrix sizes
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 127 insertions(+)
> 
> diff --git a/tests/kms_color.c b/tests/kms_color.c
> index e14b37cb6f..d9fe417ba9 100644
> --- a/tests/kms_color.c
> +++ b/tests/kms_color.c
> @@ -736,6 +736,118 @@ static void test_pipe_limited_range_ctm(data_t *data,
>  }
>  #endif
>  
> +static bool invalid_plane_gamma_test(data_t *data, igt_plane_t *plane)
> +{
> +	igt_display_t *display = &data->display;
> +	drmModePropertyPtr gamma_mode = NULL;
> +	uint32_t i;
> +
> +	igt_info("Plane invalid gamma test is running on pipe-%s plane-%s(%s)\n",
> +			kmstest_pipe_name(plane->pipe->pipe),
> +			kmstest_plane_type_name(plane->type),
> +			is_hdr_plane(plane) ? "hdr":"sdr");
> +
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> +
> +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> +
> +	/* Iterate all supported gamma modes. */
> +	for (i = 0; i < gamma_mode->count_enums; i++) {
> +		segment_data_t *segment_info = NULL;
> +		size_t lut_size = 0;
> +
> +		/* Ignore 'no gamma' from enum list. */
> +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> +			continue;
> +
> +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
> +
> +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> +				gamma_mode->enums[i].name);
> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
> +
> +		igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, gamma_mode->enums[i].name);
> +		invalid_plane_lut_sizes(display, plane,
> +					IGT_PLANE_GAMMA_LUT,
> +					lut_size);
> +
> +		clear_segment_data(segment_info);
> +
> +		/* One enum is enough. */
> +		break;
> +	}
> +
> +	drmModeFreeProperty(gamma_mode);
> +
> +	return true;
> +}
> +
> +static bool invalid_plane_degamma_test(data_t *data, igt_plane_t *plane)
> +{
> +	igt_display_t *display = &data->display;
> +	drmModePropertyPtr degamma_mode = NULL;
> +	uint32_t i;
> +
> +	igt_info("Plane invalid degamma test is running on pipe-%s plane-%s(%s)\n",
> +			kmstest_pipe_name(plane->pipe->pipe),
> +			kmstest_plane_type_name(plane->type),
> +			is_hdr_plane(plane) ? "hdr":"sdr");
> +
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
> +
> +	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
> +
> +	/* Iterate all supported degamma modes. */
> +	for (i = 0; i < degamma_mode->count_enums; i++) {
> +		segment_data_t *segment_info = NULL;
> +		size_t lut_size = 0;
> +
> +		/* Ignore 'no degamma' from enum list. */
> +		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
> +			continue;
> +
> +		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
> +
> +		segment_info = get_segment_data(data,
> +						degamma_mode->enums[i].value,
> +						degamma_mode->enums[i].name);
> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count * 2;
> +
> +		igt_plane_set_prop_enum(plane,
> +					IGT_PLANE_DEGAMMA_MODE,
> +					degamma_mode->enums[i].name);
> +		invalid_plane_lut_sizes(display, plane,
> +					IGT_PLANE_DEGAMMA_LUT,
> +					lut_size);
> +
> +		clear_segment_data(segment_info);
> +
> +		/* One enum is enough. */
> +		break;

Why is one enum enough?

The same question for the other case in this patch.


> +	}
> +
> +	drmModeFreeProperty(degamma_mode);
> +
> +	return true;
> +}
> +
> +static bool invalid_plane_ctm_test(data_t *data, igt_plane_t *plane)
> +{
> +	igt_info("Plane invalid CTM test is running on pipe-%s plane-%s(%s)\n",
> +			kmstest_pipe_name(plane->pipe->pipe),
> +			kmstest_plane_type_name(plane->type),
> +			is_hdr_plane(plane) ? "hdr":"sdr");
> +
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
> +	invalid_plane_lut_sizes(&data->display, plane,
> +				IGT_PLANE_CTM,
> +				sizeof(struct drm_color_ctm));

The code says you're trying shove a LUT into a CTM blob. I understand
that mechanically this is test you want to do, feed a wrong sized blob,
and in this case the contents do not matter (unlike with actual LUTs),
but reading this code is completely misleading and does not make sense.
It takes a while to think about what you actually want to test here,
and then reverse-engineer the code to understand that that is what
actually happens, too. That is too much mental burden for the reader to
realize that this piece of code actually works.


Thanks,
pq

> +
> +	return true;
> +}
> +
>  static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
>  {
>  	igt_output_t *output;
> @@ -1411,6 +1523,21 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
>  					ctm_tests[i].iter);
>  		}
>  	}
> +
> +	igt_describe("Negative check for invalid plane gamma lut sizes");
> +	igt_subtest_f("pipe-%s-invalid-plane-gamma-lut-sizes",
> +			kmstest_pipe_name(pipe))
> +		run_plane_color_test(data, pipe, invalid_plane_gamma_test);
> +
> +	igt_describe("Negative check for invalid plane degamma lut sizes");
> +	igt_subtest_f("pipe-%s-invalid-plane-degamma-lut-sizes",
> +			kmstest_pipe_name(pipe))
> +		run_plane_color_test(data, pipe, invalid_plane_degamma_test);
> +
> +	igt_describe("Negative check for invalid plane ctm matrix sizes");
> +	igt_subtest_f("pipe-%s-invalid-plane-ctm-matrix-sizes",
> +			kmstest_pipe_name(pipe))
> +		run_plane_color_test(data, pipe, invalid_plane_ctm_test);
>  }
>  
>  igt_main


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [igt-dev] [i-g-t 07/14] tests/kms_color: New negative tests for plane level color mgmt
@ 2021-11-18  9:19     ` Pekka Paalanen
  0 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:19 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev, dri-devel

[-- Attachment #1: Type: text/plain, Size: 6193 bytes --]

On Mon, 15 Nov 2021 15:17:52 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> Negative check for:
>  * plane gamma lut sizes
>  * plane degamma lut sizes
>  * plane ctm matrix sizes
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 127 insertions(+)
> 
> diff --git a/tests/kms_color.c b/tests/kms_color.c
> index e14b37cb6f..d9fe417ba9 100644
> --- a/tests/kms_color.c
> +++ b/tests/kms_color.c
> @@ -736,6 +736,118 @@ static void test_pipe_limited_range_ctm(data_t *data,
>  }
>  #endif
>  
> +static bool invalid_plane_gamma_test(data_t *data, igt_plane_t *plane)
> +{
> +	igt_display_t *display = &data->display;
> +	drmModePropertyPtr gamma_mode = NULL;
> +	uint32_t i;
> +
> +	igt_info("Plane invalid gamma test is running on pipe-%s plane-%s(%s)\n",
> +			kmstest_pipe_name(plane->pipe->pipe),
> +			kmstest_plane_type_name(plane->type),
> +			is_hdr_plane(plane) ? "hdr":"sdr");
> +
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> +
> +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> +
> +	/* Iterate all supported gamma modes. */
> +	for (i = 0; i < gamma_mode->count_enums; i++) {
> +		segment_data_t *segment_info = NULL;
> +		size_t lut_size = 0;
> +
> +		/* Ignore 'no gamma' from enum list. */
> +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> +			continue;
> +
> +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
> +
> +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> +				gamma_mode->enums[i].name);
> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
> +
> +		igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, gamma_mode->enums[i].name);
> +		invalid_plane_lut_sizes(display, plane,
> +					IGT_PLANE_GAMMA_LUT,
> +					lut_size);
> +
> +		clear_segment_data(segment_info);
> +
> +		/* One enum is enough. */
> +		break;
> +	}
> +
> +	drmModeFreeProperty(gamma_mode);
> +
> +	return true;
> +}
> +
> +static bool invalid_plane_degamma_test(data_t *data, igt_plane_t *plane)
> +{
> +	igt_display_t *display = &data->display;
> +	drmModePropertyPtr degamma_mode = NULL;
> +	uint32_t i;
> +
> +	igt_info("Plane invalid degamma test is running on pipe-%s plane-%s(%s)\n",
> +			kmstest_pipe_name(plane->pipe->pipe),
> +			kmstest_plane_type_name(plane->type),
> +			is_hdr_plane(plane) ? "hdr":"sdr");
> +
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
> +
> +	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
> +
> +	/* Iterate all supported degamma modes. */
> +	for (i = 0; i < degamma_mode->count_enums; i++) {
> +		segment_data_t *segment_info = NULL;
> +		size_t lut_size = 0;
> +
> +		/* Ignore 'no degamma' from enum list. */
> +		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
> +			continue;
> +
> +		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
> +
> +		segment_info = get_segment_data(data,
> +						degamma_mode->enums[i].value,
> +						degamma_mode->enums[i].name);
> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count * 2;
> +
> +		igt_plane_set_prop_enum(plane,
> +					IGT_PLANE_DEGAMMA_MODE,
> +					degamma_mode->enums[i].name);
> +		invalid_plane_lut_sizes(display, plane,
> +					IGT_PLANE_DEGAMMA_LUT,
> +					lut_size);
> +
> +		clear_segment_data(segment_info);
> +
> +		/* One enum is enough. */
> +		break;

Why is one enum enough?

The same question for the other case in this patch.


> +	}
> +
> +	drmModeFreeProperty(degamma_mode);
> +
> +	return true;
> +}
> +
> +static bool invalid_plane_ctm_test(data_t *data, igt_plane_t *plane)
> +{
> +	igt_info("Plane invalid CTM test is running on pipe-%s plane-%s(%s)\n",
> +			kmstest_pipe_name(plane->pipe->pipe),
> +			kmstest_plane_type_name(plane->type),
> +			is_hdr_plane(plane) ? "hdr":"sdr");
> +
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
> +	invalid_plane_lut_sizes(&data->display, plane,
> +				IGT_PLANE_CTM,
> +				sizeof(struct drm_color_ctm));

The code says you're trying shove a LUT into a CTM blob. I understand
that mechanically this is test you want to do, feed a wrong sized blob,
and in this case the contents do not matter (unlike with actual LUTs),
but reading this code is completely misleading and does not make sense.
It takes a while to think about what you actually want to test here,
and then reverse-engineer the code to understand that that is what
actually happens, too. That is too much mental burden for the reader to
realize that this piece of code actually works.


Thanks,
pq

> +
> +	return true;
> +}
> +
>  static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
>  {
>  	igt_output_t *output;
> @@ -1411,6 +1523,21 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
>  					ctm_tests[i].iter);
>  		}
>  	}
> +
> +	igt_describe("Negative check for invalid plane gamma lut sizes");
> +	igt_subtest_f("pipe-%s-invalid-plane-gamma-lut-sizes",
> +			kmstest_pipe_name(pipe))
> +		run_plane_color_test(data, pipe, invalid_plane_gamma_test);
> +
> +	igt_describe("Negative check for invalid plane degamma lut sizes");
> +	igt_subtest_f("pipe-%s-invalid-plane-degamma-lut-sizes",
> +			kmstest_pipe_name(pipe))
> +		run_plane_color_test(data, pipe, invalid_plane_degamma_test);
> +
> +	igt_describe("Negative check for invalid plane ctm matrix sizes");
> +	igt_subtest_f("pipe-%s-invalid-plane-ctm-matrix-sizes",
> +			kmstest_pipe_name(pipe))
> +		run_plane_color_test(data, pipe, invalid_plane_ctm_test);
>  }
>  
>  igt_main


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [i-g-t 08/14] tests/kms_color_chamelium: New subtests for Plane gamma
  2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-18  9:32     ` Pekka Paalanen
  -1 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:32 UTC (permalink / raw)
  To: Bhanuprakash Modem
  Cc: igt-dev, Kunal Joshi, Uma Shankar, dri-devel, Juha-Pekka Heikkila

[-- Attachment #1: Type: text/plain, Size: 2961 bytes --]

On Mon, 15 Nov 2021 15:17:53 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> with a maxed out gamma LUT and verify we have the same frame dump as
> drawing solid color rectangles.
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Cc: Kunal Joshi <kunal1.joshi@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color_chamelium.c | 188 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 187 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
> index 76f82d6d35..b506109271 100644
> --- a/tests/kms_color_chamelium.c
> +++ b/tests/kms_color_chamelium.c
> @@ -24,7 +24,34 @@
>  
>  #include "kms_color_helper.h"
>  
> -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level using Chamelium to verify instead of CRC");
> +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level using Chamelium to verify instead of CRC");

Now that you actually can get a captured image of the result with
Chamelium, I think the tests should be more ambitious. Do not rely on
identity curves or matrices, nor max LUT, because now you can use a
difference threshold per pixel when comparing the result with the
reference.

Use various non-trivial curves, different for each of red, green and
blue. Use non-trivial matrices that actually compute mixtures instead
of just moving red value to the green channel. Use multiple planes
simultaneously. Use different framebuffer formats, particularly with
higher than 8 bits per channel, and check the capture has the same
precision and not truncated to 8 bit.

That kind of tests would have much more proving power, and they also
help assess the precision of the hardware. Precision is important to
userspace.

These are also tests that userspace projects cannot really execute, they
do not have labs with Chamelium boards and not all drivers/hardware
support writeback connectors.

> +
> +#define MAX_SUPPORTED_PLANES 7
> +#define SDR_PLANE_BASE 3
> +
> +typedef bool (*test_t)(data_t*, igt_plane_t*);
> +
> +static bool is_hdr_plane(const igt_plane_t *plane)
> +{
> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;

This here again. I guess the previous definition of this function was
never used?

The same questions.

> +}
> +
> +static bool is_valid_plane(igt_plane_t *plane)
> +{
> +	int index = plane->index;
> +
> +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> +		return false;
> +
> +	/*
> +	 * Test 1 HDR plane, 1 SDR plane.
> +	 *
> +	 * 0,1,2 HDR planes
> +	 * 3,4,5,6 SDR planes
> +	 *
> +	 */
> +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> +}


Thanks,
pq

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [igt-dev] [i-g-t 08/14] tests/kms_color_chamelium: New subtests for Plane gamma
@ 2021-11-18  9:32     ` Pekka Paalanen
  0 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:32 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev, Kunal Joshi, dri-devel

[-- Attachment #1: Type: text/plain, Size: 2961 bytes --]

On Mon, 15 Nov 2021 15:17:53 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> with a maxed out gamma LUT and verify we have the same frame dump as
> drawing solid color rectangles.
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Cc: Kunal Joshi <kunal1.joshi@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color_chamelium.c | 188 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 187 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
> index 76f82d6d35..b506109271 100644
> --- a/tests/kms_color_chamelium.c
> +++ b/tests/kms_color_chamelium.c
> @@ -24,7 +24,34 @@
>  
>  #include "kms_color_helper.h"
>  
> -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level using Chamelium to verify instead of CRC");
> +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level using Chamelium to verify instead of CRC");

Now that you actually can get a captured image of the result with
Chamelium, I think the tests should be more ambitious. Do not rely on
identity curves or matrices, nor max LUT, because now you can use a
difference threshold per pixel when comparing the result with the
reference.

Use various non-trivial curves, different for each of red, green and
blue. Use non-trivial matrices that actually compute mixtures instead
of just moving red value to the green channel. Use multiple planes
simultaneously. Use different framebuffer formats, particularly with
higher than 8 bits per channel, and check the capture has the same
precision and not truncated to 8 bit.

That kind of tests would have much more proving power, and they also
help assess the precision of the hardware. Precision is important to
userspace.

These are also tests that userspace projects cannot really execute, they
do not have labs with Chamelium boards and not all drivers/hardware
support writeback connectors.

> +
> +#define MAX_SUPPORTED_PLANES 7
> +#define SDR_PLANE_BASE 3
> +
> +typedef bool (*test_t)(data_t*, igt_plane_t*);
> +
> +static bool is_hdr_plane(const igt_plane_t *plane)
> +{
> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;

This here again. I guess the previous definition of this function was
never used?

The same questions.

> +}
> +
> +static bool is_valid_plane(igt_plane_t *plane)
> +{
> +	int index = plane->index;
> +
> +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> +		return false;
> +
> +	/*
> +	 * Test 1 HDR plane, 1 SDR plane.
> +	 *
> +	 * 0,1,2 HDR planes
> +	 * 3,4,5,6 SDR planes
> +	 *
> +	 */
> +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> +}


Thanks,
pq

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [i-g-t 11/14] lib/igt_kms: Add pipe color mgmt properties
  2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-18  9:34     ` Pekka Paalanen
  -1 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:34 UTC (permalink / raw)
  To: Bhanuprakash Modem
  Cc: igt-dev, Uma Shankar, Mukunda Pramodh Kumar, dri-devel,
	Juha-Pekka Heikkila

[-- Attachment #1: Type: text/plain, Size: 1736 bytes --]

On Mon, 15 Nov 2021 15:17:56 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> 
> Add support for Pipe color management properties.

The commit summary and message are misleading.

This patch makes igt recognise the CRTC GAMMA_MODE KMS property.


Thanks,
pq

> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  lib/igt_kms.c | 1 +
>  lib/igt_kms.h | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index fdb83e0f91..677d26fedb 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -592,6 +592,7 @@ const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
>  	[IGT_CRTC_CTM] = "CTM",
>  	[IGT_CRTC_GAMMA_LUT] = "GAMMA_LUT",
>  	[IGT_CRTC_GAMMA_LUT_SIZE] = "GAMMA_LUT_SIZE",
> +	[IGT_CRTC_GAMMA_MODE] = "GAMMA_MODE",
>  	[IGT_CRTC_DEGAMMA_LUT] = "DEGAMMA_LUT",
>  	[IGT_CRTC_DEGAMMA_LUT_SIZE] = "DEGAMMA_LUT_SIZE",
>  	[IGT_CRTC_MODE_ID] = "MODE_ID",
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index 3a1f7243ad..5fac651fa3 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -119,6 +119,7 @@ enum igt_atomic_crtc_properties {
>         IGT_CRTC_CTM = 0,
>         IGT_CRTC_GAMMA_LUT,
>         IGT_CRTC_GAMMA_LUT_SIZE,
> +       IGT_CRTC_GAMMA_MODE,
>         IGT_CRTC_DEGAMMA_LUT,
>         IGT_CRTC_DEGAMMA_LUT_SIZE,
>         IGT_CRTC_MODE_ID,


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [igt-dev] [i-g-t 11/14] lib/igt_kms: Add pipe color mgmt properties
@ 2021-11-18  9:34     ` Pekka Paalanen
  0 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:34 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev, Mukunda Pramodh Kumar, dri-devel

[-- Attachment #1: Type: text/plain, Size: 1736 bytes --]

On Mon, 15 Nov 2021 15:17:56 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> 
> Add support for Pipe color management properties.

The commit summary and message are misleading.

This patch makes igt recognise the CRTC GAMMA_MODE KMS property.


Thanks,
pq

> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  lib/igt_kms.c | 1 +
>  lib/igt_kms.h | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index fdb83e0f91..677d26fedb 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -592,6 +592,7 @@ const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
>  	[IGT_CRTC_CTM] = "CTM",
>  	[IGT_CRTC_GAMMA_LUT] = "GAMMA_LUT",
>  	[IGT_CRTC_GAMMA_LUT_SIZE] = "GAMMA_LUT_SIZE",
> +	[IGT_CRTC_GAMMA_MODE] = "GAMMA_MODE",
>  	[IGT_CRTC_DEGAMMA_LUT] = "DEGAMMA_LUT",
>  	[IGT_CRTC_DEGAMMA_LUT_SIZE] = "DEGAMMA_LUT_SIZE",
>  	[IGT_CRTC_MODE_ID] = "MODE_ID",
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index 3a1f7243ad..5fac651fa3 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -119,6 +119,7 @@ enum igt_atomic_crtc_properties {
>         IGT_CRTC_CTM = 0,
>         IGT_CRTC_GAMMA_LUT,
>         IGT_CRTC_GAMMA_LUT_SIZE,
> +       IGT_CRTC_GAMMA_MODE,
>         IGT_CRTC_DEGAMMA_LUT,
>         IGT_CRTC_DEGAMMA_LUT_SIZE,
>         IGT_CRTC_MODE_ID,


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [i-g-t 12/14] kms_color_helper: Add helper functions to support logarithmic gamma mode
  2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-18  9:45     ` Pekka Paalanen
  -1 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:45 UTC (permalink / raw)
  To: Bhanuprakash Modem
  Cc: igt-dev, Uma Shankar, Mukunda Pramodh Kumar, dri-devel,
	Juha-Pekka Heikkila

[-- Attachment #1: Type: text/plain, Size: 9191 bytes --]

On Mon, 15 Nov 2021 15:17:57 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> 
> Add helper functions to support logarithmic gamma mode
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color_helper.c | 127 +++++++++++++++++++++++++++++++++++++++
>  tests/kms_color_helper.h |  16 +++++
>  2 files changed, 143 insertions(+)
> 
> diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> index c65b7a0f50..7ea8282df3 100644
> --- a/tests/kms_color_helper.c
> +++ b/tests/kms_color_helper.c
> @@ -190,6 +190,33 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
>  	return lut;
>  }
>  
> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> +						const gamma_lut_t *gamma,
> +						uint32_t color_depth,
> +						int off)
> +{
> +	struct drm_color_lut *lut;
> +	int i, lut_size = gamma->size;
> +	/* This is the maximum value due to 16 bit precision in hardware. */

In whose hardware?

Are igt tests not supposed to be generic for everything that exposes
the particular KMS properties?

This also hints that the UAPI design is lacking, because userspace
needs to know hardware specific things out of thin air. Display servers
are not going to have hardware-specific code. They specialise based on
the existence of KMS properties instead.

> +	uint32_t max_hw_value = (1 << 16) - 1;
> +	unsigned int max_segment_value = 1 << 24;
> +
> +	lut = malloc(sizeof(struct drm_color_lut) * lut_size);
> +
> +	for (i = 0; i < lut_size; i++) {
> +		double scaling_factor = (double)max_hw_value / (double)max_segment_value;
> +		uint32_t r = MIN((gamma->coeffs[i].r * scaling_factor), max_hw_value);
> +		uint32_t g = MIN((gamma->coeffs[i].g * scaling_factor), max_hw_value);
> +		uint32_t b = MIN((gamma->coeffs[i].b * scaling_factor), max_hw_value);
> +
> +		lut[i].red = r;
> +		lut[i].green = g;
> +		lut[i].blue = b;
> +	}
> +
> +	return lut;
> +}
> +
>  void set_degamma(data_t *data,
>  		 igt_pipe_t *pipe,
>  		 const gamma_lut_t *gamma)
> @@ -203,6 +230,15 @@ void set_degamma(data_t *data,
>  	free(lut);
>  }
>  
> +void set_pipe_gamma(igt_pipe_t *pipe,
> +		    uint64_t value,
> +		    struct drm_color_lut *lut,
> +		    uint32_t size)
> +{
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_MODE, value);
> +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
> +}
> +
>  void set_gamma(data_t *data,
>  	       igt_pipe_t *pipe, const gamma_lut_t *gamma)
>  {
> @@ -241,6 +277,51 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
>  }
>  
> +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> +					       enum igt_atomic_crtc_properties prop)
> +{
> +	igt_display_t *display = pipe->display;
> +	uint32_t prop_id = pipe->props[prop];
> +	drmModePropertyPtr drmProp;
> +
> +	igt_assert(prop_id);
> +
> +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> +
> +	igt_assert(drmProp);
> +	igt_assert(drmProp->count_enums);
> +
> +	return drmProp;
> +}
> +
> +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info)

Identity transformation?

> +{
> +	uint32_t segment, entry, index = 0;
> +	double val;
> +	int i = 0;
> +	gamma_lut_t *gamma = alloc_lut(info->entries_count);
> +
> +	igt_assert(gamma);
> +
> +	gamma->size = info->entries_count;
> +	for (segment = 0; segment < info->segment_count; segment++) {
> +		uint32_t entry_count = info->segment_data[segment].count;
> +		uint32_t start = (segment == 0) ? 0 : (1 << (segment - 1));
> +		uint32_t end = 1 << segment;
> +
> +		for (entry = 0; entry < entry_count; entry++) {
> +			val = (index == 0) ? /* First entry is Zero. */
> +				0 : start + entry *
> +				((end - start) * 1.0 / entry_count);
> +
> +			set_rgb(&gamma->coeffs[i++], val);
> +			index++;
> +		}
> +	}
> +
> +	return gamma;
> +}
> +
>  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
>  				enum igt_atomic_plane_properties prop)
>  {
> @@ -331,6 +412,7 @@ segment_data_t *get_segment_data(data_t *data,
>  	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
>  	igt_assert(info->segment_data);
>  
> +	info->entries_count = 0;

What's this?

>  	for (i = 0; i < info->segment_count; i++) {
>  		info->entries_count += lut_range[i].count;
>  		info->segment_data[i] = lut_range[i];
> @@ -341,6 +423,51 @@ segment_data_t *get_segment_data(data_t *data,
>  	return info;
>  }
>  
> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type)
> +{
> +	igt_display_t *display = &data->display;
> +	gamma_lut_t *gamma_log;
> +	drmModePropertyPtr gamma_mode = NULL;
> +	segment_data_t *segment_info = NULL;
> +	struct drm_color_lut *lut = NULL;
> +	int lut_size = 0;
> +
> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);

Is this how we are going to do cross-software DRM-master hand-over or
switching compatibility in general?

Add a new client cap for every new KMS property, and if the KMS client
does not set the property, the kernel will magically reset it to ensure
the client's expectations are met? Is that how it works?

Or why does this exist?

> +	gamma_mode = get_pipe_gamma_degamma_mode(pipe, IGT_CRTC_GAMMA_MODE);
> +
> +	for (int i = 0; i < gamma_mode->count_enums; i++) {
> +		if (!strcmp(gamma_mode->enums[i].name, "logarithmic gamma")) {
> +			segment_info = get_segment_data(data,
> +							gamma_mode->enums[i].value,
> +							gamma_mode->enums[i].name);
> +			lut_size = sizeof(struct drm_color_lut) *
> +					  segment_info->entries_count;
> +			if (type == LINEAR_GAMMA) {
> +				gamma_log = pipe_create_linear_lut(segment_info);
> +				lut = coeffs_to_logarithmic_lut(data,
> +								gamma_log,
> +								data->color_depth,
> +								0);
> +			} else if (type == MAX_GAMMA) {
> +				gamma_log = generate_table_max(segment_info->entries_count);
> +				gamma_log->size = segment_info->entries_count;
> +				lut = coeffs_to_lut(data, gamma_log,
> +						    data->color_depth, 0);
> +			}
> +			set_pipe_gamma(pipe, gamma_mode->enums[i].value,
> +				       lut, lut_size);
> +			igt_display_commit2(display, display->is_atomic
> +					    ? COMMIT_ATOMIC : COMMIT_LEGACY);
> +			break;
> +		}
> +	}
> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);

I've never seen this done before. I did not know client caps could be
reset.

> +	free(gamma_log);
> +	free(lut);
> +	clear_segment_data(segment_info);
> +	drmModeFreeProperty(gamma_mode);
> +}


Thanks,
pq

> +
>  void set_plane_gamma(igt_plane_t *plane,
>  		char *mode,
>  		struct drm_color_lut_ext *lut,
> diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> index 5a35dcaac1..c863874f0c 100644
> --- a/tests/kms_color_helper.h
> +++ b/tests/kms_color_helper.h
> @@ -70,6 +70,11 @@ typedef struct {
>  	uint32_t entries_count;
>  } segment_data_t;
>  
> +enum gamma_type {
> +	LINEAR_GAMMA,
> +	MAX_GAMMA
> +};
> +
>  #define MIN(a, b) ((a) < (b) ? (a) : (b))
>  
>  void paint_gradient_rectangles(data_t *data,
> @@ -89,6 +94,10 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
>  				    const gamma_lut_t *gamma,
>  				    uint32_t color_depth,
>  				    int off);
> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> +						const gamma_lut_t *gamma,
> +						uint32_t color_depth,
> +						int off);
>  void set_degamma(data_t *data,
>  		 igt_pipe_t *pipe,
>  		 const gamma_lut_t *gamma);
> @@ -98,12 +107,19 @@ void set_gamma(data_t *data,
>  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
>  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
>  
> +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> +					       enum igt_atomic_crtc_properties
> +					       prop);
>  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
>  	enum igt_atomic_plane_properties prop);
>  void clear_segment_data(segment_data_t *info);
> +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info);
>  struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
>  struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
>  segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
> +void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
> +		    struct drm_color_lut *lut, uint32_t size);
> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type);
>  void set_plane_gamma(igt_plane_t *plane,
>  	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
>  void set_plane_degamma(igt_plane_t *plane,


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [igt-dev] [i-g-t 12/14] kms_color_helper: Add helper functions to support logarithmic gamma mode
@ 2021-11-18  9:45     ` Pekka Paalanen
  0 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:45 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev, Mukunda Pramodh Kumar, dri-devel

[-- Attachment #1: Type: text/plain, Size: 9191 bytes --]

On Mon, 15 Nov 2021 15:17:57 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> 
> Add helper functions to support logarithmic gamma mode
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color_helper.c | 127 +++++++++++++++++++++++++++++++++++++++
>  tests/kms_color_helper.h |  16 +++++
>  2 files changed, 143 insertions(+)
> 
> diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> index c65b7a0f50..7ea8282df3 100644
> --- a/tests/kms_color_helper.c
> +++ b/tests/kms_color_helper.c
> @@ -190,6 +190,33 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
>  	return lut;
>  }
>  
> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> +						const gamma_lut_t *gamma,
> +						uint32_t color_depth,
> +						int off)
> +{
> +	struct drm_color_lut *lut;
> +	int i, lut_size = gamma->size;
> +	/* This is the maximum value due to 16 bit precision in hardware. */

In whose hardware?

Are igt tests not supposed to be generic for everything that exposes
the particular KMS properties?

This also hints that the UAPI design is lacking, because userspace
needs to know hardware specific things out of thin air. Display servers
are not going to have hardware-specific code. They specialise based on
the existence of KMS properties instead.

> +	uint32_t max_hw_value = (1 << 16) - 1;
> +	unsigned int max_segment_value = 1 << 24;
> +
> +	lut = malloc(sizeof(struct drm_color_lut) * lut_size);
> +
> +	for (i = 0; i < lut_size; i++) {
> +		double scaling_factor = (double)max_hw_value / (double)max_segment_value;
> +		uint32_t r = MIN((gamma->coeffs[i].r * scaling_factor), max_hw_value);
> +		uint32_t g = MIN((gamma->coeffs[i].g * scaling_factor), max_hw_value);
> +		uint32_t b = MIN((gamma->coeffs[i].b * scaling_factor), max_hw_value);
> +
> +		lut[i].red = r;
> +		lut[i].green = g;
> +		lut[i].blue = b;
> +	}
> +
> +	return lut;
> +}
> +
>  void set_degamma(data_t *data,
>  		 igt_pipe_t *pipe,
>  		 const gamma_lut_t *gamma)
> @@ -203,6 +230,15 @@ void set_degamma(data_t *data,
>  	free(lut);
>  }
>  
> +void set_pipe_gamma(igt_pipe_t *pipe,
> +		    uint64_t value,
> +		    struct drm_color_lut *lut,
> +		    uint32_t size)
> +{
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_MODE, value);
> +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
> +}
> +
>  void set_gamma(data_t *data,
>  	       igt_pipe_t *pipe, const gamma_lut_t *gamma)
>  {
> @@ -241,6 +277,51 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
>  }
>  
> +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> +					       enum igt_atomic_crtc_properties prop)
> +{
> +	igt_display_t *display = pipe->display;
> +	uint32_t prop_id = pipe->props[prop];
> +	drmModePropertyPtr drmProp;
> +
> +	igt_assert(prop_id);
> +
> +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> +
> +	igt_assert(drmProp);
> +	igt_assert(drmProp->count_enums);
> +
> +	return drmProp;
> +}
> +
> +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info)

Identity transformation?

> +{
> +	uint32_t segment, entry, index = 0;
> +	double val;
> +	int i = 0;
> +	gamma_lut_t *gamma = alloc_lut(info->entries_count);
> +
> +	igt_assert(gamma);
> +
> +	gamma->size = info->entries_count;
> +	for (segment = 0; segment < info->segment_count; segment++) {
> +		uint32_t entry_count = info->segment_data[segment].count;
> +		uint32_t start = (segment == 0) ? 0 : (1 << (segment - 1));
> +		uint32_t end = 1 << segment;
> +
> +		for (entry = 0; entry < entry_count; entry++) {
> +			val = (index == 0) ? /* First entry is Zero. */
> +				0 : start + entry *
> +				((end - start) * 1.0 / entry_count);
> +
> +			set_rgb(&gamma->coeffs[i++], val);
> +			index++;
> +		}
> +	}
> +
> +	return gamma;
> +}
> +
>  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
>  				enum igt_atomic_plane_properties prop)
>  {
> @@ -331,6 +412,7 @@ segment_data_t *get_segment_data(data_t *data,
>  	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
>  	igt_assert(info->segment_data);
>  
> +	info->entries_count = 0;

What's this?

>  	for (i = 0; i < info->segment_count; i++) {
>  		info->entries_count += lut_range[i].count;
>  		info->segment_data[i] = lut_range[i];
> @@ -341,6 +423,51 @@ segment_data_t *get_segment_data(data_t *data,
>  	return info;
>  }
>  
> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type)
> +{
> +	igt_display_t *display = &data->display;
> +	gamma_lut_t *gamma_log;
> +	drmModePropertyPtr gamma_mode = NULL;
> +	segment_data_t *segment_info = NULL;
> +	struct drm_color_lut *lut = NULL;
> +	int lut_size = 0;
> +
> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);

Is this how we are going to do cross-software DRM-master hand-over or
switching compatibility in general?

Add a new client cap for every new KMS property, and if the KMS client
does not set the property, the kernel will magically reset it to ensure
the client's expectations are met? Is that how it works?

Or why does this exist?

> +	gamma_mode = get_pipe_gamma_degamma_mode(pipe, IGT_CRTC_GAMMA_MODE);
> +
> +	for (int i = 0; i < gamma_mode->count_enums; i++) {
> +		if (!strcmp(gamma_mode->enums[i].name, "logarithmic gamma")) {
> +			segment_info = get_segment_data(data,
> +							gamma_mode->enums[i].value,
> +							gamma_mode->enums[i].name);
> +			lut_size = sizeof(struct drm_color_lut) *
> +					  segment_info->entries_count;
> +			if (type == LINEAR_GAMMA) {
> +				gamma_log = pipe_create_linear_lut(segment_info);
> +				lut = coeffs_to_logarithmic_lut(data,
> +								gamma_log,
> +								data->color_depth,
> +								0);
> +			} else if (type == MAX_GAMMA) {
> +				gamma_log = generate_table_max(segment_info->entries_count);
> +				gamma_log->size = segment_info->entries_count;
> +				lut = coeffs_to_lut(data, gamma_log,
> +						    data->color_depth, 0);
> +			}
> +			set_pipe_gamma(pipe, gamma_mode->enums[i].value,
> +				       lut, lut_size);
> +			igt_display_commit2(display, display->is_atomic
> +					    ? COMMIT_ATOMIC : COMMIT_LEGACY);
> +			break;
> +		}
> +	}
> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);

I've never seen this done before. I did not know client caps could be
reset.

> +	free(gamma_log);
> +	free(lut);
> +	clear_segment_data(segment_info);
> +	drmModeFreeProperty(gamma_mode);
> +}


Thanks,
pq

> +
>  void set_plane_gamma(igt_plane_t *plane,
>  		char *mode,
>  		struct drm_color_lut_ext *lut,
> diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> index 5a35dcaac1..c863874f0c 100644
> --- a/tests/kms_color_helper.h
> +++ b/tests/kms_color_helper.h
> @@ -70,6 +70,11 @@ typedef struct {
>  	uint32_t entries_count;
>  } segment_data_t;
>  
> +enum gamma_type {
> +	LINEAR_GAMMA,
> +	MAX_GAMMA
> +};
> +
>  #define MIN(a, b) ((a) < (b) ? (a) : (b))
>  
>  void paint_gradient_rectangles(data_t *data,
> @@ -89,6 +94,10 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
>  				    const gamma_lut_t *gamma,
>  				    uint32_t color_depth,
>  				    int off);
> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> +						const gamma_lut_t *gamma,
> +						uint32_t color_depth,
> +						int off);
>  void set_degamma(data_t *data,
>  		 igt_pipe_t *pipe,
>  		 const gamma_lut_t *gamma);
> @@ -98,12 +107,19 @@ void set_gamma(data_t *data,
>  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
>  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
>  
> +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> +					       enum igt_atomic_crtc_properties
> +					       prop);
>  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
>  	enum igt_atomic_plane_properties prop);
>  void clear_segment_data(segment_data_t *info);
> +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info);
>  struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
>  struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
>  segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
> +void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
> +		    struct drm_color_lut *lut, uint32_t size);
> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type);
>  void set_plane_gamma(igt_plane_t *plane,
>  	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
>  void set_plane_degamma(igt_plane_t *plane,


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [i-g-t 00/14] Add IGT support for plane color management
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-18  9:50   ` Pekka Paalanen
  -1 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:50 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev, dri-devel

[-- Attachment #1: Type: text/plain, Size: 2278 bytes --]

On Mon, 15 Nov 2021 15:17:45 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> From the Plane Color Management feature design, userspace can
> take the smart blending decisions based on hardware supported
> plane color features to obtain an accurate color profile.
> 
> These IGT patches extend the existing pipe color management
> tests to the plane level.
> 
> Kernel implementation:
> https://patchwork.freedesktop.org/series/90825/

Hi,

it's really good to get these, but I am worried that the tests here may
be too easy to pass when trying to ensure the KMS features work
correctly and in the way real userspace is going to be using them.

I also found some things that looked hardware-specific in this code
that to my understanding is supposed to be generic, and some concerns
about UAPI as well.


Thanks,
pq

> Bhanuprakash Modem (11):
>   HAX: Get uapi headers to compile the IGT
>   lib/igt_kms: Add plane color mgmt properties
>   kms_color_helper: Add helper functions for plane color mgmt
>   tests/kms_color: New subtests for Plane gamma
>   tests/kms_color: New subtests for Plane degamma
>   tests/kms_color: New subtests for Plane CTM
>   tests/kms_color: New negative tests for plane level color mgmt
>   tests/kms_color_chamelium: New subtests for Plane gamma
>   tests/kms_color_chamelium: New subtests for Plane degamma
>   tests/kms_color_chamelium: New subtests for Plane CTM
>   tests/kms_color_chamelium: Extended IGT tests to support logarithmic
>     gamma mode
> 
> Mukunda Pramodh Kumar (3):
>   lib/igt_kms: Add pipe color mgmt properties
>   kms_color_helper: Add helper functions to support logarithmic gamma
>     mode
>   tests/kms_color: Extended IGT tests to support logarithmic gamma mode
> 
>  include/drm-uapi/drm.h      |  10 +
>  include/drm-uapi/drm_mode.h |  28 ++
>  lib/igt_kms.c               |   6 +
>  lib/igt_kms.h               |   6 +
>  tests/kms_color.c           | 674 +++++++++++++++++++++++++++++++++++-
>  tests/kms_color_chamelium.c | 588 ++++++++++++++++++++++++++++++-
>  tests/kms_color_helper.c    | 300 ++++++++++++++++
>  tests/kms_color_helper.h    |  45 +++
>  8 files changed, 1648 insertions(+), 9 deletions(-)
> 
> --
> 2.32.0
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [igt-dev] [i-g-t 00/14] Add IGT support for plane color management
@ 2021-11-18  9:50   ` Pekka Paalanen
  0 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-18  9:50 UTC (permalink / raw)
  To: Bhanuprakash Modem; +Cc: igt-dev, dri-devel

[-- Attachment #1: Type: text/plain, Size: 2278 bytes --]

On Mon, 15 Nov 2021 15:17:45 +0530
Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:

> From the Plane Color Management feature design, userspace can
> take the smart blending decisions based on hardware supported
> plane color features to obtain an accurate color profile.
> 
> These IGT patches extend the existing pipe color management
> tests to the plane level.
> 
> Kernel implementation:
> https://patchwork.freedesktop.org/series/90825/

Hi,

it's really good to get these, but I am worried that the tests here may
be too easy to pass when trying to ensure the KMS features work
correctly and in the way real userspace is going to be using them.

I also found some things that looked hardware-specific in this code
that to my understanding is supposed to be generic, and some concerns
about UAPI as well.


Thanks,
pq

> Bhanuprakash Modem (11):
>   HAX: Get uapi headers to compile the IGT
>   lib/igt_kms: Add plane color mgmt properties
>   kms_color_helper: Add helper functions for plane color mgmt
>   tests/kms_color: New subtests for Plane gamma
>   tests/kms_color: New subtests for Plane degamma
>   tests/kms_color: New subtests for Plane CTM
>   tests/kms_color: New negative tests for plane level color mgmt
>   tests/kms_color_chamelium: New subtests for Plane gamma
>   tests/kms_color_chamelium: New subtests for Plane degamma
>   tests/kms_color_chamelium: New subtests for Plane CTM
>   tests/kms_color_chamelium: Extended IGT tests to support logarithmic
>     gamma mode
> 
> Mukunda Pramodh Kumar (3):
>   lib/igt_kms: Add pipe color mgmt properties
>   kms_color_helper: Add helper functions to support logarithmic gamma
>     mode
>   tests/kms_color: Extended IGT tests to support logarithmic gamma mode
> 
>  include/drm-uapi/drm.h      |  10 +
>  include/drm-uapi/drm_mode.h |  28 ++
>  lib/igt_kms.c               |   6 +
>  lib/igt_kms.h               |   6 +
>  tests/kms_color.c           | 674 +++++++++++++++++++++++++++++++++++-
>  tests/kms_color_chamelium.c | 588 ++++++++++++++++++++++++++++++-
>  tests/kms_color_helper.c    | 300 ++++++++++++++++
>  tests/kms_color_helper.h    |  45 +++
>  8 files changed, 1648 insertions(+), 9 deletions(-)
> 
> --
> 2.32.0
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [i-g-t 00/14] Add IGT support for plane color management
  2021-11-18  9:50   ` [igt-dev] " Pekka Paalanen
  (?)
@ 2021-11-26 16:54   ` Harry Wentland
  2021-11-29  9:20       ` [igt-dev] " Pekka Paalanen
  -1 siblings, 1 reply; 96+ messages in thread
From: Harry Wentland @ 2021-11-26 16:54 UTC (permalink / raw)
  To: dri-devel



On 2021-11-18 04:50, Pekka Paalanen wrote:
> On Mon, 15 Nov 2021 15:17:45 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
>> From the Plane Color Management feature design, userspace can
>> take the smart blending decisions based on hardware supported
>> plane color features to obtain an accurate color profile.
>>
>> These IGT patches extend the existing pipe color management
>> tests to the plane level.
>>
>> Kernel implementation:
>> https://patchwork.freedesktop.org/series/90825/
> 

Are these tested and passing on any current or future Intel HW?

> Hi,
> 
> it's really good to get these, but I am worried that the tests here may
> be too easy to pass when trying to ensure the KMS features work
> correctly and in the way real userspace is going to be using them.
> 

In particular per-plane color management is mainly beneficial when
using HW composition, i.e. plane blending. I don't see tests for
plane blending.

Another thing that would be good to test is to make sure the order of
operations is as documented in the KMS API, i.e. degamma -> CTM -> gamma.
In order to test this it might be good to create a test case that sets
these operations up in a way that only yields the expected outcome
if they are implemented in this order.

Last, and likely not easy to test, is the precision or accuracy of the
PWL though I am unsure whether we can even test this at all with CRC.
It looks like we might be able to test this with the Chamelium to some
degree.

> I also found some things that looked hardware-specific in this code
> that to my understanding is supposed to be generic, and some concerns
> about UAPI as well.
> 

I left some comments on intellisms in these patches.

Do you have any specifics about your concerns about UAPI?

Harry

> 
> Thanks,
> pq
> 
>> Bhanuprakash Modem (11):
>>   HAX: Get uapi headers to compile the IGT
>>   lib/igt_kms: Add plane color mgmt properties
>>   kms_color_helper: Add helper functions for plane color mgmt
>>   tests/kms_color: New subtests for Plane gamma
>>   tests/kms_color: New subtests for Plane degamma
>>   tests/kms_color: New subtests for Plane CTM
>>   tests/kms_color: New negative tests for plane level color mgmt
>>   tests/kms_color_chamelium: New subtests for Plane gamma
>>   tests/kms_color_chamelium: New subtests for Plane degamma
>>   tests/kms_color_chamelium: New subtests for Plane CTM
>>   tests/kms_color_chamelium: Extended IGT tests to support logarithmic
>>     gamma mode
>>
>> Mukunda Pramodh Kumar (3):
>>   lib/igt_kms: Add pipe color mgmt properties
>>   kms_color_helper: Add helper functions to support logarithmic gamma
>>     mode
>>   tests/kms_color: Extended IGT tests to support logarithmic gamma mode
>>
>>  include/drm-uapi/drm.h      |  10 +
>>  include/drm-uapi/drm_mode.h |  28 ++
>>  lib/igt_kms.c               |   6 +
>>  lib/igt_kms.h               |   6 +
>>  tests/kms_color.c           | 674 +++++++++++++++++++++++++++++++++++-
>>  tests/kms_color_chamelium.c | 588 ++++++++++++++++++++++++++++++-
>>  tests/kms_color_helper.c    | 300 ++++++++++++++++
>>  tests/kms_color_helper.h    |  45 +++
>>  8 files changed, 1648 insertions(+), 9 deletions(-)
>>
>> --
>> 2.32.0
>>
> 


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

* Re: [i-g-t 03/14] kms_color_helper: Add helper functions for plane color mgmt
  2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-26 16:54     ` Harry Wentland
  -1 siblings, 0 replies; 96+ messages in thread
From: Harry Wentland @ 2021-11-26 16:54 UTC (permalink / raw)
  To: Bhanuprakash Modem, igt-dev, dri-devel; +Cc: Uma Shankar, Juha-Pekka Heikkila



On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> Add helper functions to support Plane color management properties.
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color_helper.c | 173 +++++++++++++++++++++++++++++++++++++++
>  tests/kms_color_helper.h |  29 +++++++
>  2 files changed, 202 insertions(+)
> 
> diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> index d71e7bb2e6..c65b7a0f50 100644
> --- a/tests/kms_color_helper.c
> +++ b/tests/kms_color_helper.c
> @@ -241,6 +241,150 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
>  }
>  
> +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> +				enum igt_atomic_plane_properties prop)
> +{
> +	igt_display_t *display = plane->pipe->display;
> +	uint32_t prop_id = plane->props[prop];
> +	drmModePropertyPtr drmProp;
> +
> +	igt_assert(prop_id);
> +
> +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> +
> +	igt_assert(drmProp);
> +	igt_assert(drmProp->count_enums);
> +
> +	return drmProp;
> +}
> +
> +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info)
> +{
> +	uint32_t val, segment, entry, index = 0;
> +	uint32_t max_val = 0xffffffff;
> +	struct drm_color_lut_ext *lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> +	igt_assert(lut);
> +
> +	for (segment = 0; segment < info->segment_count; segment++) {
> +		uint32_t entry_count = info->segment_data[segment].count;
> +		uint32_t start = info->segment_data[segment].start;
> +		uint32_t end = info->segment_data[segment].end;
> +
> +		for (entry = 1; entry <= entry_count; entry++) {
> +			val = (index == 0) ? /* First entry is Zero. */
> +				0 : start + entry * ((end - start) * 1.0 / entry_count);
> +
> +			lut[index].red = lut[index].green = lut[index].blue = MIN(val, max_val);
> +
> +			index++;
> +		}
> +	}
> +
> +	return lut;
> +}
> +
> +struct drm_color_lut_ext *create_max_lut(segment_data_t *info)
> +{
> +	int i;
> +	struct drm_color_lut_ext *lut;
> +	uint32_t max_val = 0xffffffff;
> +
> +	lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> +	igt_assert(lut);
> +
> +	lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is Zero. */
> +
> +	for (i = 1; i < info->entries_count; i++)
> +		lut[i].red = lut[i].green = lut[i].blue = max_val;
> +
> +	return lut;
> +}
> +
> +void clear_segment_data(segment_data_t *info)
> +{
> +	if (!info)
> +		return;
> +
> +	free(info->segment_data);
> +	free(info);
> +}
> +
> +segment_data_t *get_segment_data(data_t *data,
> +				uint64_t blob_id, char *mode)
> +{
> +	drmModePropertyBlobPtr blob;
> +	struct drm_color_lut_range *lut_range = NULL;
> +	segment_data_t *info = NULL;
> +	uint32_t i;
> +
> +	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
> +	igt_assert(blob);
> +	igt_assert(blob->length);
> +
> +	info = malloc(sizeof(segment_data_t));
> +	igt_assert(info);
> +
> +	lut_range = (struct drm_color_lut_range *) blob->data;
> +	info->segment_count = blob->length / sizeof(lut_range[0]);
> +	igt_assert(info->segment_count);
> +
> +	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
> +	igt_assert(info->segment_data);
> +
> +	for (i = 0; i < info->segment_count; i++) {
> +		info->entries_count += lut_range[i].count;
> +		info->segment_data[i] = lut_range[i];
> +	}
> +
> +	drmModeFreePropertyBlob(blob);
> +
> +	return info;
> +}
> +
> +void set_plane_gamma(igt_plane_t *plane,
> +		char *mode,
> +		struct drm_color_lut_ext *lut,
> +		uint32_t size)
> +{
> +	igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, mode);
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_GAMMA_LUT, lut, size);
> +}
> +
> +void set_plane_degamma(igt_plane_t *plane,
> +		char *mode,
> +		struct drm_color_lut_ext *lut,
> +		uint32_t size)
> +{
> +	igt_plane_set_prop_enum(plane, IGT_PLANE_DEGAMMA_MODE, mode);
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_DEGAMMA_LUT, lut, size);
> +}
> +
> +void set_plane_ctm(igt_plane_t *plane, const double *coefficients)
> +{
> +	struct drm_color_ctm ctm;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
> +		if (coefficients[i] < 0) {
> +			ctm.matrix[i] =
> +				(int64_t) (-coefficients[i] *
> +				((int64_t) 1L << 32));
> +			ctm.matrix[i] |= 1ULL << 63;
> +		} else
> +			ctm.matrix[i] =
> +				(int64_t) (coefficients[i] *
> +				((int64_t) 1L << 32));
> +	}
> +
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_CTM, &ctm, sizeof(ctm));
> +}
> +
> +void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
> +{
> +	if (igt_plane_has_prop(plane, prop))
> +		igt_plane_replace_prop_blob(plane, prop, NULL, 0);
> +}
> +
>  drmModePropertyBlobPtr
>  get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  {
> @@ -274,6 +418,19 @@ pipe_set_property_blob_id(igt_pipe_t *pipe,
>  	return ret;
>  }
>  
> +static int
> +plane_set_property_blob(igt_display_t *display,
> +			igt_plane_t *plane,
> +			enum igt_atomic_plane_properties prop,
> +			void *ptr, size_t length)
> +{
> +	igt_plane_replace_prop_blob(plane, prop, ptr, length);
> +
> +	return igt_display_try_commit2(display,
> +				       display->is_atomic ?
> +				       COMMIT_ATOMIC : COMMIT_LEGACY);
> +}
> +
>  int
>  pipe_set_property_blob(igt_pipe_t *pipe,
>  		       enum igt_atomic_crtc_properties prop,
> @@ -319,6 +476,22 @@ invalid_lut_sizes(data_t *data, enum pipe p,
>  	free(lut);
>  }
>  
> +void
> +invalid_plane_lut_sizes(igt_display_t *display,
> +			igt_plane_t *plane,
> +			enum igt_atomic_plane_properties prop,
> +			size_t lut_size)
> +{
> +	void *lut = malloc(lut_size * 2);
> +	igt_assert(lut);
> +
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, 1), -EINVAL);
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size + 1), -EINVAL);
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size - 1), -EINVAL);
> +
> +	free(lut);
> +}

This might make more sense as part of patch 7, though I don't have a
strong preference.

Harry

> +
>  void
>  invalid_gamma_lut_sizes(data_t *data, enum pipe p)
>  {
> diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> index bb6f0054f3..5a35dcaac1 100644
> --- a/tests/kms_color_helper.h
> +++ b/tests/kms_color_helper.h
> @@ -64,6 +64,14 @@ typedef struct {
>  	color_t coeffs[];
>  } gamma_lut_t;
>  
> +typedef struct {
> +	uint32_t segment_count;
> +	struct drm_color_lut_range *segment_data;
> +	uint32_t entries_count;
> +} segment_data_t;
> +
> +#define MIN(a, b) ((a) < (b) ? (a) : (b))
> +
>  void paint_gradient_rectangles(data_t *data,
>  			       drmModeModeInfo *mode,
>  			       color_t *colors,
> @@ -90,10 +98,31 @@ void set_gamma(data_t *data,
>  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
>  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
>  
> +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> +	enum igt_atomic_plane_properties prop);
> +void clear_segment_data(segment_data_t *info);
> +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> +struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> +segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
> +void set_plane_gamma(igt_plane_t *plane,
> +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> +void set_plane_degamma(igt_plane_t *plane,
> +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> +void set_plane_ctm(igt_plane_t *plane, const double *coefficients);
> +void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop);
> +void invalid_plane_lut_sizes(igt_display_t *display,
> +			   igt_plane_t *plane,
> +			   enum igt_atomic_plane_properties prop,
> +			   size_t lut_size);
> +
>  #define disable_degamma(pipe) disable_prop(pipe, IGT_CRTC_DEGAMMA_LUT)
>  #define disable_gamma(pipe) disable_prop(pipe, IGT_CRTC_GAMMA_LUT)
>  #define disable_ctm(pipe) disable_prop(pipe, IGT_CRTC_CTM)
>  
> +#define disable_plane_degamma(plane) disable_plane_prop(plane, IGT_PLANE_DEGAMMA_LUT)
> +#define disable_plane_gamma(plane) disable_plane_prop(plane, IGT_PLANE_GAMMA_LUT)
> +#define disable_plane_ctm(plane) disable_plane_prop(plane, IGT_PLANE_CTM)
> +
>  drmModePropertyBlobPtr get_blob(data_t *data, igt_pipe_t *pipe,
>  				enum igt_atomic_crtc_properties prop);
>  bool crc_equal(igt_crc_t *a, igt_crc_t *b);
> 


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

* Re: [igt-dev] [i-g-t 03/14] kms_color_helper: Add helper functions for plane color mgmt
@ 2021-11-26 16:54     ` Harry Wentland
  0 siblings, 0 replies; 96+ messages in thread
From: Harry Wentland @ 2021-11-26 16:54 UTC (permalink / raw)
  To: Bhanuprakash Modem, igt-dev, dri-devel



On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> Add helper functions to support Plane color management properties.
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color_helper.c | 173 +++++++++++++++++++++++++++++++++++++++
>  tests/kms_color_helper.h |  29 +++++++
>  2 files changed, 202 insertions(+)
> 
> diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> index d71e7bb2e6..c65b7a0f50 100644
> --- a/tests/kms_color_helper.c
> +++ b/tests/kms_color_helper.c
> @@ -241,6 +241,150 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
>  }
>  
> +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> +				enum igt_atomic_plane_properties prop)
> +{
> +	igt_display_t *display = plane->pipe->display;
> +	uint32_t prop_id = plane->props[prop];
> +	drmModePropertyPtr drmProp;
> +
> +	igt_assert(prop_id);
> +
> +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> +
> +	igt_assert(drmProp);
> +	igt_assert(drmProp->count_enums);
> +
> +	return drmProp;
> +}
> +
> +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info)
> +{
> +	uint32_t val, segment, entry, index = 0;
> +	uint32_t max_val = 0xffffffff;
> +	struct drm_color_lut_ext *lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> +	igt_assert(lut);
> +
> +	for (segment = 0; segment < info->segment_count; segment++) {
> +		uint32_t entry_count = info->segment_data[segment].count;
> +		uint32_t start = info->segment_data[segment].start;
> +		uint32_t end = info->segment_data[segment].end;
> +
> +		for (entry = 1; entry <= entry_count; entry++) {
> +			val = (index == 0) ? /* First entry is Zero. */
> +				0 : start + entry * ((end - start) * 1.0 / entry_count);
> +
> +			lut[index].red = lut[index].green = lut[index].blue = MIN(val, max_val);
> +
> +			index++;
> +		}
> +	}
> +
> +	return lut;
> +}
> +
> +struct drm_color_lut_ext *create_max_lut(segment_data_t *info)
> +{
> +	int i;
> +	struct drm_color_lut_ext *lut;
> +	uint32_t max_val = 0xffffffff;
> +
> +	lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> +	igt_assert(lut);
> +
> +	lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is Zero. */
> +
> +	for (i = 1; i < info->entries_count; i++)
> +		lut[i].red = lut[i].green = lut[i].blue = max_val;
> +
> +	return lut;
> +}
> +
> +void clear_segment_data(segment_data_t *info)
> +{
> +	if (!info)
> +		return;
> +
> +	free(info->segment_data);
> +	free(info);
> +}
> +
> +segment_data_t *get_segment_data(data_t *data,
> +				uint64_t blob_id, char *mode)
> +{
> +	drmModePropertyBlobPtr blob;
> +	struct drm_color_lut_range *lut_range = NULL;
> +	segment_data_t *info = NULL;
> +	uint32_t i;
> +
> +	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
> +	igt_assert(blob);
> +	igt_assert(blob->length);
> +
> +	info = malloc(sizeof(segment_data_t));
> +	igt_assert(info);
> +
> +	lut_range = (struct drm_color_lut_range *) blob->data;
> +	info->segment_count = blob->length / sizeof(lut_range[0]);
> +	igt_assert(info->segment_count);
> +
> +	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
> +	igt_assert(info->segment_data);
> +
> +	for (i = 0; i < info->segment_count; i++) {
> +		info->entries_count += lut_range[i].count;
> +		info->segment_data[i] = lut_range[i];
> +	}
> +
> +	drmModeFreePropertyBlob(blob);
> +
> +	return info;
> +}
> +
> +void set_plane_gamma(igt_plane_t *plane,
> +		char *mode,
> +		struct drm_color_lut_ext *lut,
> +		uint32_t size)
> +{
> +	igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, mode);
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_GAMMA_LUT, lut, size);
> +}
> +
> +void set_plane_degamma(igt_plane_t *plane,
> +		char *mode,
> +		struct drm_color_lut_ext *lut,
> +		uint32_t size)
> +{
> +	igt_plane_set_prop_enum(plane, IGT_PLANE_DEGAMMA_MODE, mode);
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_DEGAMMA_LUT, lut, size);
> +}
> +
> +void set_plane_ctm(igt_plane_t *plane, const double *coefficients)
> +{
> +	struct drm_color_ctm ctm;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
> +		if (coefficients[i] < 0) {
> +			ctm.matrix[i] =
> +				(int64_t) (-coefficients[i] *
> +				((int64_t) 1L << 32));
> +			ctm.matrix[i] |= 1ULL << 63;
> +		} else
> +			ctm.matrix[i] =
> +				(int64_t) (coefficients[i] *
> +				((int64_t) 1L << 32));
> +	}
> +
> +	igt_plane_replace_prop_blob(plane, IGT_PLANE_CTM, &ctm, sizeof(ctm));
> +}
> +
> +void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
> +{
> +	if (igt_plane_has_prop(plane, prop))
> +		igt_plane_replace_prop_blob(plane, prop, NULL, 0);
> +}
> +
>  drmModePropertyBlobPtr
>  get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  {
> @@ -274,6 +418,19 @@ pipe_set_property_blob_id(igt_pipe_t *pipe,
>  	return ret;
>  }
>  
> +static int
> +plane_set_property_blob(igt_display_t *display,
> +			igt_plane_t *plane,
> +			enum igt_atomic_plane_properties prop,
> +			void *ptr, size_t length)
> +{
> +	igt_plane_replace_prop_blob(plane, prop, ptr, length);
> +
> +	return igt_display_try_commit2(display,
> +				       display->is_atomic ?
> +				       COMMIT_ATOMIC : COMMIT_LEGACY);
> +}
> +
>  int
>  pipe_set_property_blob(igt_pipe_t *pipe,
>  		       enum igt_atomic_crtc_properties prop,
> @@ -319,6 +476,22 @@ invalid_lut_sizes(data_t *data, enum pipe p,
>  	free(lut);
>  }
>  
> +void
> +invalid_plane_lut_sizes(igt_display_t *display,
> +			igt_plane_t *plane,
> +			enum igt_atomic_plane_properties prop,
> +			size_t lut_size)
> +{
> +	void *lut = malloc(lut_size * 2);
> +	igt_assert(lut);
> +
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, 1), -EINVAL);
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size + 1), -EINVAL);
> +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size - 1), -EINVAL);
> +
> +	free(lut);
> +}

This might make more sense as part of patch 7, though I don't have a
strong preference.

Harry

> +
>  void
>  invalid_gamma_lut_sizes(data_t *data, enum pipe p)
>  {
> diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> index bb6f0054f3..5a35dcaac1 100644
> --- a/tests/kms_color_helper.h
> +++ b/tests/kms_color_helper.h
> @@ -64,6 +64,14 @@ typedef struct {
>  	color_t coeffs[];
>  } gamma_lut_t;
>  
> +typedef struct {
> +	uint32_t segment_count;
> +	struct drm_color_lut_range *segment_data;
> +	uint32_t entries_count;
> +} segment_data_t;
> +
> +#define MIN(a, b) ((a) < (b) ? (a) : (b))
> +
>  void paint_gradient_rectangles(data_t *data,
>  			       drmModeModeInfo *mode,
>  			       color_t *colors,
> @@ -90,10 +98,31 @@ void set_gamma(data_t *data,
>  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
>  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
>  
> +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> +	enum igt_atomic_plane_properties prop);
> +void clear_segment_data(segment_data_t *info);
> +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> +struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> +segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
> +void set_plane_gamma(igt_plane_t *plane,
> +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> +void set_plane_degamma(igt_plane_t *plane,
> +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> +void set_plane_ctm(igt_plane_t *plane, const double *coefficients);
> +void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop);
> +void invalid_plane_lut_sizes(igt_display_t *display,
> +			   igt_plane_t *plane,
> +			   enum igt_atomic_plane_properties prop,
> +			   size_t lut_size);
> +
>  #define disable_degamma(pipe) disable_prop(pipe, IGT_CRTC_DEGAMMA_LUT)
>  #define disable_gamma(pipe) disable_prop(pipe, IGT_CRTC_GAMMA_LUT)
>  #define disable_ctm(pipe) disable_prop(pipe, IGT_CRTC_CTM)
>  
> +#define disable_plane_degamma(plane) disable_plane_prop(plane, IGT_PLANE_DEGAMMA_LUT)
> +#define disable_plane_gamma(plane) disable_plane_prop(plane, IGT_PLANE_GAMMA_LUT)
> +#define disable_plane_ctm(plane) disable_plane_prop(plane, IGT_PLANE_CTM)
> +
>  drmModePropertyBlobPtr get_blob(data_t *data, igt_pipe_t *pipe,
>  				enum igt_atomic_crtc_properties prop);
>  bool crc_equal(igt_crc_t *a, igt_crc_t *b);
> 

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

* Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
  2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-26 16:55     ` Harry Wentland
  -1 siblings, 0 replies; 96+ messages in thread
From: Harry Wentland @ 2021-11-26 16:55 UTC (permalink / raw)
  To: Bhanuprakash Modem, igt-dev, dri-devel; +Cc: Uma Shankar, Juha-Pekka Heikkila



On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> with a maxed out gamma LUT and verify we have the same CRC as drawing solid
> color rectangles.
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 178 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/kms_color.c b/tests/kms_color.c
> index 775f35964f..b45d66762f 100644
> --- a/tests/kms_color.c
> +++ b/tests/kms_color.c
> @@ -24,7 +24,34 @@
>  
>  #include "kms_color_helper.h"
>  
> -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
> +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
> +
> +#define MAX_SUPPORTED_PLANES 7
> +#define SDR_PLANE_BASE 3
> +
> +typedef bool (*test_t)(data_t*, igt_plane_t*);
> +
> +static bool is_hdr_plane(const igt_plane_t *plane)
> +{
> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> +}
> +
> +static bool is_valid_plane(igt_plane_t *plane)
> +{
> +	int index = plane->index;
> +
> +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> +		return false;
> +
> +	/*
> +	 * Test 1 HDR plane, 1 SDR plane.
> +	 *
> +	 * 0,1,2 HDR planes
> +	 * 3,4,5,6 SDR planes
> +	 *
> +	 */

This seems to be about Intel HW. AMD HW for example does
not have HDR or SDR planes, only one generic plane.

> +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> +}
>  
>  static void test_pipe_degamma(data_t *data,
>  			      igt_plane_t *primary)
> @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t *data,
>  }
>  #endif
>  
> +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> +{
> +	igt_output_t *output;
> +	igt_display_t *display = &data->display;
> +	drmModeModeInfo *mode;
> +	struct igt_fb fb;
> +	drmModePropertyPtr gamma_mode = NULL;
> +	uint32_t i;
> +	bool ret = true;
> +	igt_pipe_crc_t *pipe_crc = NULL;
> +	color_t red_green_blue[] = {
> +		{ 1.0, 0.0, 0.0 },
> +		{ 0.0, 1.0, 0.0 },
> +		{ 0.0, 0.0, 1.0 }
> +	};
> +
> +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
> +			kmstest_pipe_name(plane->pipe->pipe),
> +			kmstest_plane_type_name(plane->type),
> +			is_hdr_plane(plane) ? "hdr":"sdr");
> +

is_hdr_plane is Intel-specific.

> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> +
> +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
> +				  plane->pipe->pipe,
> +				  INTEL_PIPE_CRC_SOURCE_AUTO);
> +
> +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
> +	igt_assert(output);
> +
> +	igt_output_set_pipe(output, plane->pipe->pipe);
> +	mode = igt_output_get_mode(output);
> +
> +	/* Create a framebuffer at the size of the output. */
> +	igt_assert(igt_create_fb(data->drm_fd,
> +			      mode->hdisplay,
> +			      mode->vdisplay,
> +			      DRM_FORMAT_XRGB8888,
> +			      DRM_FORMAT_MOD_LINEAR,
> +			      &fb));
> +	igt_plane_set_fb(plane, &fb);
> +
> +	/* Disable Pipe color props. */
> +	disable_ctm(plane->pipe);
> +	disable_degamma(plane->pipe);
> +	disable_gamma(plane->pipe);
> +
> +	disable_plane_ctm(plane);
> +	disable_plane_degamma(plane);
> +	igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +
> +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> +
> +	/* Iterate all supported gamma modes. */
> +	for (i = 0; i < gamma_mode->count_enums; i++) {
> +		igt_crc_t crc_gamma, crc_fullcolors;
> +		segment_data_t *segment_info = NULL;
> +		struct drm_color_lut_ext *lut = NULL;
> +		uint32_t lut_size = 0;
> +
> +		/* Ignore 'no gamma' from enum list. */
> +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> +			continue;
> +

It might still make sense to test that this is doing bypass.

> +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
> +
> +		/* Draw solid colors with no gamma transformation. */
> +		disable_plane_gamma(plane);
> +		paint_rectangles(data, mode, red_green_blue, &fb);
> +		igt_plane_set_fb(plane, &fb);
> +		igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +		igt_wait_for_vblank(data->drm_fd,
> +			display->pipes[plane->pipe->pipe].crtc_offset);
> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
> +
> +		/* Draw gradient colors with gamma LUT to remap all
> +		 * values to max red/green/blue.
> +		 */
> +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> +				gamma_mode->enums[i].name);
> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
> +		lut = create_max_lut(segment_info);
> +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
> +
> +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
> +		igt_plane_set_fb(plane, &fb);
> +		igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +		igt_wait_for_vblank(data->drm_fd,
> +			display->pipes[plane->pipe->pipe].crtc_offset);
> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
> +
> +		/* Verify that the CRC of the software computed output is
> +		 * equal to the CRC of the gamma LUT transformation output.
> +		 */
> +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
> +
> +		free(lut);
> +		clear_segment_data(segment_info);
> +	}
> +
> +	disable_plane_gamma(plane);
> +	igt_plane_set_fb(plane, NULL);
> +	igt_output_set_pipe(output, PIPE_NONE);
> +	igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +
> +	igt_pipe_crc_free(pipe_crc);
> +	drmModeFreeProperty(gamma_mode);
> +
> +	return ret;
> +}
> +
>  static void
>  prep_pipe(data_t *data, enum pipe p)
>  {
> @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
>  		invalid_ctm_matrix_sizes(data, p);
>  }
>  
> +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
> +{
> +	igt_plane_t *plane;
> +	int count = 0;
> +
> +	for_each_plane_on_pipe(&data->display, pipe, plane) {
> +		if (!is_valid_plane(plane))
> +			continue;
> +
> +		igt_assert(test(data, plane));
> +
> +		count++;
> +	}
> +
> +	igt_require_f(count, "No valid planes found.\n");
> +}
> +
> +static void run_tests_for_plane(data_t *data, enum pipe pipe)
> +{
> +	igt_fixture {
> +		igt_require_pipe(&data->display, pipe);
> +		igt_require_pipe_crc(data->drm_fd);
> +		igt_require(data->display.pipes[pipe].n_planes > 0);
> +		igt_display_require_output_on_pipe(&data->display, pipe);
> +	}
> +
> +	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");

I can't seem to see the linear LUT test. This only seems to test
the max LUT.

Harry

> +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
> +		run_plane_color_test(data, pipe, plane_gamma_test);
> +}
> +
>  igt_main
>  {
>  	data_t data = {};
> @@ -910,6 +1084,9 @@ igt_main
>  
>  		igt_subtest_group
>  			run_invalid_tests_for_pipe(&data, pipe);
> +
> +		igt_subtest_group
> +			run_tests_for_plane(&data, pipe);
>  	}
>  
>  	igt_fixture {
> 


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

* Re: [igt-dev] [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
@ 2021-11-26 16:55     ` Harry Wentland
  0 siblings, 0 replies; 96+ messages in thread
From: Harry Wentland @ 2021-11-26 16:55 UTC (permalink / raw)
  To: Bhanuprakash Modem, igt-dev, dri-devel



On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> with a maxed out gamma LUT and verify we have the same CRC as drawing solid
> color rectangles.
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 178 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/kms_color.c b/tests/kms_color.c
> index 775f35964f..b45d66762f 100644
> --- a/tests/kms_color.c
> +++ b/tests/kms_color.c
> @@ -24,7 +24,34 @@
>  
>  #include "kms_color_helper.h"
>  
> -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
> +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
> +
> +#define MAX_SUPPORTED_PLANES 7
> +#define SDR_PLANE_BASE 3
> +
> +typedef bool (*test_t)(data_t*, igt_plane_t*);
> +
> +static bool is_hdr_plane(const igt_plane_t *plane)
> +{
> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> +}
> +
> +static bool is_valid_plane(igt_plane_t *plane)
> +{
> +	int index = plane->index;
> +
> +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> +		return false;
> +
> +	/*
> +	 * Test 1 HDR plane, 1 SDR plane.
> +	 *
> +	 * 0,1,2 HDR planes
> +	 * 3,4,5,6 SDR planes
> +	 *
> +	 */

This seems to be about Intel HW. AMD HW for example does
not have HDR or SDR planes, only one generic plane.

> +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> +}
>  
>  static void test_pipe_degamma(data_t *data,
>  			      igt_plane_t *primary)
> @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t *data,
>  }
>  #endif
>  
> +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> +{
> +	igt_output_t *output;
> +	igt_display_t *display = &data->display;
> +	drmModeModeInfo *mode;
> +	struct igt_fb fb;
> +	drmModePropertyPtr gamma_mode = NULL;
> +	uint32_t i;
> +	bool ret = true;
> +	igt_pipe_crc_t *pipe_crc = NULL;
> +	color_t red_green_blue[] = {
> +		{ 1.0, 0.0, 0.0 },
> +		{ 0.0, 1.0, 0.0 },
> +		{ 0.0, 0.0, 1.0 }
> +	};
> +
> +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
> +			kmstest_pipe_name(plane->pipe->pipe),
> +			kmstest_plane_type_name(plane->type),
> +			is_hdr_plane(plane) ? "hdr":"sdr");
> +

is_hdr_plane is Intel-specific.

> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> +
> +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
> +				  plane->pipe->pipe,
> +				  INTEL_PIPE_CRC_SOURCE_AUTO);
> +
> +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
> +	igt_assert(output);
> +
> +	igt_output_set_pipe(output, plane->pipe->pipe);
> +	mode = igt_output_get_mode(output);
> +
> +	/* Create a framebuffer at the size of the output. */
> +	igt_assert(igt_create_fb(data->drm_fd,
> +			      mode->hdisplay,
> +			      mode->vdisplay,
> +			      DRM_FORMAT_XRGB8888,
> +			      DRM_FORMAT_MOD_LINEAR,
> +			      &fb));
> +	igt_plane_set_fb(plane, &fb);
> +
> +	/* Disable Pipe color props. */
> +	disable_ctm(plane->pipe);
> +	disable_degamma(plane->pipe);
> +	disable_gamma(plane->pipe);
> +
> +	disable_plane_ctm(plane);
> +	disable_plane_degamma(plane);
> +	igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +
> +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> +
> +	/* Iterate all supported gamma modes. */
> +	for (i = 0; i < gamma_mode->count_enums; i++) {
> +		igt_crc_t crc_gamma, crc_fullcolors;
> +		segment_data_t *segment_info = NULL;
> +		struct drm_color_lut_ext *lut = NULL;
> +		uint32_t lut_size = 0;
> +
> +		/* Ignore 'no gamma' from enum list. */
> +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> +			continue;
> +

It might still make sense to test that this is doing bypass.

> +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
> +
> +		/* Draw solid colors with no gamma transformation. */
> +		disable_plane_gamma(plane);
> +		paint_rectangles(data, mode, red_green_blue, &fb);
> +		igt_plane_set_fb(plane, &fb);
> +		igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +		igt_wait_for_vblank(data->drm_fd,
> +			display->pipes[plane->pipe->pipe].crtc_offset);
> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
> +
> +		/* Draw gradient colors with gamma LUT to remap all
> +		 * values to max red/green/blue.
> +		 */
> +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> +				gamma_mode->enums[i].name);
> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
> +		lut = create_max_lut(segment_info);
> +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
> +
> +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
> +		igt_plane_set_fb(plane, &fb);
> +		igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +		igt_wait_for_vblank(data->drm_fd,
> +			display->pipes[plane->pipe->pipe].crtc_offset);
> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
> +
> +		/* Verify that the CRC of the software computed output is
> +		 * equal to the CRC of the gamma LUT transformation output.
> +		 */
> +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
> +
> +		free(lut);
> +		clear_segment_data(segment_info);
> +	}
> +
> +	disable_plane_gamma(plane);
> +	igt_plane_set_fb(plane, NULL);
> +	igt_output_set_pipe(output, PIPE_NONE);
> +	igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +
> +	igt_pipe_crc_free(pipe_crc);
> +	drmModeFreeProperty(gamma_mode);
> +
> +	return ret;
> +}
> +
>  static void
>  prep_pipe(data_t *data, enum pipe p)
>  {
> @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
>  		invalid_ctm_matrix_sizes(data, p);
>  }
>  
> +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
> +{
> +	igt_plane_t *plane;
> +	int count = 0;
> +
> +	for_each_plane_on_pipe(&data->display, pipe, plane) {
> +		if (!is_valid_plane(plane))
> +			continue;
> +
> +		igt_assert(test(data, plane));
> +
> +		count++;
> +	}
> +
> +	igt_require_f(count, "No valid planes found.\n");
> +}
> +
> +static void run_tests_for_plane(data_t *data, enum pipe pipe)
> +{
> +	igt_fixture {
> +		igt_require_pipe(&data->display, pipe);
> +		igt_require_pipe_crc(data->drm_fd);
> +		igt_require(data->display.pipes[pipe].n_planes > 0);
> +		igt_display_require_output_on_pipe(&data->display, pipe);
> +	}
> +
> +	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");

I can't seem to see the linear LUT test. This only seems to test
the max LUT.

Harry

> +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
> +		run_plane_color_test(data, pipe, plane_gamma_test);
> +}
> +
>  igt_main
>  {
>  	data_t data = {};
> @@ -910,6 +1084,9 @@ igt_main
>  
>  		igt_subtest_group
>  			run_invalid_tests_for_pipe(&data, pipe);
> +
> +		igt_subtest_group
> +			run_tests_for_plane(&data, pipe);
>  	}
>  
>  	igt_fixture {
> 

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

* Re: [i-g-t 06/14] tests/kms_color: New subtests for Plane CTM
  2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
  (?)
@ 2021-11-26 16:55   ` Harry Wentland
  -1 siblings, 0 replies; 96+ messages in thread
From: Harry Wentland @ 2021-11-26 16:55 UTC (permalink / raw)
  To: Bhanuprakash Modem, igt-dev, dri-devel; +Cc: Uma Shankar, Juha-Pekka Heikkila



On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> To verify plane CTM, draw 3 rectangles using before colors with the
> ctm matrix applied and verify the CRC is equal to using after colors
> with an identify ctm matrix.
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 225 insertions(+)
> 
> diff --git a/tests/kms_color.c b/tests/kms_color.c
> index 920a5eaadd..e14b37cb6f 100644
> --- a/tests/kms_color.c
> +++ b/tests/kms_color.c
> @@ -53,6 +53,77 @@ static bool is_valid_plane(igt_plane_t *plane)
>  	return index >= 0 && index < MAX_SUPPORTED_PLANES;
>  }
>  
> +struct {
> +	const char *test_name;
> +	int iter;
> +	color_t expected_colors[3];
> +	double ctm[9];
> +} ctm_tests[] = {
> +	{"plane-ctm-red-to-blue", 0,
> +					{{ 0.0, 0.0, 1.0 },
> +					 { 0.0, 1.0, 0.0 },
> +					 { 0.0, 0.0, 1.0 }},
> +		{ 0.0, 0.0, 0.0,
> +		  0.0, 1.0, 0.0,
> +		  1.0, 0.0, 1.0 },
> +	},
> +	{"plane-ctm-green-to-red", 0,
> +					{{ 1.0, 0.0, 0.0 },
> +					 { 1.0, 0.0, 0.0 },
> +					 { 0.0, 0.0, 1.0 }},
> +		{ 1.0, 1.0, 0.0,
> +		  0.0, 0.0, 0.0,
> +		  0.0, 0.0, 1.0 },
> +	},
> +	{"plane-ctm-blue-to-red", 0,
> +					{{ 1.0, 0.0, 0.0 },
> +					 { 0.0, 1.0, 0.0 },
> +					 { 1.0, 0.0, 0.0 }},
> +		{ 1.0, 0.0, 1.0,
> +		  0.0, 1.0, 0.0,
> +		  0.0, 0.0, 0.0 },
> +	},
> +	{"plane-ctm-max", 0,
> +					{{ 1.0, 0.0, 0.0 },
> +					 { 0.0, 1.0, 0.0 },
> +					 { 0.0, 0.0, 1.0 }},
> +		{ 100.0, 0.0, 0.0,
> +		  0.0, 100.0, 0.0,
> +		  0.0, 0.0, 100.0 },
> +	},
> +	{"plane-ctm-negative", 0,
> +					{{ 0.0, 0.0, 0.0 },
> +					 { 0.0, 0.0, 0.0 },
> +					 { 0.0, 0.0, 0.0 }},
> +		{ -1.0, 0.0, 0.0,
> +		   0.0, -1.0, 0.0,
> +		   0.0, 0.0, -1.0 },
> +	},
> +	/* We tests a few values around the expected result because
> +	 * it depends on the hardware we're dealing with, we can
> +	 * either get clamped or rounded values and we also need to
> +	 * account for odd number of items in the LUTs.
> +	 */
> +	{"plane-ctm-0-25", 5,
> +					{{ 0.0, }, { 0.0, }, { 0.0, }},
> +		{ 0.25, 0.0,  0.0,
> +		  0.0,  0.25, 0.0,
> +		  0.0,  0.0,  0.25 },
> +	},
> +	{"plane-ctm-0-50", 5,
> +					{{ 0.0, }, { 0.0, }, { 0.0, }},
> +		{ 0.5,  0.0,  0.0,
> +		  0.0,  0.5,  0.0,
> +		  0.0,  0.0,  0.5 },
> +	},
> +	{"plane-ctm-0-75", 7,
> +					{{ 0.0, }, { 0.0, }, { 0.0, }},
> +		{ 0.75, 0.0,  0.0,
> +		  0.0,  0.75, 0.0,
> +		  0.0,  0.0,  0.75 },
> +	},
> +};
> +
>  static void test_pipe_degamma(data_t *data,
>  			      igt_plane_t *primary)
>  {
> @@ -900,6 +971,99 @@ static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
>  	return ret;
>  }
>  
> +static bool test_plane_ctm(data_t *data,
> +			  igt_plane_t *plane,
> +			  color_t *before,
> +			  color_t *after,
> +			  double *ctm_matrix)
> +{
> +	const double ctm_identity[] = {
> +		1.0, 0.0, 0.0,
> +		0.0, 1.0, 0.0,
> +		0.0, 0.0, 1.0
> +	};
> +	igt_output_t *output;
> +	igt_display_t *display = &data->display;
> +	drmModeModeInfo *mode;
> +	struct igt_fb fb;
> +	igt_crc_t crc_software, crc_hardware;
> +	igt_pipe_crc_t *pipe_crc = NULL;
> +	bool ret = true;
> +
> +	igt_info("Plane CTM test is running on pipe-%s plane-%s(%s)\n",
> +			kmstest_pipe_name(plane->pipe->pipe),
> +			kmstest_plane_type_name(plane->type),
> +			is_hdr_plane(plane) ? "hdr":"sdr");
> +
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
> +
> +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
> +				  plane->pipe->pipe,
> +				  INTEL_PIPE_CRC_SOURCE_AUTO);
> +
> +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
> +	igt_assert(output);
> +
> +	igt_output_set_pipe(output, plane->pipe->pipe);
> +	mode = igt_output_get_mode(output);
> +
> +	/* Create a framebuffer at the size of the output. */
> +	igt_assert(igt_create_fb(data->drm_fd,
> +			      mode->hdisplay,
> +			      mode->vdisplay,
> +			      DRM_FORMAT_XRGB8888,
> +			      DRM_FORMAT_MOD_LINEAR,
> +			      &fb));
> +
> +	igt_plane_set_fb(plane, &fb);
> +
> +	/* Disable Pipe color props. */
> +	disable_degamma(plane->pipe);
> +	disable_gamma(plane->pipe);
> +	disable_ctm(plane->pipe);
> +
> +	disable_plane_gamma(plane);
> +	disable_plane_degamma(plane);
> +	igt_display_commit2(display, display->is_atomic ?
> +				COMMIT_ATOMIC : COMMIT_LEGACY);
> +
> +	/* Without CTM transformation. */
> +	paint_rectangles(data, mode, after, &fb);
> +	igt_plane_set_fb(plane, &fb);
> +	set_plane_ctm(plane, ctm_identity);
> +	igt_display_commit2(display, display->is_atomic ?
> +				COMMIT_ATOMIC : COMMIT_LEGACY);
> +	igt_wait_for_vblank(data->drm_fd,
> +			display->pipes[plane->pipe->pipe].crtc_offset);
> +	igt_pipe_crc_collect_crc(pipe_crc, &crc_software);
> +
> +	/* With CTM transformation. */
> +	paint_rectangles(data, mode, before, &fb);
> +	igt_plane_set_fb(plane, &fb);
> +	set_plane_ctm(plane, ctm_matrix);
> +	igt_display_commit2(display, display->is_atomic ?
> +				COMMIT_ATOMIC : COMMIT_LEGACY);
> +	igt_wait_for_vblank(data->drm_fd,
> +			display->pipes[plane->pipe->pipe].crtc_offset);
> +	igt_pipe_crc_collect_crc(pipe_crc, &crc_hardware);
> +
> +	/* Verify that the CRC of the software computed ouutput
> +	 * is equal to the CRC of the CTM matrix transformation
> +	 * output.
> +	 */
> +	ret = igt_check_crc_equal(&crc_software, &crc_hardware);
> +
> +	disable_plane_ctm(plane);
> +	igt_plane_set_fb(plane, NULL);
> +	igt_output_set_pipe(output, PIPE_NONE);
> +	igt_display_commit2(display, display->is_atomic ?
> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> +
> +	igt_pipe_crc_free(pipe_crc);
> +
> +	return ret;
> +}
> +
>  static void
>  prep_pipe(data_t *data, enum pipe p)
>  {
> @@ -1169,8 +1333,57 @@ static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
>  	igt_require_f(count, "No valid planes found.\n");
>  }
>  
> +static void run_plane_ctm_test(data_t *data,
> +				enum pipe pipe,
> +				color_t *expected,
> +				double *ctm,
> +				int iter)
> +{
> +	igt_plane_t *plane;
> +	bool result;
> +	int i, count = 0;
> +	double delta = 1.0 / (1 << 8);
> +	color_t red_green_blue[] = {
> +		{ 1.0, 0.0, 0.0 },
> +		{ 0.0, 1.0, 0.0 },
> +		{ 0.0, 0.0, 1.0 }
> +	};
> +
> +	for_each_plane_on_pipe(&data->display, pipe, plane) {
> +		if (!is_valid_plane(plane))
> +			continue;
> +
> +		result = false;
> +
> +		if (!iter)
> +			result |= test_plane_ctm(data, plane,
> +					red_green_blue, expected,
> +					ctm);
> +
> +		for (i = 0; i < iter; i++) {
> +			expected[0].r =
> +			expected[1].g =
> +			expected[2].b =
> +				ctm[0] + delta * (i - (iter/2));
> +

This bracketing likely depends closely on HW. I am curious if we
can get this to work on various HW.

Harry

> +			result |= test_plane_ctm(data, plane,
> +					red_green_blue,	expected,
> +					ctm);
> +			if (result)
> +				break;
> +		}
> +
> +		igt_assert(result);
> +		count++;
> +	}
> +
> +	igt_require_f(count, "No valid planes found.\n");
> +}
> +
>  static void run_tests_for_plane(data_t *data, enum pipe pipe)
>  {
> +	int i;
> +
>  	igt_fixture {
>  		igt_require_pipe(&data->display, pipe);
>  		igt_require_pipe_crc(data->drm_fd);
> @@ -1186,6 +1399,18 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
>  	igt_subtest_f("pipe-%s-plane-degamma",
>  			kmstest_pipe_name(pipe))
>  		run_plane_color_test(data, pipe, plane_degamma_test);
> +
> +	for (i = 0; i < ARRAY_SIZE(ctm_tests); i++) {
> +		igt_describe("Compare after applying ctm matrix & identity matrix");
> +		igt_subtest_f("pipe-%s-%s",
> +				kmstest_pipe_name(pipe),
> +				ctm_tests[i].test_name) {
> +			run_plane_ctm_test(data, pipe,
> +					ctm_tests[i].expected_colors,
> +					ctm_tests[i].ctm,
> +					ctm_tests[i].iter);
> +		}
> +	}
>  }
>  
>  igt_main
> 


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

* Re: [i-g-t 12/14] kms_color_helper: Add helper functions to support logarithmic gamma mode
  2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
@ 2021-11-26 16:55     ` Harry Wentland
  -1 siblings, 0 replies; 96+ messages in thread
From: Harry Wentland @ 2021-11-26 16:55 UTC (permalink / raw)
  To: Bhanuprakash Modem, igt-dev, dri-devel
  Cc: Uma Shankar, Mukunda Pramodh Kumar, Juha-Pekka Heikkila



On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> 
> Add helper functions to support logarithmic gamma mode
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color_helper.c | 127 +++++++++++++++++++++++++++++++++++++++
>  tests/kms_color_helper.h |  16 +++++
>  2 files changed, 143 insertions(+)
> 
> diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> index c65b7a0f50..7ea8282df3 100644
> --- a/tests/kms_color_helper.c
> +++ b/tests/kms_color_helper.c
> @@ -190,6 +190,33 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
>  	return lut;
>  }
>  
> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> +						const gamma_lut_t *gamma,
> +						uint32_t color_depth,
> +						int off)

How does this create a logarithmic LUT? It seems to do the same
as coeffs_to_lut (which is also full of intellisms) except that
it also scales the values by max_hw_value / max_segment_value for
reasons that are not obvious to me.

> +{
> +	struct drm_color_lut *lut;
> +	int i, lut_size = gamma->size;
> +	/* This is the maximum value due to 16 bit precision in hardware. */
> +	uint32_t max_hw_value = (1 << 16) - 1;
> +	unsigned int max_segment_value = 1 << 24;
> +


This looks like it is specific to Intel HW. Intel-specific things should
not live in kms_ tests.

Shouldn't these be encoded in the drm_color_lut_range definitions?

To be honest I am not clear why max_hw_value and max_segment_value
differ here.

Harry

> +	lut = malloc(sizeof(struct drm_color_lut) * lut_size);
> +
> +	for (i = 0; i < lut_size; i++) {
> +		double scaling_factor = (double)max_hw_value / (double)max_segment_value;
> +		uint32_t r = MIN((gamma->coeffs[i].r * scaling_factor), max_hw_value);
> +		uint32_t g = MIN((gamma->coeffs[i].g * scaling_factor), max_hw_value);
> +		uint32_t b = MIN((gamma->coeffs[i].b * scaling_factor), max_hw_value);
> +
> +		lut[i].red = r;
> +		lut[i].green = g;
> +		lut[i].blue = b;
> +	}
> +
> +	return lut;
> +}
> +
>  void set_degamma(data_t *data,
>  		 igt_pipe_t *pipe,
>  		 const gamma_lut_t *gamma)
> @@ -203,6 +230,15 @@ void set_degamma(data_t *data,
>  	free(lut);
>  }
>  
> +void set_pipe_gamma(igt_pipe_t *pipe,
> +		    uint64_t value,
> +		    struct drm_color_lut *lut,
> +		    uint32_t size)
> +{
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_MODE, value);
> +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
> +}
> +
>  void set_gamma(data_t *data,
>  	       igt_pipe_t *pipe, const gamma_lut_t *gamma)
>  {
> @@ -241,6 +277,51 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
>  }
>  
> +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> +					       enum igt_atomic_crtc_properties prop)
> +{
> +	igt_display_t *display = pipe->display;
> +	uint32_t prop_id = pipe->props[prop];
> +	drmModePropertyPtr drmProp;
> +
> +	igt_assert(prop_id);
> +
> +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> +
> +	igt_assert(drmProp);
> +	igt_assert(drmProp->count_enums);
> +
> +	return drmProp;
> +}
> +
> +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info)
> +{
> +	uint32_t segment, entry, index = 0;
> +	double val;
> +	int i = 0;
> +	gamma_lut_t *gamma = alloc_lut(info->entries_count);
> +
> +	igt_assert(gamma);
> +
> +	gamma->size = info->entries_count;
> +	for (segment = 0; segment < info->segment_count; segment++) {
> +		uint32_t entry_count = info->segment_data[segment].count;
> +		uint32_t start = (segment == 0) ? 0 : (1 << (segment - 1));
> +		uint32_t end = 1 << segment;
> +
> +		for (entry = 0; entry < entry_count; entry++) {
> +			val = (index == 0) ? /* First entry is Zero. */
> +				0 : start + entry *
> +				((end - start) * 1.0 / entry_count);
> +
> +			set_rgb(&gamma->coeffs[i++], val);
> +			index++;
> +		}
> +	}
> +
> +	return gamma;
> +}
> +
>  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
>  				enum igt_atomic_plane_properties prop)
>  {
> @@ -331,6 +412,7 @@ segment_data_t *get_segment_data(data_t *data,
>  	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
>  	igt_assert(info->segment_data);
>  
> +	info->entries_count = 0;
>  	for (i = 0; i < info->segment_count; i++) {
>  		info->entries_count += lut_range[i].count;
>  		info->segment_data[i] = lut_range[i];
> @@ -341,6 +423,51 @@ segment_data_t *get_segment_data(data_t *data,
>  	return info;
>  }
>  
> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type)
> +{
> +	igt_display_t *display = &data->display;
> +	gamma_lut_t *gamma_log;
> +	drmModePropertyPtr gamma_mode = NULL;
> +	segment_data_t *segment_info = NULL;
> +	struct drm_color_lut *lut = NULL;
> +	int lut_size = 0;
> +
> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
> +	gamma_mode = get_pipe_gamma_degamma_mode(pipe, IGT_CRTC_GAMMA_MODE);
> +
> +	for (int i = 0; i < gamma_mode->count_enums; i++) {
> +		if (!strcmp(gamma_mode->enums[i].name, "logarithmic gamma")) {
> +			segment_info = get_segment_data(data,
> +							gamma_mode->enums[i].value,
> +							gamma_mode->enums[i].name);
> +			lut_size = sizeof(struct drm_color_lut) *
> +					  segment_info->entries_count;
> +			if (type == LINEAR_GAMMA) {
> +				gamma_log = pipe_create_linear_lut(segment_info);
> +				lut = coeffs_to_logarithmic_lut(data,
> +								gamma_log,
> +								data->color_depth,
> +								0);
> +			} else if (type == MAX_GAMMA) {
> +				gamma_log = generate_table_max(segment_info->entries_count);
> +				gamma_log->size = segment_info->entries_count;
> +				lut = coeffs_to_lut(data, gamma_log,
> +						    data->color_depth, 0);
> +			}
> +			set_pipe_gamma(pipe, gamma_mode->enums[i].value,
> +				       lut, lut_size);
> +			igt_display_commit2(display, display->is_atomic
> +					    ? COMMIT_ATOMIC : COMMIT_LEGACY);
> +			break;
> +		}
> +	}
> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
> +	free(gamma_log);
> +	free(lut);
> +	clear_segment_data(segment_info);
> +	drmModeFreeProperty(gamma_mode);
> +}
> +
>  void set_plane_gamma(igt_plane_t *plane,
>  		char *mode,
>  		struct drm_color_lut_ext *lut,
> diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> index 5a35dcaac1..c863874f0c 100644
> --- a/tests/kms_color_helper.h
> +++ b/tests/kms_color_helper.h
> @@ -70,6 +70,11 @@ typedef struct {
>  	uint32_t entries_count;
>  } segment_data_t;
>  
> +enum gamma_type {
> +	LINEAR_GAMMA,
> +	MAX_GAMMA
> +};
> +
>  #define MIN(a, b) ((a) < (b) ? (a) : (b))
>  
>  void paint_gradient_rectangles(data_t *data,
> @@ -89,6 +94,10 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
>  				    const gamma_lut_t *gamma,
>  				    uint32_t color_depth,
>  				    int off);
> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> +						const gamma_lut_t *gamma,
> +						uint32_t color_depth,
> +						int off);
>  void set_degamma(data_t *data,
>  		 igt_pipe_t *pipe,
>  		 const gamma_lut_t *gamma);
> @@ -98,12 +107,19 @@ void set_gamma(data_t *data,
>  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
>  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
>  
> +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> +					       enum igt_atomic_crtc_properties
> +					       prop);
>  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
>  	enum igt_atomic_plane_properties prop);
>  void clear_segment_data(segment_data_t *info);
> +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info);
>  struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
>  struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
>  segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
> +void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
> +		    struct drm_color_lut *lut, uint32_t size);
> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type);
>  void set_plane_gamma(igt_plane_t *plane,
>  	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
>  void set_plane_degamma(igt_plane_t *plane,
> 


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

* Re: [igt-dev] [i-g-t 12/14] kms_color_helper: Add helper functions to support logarithmic gamma mode
@ 2021-11-26 16:55     ` Harry Wentland
  0 siblings, 0 replies; 96+ messages in thread
From: Harry Wentland @ 2021-11-26 16:55 UTC (permalink / raw)
  To: Bhanuprakash Modem, igt-dev, dri-devel; +Cc: Mukunda Pramodh Kumar



On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> 
> Add helper functions to support logarithmic gamma mode
> 
> Cc: Harry Wentland <harry.wentland@amd.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> Cc: Uma Shankar <uma.shankar@intel.com>
> Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> ---
>  tests/kms_color_helper.c | 127 +++++++++++++++++++++++++++++++++++++++
>  tests/kms_color_helper.h |  16 +++++
>  2 files changed, 143 insertions(+)
> 
> diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> index c65b7a0f50..7ea8282df3 100644
> --- a/tests/kms_color_helper.c
> +++ b/tests/kms_color_helper.c
> @@ -190,6 +190,33 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
>  	return lut;
>  }
>  
> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> +						const gamma_lut_t *gamma,
> +						uint32_t color_depth,
> +						int off)

How does this create a logarithmic LUT? It seems to do the same
as coeffs_to_lut (which is also full of intellisms) except that
it also scales the values by max_hw_value / max_segment_value for
reasons that are not obvious to me.

> +{
> +	struct drm_color_lut *lut;
> +	int i, lut_size = gamma->size;
> +	/* This is the maximum value due to 16 bit precision in hardware. */
> +	uint32_t max_hw_value = (1 << 16) - 1;
> +	unsigned int max_segment_value = 1 << 24;
> +


This looks like it is specific to Intel HW. Intel-specific things should
not live in kms_ tests.

Shouldn't these be encoded in the drm_color_lut_range definitions?

To be honest I am not clear why max_hw_value and max_segment_value
differ here.

Harry

> +	lut = malloc(sizeof(struct drm_color_lut) * lut_size);
> +
> +	for (i = 0; i < lut_size; i++) {
> +		double scaling_factor = (double)max_hw_value / (double)max_segment_value;
> +		uint32_t r = MIN((gamma->coeffs[i].r * scaling_factor), max_hw_value);
> +		uint32_t g = MIN((gamma->coeffs[i].g * scaling_factor), max_hw_value);
> +		uint32_t b = MIN((gamma->coeffs[i].b * scaling_factor), max_hw_value);
> +
> +		lut[i].red = r;
> +		lut[i].green = g;
> +		lut[i].blue = b;
> +	}
> +
> +	return lut;
> +}
> +
>  void set_degamma(data_t *data,
>  		 igt_pipe_t *pipe,
>  		 const gamma_lut_t *gamma)
> @@ -203,6 +230,15 @@ void set_degamma(data_t *data,
>  	free(lut);
>  }
>  
> +void set_pipe_gamma(igt_pipe_t *pipe,
> +		    uint64_t value,
> +		    struct drm_color_lut *lut,
> +		    uint32_t size)
> +{
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_MODE, value);
> +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
> +}
> +
>  void set_gamma(data_t *data,
>  	       igt_pipe_t *pipe, const gamma_lut_t *gamma)
>  {
> @@ -241,6 +277,51 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
>  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
>  }
>  
> +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> +					       enum igt_atomic_crtc_properties prop)
> +{
> +	igt_display_t *display = pipe->display;
> +	uint32_t prop_id = pipe->props[prop];
> +	drmModePropertyPtr drmProp;
> +
> +	igt_assert(prop_id);
> +
> +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> +
> +	igt_assert(drmProp);
> +	igt_assert(drmProp->count_enums);
> +
> +	return drmProp;
> +}
> +
> +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info)
> +{
> +	uint32_t segment, entry, index = 0;
> +	double val;
> +	int i = 0;
> +	gamma_lut_t *gamma = alloc_lut(info->entries_count);
> +
> +	igt_assert(gamma);
> +
> +	gamma->size = info->entries_count;
> +	for (segment = 0; segment < info->segment_count; segment++) {
> +		uint32_t entry_count = info->segment_data[segment].count;
> +		uint32_t start = (segment == 0) ? 0 : (1 << (segment - 1));
> +		uint32_t end = 1 << segment;
> +
> +		for (entry = 0; entry < entry_count; entry++) {
> +			val = (index == 0) ? /* First entry is Zero. */
> +				0 : start + entry *
> +				((end - start) * 1.0 / entry_count);
> +
> +			set_rgb(&gamma->coeffs[i++], val);
> +			index++;
> +		}
> +	}
> +
> +	return gamma;
> +}
> +
>  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
>  				enum igt_atomic_plane_properties prop)
>  {
> @@ -331,6 +412,7 @@ segment_data_t *get_segment_data(data_t *data,
>  	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
>  	igt_assert(info->segment_data);
>  
> +	info->entries_count = 0;
>  	for (i = 0; i < info->segment_count; i++) {
>  		info->entries_count += lut_range[i].count;
>  		info->segment_data[i] = lut_range[i];
> @@ -341,6 +423,51 @@ segment_data_t *get_segment_data(data_t *data,
>  	return info;
>  }
>  
> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type)
> +{
> +	igt_display_t *display = &data->display;
> +	gamma_lut_t *gamma_log;
> +	drmModePropertyPtr gamma_mode = NULL;
> +	segment_data_t *segment_info = NULL;
> +	struct drm_color_lut *lut = NULL;
> +	int lut_size = 0;
> +
> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
> +	gamma_mode = get_pipe_gamma_degamma_mode(pipe, IGT_CRTC_GAMMA_MODE);
> +
> +	for (int i = 0; i < gamma_mode->count_enums; i++) {
> +		if (!strcmp(gamma_mode->enums[i].name, "logarithmic gamma")) {
> +			segment_info = get_segment_data(data,
> +							gamma_mode->enums[i].value,
> +							gamma_mode->enums[i].name);
> +			lut_size = sizeof(struct drm_color_lut) *
> +					  segment_info->entries_count;
> +			if (type == LINEAR_GAMMA) {
> +				gamma_log = pipe_create_linear_lut(segment_info);
> +				lut = coeffs_to_logarithmic_lut(data,
> +								gamma_log,
> +								data->color_depth,
> +								0);
> +			} else if (type == MAX_GAMMA) {
> +				gamma_log = generate_table_max(segment_info->entries_count);
> +				gamma_log->size = segment_info->entries_count;
> +				lut = coeffs_to_lut(data, gamma_log,
> +						    data->color_depth, 0);
> +			}
> +			set_pipe_gamma(pipe, gamma_mode->enums[i].value,
> +				       lut, lut_size);
> +			igt_display_commit2(display, display->is_atomic
> +					    ? COMMIT_ATOMIC : COMMIT_LEGACY);
> +			break;
> +		}
> +	}
> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
> +	free(gamma_log);
> +	free(lut);
> +	clear_segment_data(segment_info);
> +	drmModeFreeProperty(gamma_mode);
> +}
> +
>  void set_plane_gamma(igt_plane_t *plane,
>  		char *mode,
>  		struct drm_color_lut_ext *lut,
> diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> index 5a35dcaac1..c863874f0c 100644
> --- a/tests/kms_color_helper.h
> +++ b/tests/kms_color_helper.h
> @@ -70,6 +70,11 @@ typedef struct {
>  	uint32_t entries_count;
>  } segment_data_t;
>  
> +enum gamma_type {
> +	LINEAR_GAMMA,
> +	MAX_GAMMA
> +};
> +
>  #define MIN(a, b) ((a) < (b) ? (a) : (b))
>  
>  void paint_gradient_rectangles(data_t *data,
> @@ -89,6 +94,10 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
>  				    const gamma_lut_t *gamma,
>  				    uint32_t color_depth,
>  				    int off);
> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> +						const gamma_lut_t *gamma,
> +						uint32_t color_depth,
> +						int off);
>  void set_degamma(data_t *data,
>  		 igt_pipe_t *pipe,
>  		 const gamma_lut_t *gamma);
> @@ -98,12 +107,19 @@ void set_gamma(data_t *data,
>  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
>  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
>  
> +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> +					       enum igt_atomic_crtc_properties
> +					       prop);
>  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
>  	enum igt_atomic_plane_properties prop);
>  void clear_segment_data(segment_data_t *info);
> +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info);
>  struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
>  struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
>  segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
> +void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
> +		    struct drm_color_lut *lut, uint32_t size);
> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type);
>  void set_plane_gamma(igt_plane_t *plane,
>  	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
>  void set_plane_degamma(igt_plane_t *plane,
> 

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

* Re: [i-g-t 00/14] Add IGT support for plane color management
  2021-11-26 16:54   ` Harry Wentland
@ 2021-11-29  9:20       ` Pekka Paalanen
  0 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-29  9:20 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Mukunda Pramodh Kumar, Juha-Pekka Heikkila, dri-devel, igt-dev,
	Uma Shankar, Bhanuprakash Modem

[-- Attachment #1: Type: text/plain, Size: 3455 bytes --]

On Fri, 26 Nov 2021 11:54:55 -0500
Harry Wentland <harry.wentland@amd.com> wrote:

> On 2021-11-18 04:50, Pekka Paalanen wrote:
> > On Mon, 15 Nov 2021 15:17:45 +0530
> > Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> >   
> >> From the Plane Color Management feature design, userspace can
> >> take the smart blending decisions based on hardware supported
> >> plane color features to obtain an accurate color profile.
> >>
> >> These IGT patches extend the existing pipe color management
> >> tests to the plane level.
> >>
> >> Kernel implementation:
> >> https://patchwork.freedesktop.org/series/90825/  

...

> > I also found some things that looked hardware-specific in this code
> > that to my understanding is supposed to be generic, and some concerns
> > about UAPI as well.
> >   
> 
> I left some comments on intellisms in these patches.
> 
> Do you have any specifics about your concerns about UAPI?

Yeah, the comments I left in the patches:

patch 3:

> Having to explicitly special-case index zero feels odd to me. Why does
> it need explicit special-casing?
> 
> To me it's a hint that the definitions of .start and .end are somehow
> inconsistent.

patch 4 and 8:

> > +static bool is_hdr_plane(const igt_plane_t *plane)
> > +{
> > +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;  
> 
> How can this be right for all KMS drivers?
> 
> What is a HDR plane?

patch 12:

> > +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> > +						const gamma_lut_t *gamma,
> > +						uint32_t color_depth,
> > +						int off)
> > +{
> > +	struct drm_color_lut *lut;
> > +	int i, lut_size = gamma->size;
> > +	/* This is the maximum value due to 16 bit precision in hardware. */  
> 
> In whose hardware?
> 
> Are igt tests not supposed to be generic for everything that exposes
> the particular KMS properties?
> 
> This also hints that the UAPI design is lacking, because userspace
> needs to know hardware specific things out of thin air. Display servers
> are not going to have hardware-specific code. They specialise based on
> the existence of KMS properties instead.

...

> > +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type)
> > +{
> > +	igt_display_t *display = &data->display;
> > +	gamma_lut_t *gamma_log;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	segment_data_t *segment_info = NULL;
> > +	struct drm_color_lut *lut = NULL;
> > +	int lut_size = 0;
> > +
> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);  
> 
> Is this how we are going to do cross-software DRM-master hand-over or
> switching compatibility in general?
> 
> Add a new client cap for every new KMS property, and if the KMS client
> does not set the property, the kernel will magically reset it to ensure
> the client's expectations are met? Is that how it works?
> 
> Or why does this exist?

...

> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);  
> 
> I've never seen this done before. I did not know client caps could be
> reset.


So, patch 12 has the biggest UAPI questions, and patch 3 may need a
UAPI change as well. The comments in patches 4 and 8 could be addressed
with just removing that code since the concept of HDR/SDR planes does
not exist in UAPI. Or, if that concept is needed then it's another UAPI
problem.


Thanks,
pq

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [igt-dev] [i-g-t 00/14] Add IGT support for plane color management
@ 2021-11-29  9:20       ` Pekka Paalanen
  0 siblings, 0 replies; 96+ messages in thread
From: Pekka Paalanen @ 2021-11-29  9:20 UTC (permalink / raw)
  To: Harry Wentland; +Cc: Mukunda Pramodh Kumar, dri-devel, igt-dev

[-- Attachment #1: Type: text/plain, Size: 3455 bytes --]

On Fri, 26 Nov 2021 11:54:55 -0500
Harry Wentland <harry.wentland@amd.com> wrote:

> On 2021-11-18 04:50, Pekka Paalanen wrote:
> > On Mon, 15 Nov 2021 15:17:45 +0530
> > Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> >   
> >> From the Plane Color Management feature design, userspace can
> >> take the smart blending decisions based on hardware supported
> >> plane color features to obtain an accurate color profile.
> >>
> >> These IGT patches extend the existing pipe color management
> >> tests to the plane level.
> >>
> >> Kernel implementation:
> >> https://patchwork.freedesktop.org/series/90825/  

...

> > I also found some things that looked hardware-specific in this code
> > that to my understanding is supposed to be generic, and some concerns
> > about UAPI as well.
> >   
> 
> I left some comments on intellisms in these patches.
> 
> Do you have any specifics about your concerns about UAPI?

Yeah, the comments I left in the patches:

patch 3:

> Having to explicitly special-case index zero feels odd to me. Why does
> it need explicit special-casing?
> 
> To me it's a hint that the definitions of .start and .end are somehow
> inconsistent.

patch 4 and 8:

> > +static bool is_hdr_plane(const igt_plane_t *plane)
> > +{
> > +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;  
> 
> How can this be right for all KMS drivers?
> 
> What is a HDR plane?

patch 12:

> > +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> > +						const gamma_lut_t *gamma,
> > +						uint32_t color_depth,
> > +						int off)
> > +{
> > +	struct drm_color_lut *lut;
> > +	int i, lut_size = gamma->size;
> > +	/* This is the maximum value due to 16 bit precision in hardware. */  
> 
> In whose hardware?
> 
> Are igt tests not supposed to be generic for everything that exposes
> the particular KMS properties?
> 
> This also hints that the UAPI design is lacking, because userspace
> needs to know hardware specific things out of thin air. Display servers
> are not going to have hardware-specific code. They specialise based on
> the existence of KMS properties instead.

...

> > +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type)
> > +{
> > +	igt_display_t *display = &data->display;
> > +	gamma_lut_t *gamma_log;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	segment_data_t *segment_info = NULL;
> > +	struct drm_color_lut *lut = NULL;
> > +	int lut_size = 0;
> > +
> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);  
> 
> Is this how we are going to do cross-software DRM-master hand-over or
> switching compatibility in general?
> 
> Add a new client cap for every new KMS property, and if the KMS client
> does not set the property, the kernel will magically reset it to ensure
> the client's expectations are met? Is that how it works?
> 
> Or why does this exist?

...

> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);  
> 
> I've never seen this done before. I did not know client caps could be
> reset.


So, patch 12 has the biggest UAPI questions, and patch 3 may need a
UAPI change as well. The comments in patches 4 and 8 could be addressed
with just removing that code since the concept of HDR/SDR planes does
not exist in UAPI. Or, if that concept is needed then it's another UAPI
problem.


Thanks,
pq

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [igt-dev] [i-g-t 07/14] tests/kms_color: New negative tests for plane level color mgmt
  2021-11-18  9:19     ` [igt-dev] " Pekka Paalanen
  (?)
@ 2021-11-29 14:56     ` Harry Wentland
  -1 siblings, 0 replies; 96+ messages in thread
From: Harry Wentland @ 2021-11-29 14:56 UTC (permalink / raw)
  To: Pekka Paalanen, Bhanuprakash Modem; +Cc: igt-dev, dri-devel



On 2021-11-18 04:19, Pekka Paalanen wrote:
> On Mon, 15 Nov 2021 15:17:52 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
>> Negative check for:
>>  * plane gamma lut sizes
>>  * plane degamma lut sizes
>>  * plane ctm matrix sizes
>>
>> Cc: Harry Wentland <harry.wentland@amd.com>
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
>> Cc: Uma Shankar <uma.shankar@intel.com>
>> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
>> ---
>>  tests/kms_color.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 127 insertions(+)
>>
>> diff --git a/tests/kms_color.c b/tests/kms_color.c
>> index e14b37cb6f..d9fe417ba9 100644
>> --- a/tests/kms_color.c
>> +++ b/tests/kms_color.c
>> @@ -736,6 +736,118 @@ static void test_pipe_limited_range_ctm(data_t *data,
>>  }
>>  #endif
>>  
>> +static bool invalid_plane_gamma_test(data_t *data, igt_plane_t *plane)
>> +{
>> +	igt_display_t *display = &data->display;
>> +	drmModePropertyPtr gamma_mode = NULL;
>> +	uint32_t i;
>> +
>> +	igt_info("Plane invalid gamma test is running on pipe-%s plane-%s(%s)\n",
>> +			kmstest_pipe_name(plane->pipe->pipe),
>> +			kmstest_plane_type_name(plane->type),
>> +			is_hdr_plane(plane) ? "hdr":"sdr");
>> +
>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
>> +
>> +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
>> +
>> +	/* Iterate all supported gamma modes. */
>> +	for (i = 0; i < gamma_mode->count_enums; i++) {
>> +		segment_data_t *segment_info = NULL;
>> +		size_t lut_size = 0;
>> +
>> +		/* Ignore 'no gamma' from enum list. */
>> +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
>> +			continue;
>> +
>> +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
>> +
>> +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
>> +				gamma_mode->enums[i].name);
>> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
>> +
>> +		igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, gamma_mode->enums[i].name);
>> +		invalid_plane_lut_sizes(display, plane,
>> +					IGT_PLANE_GAMMA_LUT,
>> +					lut_size);
>> +
>> +		clear_segment_data(segment_info);
>> +
>> +		/* One enum is enough. */
>> +		break;
>> +	}
>> +
>> +	drmModeFreeProperty(gamma_mode);
>> +
>> +	return true;
>> +}
>> +
>> +static bool invalid_plane_degamma_test(data_t *data, igt_plane_t *plane)
>> +{
>> +	igt_display_t *display = &data->display;
>> +	drmModePropertyPtr degamma_mode = NULL;
>> +	uint32_t i;
>> +
>> +	igt_info("Plane invalid degamma test is running on pipe-%s plane-%s(%s)\n",
>> +			kmstest_pipe_name(plane->pipe->pipe),
>> +			kmstest_plane_type_name(plane->type),
>> +			is_hdr_plane(plane) ? "hdr":"sdr");
>> +
>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
>> +
>> +	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
>> +
>> +	/* Iterate all supported degamma modes. */
>> +	for (i = 0; i < degamma_mode->count_enums; i++) {
>> +		segment_data_t *segment_info = NULL;
>> +		size_t lut_size = 0;
>> +
>> +		/* Ignore 'no degamma' from enum list. */
>> +		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
>> +			continue;
>> +
>> +		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
>> +
>> +		segment_info = get_segment_data(data,
>> +						degamma_mode->enums[i].value,
>> +						degamma_mode->enums[i].name);
>> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count * 2;
>> +
>> +		igt_plane_set_prop_enum(plane,
>> +					IGT_PLANE_DEGAMMA_MODE,
>> +					degamma_mode->enums[i].name);
>> +		invalid_plane_lut_sizes(display, plane,
>> +					IGT_PLANE_DEGAMMA_LUT,
>> +					lut_size);
>> +
>> +		clear_segment_data(segment_info);
>> +
>> +		/* One enum is enough. */
>> +		break;
> 
> Why is one enum enough?
> 

I think it's another intellism since Uma's patches only
report one enum.

Since the API is designed to allow for multiple enums the test
should just run on all of them. It'd be a trivial change to the
test.

Harry

> The same question for the other case in this patch.
> 
> 
>> +	}
>> +
>> +	drmModeFreeProperty(degamma_mode);
>> +
>> +	return true;
>> +}
>> +
>> +static bool invalid_plane_ctm_test(data_t *data, igt_plane_t *plane)
>> +{
>> +	igt_info("Plane invalid CTM test is running on pipe-%s plane-%s(%s)\n",
>> +			kmstest_pipe_name(plane->pipe->pipe),
>> +			kmstest_plane_type_name(plane->type),
>> +			is_hdr_plane(plane) ? "hdr":"sdr");
>> +
>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
>> +	invalid_plane_lut_sizes(&data->display, plane,
>> +				IGT_PLANE_CTM,
>> +				sizeof(struct drm_color_ctm));
> 
> The code says you're trying shove a LUT into a CTM blob. I understand
> that mechanically this is test you want to do, feed a wrong sized blob,
> and in this case the contents do not matter (unlike with actual LUTs),
> but reading this code is completely misleading and does not make sense.
> It takes a while to think about what you actually want to test here,
> and then reverse-engineer the code to understand that that is what
> actually happens, too. That is too much mental burden for the reader to
> realize that this piece of code actually works.
> 
> 
> Thanks,
> pq
> 
>> +
>> +	return true;
>> +}
>> +
>>  static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
>>  {
>>  	igt_output_t *output;
>> @@ -1411,6 +1523,21 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
>>  					ctm_tests[i].iter);
>>  		}
>>  	}
>> +
>> +	igt_describe("Negative check for invalid plane gamma lut sizes");
>> +	igt_subtest_f("pipe-%s-invalid-plane-gamma-lut-sizes",
>> +			kmstest_pipe_name(pipe))
>> +		run_plane_color_test(data, pipe, invalid_plane_gamma_test);
>> +
>> +	igt_describe("Negative check for invalid plane degamma lut sizes");
>> +	igt_subtest_f("pipe-%s-invalid-plane-degamma-lut-sizes",
>> +			kmstest_pipe_name(pipe))
>> +		run_plane_color_test(data, pipe, invalid_plane_degamma_test);
>> +
>> +	igt_describe("Negative check for invalid plane ctm matrix sizes");
>> +	igt_subtest_f("pipe-%s-invalid-plane-ctm-matrix-sizes",
>> +			kmstest_pipe_name(pipe))
>> +		run_plane_color_test(data, pipe, invalid_plane_ctm_test);
>>  }
>>  
>>  igt_main
> 


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

* Re: [i-g-t 00/14] Add IGT support for plane color management
  2021-11-29  9:20       ` [igt-dev] " Pekka Paalanen
  (?)
@ 2021-11-29 15:20       ` Harry Wentland
  2022-01-03  4:11           ` [igt-dev] " Modem, Bhanuprakash
  -1 siblings, 1 reply; 96+ messages in thread
From: Harry Wentland @ 2021-11-29 15:20 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: Mukunda Pramodh Kumar, Juha-Pekka Heikkila, dri-devel, igt-dev,
	Uma Shankar, Bhanuprakash Modem



On 2021-11-29 04:20, Pekka Paalanen wrote:
> On Fri, 26 Nov 2021 11:54:55 -0500
> Harry Wentland <harry.wentland@amd.com> wrote:
> 
>> On 2021-11-18 04:50, Pekka Paalanen wrote:
>>> On Mon, 15 Nov 2021 15:17:45 +0530
>>> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
>>>   
>>>> From the Plane Color Management feature design, userspace can
>>>> take the smart blending decisions based on hardware supported
>>>> plane color features to obtain an accurate color profile.
>>>>
>>>> These IGT patches extend the existing pipe color management
>>>> tests to the plane level.
>>>>
>>>> Kernel implementation:
>>>> https://patchwork.freedesktop.org/series/90825/  
> 
> ...
> 
>>> I also found some things that looked hardware-specific in this code
>>> that to my understanding is supposed to be generic, and some concerns
>>> about UAPI as well.
>>>   
>>
>> I left some comments on intellisms in these patches.
>>
>> Do you have any specifics about your concerns about UAPI?
> 
> Yeah, the comments I left in the patches:
> 
> patch 3:
> 
>> Having to explicitly special-case index zero feels odd to me. Why does
>> it need explicit special-casing?
>>
>> To me it's a hint that the definitions of .start and .end are somehow
>> inconsistent.
> 
> patch 4 and 8:
> 
>>> +static bool is_hdr_plane(const igt_plane_t *plane)
>>> +{
>>> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;  
>>
>> How can this be right for all KMS drivers?
>>
>> What is a HDR plane?
> 
> patch 12:
> 
>>> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
>>> +						const gamma_lut_t *gamma,
>>> +						uint32_t color_depth,
>>> +						int off)
>>> +{
>>> +	struct drm_color_lut *lut;
>>> +	int i, lut_size = gamma->size;
>>> +	/* This is the maximum value due to 16 bit precision in hardware. */  
>>
>> In whose hardware?
>>
>> Are igt tests not supposed to be generic for everything that exposes
>> the particular KMS properties?
>>
>> This also hints that the UAPI design is lacking, because userspace
>> needs to know hardware specific things out of thin air. Display servers
>> are not going to have hardware-specific code. They specialise based on
>> the existence of KMS properties instead.
> 
> ...
> 
>>> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type)
>>> +{
>>> +	igt_display_t *display = &data->display;
>>> +	gamma_lut_t *gamma_log;
>>> +	drmModePropertyPtr gamma_mode = NULL;
>>> +	segment_data_t *segment_info = NULL;
>>> +	struct drm_color_lut *lut = NULL;
>>> +	int lut_size = 0;
>>> +
>>> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);  
>>
>> Is this how we are going to do cross-software DRM-master hand-over or
>> switching compatibility in general?
>>
>> Add a new client cap for every new KMS property, and if the KMS client
>> does not set the property, the kernel will magically reset it to ensure
>> the client's expectations are met? Is that how it works?
>>
>> Or why does this exist?
> 
> ...
> 
>>> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);  
>>
>> I've never seen this done before. I did not know client caps could be
>> reset.
> 
> 
> So, patch 12 has the biggest UAPI questions, and patch 3 may need a
> UAPI change as well. The comments in patches 4 and 8 could be addressed
> with just removing that code since the concept of HDR/SDR planes does
> not exist in UAPI. Or, if that concept is needed then it's another UAPI
> problem.
> 

Thanks for reiterating your points. I missed your earlier replies and
found them in my IGT folder just now.

Looks like we're on the same page.

Harry

> 
> Thanks,
> pq
> 


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

* RE: [i-g-t 03/14] kms_color_helper: Add helper functions for plane color mgmt
  2021-11-18  8:41     ` [igt-dev] " Pekka Paalanen
@ 2022-01-03  4:02       ` Modem, Bhanuprakash
  -1 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:02 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: igt-dev, Shankar, Uma, dri-devel

> From: Pekka Paalanen <ppaalanen@gmail.com>
> Sent: Thursday, November 18, 2021 2:11 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>
> Cc: igt-dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org; Juha-Pekka
> Heikkila <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 03/14] kms_color_helper: Add helper functions for plane
> color mgmt
> 
> On Mon, 15 Nov 2021 15:17:48 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
> > Add helper functions to support Plane color management properties.
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color_helper.c | 173 +++++++++++++++++++++++++++++++++++++++
> >  tests/kms_color_helper.h |  29 +++++++
> >  2 files changed, 202 insertions(+)
> >
> > diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> > index d71e7bb2e6..c65b7a0f50 100644
> > --- a/tests/kms_color_helper.c
> > +++ b/tests/kms_color_helper.c
> > @@ -241,6 +241,150 @@ void disable_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
> >  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
> >  }
> >
> > +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> > +				enum igt_atomic_plane_properties prop)
> > +{
> > +	igt_display_t *display = plane->pipe->display;
> > +	uint32_t prop_id = plane->props[prop];
> > +	drmModePropertyPtr drmProp;
> > +
> > +	igt_assert(prop_id);
> > +
> > +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> > +
> > +	igt_assert(drmProp);
> > +	igt_assert(drmProp->count_enums);
> > +
> > +	return drmProp;
> > +}
> > +
> > +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info)
> 
> Hi,
> 
> this actually creates an identity transformation as a LUT, does it not?
> If so, it should be named that way. A linear transformation
> represented by a LUT may not be identity transformation.

I'll float a new rev by renaming it to identity.

> 
> Identity is quite a bad case to test with, because it is a no-op, and
> simply accidentally disabling the whole LUT will pass a writeback test. 
> 
> > +{
> > +	uint32_t val, segment, entry, index = 0;
> > +	uint32_t max_val = 0xffffffff;
> > +	struct drm_color_lut_ext *lut = malloc(sizeof(struct drm_color_lut_ext)
> * info->entries_count);
> > +	igt_assert(lut);
> > +
> > +	for (segment = 0; segment < info->segment_count; segment++) {
> > +		uint32_t entry_count = info->segment_data[segment].count;
> > +		uint32_t start = info->segment_data[segment].start;
> > +		uint32_t end = info->segment_data[segment].end;
> > +
> > +		for (entry = 1; entry <= entry_count; entry++) {
> > +			val = (index == 0) ? /* First entry is Zero. */
> > +				0 : start + entry * ((end - start) * 1.0 / entry_count);
> 
> Having to explicitly special-case index zero feels odd to me. Why does
> it need explicit special-casing?
> 
> To me it's a hint that the definitions of .start and .end are somehow
> inconsistent.

Intel hardware is expecting the first value as zero for any kind of LUT (Please
refer CRTC implementation), and yes we can remove this logic from this helper
function & should be handled in individual tests. I'll float a new rev with this
change.

> 
> > +
> > +			lut[index].red = lut[index].green = lut[index].blue =
> MIN(val, max_val);
> 
> There are tests that use different curves for each of red, green and
> blue and check that they also work, right?
> 
> > +
> > +			index++;
> > +		}
> > +	}
> > +
> > +	return lut;
> > +}
> > +
> > +struct drm_color_lut_ext *create_max_lut(segment_data_t *info)
> 
> What is the point of testing this pathological case?

The intension of this function is to convert gradient colors to solid
colors. (Please refer the patch 04/14 in this series)

Compare "gradient colors + maxed out plane gamma LUT" and "solid color +
unity plane gamma LUT"

> 
> > +{
> > +	int i;
> > +	struct drm_color_lut_ext *lut;
> > +	uint32_t max_val = 0xffffffff;
> > +
> > +	lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> > +	igt_assert(lut);
> > +
> > +	lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is Zero. */
> 
> It's not a max LUT, if the first entry is zero.

Please check the previous comments

> 
> > +
> > +	for (i = 1; i < info->entries_count; i++)
> > +		lut[i].red = lut[i].green = lut[i].blue = max_val;
> > +
> > +	return lut;
> > +}
> > +
> > +void clear_segment_data(segment_data_t *info)
> > +{
> > +	if (!info)
> > +		return;
> > +
> > +	free(info->segment_data);
> > +	free(info);
> > +}
> > +
> > +segment_data_t *get_segment_data(data_t *data,
> > +				uint64_t blob_id, char *mode)
> > +{
> > +	drmModePropertyBlobPtr blob;
> > +	struct drm_color_lut_range *lut_range = NULL;
> > +	segment_data_t *info = NULL;
> > +	uint32_t i;
> > +
> > +	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
> > +	igt_assert(blob);
> > +	igt_assert(blob->length);
> > +
> > +	info = malloc(sizeof(segment_data_t));
> > +	igt_assert(info);
> > +
> > +	lut_range = (struct drm_color_lut_range *) blob->data;
> > +	info->segment_count = blob->length / sizeof(lut_range[0]);
> > +	igt_assert(info->segment_count);
> > +
> > +	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info-
> >segment_count);
> > +	igt_assert(info->segment_data);
> > +
> > +	for (i = 0; i < info->segment_count; i++) {
> > +		info->entries_count += lut_range[i].count;
> > +		info->segment_data[i] = lut_range[i];
> > +	}
> > +
> > +	drmModeFreePropertyBlob(blob);
> > +
> > +	return info;
> > +}
> > +
> > +void set_plane_gamma(igt_plane_t *plane,
> > +		char *mode,
> > +		struct drm_color_lut_ext *lut,
> > +		uint32_t size)
> > +{
> > +	igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, mode);
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_GAMMA_LUT, lut, size);
> > +}
> > +
> > +void set_plane_degamma(igt_plane_t *plane,
> > +		char *mode,
> > +		struct drm_color_lut_ext *lut,
> > +		uint32_t size)
> > +{
> > +	igt_plane_set_prop_enum(plane, IGT_PLANE_DEGAMMA_MODE, mode);
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_DEGAMMA_LUT, lut, size);
> > +}
> > +
> > +void set_plane_ctm(igt_plane_t *plane, const double *coefficients)
> > +{
> > +	struct drm_color_ctm ctm;
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
> > +		if (coefficients[i] < 0) {
> > +			ctm.matrix[i] =
> > +				(int64_t) (-coefficients[i] *
> > +				((int64_t) 1L << 32));
> > +			ctm.matrix[i] |= 1ULL << 63;
> > +		} else
> > +			ctm.matrix[i] =
> > +				(int64_t) (coefficients[i] *
> > +				((int64_t) 1L << 32));
> > +	}
> 
> Is this literally the only function that converts double to the KMS
> matrix element type? If not, I think the value conversion should be a
> separate function that just converts a single value, and be called from
> all sites that need the same conversion.

Sure, I'll float a new rev by adding a new function

> 
> > +
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_CTM, &ctm, sizeof(ctm));
> > +}
> > +
> > +void disable_plane_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop)
> > +{
> > +	if (igt_plane_has_prop(plane, prop))
> > +		igt_plane_replace_prop_blob(plane, prop, NULL, 0);
> > +}
> > +
> >  drmModePropertyBlobPtr
> >  get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties
> prop)
> >  {
> > @@ -274,6 +418,19 @@ pipe_set_property_blob_id(igt_pipe_t *pipe,
> >  	return ret;
> >  }
> >
> > +static int
> > +plane_set_property_blob(igt_display_t *display,
> > +			igt_plane_t *plane,
> > +			enum igt_atomic_plane_properties prop,
> > +			void *ptr, size_t length)
> > +{
> > +	igt_plane_replace_prop_blob(plane, prop, ptr, length);
> > +
> > +	return igt_display_try_commit2(display,
> > +				       display->is_atomic ?
> > +				       COMMIT_ATOMIC : COMMIT_LEGACY);
> > +}
> > +
> >  int
> >  pipe_set_property_blob(igt_pipe_t *pipe,
> >  		       enum igt_atomic_crtc_properties prop,
> > @@ -319,6 +476,22 @@ invalid_lut_sizes(data_t *data, enum pipe p,
> >  	free(lut);
> >  }
> >
> > +void
> > +invalid_plane_lut_sizes(igt_display_t *display,
> > +			igt_plane_t *plane,
> > +			enum igt_atomic_plane_properties prop,
> > +			size_t lut_size)
> > +{
> > +	void *lut = malloc(lut_size * 2);
> 
> Feeding garbage data does not seem like a good idea. Maybe it can lead
> to EINVAL even when the driver misses the size check because the values
> are illegal?
> 
> I think this needs to craft a real and good lut data blob, with the
> only problem that it is of the wrong size.

Yes, we can do that. But my intension is to validate the size check only.
Read the lut_size from uapi & try with "lut_size +/- 1"

I think for now we can go with zero lut: `memset(lut, 0, (lut_size *2));`
I am also planning to add few tests for invalid LUTs in next phase later.

- Bhanu

> 
> > +	igt_assert(lut);
> > +
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, 1), -
> EINVAL);
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut,
> lut_size + 1), -EINVAL);
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut,
> lut_size - 1), -EINVAL);
> > +
> > +	free(lut);
> > +}
> 
> Thanks,
> pq
> 
> 
> > +
> >  void
> >  invalid_gamma_lut_sizes(data_t *data, enum pipe p)
> >  {
> > diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> > index bb6f0054f3..5a35dcaac1 100644
> > --- a/tests/kms_color_helper.h
> > +++ b/tests/kms_color_helper.h
> > @@ -64,6 +64,14 @@ typedef struct {
> >  	color_t coeffs[];
> >  } gamma_lut_t;
> >
> > +typedef struct {
> > +	uint32_t segment_count;
> > +	struct drm_color_lut_range *segment_data;
> > +	uint32_t entries_count;
> > +} segment_data_t;
> > +
> > +#define MIN(a, b) ((a) < (b) ? (a) : (b))
> > +
> >  void paint_gradient_rectangles(data_t *data,
> >  			       drmModeModeInfo *mode,
> >  			       color_t *colors,
> > @@ -90,10 +98,31 @@ void set_gamma(data_t *data,
> >  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
> >  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
> >
> > +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> > +	enum igt_atomic_plane_properties prop);
> > +void clear_segment_data(segment_data_t *info);
> > +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> > +struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> > +segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char
> *mode);
> > +void set_plane_gamma(igt_plane_t *plane,
> > +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> > +void set_plane_degamma(igt_plane_t *plane,
> > +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> > +void set_plane_ctm(igt_plane_t *plane, const double *coefficients);
> > +void disable_plane_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop);
> > +void invalid_plane_lut_sizes(igt_display_t *display,
> > +			   igt_plane_t *plane,
> > +			   enum igt_atomic_plane_properties prop,
> > +			   size_t lut_size);
> > +
> >  #define disable_degamma(pipe) disable_prop(pipe, IGT_CRTC_DEGAMMA_LUT)
> >  #define disable_gamma(pipe) disable_prop(pipe, IGT_CRTC_GAMMA_LUT)
> >  #define disable_ctm(pipe) disable_prop(pipe, IGT_CRTC_CTM)
> >
> > +#define disable_plane_degamma(plane) disable_plane_prop(plane,
> IGT_PLANE_DEGAMMA_LUT)
> > +#define disable_plane_gamma(plane) disable_plane_prop(plane,
> IGT_PLANE_GAMMA_LUT)
> > +#define disable_plane_ctm(plane) disable_plane_prop(plane, IGT_PLANE_CTM)
> > +
> >  drmModePropertyBlobPtr get_blob(data_t *data, igt_pipe_t *pipe,
> >  				enum igt_atomic_crtc_properties prop);
> >  bool crc_equal(igt_crc_t *a, igt_crc_t *b);


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

* Re: [igt-dev] [i-g-t 03/14] kms_color_helper: Add helper functions for plane color mgmt
@ 2022-01-03  4:02       ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:02 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: igt-dev, dri-devel

> From: Pekka Paalanen <ppaalanen@gmail.com>
> Sent: Thursday, November 18, 2021 2:11 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>
> Cc: igt-dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org; Juha-Pekka
> Heikkila <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 03/14] kms_color_helper: Add helper functions for plane
> color mgmt
> 
> On Mon, 15 Nov 2021 15:17:48 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
> > Add helper functions to support Plane color management properties.
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color_helper.c | 173 +++++++++++++++++++++++++++++++++++++++
> >  tests/kms_color_helper.h |  29 +++++++
> >  2 files changed, 202 insertions(+)
> >
> > diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> > index d71e7bb2e6..c65b7a0f50 100644
> > --- a/tests/kms_color_helper.c
> > +++ b/tests/kms_color_helper.c
> > @@ -241,6 +241,150 @@ void disable_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
> >  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
> >  }
> >
> > +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> > +				enum igt_atomic_plane_properties prop)
> > +{
> > +	igt_display_t *display = plane->pipe->display;
> > +	uint32_t prop_id = plane->props[prop];
> > +	drmModePropertyPtr drmProp;
> > +
> > +	igt_assert(prop_id);
> > +
> > +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> > +
> > +	igt_assert(drmProp);
> > +	igt_assert(drmProp->count_enums);
> > +
> > +	return drmProp;
> > +}
> > +
> > +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info)
> 
> Hi,
> 
> this actually creates an identity transformation as a LUT, does it not?
> If so, it should be named that way. A linear transformation
> represented by a LUT may not be identity transformation.

I'll float a new rev by renaming it to identity.

> 
> Identity is quite a bad case to test with, because it is a no-op, and
> simply accidentally disabling the whole LUT will pass a writeback test. 
> 
> > +{
> > +	uint32_t val, segment, entry, index = 0;
> > +	uint32_t max_val = 0xffffffff;
> > +	struct drm_color_lut_ext *lut = malloc(sizeof(struct drm_color_lut_ext)
> * info->entries_count);
> > +	igt_assert(lut);
> > +
> > +	for (segment = 0; segment < info->segment_count; segment++) {
> > +		uint32_t entry_count = info->segment_data[segment].count;
> > +		uint32_t start = info->segment_data[segment].start;
> > +		uint32_t end = info->segment_data[segment].end;
> > +
> > +		for (entry = 1; entry <= entry_count; entry++) {
> > +			val = (index == 0) ? /* First entry is Zero. */
> > +				0 : start + entry * ((end - start) * 1.0 / entry_count);
> 
> Having to explicitly special-case index zero feels odd to me. Why does
> it need explicit special-casing?
> 
> To me it's a hint that the definitions of .start and .end are somehow
> inconsistent.

Intel hardware is expecting the first value as zero for any kind of LUT (Please
refer CRTC implementation), and yes we can remove this logic from this helper
function & should be handled in individual tests. I'll float a new rev with this
change.

> 
> > +
> > +			lut[index].red = lut[index].green = lut[index].blue =
> MIN(val, max_val);
> 
> There are tests that use different curves for each of red, green and
> blue and check that they also work, right?
> 
> > +
> > +			index++;
> > +		}
> > +	}
> > +
> > +	return lut;
> > +}
> > +
> > +struct drm_color_lut_ext *create_max_lut(segment_data_t *info)
> 
> What is the point of testing this pathological case?

The intension of this function is to convert gradient colors to solid
colors. (Please refer the patch 04/14 in this series)

Compare "gradient colors + maxed out plane gamma LUT" and "solid color +
unity plane gamma LUT"

> 
> > +{
> > +	int i;
> > +	struct drm_color_lut_ext *lut;
> > +	uint32_t max_val = 0xffffffff;
> > +
> > +	lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> > +	igt_assert(lut);
> > +
> > +	lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is Zero. */
> 
> It's not a max LUT, if the first entry is zero.

Please check the previous comments

> 
> > +
> > +	for (i = 1; i < info->entries_count; i++)
> > +		lut[i].red = lut[i].green = lut[i].blue = max_val;
> > +
> > +	return lut;
> > +}
> > +
> > +void clear_segment_data(segment_data_t *info)
> > +{
> > +	if (!info)
> > +		return;
> > +
> > +	free(info->segment_data);
> > +	free(info);
> > +}
> > +
> > +segment_data_t *get_segment_data(data_t *data,
> > +				uint64_t blob_id, char *mode)
> > +{
> > +	drmModePropertyBlobPtr blob;
> > +	struct drm_color_lut_range *lut_range = NULL;
> > +	segment_data_t *info = NULL;
> > +	uint32_t i;
> > +
> > +	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
> > +	igt_assert(blob);
> > +	igt_assert(blob->length);
> > +
> > +	info = malloc(sizeof(segment_data_t));
> > +	igt_assert(info);
> > +
> > +	lut_range = (struct drm_color_lut_range *) blob->data;
> > +	info->segment_count = blob->length / sizeof(lut_range[0]);
> > +	igt_assert(info->segment_count);
> > +
> > +	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info-
> >segment_count);
> > +	igt_assert(info->segment_data);
> > +
> > +	for (i = 0; i < info->segment_count; i++) {
> > +		info->entries_count += lut_range[i].count;
> > +		info->segment_data[i] = lut_range[i];
> > +	}
> > +
> > +	drmModeFreePropertyBlob(blob);
> > +
> > +	return info;
> > +}
> > +
> > +void set_plane_gamma(igt_plane_t *plane,
> > +		char *mode,
> > +		struct drm_color_lut_ext *lut,
> > +		uint32_t size)
> > +{
> > +	igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, mode);
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_GAMMA_LUT, lut, size);
> > +}
> > +
> > +void set_plane_degamma(igt_plane_t *plane,
> > +		char *mode,
> > +		struct drm_color_lut_ext *lut,
> > +		uint32_t size)
> > +{
> > +	igt_plane_set_prop_enum(plane, IGT_PLANE_DEGAMMA_MODE, mode);
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_DEGAMMA_LUT, lut, size);
> > +}
> > +
> > +void set_plane_ctm(igt_plane_t *plane, const double *coefficients)
> > +{
> > +	struct drm_color_ctm ctm;
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
> > +		if (coefficients[i] < 0) {
> > +			ctm.matrix[i] =
> > +				(int64_t) (-coefficients[i] *
> > +				((int64_t) 1L << 32));
> > +			ctm.matrix[i] |= 1ULL << 63;
> > +		} else
> > +			ctm.matrix[i] =
> > +				(int64_t) (coefficients[i] *
> > +				((int64_t) 1L << 32));
> > +	}
> 
> Is this literally the only function that converts double to the KMS
> matrix element type? If not, I think the value conversion should be a
> separate function that just converts a single value, and be called from
> all sites that need the same conversion.

Sure, I'll float a new rev by adding a new function

> 
> > +
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_CTM, &ctm, sizeof(ctm));
> > +}
> > +
> > +void disable_plane_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop)
> > +{
> > +	if (igt_plane_has_prop(plane, prop))
> > +		igt_plane_replace_prop_blob(plane, prop, NULL, 0);
> > +}
> > +
> >  drmModePropertyBlobPtr
> >  get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties
> prop)
> >  {
> > @@ -274,6 +418,19 @@ pipe_set_property_blob_id(igt_pipe_t *pipe,
> >  	return ret;
> >  }
> >
> > +static int
> > +plane_set_property_blob(igt_display_t *display,
> > +			igt_plane_t *plane,
> > +			enum igt_atomic_plane_properties prop,
> > +			void *ptr, size_t length)
> > +{
> > +	igt_plane_replace_prop_blob(plane, prop, ptr, length);
> > +
> > +	return igt_display_try_commit2(display,
> > +				       display->is_atomic ?
> > +				       COMMIT_ATOMIC : COMMIT_LEGACY);
> > +}
> > +
> >  int
> >  pipe_set_property_blob(igt_pipe_t *pipe,
> >  		       enum igt_atomic_crtc_properties prop,
> > @@ -319,6 +476,22 @@ invalid_lut_sizes(data_t *data, enum pipe p,
> >  	free(lut);
> >  }
> >
> > +void
> > +invalid_plane_lut_sizes(igt_display_t *display,
> > +			igt_plane_t *plane,
> > +			enum igt_atomic_plane_properties prop,
> > +			size_t lut_size)
> > +{
> > +	void *lut = malloc(lut_size * 2);
> 
> Feeding garbage data does not seem like a good idea. Maybe it can lead
> to EINVAL even when the driver misses the size check because the values
> are illegal?
> 
> I think this needs to craft a real and good lut data blob, with the
> only problem that it is of the wrong size.

Yes, we can do that. But my intension is to validate the size check only.
Read the lut_size from uapi & try with "lut_size +/- 1"

I think for now we can go with zero lut: `memset(lut, 0, (lut_size *2));`
I am also planning to add few tests for invalid LUTs in next phase later.

- Bhanu

> 
> > +	igt_assert(lut);
> > +
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, 1), -
> EINVAL);
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut,
> lut_size + 1), -EINVAL);
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut,
> lut_size - 1), -EINVAL);
> > +
> > +	free(lut);
> > +}
> 
> Thanks,
> pq
> 
> 
> > +
> >  void
> >  invalid_gamma_lut_sizes(data_t *data, enum pipe p)
> >  {
> > diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> > index bb6f0054f3..5a35dcaac1 100644
> > --- a/tests/kms_color_helper.h
> > +++ b/tests/kms_color_helper.h
> > @@ -64,6 +64,14 @@ typedef struct {
> >  	color_t coeffs[];
> >  } gamma_lut_t;
> >
> > +typedef struct {
> > +	uint32_t segment_count;
> > +	struct drm_color_lut_range *segment_data;
> > +	uint32_t entries_count;
> > +} segment_data_t;
> > +
> > +#define MIN(a, b) ((a) < (b) ? (a) : (b))
> > +
> >  void paint_gradient_rectangles(data_t *data,
> >  			       drmModeModeInfo *mode,
> >  			       color_t *colors,
> > @@ -90,10 +98,31 @@ void set_gamma(data_t *data,
> >  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
> >  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
> >
> > +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> > +	enum igt_atomic_plane_properties prop);
> > +void clear_segment_data(segment_data_t *info);
> > +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> > +struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> > +segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char
> *mode);
> > +void set_plane_gamma(igt_plane_t *plane,
> > +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> > +void set_plane_degamma(igt_plane_t *plane,
> > +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> > +void set_plane_ctm(igt_plane_t *plane, const double *coefficients);
> > +void disable_plane_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop);
> > +void invalid_plane_lut_sizes(igt_display_t *display,
> > +			   igt_plane_t *plane,
> > +			   enum igt_atomic_plane_properties prop,
> > +			   size_t lut_size);
> > +
> >  #define disable_degamma(pipe) disable_prop(pipe, IGT_CRTC_DEGAMMA_LUT)
> >  #define disable_gamma(pipe) disable_prop(pipe, IGT_CRTC_GAMMA_LUT)
> >  #define disable_ctm(pipe) disable_prop(pipe, IGT_CRTC_CTM)
> >
> > +#define disable_plane_degamma(plane) disable_plane_prop(plane,
> IGT_PLANE_DEGAMMA_LUT)
> > +#define disable_plane_gamma(plane) disable_plane_prop(plane,
> IGT_PLANE_GAMMA_LUT)
> > +#define disable_plane_ctm(plane) disable_plane_prop(plane, IGT_PLANE_CTM)
> > +
> >  drmModePropertyBlobPtr get_blob(data_t *data, igt_pipe_t *pipe,
> >  				enum igt_atomic_crtc_properties prop);
> >  bool crc_equal(igt_crc_t *a, igt_crc_t *b);


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

* RE: [i-g-t 03/14] kms_color_helper: Add helper functions for plane color mgmt
  2021-11-26 16:54     ` [igt-dev] " Harry Wentland
@ 2022-01-03  4:02       ` Modem, Bhanuprakash
  -1 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:02 UTC (permalink / raw)
  To: Harry Wentland, igt-dev, dri-devel; +Cc: Shankar, Uma

> From: Harry Wentland <harry.wentland@amd.com>
> Sent: Friday, November 26, 2021 10:25 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 03/14] kms_color_helper: Add helper functions for plane
> color mgmt
> 
> On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> > Add helper functions to support Plane color management properties.
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color_helper.c | 173 +++++++++++++++++++++++++++++++++++++++
> >  tests/kms_color_helper.h |  29 +++++++
> >  2 files changed, 202 insertions(+)
> >
> > diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> > index d71e7bb2e6..c65b7a0f50 100644
> > --- a/tests/kms_color_helper.c
> > +++ b/tests/kms_color_helper.c
> > @@ -241,6 +241,150 @@ void disable_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
> >  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
> >  }
> >
> > +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> > +				enum igt_atomic_plane_properties prop)
> > +{
> > +	igt_display_t *display = plane->pipe->display;
> > +	uint32_t prop_id = plane->props[prop];
> > +	drmModePropertyPtr drmProp;
> > +
> > +	igt_assert(prop_id);
> > +
> > +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> > +
> > +	igt_assert(drmProp);
> > +	igt_assert(drmProp->count_enums);
> > +
> > +	return drmProp;
> > +}
> > +
> > +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info)
> > +{
> > +	uint32_t val, segment, entry, index = 0;
> > +	uint32_t max_val = 0xffffffff;
> > +	struct drm_color_lut_ext *lut = malloc(sizeof(struct drm_color_lut_ext)
> * info->entries_count);
> > +	igt_assert(lut);
> > +
> > +	for (segment = 0; segment < info->segment_count; segment++) {
> > +		uint32_t entry_count = info->segment_data[segment].count;
> > +		uint32_t start = info->segment_data[segment].start;
> > +		uint32_t end = info->segment_data[segment].end;
> > +
> > +		for (entry = 1; entry <= entry_count; entry++) {
> > +			val = (index == 0) ? /* First entry is Zero. */
> > +				0 : start + entry * ((end - start) * 1.0 / entry_count);
> > +
> > +			lut[index].red = lut[index].green = lut[index].blue =
> MIN(val, max_val);
> > +
> > +			index++;
> > +		}
> > +	}
> > +
> > +	return lut;
> > +}
> > +
> > +struct drm_color_lut_ext *create_max_lut(segment_data_t *info)
> > +{
> > +	int i;
> > +	struct drm_color_lut_ext *lut;
> > +	uint32_t max_val = 0xffffffff;
> > +
> > +	lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> > +	igt_assert(lut);
> > +
> > +	lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is Zero. */
> > +
> > +	for (i = 1; i < info->entries_count; i++)
> > +		lut[i].red = lut[i].green = lut[i].blue = max_val;
> > +
> > +	return lut;
> > +}
> > +
> > +void clear_segment_data(segment_data_t *info)
> > +{
> > +	if (!info)
> > +		return;
> > +
> > +	free(info->segment_data);
> > +	free(info);
> > +}
> > +
> > +segment_data_t *get_segment_data(data_t *data,
> > +				uint64_t blob_id, char *mode)
> > +{
> > +	drmModePropertyBlobPtr blob;
> > +	struct drm_color_lut_range *lut_range = NULL;
> > +	segment_data_t *info = NULL;
> > +	uint32_t i;
> > +
> > +	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
> > +	igt_assert(blob);
> > +	igt_assert(blob->length);
> > +
> > +	info = malloc(sizeof(segment_data_t));
> > +	igt_assert(info);
> > +
> > +	lut_range = (struct drm_color_lut_range *) blob->data;
> > +	info->segment_count = blob->length / sizeof(lut_range[0]);
> > +	igt_assert(info->segment_count);
> > +
> > +	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info-
> >segment_count);
> > +	igt_assert(info->segment_data);
> > +
> > +	for (i = 0; i < info->segment_count; i++) {
> > +		info->entries_count += lut_range[i].count;
> > +		info->segment_data[i] = lut_range[i];
> > +	}
> > +
> > +	drmModeFreePropertyBlob(blob);
> > +
> > +	return info;
> > +}
> > +
> > +void set_plane_gamma(igt_plane_t *plane,
> > +		char *mode,
> > +		struct drm_color_lut_ext *lut,
> > +		uint32_t size)
> > +{
> > +	igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, mode);
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_GAMMA_LUT, lut, size);
> > +}
> > +
> > +void set_plane_degamma(igt_plane_t *plane,
> > +		char *mode,
> > +		struct drm_color_lut_ext *lut,
> > +		uint32_t size)
> > +{
> > +	igt_plane_set_prop_enum(plane, IGT_PLANE_DEGAMMA_MODE, mode);
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_DEGAMMA_LUT, lut, size);
> > +}
> > +
> > +void set_plane_ctm(igt_plane_t *plane, const double *coefficients)
> > +{
> > +	struct drm_color_ctm ctm;
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
> > +		if (coefficients[i] < 0) {
> > +			ctm.matrix[i] =
> > +				(int64_t) (-coefficients[i] *
> > +				((int64_t) 1L << 32));
> > +			ctm.matrix[i] |= 1ULL << 63;
> > +		} else
> > +			ctm.matrix[i] =
> > +				(int64_t) (coefficients[i] *
> > +				((int64_t) 1L << 32));
> > +	}
> > +
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_CTM, &ctm, sizeof(ctm));
> > +}
> > +
> > +void disable_plane_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop)
> > +{
> > +	if (igt_plane_has_prop(plane, prop))
> > +		igt_plane_replace_prop_blob(plane, prop, NULL, 0);
> > +}
> > +
> >  drmModePropertyBlobPtr
> >  get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties
> prop)
> >  {
> > @@ -274,6 +418,19 @@ pipe_set_property_blob_id(igt_pipe_t *pipe,
> >  	return ret;
> >  }
> >
> > +static int
> > +plane_set_property_blob(igt_display_t *display,
> > +			igt_plane_t *plane,
> > +			enum igt_atomic_plane_properties prop,
> > +			void *ptr, size_t length)
> > +{
> > +	igt_plane_replace_prop_blob(plane, prop, ptr, length);
> > +
> > +	return igt_display_try_commit2(display,
> > +				       display->is_atomic ?
> > +				       COMMIT_ATOMIC : COMMIT_LEGACY);
> > +}
> > +
> >  int
> >  pipe_set_property_blob(igt_pipe_t *pipe,
> >  		       enum igt_atomic_crtc_properties prop,
> > @@ -319,6 +476,22 @@ invalid_lut_sizes(data_t *data, enum pipe p,
> >  	free(lut);
> >  }
> >
> > +void
> > +invalid_plane_lut_sizes(igt_display_t *display,
> > +			igt_plane_t *plane,
> > +			enum igt_atomic_plane_properties prop,
> > +			size_t lut_size)
> > +{
> > +	void *lut = malloc(lut_size * 2);
> > +	igt_assert(lut);
> > +
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, 1), -
> EINVAL);
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut,
> lut_size + 1), -EINVAL);
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut,
> lut_size - 1), -EINVAL);
> > +
> > +	free(lut);
> > +}
> 
> This might make more sense as part of patch 7, though I don't have a
> strong preference.

Agreed, I thought it would be good if we have all the helper functions
in one place.

-Bhanu

> 
> Harry
> 
> > +
> >  void
> >  invalid_gamma_lut_sizes(data_t *data, enum pipe p)
> >  {
> > diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> > index bb6f0054f3..5a35dcaac1 100644
> > --- a/tests/kms_color_helper.h
> > +++ b/tests/kms_color_helper.h
> > @@ -64,6 +64,14 @@ typedef struct {
> >  	color_t coeffs[];
> >  } gamma_lut_t;
> >
> > +typedef struct {
> > +	uint32_t segment_count;
> > +	struct drm_color_lut_range *segment_data;
> > +	uint32_t entries_count;
> > +} segment_data_t;
> > +
> > +#define MIN(a, b) ((a) < (b) ? (a) : (b))
> > +
> >  void paint_gradient_rectangles(data_t *data,
> >  			       drmModeModeInfo *mode,
> >  			       color_t *colors,
> > @@ -90,10 +98,31 @@ void set_gamma(data_t *data,
> >  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
> >  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
> >
> > +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> > +	enum igt_atomic_plane_properties prop);
> > +void clear_segment_data(segment_data_t *info);
> > +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> > +struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> > +segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char
> *mode);
> > +void set_plane_gamma(igt_plane_t *plane,
> > +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> > +void set_plane_degamma(igt_plane_t *plane,
> > +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> > +void set_plane_ctm(igt_plane_t *plane, const double *coefficients);
> > +void disable_plane_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop);
> > +void invalid_plane_lut_sizes(igt_display_t *display,
> > +			   igt_plane_t *plane,
> > +			   enum igt_atomic_plane_properties prop,
> > +			   size_t lut_size);
> > +
> >  #define disable_degamma(pipe) disable_prop(pipe, IGT_CRTC_DEGAMMA_LUT)
> >  #define disable_gamma(pipe) disable_prop(pipe, IGT_CRTC_GAMMA_LUT)
> >  #define disable_ctm(pipe) disable_prop(pipe, IGT_CRTC_CTM)
> >
> > +#define disable_plane_degamma(plane) disable_plane_prop(plane,
> IGT_PLANE_DEGAMMA_LUT)
> > +#define disable_plane_gamma(plane) disable_plane_prop(plane,
> IGT_PLANE_GAMMA_LUT)
> > +#define disable_plane_ctm(plane) disable_plane_prop(plane, IGT_PLANE_CTM)
> > +
> >  drmModePropertyBlobPtr get_blob(data_t *data, igt_pipe_t *pipe,
> >  				enum igt_atomic_crtc_properties prop);
> >  bool crc_equal(igt_crc_t *a, igt_crc_t *b);
> >


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

* Re: [igt-dev] [i-g-t 03/14] kms_color_helper: Add helper functions for plane color mgmt
@ 2022-01-03  4:02       ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:02 UTC (permalink / raw)
  To: Harry Wentland, igt-dev, dri-devel; +Cc: ppaalanen

> From: Harry Wentland <harry.wentland@amd.com>
> Sent: Friday, November 26, 2021 10:25 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 03/14] kms_color_helper: Add helper functions for plane
> color mgmt
> 
> On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> > Add helper functions to support Plane color management properties.
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color_helper.c | 173 +++++++++++++++++++++++++++++++++++++++
> >  tests/kms_color_helper.h |  29 +++++++
> >  2 files changed, 202 insertions(+)
> >
> > diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> > index d71e7bb2e6..c65b7a0f50 100644
> > --- a/tests/kms_color_helper.c
> > +++ b/tests/kms_color_helper.c
> > @@ -241,6 +241,150 @@ void disable_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
> >  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
> >  }
> >
> > +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> > +				enum igt_atomic_plane_properties prop)
> > +{
> > +	igt_display_t *display = plane->pipe->display;
> > +	uint32_t prop_id = plane->props[prop];
> > +	drmModePropertyPtr drmProp;
> > +
> > +	igt_assert(prop_id);
> > +
> > +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> > +
> > +	igt_assert(drmProp);
> > +	igt_assert(drmProp->count_enums);
> > +
> > +	return drmProp;
> > +}
> > +
> > +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info)
> > +{
> > +	uint32_t val, segment, entry, index = 0;
> > +	uint32_t max_val = 0xffffffff;
> > +	struct drm_color_lut_ext *lut = malloc(sizeof(struct drm_color_lut_ext)
> * info->entries_count);
> > +	igt_assert(lut);
> > +
> > +	for (segment = 0; segment < info->segment_count; segment++) {
> > +		uint32_t entry_count = info->segment_data[segment].count;
> > +		uint32_t start = info->segment_data[segment].start;
> > +		uint32_t end = info->segment_data[segment].end;
> > +
> > +		for (entry = 1; entry <= entry_count; entry++) {
> > +			val = (index == 0) ? /* First entry is Zero. */
> > +				0 : start + entry * ((end - start) * 1.0 / entry_count);
> > +
> > +			lut[index].red = lut[index].green = lut[index].blue =
> MIN(val, max_val);
> > +
> > +			index++;
> > +		}
> > +	}
> > +
> > +	return lut;
> > +}
> > +
> > +struct drm_color_lut_ext *create_max_lut(segment_data_t *info)
> > +{
> > +	int i;
> > +	struct drm_color_lut_ext *lut;
> > +	uint32_t max_val = 0xffffffff;
> > +
> > +	lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
> > +	igt_assert(lut);
> > +
> > +	lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is Zero. */
> > +
> > +	for (i = 1; i < info->entries_count; i++)
> > +		lut[i].red = lut[i].green = lut[i].blue = max_val;
> > +
> > +	return lut;
> > +}
> > +
> > +void clear_segment_data(segment_data_t *info)
> > +{
> > +	if (!info)
> > +		return;
> > +
> > +	free(info->segment_data);
> > +	free(info);
> > +}
> > +
> > +segment_data_t *get_segment_data(data_t *data,
> > +				uint64_t blob_id, char *mode)
> > +{
> > +	drmModePropertyBlobPtr blob;
> > +	struct drm_color_lut_range *lut_range = NULL;
> > +	segment_data_t *info = NULL;
> > +	uint32_t i;
> > +
> > +	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
> > +	igt_assert(blob);
> > +	igt_assert(blob->length);
> > +
> > +	info = malloc(sizeof(segment_data_t));
> > +	igt_assert(info);
> > +
> > +	lut_range = (struct drm_color_lut_range *) blob->data;
> > +	info->segment_count = blob->length / sizeof(lut_range[0]);
> > +	igt_assert(info->segment_count);
> > +
> > +	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info-
> >segment_count);
> > +	igt_assert(info->segment_data);
> > +
> > +	for (i = 0; i < info->segment_count; i++) {
> > +		info->entries_count += lut_range[i].count;
> > +		info->segment_data[i] = lut_range[i];
> > +	}
> > +
> > +	drmModeFreePropertyBlob(blob);
> > +
> > +	return info;
> > +}
> > +
> > +void set_plane_gamma(igt_plane_t *plane,
> > +		char *mode,
> > +		struct drm_color_lut_ext *lut,
> > +		uint32_t size)
> > +{
> > +	igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, mode);
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_GAMMA_LUT, lut, size);
> > +}
> > +
> > +void set_plane_degamma(igt_plane_t *plane,
> > +		char *mode,
> > +		struct drm_color_lut_ext *lut,
> > +		uint32_t size)
> > +{
> > +	igt_plane_set_prop_enum(plane, IGT_PLANE_DEGAMMA_MODE, mode);
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_DEGAMMA_LUT, lut, size);
> > +}
> > +
> > +void set_plane_ctm(igt_plane_t *plane, const double *coefficients)
> > +{
> > +	struct drm_color_ctm ctm;
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
> > +		if (coefficients[i] < 0) {
> > +			ctm.matrix[i] =
> > +				(int64_t) (-coefficients[i] *
> > +				((int64_t) 1L << 32));
> > +			ctm.matrix[i] |= 1ULL << 63;
> > +		} else
> > +			ctm.matrix[i] =
> > +				(int64_t) (coefficients[i] *
> > +				((int64_t) 1L << 32));
> > +	}
> > +
> > +	igt_plane_replace_prop_blob(plane, IGT_PLANE_CTM, &ctm, sizeof(ctm));
> > +}
> > +
> > +void disable_plane_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop)
> > +{
> > +	if (igt_plane_has_prop(plane, prop))
> > +		igt_plane_replace_prop_blob(plane, prop, NULL, 0);
> > +}
> > +
> >  drmModePropertyBlobPtr
> >  get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties
> prop)
> >  {
> > @@ -274,6 +418,19 @@ pipe_set_property_blob_id(igt_pipe_t *pipe,
> >  	return ret;
> >  }
> >
> > +static int
> > +plane_set_property_blob(igt_display_t *display,
> > +			igt_plane_t *plane,
> > +			enum igt_atomic_plane_properties prop,
> > +			void *ptr, size_t length)
> > +{
> > +	igt_plane_replace_prop_blob(plane, prop, ptr, length);
> > +
> > +	return igt_display_try_commit2(display,
> > +				       display->is_atomic ?
> > +				       COMMIT_ATOMIC : COMMIT_LEGACY);
> > +}
> > +
> >  int
> >  pipe_set_property_blob(igt_pipe_t *pipe,
> >  		       enum igt_atomic_crtc_properties prop,
> > @@ -319,6 +476,22 @@ invalid_lut_sizes(data_t *data, enum pipe p,
> >  	free(lut);
> >  }
> >
> > +void
> > +invalid_plane_lut_sizes(igt_display_t *display,
> > +			igt_plane_t *plane,
> > +			enum igt_atomic_plane_properties prop,
> > +			size_t lut_size)
> > +{
> > +	void *lut = malloc(lut_size * 2);
> > +	igt_assert(lut);
> > +
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, 1), -
> EINVAL);
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut,
> lut_size + 1), -EINVAL);
> > +	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut,
> lut_size - 1), -EINVAL);
> > +
> > +	free(lut);
> > +}
> 
> This might make more sense as part of patch 7, though I don't have a
> strong preference.

Agreed, I thought it would be good if we have all the helper functions
in one place.

-Bhanu

> 
> Harry
> 
> > +
> >  void
> >  invalid_gamma_lut_sizes(data_t *data, enum pipe p)
> >  {
> > diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> > index bb6f0054f3..5a35dcaac1 100644
> > --- a/tests/kms_color_helper.h
> > +++ b/tests/kms_color_helper.h
> > @@ -64,6 +64,14 @@ typedef struct {
> >  	color_t coeffs[];
> >  } gamma_lut_t;
> >
> > +typedef struct {
> > +	uint32_t segment_count;
> > +	struct drm_color_lut_range *segment_data;
> > +	uint32_t entries_count;
> > +} segment_data_t;
> > +
> > +#define MIN(a, b) ((a) < (b) ? (a) : (b))
> > +
> >  void paint_gradient_rectangles(data_t *data,
> >  			       drmModeModeInfo *mode,
> >  			       color_t *colors,
> > @@ -90,10 +98,31 @@ void set_gamma(data_t *data,
> >  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
> >  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
> >
> > +drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> > +	enum igt_atomic_plane_properties prop);
> > +void clear_segment_data(segment_data_t *info);
> > +struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> > +struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> > +segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char
> *mode);
> > +void set_plane_gamma(igt_plane_t *plane,
> > +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> > +void set_plane_degamma(igt_plane_t *plane,
> > +	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> > +void set_plane_ctm(igt_plane_t *plane, const double *coefficients);
> > +void disable_plane_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop);
> > +void invalid_plane_lut_sizes(igt_display_t *display,
> > +			   igt_plane_t *plane,
> > +			   enum igt_atomic_plane_properties prop,
> > +			   size_t lut_size);
> > +
> >  #define disable_degamma(pipe) disable_prop(pipe, IGT_CRTC_DEGAMMA_LUT)
> >  #define disable_gamma(pipe) disable_prop(pipe, IGT_CRTC_GAMMA_LUT)
> >  #define disable_ctm(pipe) disable_prop(pipe, IGT_CRTC_CTM)
> >
> > +#define disable_plane_degamma(plane) disable_plane_prop(plane,
> IGT_PLANE_DEGAMMA_LUT)
> > +#define disable_plane_gamma(plane) disable_plane_prop(plane,
> IGT_PLANE_GAMMA_LUT)
> > +#define disable_plane_ctm(plane) disable_plane_prop(plane, IGT_PLANE_CTM)
> > +
> >  drmModePropertyBlobPtr get_blob(data_t *data, igt_pipe_t *pipe,
> >  				enum igt_atomic_crtc_properties prop);
> >  bool crc_equal(igt_crc_t *a, igt_crc_t *b);
> >


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

* RE: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
  2021-11-26 16:55     ` [igt-dev] " Harry Wentland
@ 2022-01-03  4:05       ` Modem, Bhanuprakash
  -1 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:05 UTC (permalink / raw)
  To: Harry Wentland, igt-dev, dri-devel; +Cc: Shankar, Uma

> From: Harry Wentland <harry.wentland@amd.com>
> Sent: Friday, November 26, 2021 10:25 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
> 
> On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> > To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> > with a maxed out gamma LUT and verify we have the same CRC as drawing solid
> > color rectangles.
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 178 insertions(+), 1 deletion(-)
> >
> > diff --git a/tests/kms_color.c b/tests/kms_color.c
> > index 775f35964f..b45d66762f 100644
> > --- a/tests/kms_color.c
> > +++ b/tests/kms_color.c
> > @@ -24,7 +24,34 @@
> >
> >  #include "kms_color_helper.h"
> >
> > -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
> > +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
> > +
> > +#define MAX_SUPPORTED_PLANES 7
> > +#define SDR_PLANE_BASE 3
> > +
> > +typedef bool (*test_t)(data_t*, igt_plane_t*);
> > +
> > +static bool is_hdr_plane(const igt_plane_t *plane)
> > +{
> > +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> > +}
> > +
> > +static bool is_valid_plane(igt_plane_t *plane)
> > +{
> > +	int index = plane->index;
> > +
> > +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> > +		return false;
> > +
> > +	/*
> > +	 * Test 1 HDR plane, 1 SDR plane.
> > +	 *
> > +	 * 0,1,2 HDR planes
> > +	 * 3,4,5,6 SDR planes
> > +	 *
> > +	 */
> 
> This seems to be about Intel HW. AMD HW for example does
> not have HDR or SDR planes, only one generic plane.
> 
> > +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> > +}
> >
> >  static void test_pipe_degamma(data_t *data,
> >  			      igt_plane_t *primary)
> > @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t *data,
> >  }
> >  #endif
> >
> > +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> > +{
> > +	igt_output_t *output;
> > +	igt_display_t *display = &data->display;
> > +	drmModeModeInfo *mode;
> > +	struct igt_fb fb;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	uint32_t i;
> > +	bool ret = true;
> > +	igt_pipe_crc_t *pipe_crc = NULL;
> > +	color_t red_green_blue[] = {
> > +		{ 1.0, 0.0, 0.0 },
> > +		{ 0.0, 1.0, 0.0 },
> > +		{ 0.0, 0.0, 1.0 }
> > +	};
> > +
> > +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
> > +			kmstest_pipe_name(plane->pipe->pipe),
> > +			kmstest_plane_type_name(plane->type),
> > +			is_hdr_plane(plane) ? "hdr":"sdr");
> > +
> 
> is_hdr_plane is Intel-specific.
> 
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> > +
> > +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
> > +				  plane->pipe->pipe,
> > +				  INTEL_PIPE_CRC_SOURCE_AUTO);
> > +
> > +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
> > +	igt_assert(output);
> > +
> > +	igt_output_set_pipe(output, plane->pipe->pipe);
> > +	mode = igt_output_get_mode(output);
> > +
> > +	/* Create a framebuffer at the size of the output. */
> > +	igt_assert(igt_create_fb(data->drm_fd,
> > +			      mode->hdisplay,
> > +			      mode->vdisplay,
> > +			      DRM_FORMAT_XRGB8888,
> > +			      DRM_FORMAT_MOD_LINEAR,
> > +			      &fb));
> > +	igt_plane_set_fb(plane, &fb);
> > +
> > +	/* Disable Pipe color props. */
> > +	disable_ctm(plane->pipe);
> > +	disable_degamma(plane->pipe);
> > +	disable_gamma(plane->pipe);
> > +
> > +	disable_plane_ctm(plane);
> > +	disable_plane_degamma(plane);
> > +	igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +
> > +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> > +
> > +	/* Iterate all supported gamma modes. */
> > +	for (i = 0; i < gamma_mode->count_enums; i++) {
> > +		igt_crc_t crc_gamma, crc_fullcolors;
> > +		segment_data_t *segment_info = NULL;
> > +		struct drm_color_lut_ext *lut = NULL;
> > +		uint32_t lut_size = 0;
> > +
> > +		/* Ignore 'no gamma' from enum list. */
> > +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> > +			continue;
> > +
> 
> It might still make sense to test that this is doing bypass.

As we know gamma_mode->enum[i].name represents the name of the
gamma mode and gamma_mode->enum[i].value would be the LUT blob
address of that particular gamma_mode.

For "no gamma" case the blob address is NULL, so we can't commit
this mode. Hence skipping this mode.

> 
> > +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode-
> >enums[i].name);
> > +
> > +		/* Draw solid colors with no gamma transformation. */
> > +		disable_plane_gamma(plane);
> > +		paint_rectangles(data, mode, red_green_blue, &fb);
> > +		igt_plane_set_fb(plane, &fb);
> > +		igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +		igt_wait_for_vblank(data->drm_fd,
> > +			display->pipes[plane->pipe->pipe].crtc_offset);
> > +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
> > +
> > +		/* Draw gradient colors with gamma LUT to remap all
> > +		 * values to max red/green/blue.
> > +		 */
> > +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> > +				gamma_mode->enums[i].name);
> > +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
> >entries_count;
> > +		lut = create_max_lut(segment_info);
> > +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
> > +
> > +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
> > +		igt_plane_set_fb(plane, &fb);
> > +		igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +		igt_wait_for_vblank(data->drm_fd,
> > +			display->pipes[plane->pipe->pipe].crtc_offset);
> > +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
> > +
> > +		/* Verify that the CRC of the software computed output is
> > +		 * equal to the CRC of the gamma LUT transformation output.
> > +		 */
> > +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
> > +
> > +		free(lut);
> > +		clear_segment_data(segment_info);
> > +	}
> > +
> > +	disable_plane_gamma(plane);
> > +	igt_plane_set_fb(plane, NULL);
> > +	igt_output_set_pipe(output, PIPE_NONE);
> > +	igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +
> > +	igt_pipe_crc_free(pipe_crc);
> > +	drmModeFreeProperty(gamma_mode);
> > +
> > +	return ret;
> > +}
> > +
> >  static void
> >  prep_pipe(data_t *data, enum pipe p)
> >  {
> > @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
> >  		invalid_ctm_matrix_sizes(data, p);
> >  }
> >
> > +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
> > +{
> > +	igt_plane_t *plane;
> > +	int count = 0;
> > +
> > +	for_each_plane_on_pipe(&data->display, pipe, plane) {
> > +		if (!is_valid_plane(plane))
> > +			continue;
> > +
> > +		igt_assert(test(data, plane));
> > +
> > +		count++;
> > +	}
> > +
> > +	igt_require_f(count, "No valid planes found.\n");
> > +}
> > +
> > +static void run_tests_for_plane(data_t *data, enum pipe pipe)
> > +{
> > +	igt_fixture {
> > +		igt_require_pipe(&data->display, pipe);
> > +		igt_require_pipe_crc(data->drm_fd);
> > +		igt_require(data->display.pipes[pipe].n_planes > 0);
> > +		igt_display_require_output_on_pipe(&data->display, pipe);
> > +	}
> > +
> > +	igt_describe("Compare maxed out plane gamma LUT and solid color linear
> LUT");
> 
> I can't seem to see the linear LUT test. This only seems to test
> the max LUT.
> 
> Harry
> 
> > +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
> > +		run_plane_color_test(data, pipe, plane_gamma_test);
> > +}
> > +
> >  igt_main
> >  {
> >  	data_t data = {};
> > @@ -910,6 +1084,9 @@ igt_main
> >
> >  		igt_subtest_group
> >  			run_invalid_tests_for_pipe(&data, pipe);
> > +
> > +		igt_subtest_group
> > +			run_tests_for_plane(&data, pipe);
> >  	}
> >
> >  	igt_fixture {
> >


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

* Re: [igt-dev] [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
@ 2022-01-03  4:05       ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:05 UTC (permalink / raw)
  To: Harry Wentland, igt-dev, dri-devel; +Cc: ppaalanen

> From: Harry Wentland <harry.wentland@amd.com>
> Sent: Friday, November 26, 2021 10:25 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
> 
> On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> > To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> > with a maxed out gamma LUT and verify we have the same CRC as drawing solid
> > color rectangles.
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 178 insertions(+), 1 deletion(-)
> >
> > diff --git a/tests/kms_color.c b/tests/kms_color.c
> > index 775f35964f..b45d66762f 100644
> > --- a/tests/kms_color.c
> > +++ b/tests/kms_color.c
> > @@ -24,7 +24,34 @@
> >
> >  #include "kms_color_helper.h"
> >
> > -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
> > +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
> > +
> > +#define MAX_SUPPORTED_PLANES 7
> > +#define SDR_PLANE_BASE 3
> > +
> > +typedef bool (*test_t)(data_t*, igt_plane_t*);
> > +
> > +static bool is_hdr_plane(const igt_plane_t *plane)
> > +{
> > +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> > +}
> > +
> > +static bool is_valid_plane(igt_plane_t *plane)
> > +{
> > +	int index = plane->index;
> > +
> > +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> > +		return false;
> > +
> > +	/*
> > +	 * Test 1 HDR plane, 1 SDR plane.
> > +	 *
> > +	 * 0,1,2 HDR planes
> > +	 * 3,4,5,6 SDR planes
> > +	 *
> > +	 */
> 
> This seems to be about Intel HW. AMD HW for example does
> not have HDR or SDR planes, only one generic plane.
> 
> > +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> > +}
> >
> >  static void test_pipe_degamma(data_t *data,
> >  			      igt_plane_t *primary)
> > @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t *data,
> >  }
> >  #endif
> >
> > +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> > +{
> > +	igt_output_t *output;
> > +	igt_display_t *display = &data->display;
> > +	drmModeModeInfo *mode;
> > +	struct igt_fb fb;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	uint32_t i;
> > +	bool ret = true;
> > +	igt_pipe_crc_t *pipe_crc = NULL;
> > +	color_t red_green_blue[] = {
> > +		{ 1.0, 0.0, 0.0 },
> > +		{ 0.0, 1.0, 0.0 },
> > +		{ 0.0, 0.0, 1.0 }
> > +	};
> > +
> > +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
> > +			kmstest_pipe_name(plane->pipe->pipe),
> > +			kmstest_plane_type_name(plane->type),
> > +			is_hdr_plane(plane) ? "hdr":"sdr");
> > +
> 
> is_hdr_plane is Intel-specific.
> 
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> > +
> > +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
> > +				  plane->pipe->pipe,
> > +				  INTEL_PIPE_CRC_SOURCE_AUTO);
> > +
> > +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
> > +	igt_assert(output);
> > +
> > +	igt_output_set_pipe(output, plane->pipe->pipe);
> > +	mode = igt_output_get_mode(output);
> > +
> > +	/* Create a framebuffer at the size of the output. */
> > +	igt_assert(igt_create_fb(data->drm_fd,
> > +			      mode->hdisplay,
> > +			      mode->vdisplay,
> > +			      DRM_FORMAT_XRGB8888,
> > +			      DRM_FORMAT_MOD_LINEAR,
> > +			      &fb));
> > +	igt_plane_set_fb(plane, &fb);
> > +
> > +	/* Disable Pipe color props. */
> > +	disable_ctm(plane->pipe);
> > +	disable_degamma(plane->pipe);
> > +	disable_gamma(plane->pipe);
> > +
> > +	disable_plane_ctm(plane);
> > +	disable_plane_degamma(plane);
> > +	igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +
> > +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> > +
> > +	/* Iterate all supported gamma modes. */
> > +	for (i = 0; i < gamma_mode->count_enums; i++) {
> > +		igt_crc_t crc_gamma, crc_fullcolors;
> > +		segment_data_t *segment_info = NULL;
> > +		struct drm_color_lut_ext *lut = NULL;
> > +		uint32_t lut_size = 0;
> > +
> > +		/* Ignore 'no gamma' from enum list. */
> > +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> > +			continue;
> > +
> 
> It might still make sense to test that this is doing bypass.

As we know gamma_mode->enum[i].name represents the name of the
gamma mode and gamma_mode->enum[i].value would be the LUT blob
address of that particular gamma_mode.

For "no gamma" case the blob address is NULL, so we can't commit
this mode. Hence skipping this mode.

> 
> > +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode-
> >enums[i].name);
> > +
> > +		/* Draw solid colors with no gamma transformation. */
> > +		disable_plane_gamma(plane);
> > +		paint_rectangles(data, mode, red_green_blue, &fb);
> > +		igt_plane_set_fb(plane, &fb);
> > +		igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +		igt_wait_for_vblank(data->drm_fd,
> > +			display->pipes[plane->pipe->pipe].crtc_offset);
> > +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
> > +
> > +		/* Draw gradient colors with gamma LUT to remap all
> > +		 * values to max red/green/blue.
> > +		 */
> > +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> > +				gamma_mode->enums[i].name);
> > +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
> >entries_count;
> > +		lut = create_max_lut(segment_info);
> > +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
> > +
> > +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
> > +		igt_plane_set_fb(plane, &fb);
> > +		igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +		igt_wait_for_vblank(data->drm_fd,
> > +			display->pipes[plane->pipe->pipe].crtc_offset);
> > +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
> > +
> > +		/* Verify that the CRC of the software computed output is
> > +		 * equal to the CRC of the gamma LUT transformation output.
> > +		 */
> > +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
> > +
> > +		free(lut);
> > +		clear_segment_data(segment_info);
> > +	}
> > +
> > +	disable_plane_gamma(plane);
> > +	igt_plane_set_fb(plane, NULL);
> > +	igt_output_set_pipe(output, PIPE_NONE);
> > +	igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +
> > +	igt_pipe_crc_free(pipe_crc);
> > +	drmModeFreeProperty(gamma_mode);
> > +
> > +	return ret;
> > +}
> > +
> >  static void
> >  prep_pipe(data_t *data, enum pipe p)
> >  {
> > @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
> >  		invalid_ctm_matrix_sizes(data, p);
> >  }
> >
> > +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
> > +{
> > +	igt_plane_t *plane;
> > +	int count = 0;
> > +
> > +	for_each_plane_on_pipe(&data->display, pipe, plane) {
> > +		if (!is_valid_plane(plane))
> > +			continue;
> > +
> > +		igt_assert(test(data, plane));
> > +
> > +		count++;
> > +	}
> > +
> > +	igt_require_f(count, "No valid planes found.\n");
> > +}
> > +
> > +static void run_tests_for_plane(data_t *data, enum pipe pipe)
> > +{
> > +	igt_fixture {
> > +		igt_require_pipe(&data->display, pipe);
> > +		igt_require_pipe_crc(data->drm_fd);
> > +		igt_require(data->display.pipes[pipe].n_planes > 0);
> > +		igt_display_require_output_on_pipe(&data->display, pipe);
> > +	}
> > +
> > +	igt_describe("Compare maxed out plane gamma LUT and solid color linear
> LUT");
> 
> I can't seem to see the linear LUT test. This only seems to test
> the max LUT.
> 
> Harry
> 
> > +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
> > +		run_plane_color_test(data, pipe, plane_gamma_test);
> > +}
> > +
> >  igt_main
> >  {
> >  	data_t data = {};
> > @@ -910,6 +1084,9 @@ igt_main
> >
> >  		igt_subtest_group
> >  			run_invalid_tests_for_pipe(&data, pipe);
> > +
> > +		igt_subtest_group
> > +			run_tests_for_plane(&data, pipe);
> >  	}
> >
> >  	igt_fixture {
> >


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

* RE: [i-g-t 07/14] tests/kms_color: New negative tests for plane level color mgmt
  2021-11-18  9:19     ` [igt-dev] " Pekka Paalanen
@ 2022-01-03  4:05       ` Modem, Bhanuprakash
  -1 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:05 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: igt-dev, Shankar, Uma, dri-devel

> From: Pekka Paalanen <ppaalanen@gmail.com>
> Sent: Thursday, November 18, 2021 2:50 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>
> Cc: igt-dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org; Juha-Pekka
> Heikkila <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 07/14] tests/kms_color: New negative tests for plane level
> color mgmt
> 
> On Mon, 15 Nov 2021 15:17:52 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
> > Negative check for:
> >  * plane gamma lut sizes
> >  * plane degamma lut sizes
> >  * plane ctm matrix sizes
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 127 insertions(+)
> >
> > diff --git a/tests/kms_color.c b/tests/kms_color.c
> > index e14b37cb6f..d9fe417ba9 100644
> > --- a/tests/kms_color.c
> > +++ b/tests/kms_color.c
> > @@ -736,6 +736,118 @@ static void test_pipe_limited_range_ctm(data_t *data,
> >  }
> >  #endif
> >
> > +static bool invalid_plane_gamma_test(data_t *data, igt_plane_t *plane)
> > +{
> > +	igt_display_t *display = &data->display;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	uint32_t i;
> > +
> > +	igt_info("Plane invalid gamma test is running on pipe-%s plane-
> %s(%s)\n",
> > +			kmstest_pipe_name(plane->pipe->pipe),
> > +			kmstest_plane_type_name(plane->type),
> > +			is_hdr_plane(plane) ? "hdr":"sdr");
> > +
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> > +
> > +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> > +
> > +	/* Iterate all supported gamma modes. */
> > +	for (i = 0; i < gamma_mode->count_enums; i++) {
> > +		segment_data_t *segment_info = NULL;
> > +		size_t lut_size = 0;
> > +
> > +		/* Ignore 'no gamma' from enum list. */
> > +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> > +			continue;
> > +
> > +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode-
> >enums[i].name);
> > +
> > +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> > +				gamma_mode->enums[i].name);
> > +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
> >entries_count;
> > +
> > +		igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, gamma_mode-
> >enums[i].name);
> > +		invalid_plane_lut_sizes(display, plane,
> > +					IGT_PLANE_GAMMA_LUT,
> > +					lut_size);
> > +
> > +		clear_segment_data(segment_info);
> > +
> > +		/* One enum is enough. */
> > +		break;
> > +	}
> > +
> > +	drmModeFreeProperty(gamma_mode);
> > +
> > +	return true;
> > +}
> > +
> > +static bool invalid_plane_degamma_test(data_t *data, igt_plane_t *plane)
> > +{
> > +	igt_display_t *display = &data->display;
> > +	drmModePropertyPtr degamma_mode = NULL;
> > +	uint32_t i;
> > +
> > +	igt_info("Plane invalid degamma test is running on pipe-%s plane-
> %s(%s)\n",
> > +			kmstest_pipe_name(plane->pipe->pipe),
> > +			kmstest_plane_type_name(plane->type),
> > +			is_hdr_plane(plane) ? "hdr":"sdr");
> > +
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
> > +
> > +	degamma_mode = get_plane_gamma_degamma_mode(plane,
> IGT_PLANE_DEGAMMA_MODE);
> > +
> > +	/* Iterate all supported degamma modes. */
> > +	for (i = 0; i < degamma_mode->count_enums; i++) {
> > +		segment_data_t *segment_info = NULL;
> > +		size_t lut_size = 0;
> > +
> > +		/* Ignore 'no degamma' from enum list. */
> > +		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
> > +			continue;
> > +
> > +		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode-
> >enums[i].name);
> > +
> > +		segment_info = get_segment_data(data,
> > +						degamma_mode->enums[i].value,
> > +						degamma_mode->enums[i].name);
> > +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
> >entries_count * 2;
> > +
> > +		igt_plane_set_prop_enum(plane,
> > +					IGT_PLANE_DEGAMMA_MODE,
> > +					degamma_mode->enums[i].name);
> > +		invalid_plane_lut_sizes(display, plane,
> > +					IGT_PLANE_DEGAMMA_LUT,
> > +					lut_size);
> > +
> > +		clear_segment_data(segment_info);
> > +
> > +		/* One enum is enough. */
> > +		break;
> 
> Why is one enum enough?
> 
> The same question for the other case in this patch.

This is just for CI time optimization, seems we don't save much CI time
I'll remove this & float a new rev.

> 
> 
> > +	}
> > +
> > +	drmModeFreeProperty(degamma_mode);
> > +
> > +	return true;
> > +}
> > +
> > +static bool invalid_plane_ctm_test(data_t *data, igt_plane_t *plane)
> > +{
> > +	igt_info("Plane invalid CTM test is running on pipe-%s plane-%s(%s)\n",
> > +			kmstest_pipe_name(plane->pipe->pipe),
> > +			kmstest_plane_type_name(plane->type),
> > +			is_hdr_plane(plane) ? "hdr":"sdr");
> > +
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
> > +	invalid_plane_lut_sizes(&data->display, plane,
> > +				IGT_PLANE_CTM,
> > +				sizeof(struct drm_color_ctm));
> 
> The code says you're trying shove a LUT into a CTM blob. I understand
> that mechanically this is test you want to do, feed a wrong sized blob,
> and in this case the contents do not matter (unlike with actual LUTs),
> but reading this code is completely misleading and does not make sense.
> It takes a while to think about what you actually want to test here,
> and then reverse-engineer the code to understand that that is what
> actually happens, too. That is too much mental burden for the reader to
> realize that this piece of code actually works.
> 

Sorry for the poor documentation, I'll try to add some comments.

- Bhanu

> 
> Thanks,
> pq
> 
> > +
> > +	return true;
> > +}
> > +
> >  static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> >  {
> >  	igt_output_t *output;
> > @@ -1411,6 +1523,21 @@ static void run_tests_for_plane(data_t *data, enum
> pipe pipe)
> >  					ctm_tests[i].iter);
> >  		}
> >  	}
> > +
> > +	igt_describe("Negative check for invalid plane gamma lut sizes");
> > +	igt_subtest_f("pipe-%s-invalid-plane-gamma-lut-sizes",
> > +			kmstest_pipe_name(pipe))
> > +		run_plane_color_test(data, pipe, invalid_plane_gamma_test);
> > +
> > +	igt_describe("Negative check for invalid plane degamma lut sizes");
> > +	igt_subtest_f("pipe-%s-invalid-plane-degamma-lut-sizes",
> > +			kmstest_pipe_name(pipe))
> > +		run_plane_color_test(data, pipe, invalid_plane_degamma_test);
> > +
> > +	igt_describe("Negative check for invalid plane ctm matrix sizes");
> > +	igt_subtest_f("pipe-%s-invalid-plane-ctm-matrix-sizes",
> > +			kmstest_pipe_name(pipe))
> > +		run_plane_color_test(data, pipe, invalid_plane_ctm_test);
> >  }
> >
> >  igt_main


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

* Re: [igt-dev] [i-g-t 07/14] tests/kms_color: New negative tests for plane level color mgmt
@ 2022-01-03  4:05       ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:05 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: igt-dev, dri-devel

> From: Pekka Paalanen <ppaalanen@gmail.com>
> Sent: Thursday, November 18, 2021 2:50 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>
> Cc: igt-dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org; Juha-Pekka
> Heikkila <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 07/14] tests/kms_color: New negative tests for plane level
> color mgmt
> 
> On Mon, 15 Nov 2021 15:17:52 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
> > Negative check for:
> >  * plane gamma lut sizes
> >  * plane degamma lut sizes
> >  * plane ctm matrix sizes
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 127 insertions(+)
> >
> > diff --git a/tests/kms_color.c b/tests/kms_color.c
> > index e14b37cb6f..d9fe417ba9 100644
> > --- a/tests/kms_color.c
> > +++ b/tests/kms_color.c
> > @@ -736,6 +736,118 @@ static void test_pipe_limited_range_ctm(data_t *data,
> >  }
> >  #endif
> >
> > +static bool invalid_plane_gamma_test(data_t *data, igt_plane_t *plane)
> > +{
> > +	igt_display_t *display = &data->display;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	uint32_t i;
> > +
> > +	igt_info("Plane invalid gamma test is running on pipe-%s plane-
> %s(%s)\n",
> > +			kmstest_pipe_name(plane->pipe->pipe),
> > +			kmstest_plane_type_name(plane->type),
> > +			is_hdr_plane(plane) ? "hdr":"sdr");
> > +
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> > +
> > +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> > +
> > +	/* Iterate all supported gamma modes. */
> > +	for (i = 0; i < gamma_mode->count_enums; i++) {
> > +		segment_data_t *segment_info = NULL;
> > +		size_t lut_size = 0;
> > +
> > +		/* Ignore 'no gamma' from enum list. */
> > +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> > +			continue;
> > +
> > +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode-
> >enums[i].name);
> > +
> > +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> > +				gamma_mode->enums[i].name);
> > +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
> >entries_count;
> > +
> > +		igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, gamma_mode-
> >enums[i].name);
> > +		invalid_plane_lut_sizes(display, plane,
> > +					IGT_PLANE_GAMMA_LUT,
> > +					lut_size);
> > +
> > +		clear_segment_data(segment_info);
> > +
> > +		/* One enum is enough. */
> > +		break;
> > +	}
> > +
> > +	drmModeFreeProperty(gamma_mode);
> > +
> > +	return true;
> > +}
> > +
> > +static bool invalid_plane_degamma_test(data_t *data, igt_plane_t *plane)
> > +{
> > +	igt_display_t *display = &data->display;
> > +	drmModePropertyPtr degamma_mode = NULL;
> > +	uint32_t i;
> > +
> > +	igt_info("Plane invalid degamma test is running on pipe-%s plane-
> %s(%s)\n",
> > +			kmstest_pipe_name(plane->pipe->pipe),
> > +			kmstest_plane_type_name(plane->type),
> > +			is_hdr_plane(plane) ? "hdr":"sdr");
> > +
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
> > +
> > +	degamma_mode = get_plane_gamma_degamma_mode(plane,
> IGT_PLANE_DEGAMMA_MODE);
> > +
> > +	/* Iterate all supported degamma modes. */
> > +	for (i = 0; i < degamma_mode->count_enums; i++) {
> > +		segment_data_t *segment_info = NULL;
> > +		size_t lut_size = 0;
> > +
> > +		/* Ignore 'no degamma' from enum list. */
> > +		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
> > +			continue;
> > +
> > +		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode-
> >enums[i].name);
> > +
> > +		segment_info = get_segment_data(data,
> > +						degamma_mode->enums[i].value,
> > +						degamma_mode->enums[i].name);
> > +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
> >entries_count * 2;
> > +
> > +		igt_plane_set_prop_enum(plane,
> > +					IGT_PLANE_DEGAMMA_MODE,
> > +					degamma_mode->enums[i].name);
> > +		invalid_plane_lut_sizes(display, plane,
> > +					IGT_PLANE_DEGAMMA_LUT,
> > +					lut_size);
> > +
> > +		clear_segment_data(segment_info);
> > +
> > +		/* One enum is enough. */
> > +		break;
> 
> Why is one enum enough?
> 
> The same question for the other case in this patch.

This is just for CI time optimization, seems we don't save much CI time
I'll remove this & float a new rev.

> 
> 
> > +	}
> > +
> > +	drmModeFreeProperty(degamma_mode);
> > +
> > +	return true;
> > +}
> > +
> > +static bool invalid_plane_ctm_test(data_t *data, igt_plane_t *plane)
> > +{
> > +	igt_info("Plane invalid CTM test is running on pipe-%s plane-%s(%s)\n",
> > +			kmstest_pipe_name(plane->pipe->pipe),
> > +			kmstest_plane_type_name(plane->type),
> > +			is_hdr_plane(plane) ? "hdr":"sdr");
> > +
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
> > +	invalid_plane_lut_sizes(&data->display, plane,
> > +				IGT_PLANE_CTM,
> > +				sizeof(struct drm_color_ctm));
> 
> The code says you're trying shove a LUT into a CTM blob. I understand
> that mechanically this is test you want to do, feed a wrong sized blob,
> and in this case the contents do not matter (unlike with actual LUTs),
> but reading this code is completely misleading and does not make sense.
> It takes a while to think about what you actually want to test here,
> and then reverse-engineer the code to understand that that is what
> actually happens, too. That is too much mental burden for the reader to
> realize that this piece of code actually works.
> 

Sorry for the poor documentation, I'll try to add some comments.

- Bhanu

> 
> Thanks,
> pq
> 
> > +
> > +	return true;
> > +}
> > +
> >  static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> >  {
> >  	igt_output_t *output;
> > @@ -1411,6 +1523,21 @@ static void run_tests_for_plane(data_t *data, enum
> pipe pipe)
> >  					ctm_tests[i].iter);
> >  		}
> >  	}
> > +
> > +	igt_describe("Negative check for invalid plane gamma lut sizes");
> > +	igt_subtest_f("pipe-%s-invalid-plane-gamma-lut-sizes",
> > +			kmstest_pipe_name(pipe))
> > +		run_plane_color_test(data, pipe, invalid_plane_gamma_test);
> > +
> > +	igt_describe("Negative check for invalid plane degamma lut sizes");
> > +	igt_subtest_f("pipe-%s-invalid-plane-degamma-lut-sizes",
> > +			kmstest_pipe_name(pipe))
> > +		run_plane_color_test(data, pipe, invalid_plane_degamma_test);
> > +
> > +	igt_describe("Negative check for invalid plane ctm matrix sizes");
> > +	igt_subtest_f("pipe-%s-invalid-plane-ctm-matrix-sizes",
> > +			kmstest_pipe_name(pipe))
> > +		run_plane_color_test(data, pipe, invalid_plane_ctm_test);
> >  }
> >
> >  igt_main


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

* RE: [i-g-t 08/14] tests/kms_color_chamelium: New subtests for Plane gamma
  2021-11-18  9:32     ` [igt-dev] " Pekka Paalanen
@ 2022-01-03  4:06       ` Modem, Bhanuprakash
  -1 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:06 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: igt-dev, Joshi, Kunal1, Shankar, Uma, dri-devel

> From: Pekka Paalanen <ppaalanen@gmail.com>
> Sent: Thursday, November 18, 2021 3:02 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>
> Cc: igt-dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org; Joshi,
> Kunal1 <kunal1.joshi@intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 08/14] tests/kms_color_chamelium: New subtests for Plane
> gamma
> 
> On Mon, 15 Nov 2021 15:17:53 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
> > To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> > with a maxed out gamma LUT and verify we have the same frame dump as
> > drawing solid color rectangles.
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Cc: Kunal Joshi <kunal1.joshi@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color_chamelium.c | 188 +++++++++++++++++++++++++++++++++++-
> >  1 file changed, 187 insertions(+), 1 deletion(-)
> >
> > diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
> > index 76f82d6d35..b506109271 100644
> > --- a/tests/kms_color_chamelium.c
> > +++ b/tests/kms_color_chamelium.c
> > @@ -24,7 +24,34 @@
> >
> >  #include "kms_color_helper.h"
> >
> > -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level using Chamelium to
> verify instead of CRC");
> > +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level using
> Chamelium to verify instead of CRC");
> 
> Now that you actually can get a captured image of the result with
> Chamelium, I think the tests should be more ambitious. Do not rely on
> identity curves or matrices, nor max LUT, because now you can use a
> difference threshold per pixel when comparing the result with the
> reference.
> 
> Use various non-trivial curves, different for each of red, green and
> blue. Use non-trivial matrices that actually compute mixtures instead
> of just moving red value to the green channel. Use multiple planes
> simultaneously. Use different framebuffer formats, particularly with
> higher than 8 bits per channel, and check the capture has the same
> precision and not truncated to 8 bit.
> 
> That kind of tests would have much more proving power, and they also
> help assess the precision of the hardware. Precision is important to
> userspace.
> 
> These are also tests that userspace projects cannot really execute, they
> do not have labs with Chamelium boards and not all drivers/hardware
> support writeback connectors.

Thanks for the review Pekka,
We are planning to add these kind of Advanced tests in next phase.

- Bhanu
 
> 
> > +
> > +#define MAX_SUPPORTED_PLANES 7
> > +#define SDR_PLANE_BASE 3
> > +
> > +typedef bool (*test_t)(data_t*, igt_plane_t*);
> > +
> > +static bool is_hdr_plane(const igt_plane_t *plane)
> > +{
> > +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> 
> This here again. I guess the previous definition of this function was
> never used?
> 
> The same questions.
> 
> > +}
> > +
> > +static bool is_valid_plane(igt_plane_t *plane)
> > +{
> > +	int index = plane->index;
> > +
> > +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> > +		return false;
> > +
> > +	/*
> > +	 * Test 1 HDR plane, 1 SDR plane.
> > +	 *
> > +	 * 0,1,2 HDR planes
> > +	 * 3,4,5,6 SDR planes
> > +	 *
> > +	 */
> > +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> > +}
> 
> 
> Thanks,
> pq

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

* Re: [igt-dev] [i-g-t 08/14] tests/kms_color_chamelium: New subtests for Plane gamma
@ 2022-01-03  4:06       ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:06 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: igt-dev, Joshi, Kunal1, dri-devel

> From: Pekka Paalanen <ppaalanen@gmail.com>
> Sent: Thursday, November 18, 2021 3:02 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>
> Cc: igt-dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org; Joshi,
> Kunal1 <kunal1.joshi@intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 08/14] tests/kms_color_chamelium: New subtests for Plane
> gamma
> 
> On Mon, 15 Nov 2021 15:17:53 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
> > To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> > with a maxed out gamma LUT and verify we have the same frame dump as
> > drawing solid color rectangles.
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Cc: Kunal Joshi <kunal1.joshi@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color_chamelium.c | 188 +++++++++++++++++++++++++++++++++++-
> >  1 file changed, 187 insertions(+), 1 deletion(-)
> >
> > diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
> > index 76f82d6d35..b506109271 100644
> > --- a/tests/kms_color_chamelium.c
> > +++ b/tests/kms_color_chamelium.c
> > @@ -24,7 +24,34 @@
> >
> >  #include "kms_color_helper.h"
> >
> > -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level using Chamelium to
> verify instead of CRC");
> > +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level using
> Chamelium to verify instead of CRC");
> 
> Now that you actually can get a captured image of the result with
> Chamelium, I think the tests should be more ambitious. Do not rely on
> identity curves or matrices, nor max LUT, because now you can use a
> difference threshold per pixel when comparing the result with the
> reference.
> 
> Use various non-trivial curves, different for each of red, green and
> blue. Use non-trivial matrices that actually compute mixtures instead
> of just moving red value to the green channel. Use multiple planes
> simultaneously. Use different framebuffer formats, particularly with
> higher than 8 bits per channel, and check the capture has the same
> precision and not truncated to 8 bit.
> 
> That kind of tests would have much more proving power, and they also
> help assess the precision of the hardware. Precision is important to
> userspace.
> 
> These are also tests that userspace projects cannot really execute, they
> do not have labs with Chamelium boards and not all drivers/hardware
> support writeback connectors.

Thanks for the review Pekka,
We are planning to add these kind of Advanced tests in next phase.

- Bhanu
 
> 
> > +
> > +#define MAX_SUPPORTED_PLANES 7
> > +#define SDR_PLANE_BASE 3
> > +
> > +typedef bool (*test_t)(data_t*, igt_plane_t*);
> > +
> > +static bool is_hdr_plane(const igt_plane_t *plane)
> > +{
> > +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> 
> This here again. I guess the previous definition of this function was
> never used?
> 
> The same questions.
> 
> > +}
> > +
> > +static bool is_valid_plane(igt_plane_t *plane)
> > +{
> > +	int index = plane->index;
> > +
> > +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> > +		return false;
> > +
> > +	/*
> > +	 * Test 1 HDR plane, 1 SDR plane.
> > +	 *
> > +	 * 0,1,2 HDR planes
> > +	 * 3,4,5,6 SDR planes
> > +	 *
> > +	 */
> > +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> > +}
> 
> 
> Thanks,
> pq

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

* RE: [i-g-t 12/14] kms_color_helper: Add helper functions to support logarithmic gamma mode
  2021-11-18  9:45     ` [igt-dev] " Pekka Paalanen
@ 2022-01-03  4:07       ` Modem, Bhanuprakash
  -1 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:07 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: igt-dev, Shankar, Uma, Kumar,  Mukunda Pramodh, dri-devel

> From: Pekka Paalanen <ppaalanen@gmail.com>
> Sent: Thursday, November 18, 2021 3:15 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>
> Cc: igt-dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org; Kumar,
> Mukunda Pramodh <mukunda.pramodh.kumar@intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 12/14] kms_color_helper: Add helper functions to support
> logarithmic gamma mode
> 
> On Mon, 15 Nov 2021 15:17:57 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
> > From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> >
> > Add helper functions to support logarithmic gamma mode
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color_helper.c | 127 +++++++++++++++++++++++++++++++++++++++
> >  tests/kms_color_helper.h |  16 +++++
> >  2 files changed, 143 insertions(+)
> >
> > diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> > index c65b7a0f50..7ea8282df3 100644
> > --- a/tests/kms_color_helper.c
> > +++ b/tests/kms_color_helper.c
> > @@ -190,6 +190,33 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
> >  	return lut;
> >  }
> >
> > +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> > +						const gamma_lut_t *gamma,
> > +						uint32_t color_depth,
> > +						int off)
> > +{
> > +	struct drm_color_lut *lut;
> > +	int i, lut_size = gamma->size;
> > +	/* This is the maximum value due to 16 bit precision in hardware. */
> 
> In whose hardware?
> 
> Are igt tests not supposed to be generic for everything that exposes
> the particular KMS properties?
> 
> This also hints that the UAPI design is lacking, because userspace
> needs to know hardware specific things out of thin air. Display servers
> are not going to have hardware-specific code. They specialise based on
> the existence of KMS properties instead.

Yeah, the comment is misleading and variable names also bit confusing.

As uapi supports U0.16 precision the max supported value would be (1 << 16) - 1
and Intel h/w supports max value of (1 << 24) so we need to scale the values
accordingly.

So, need to drop h/w specific hardcoded stuff and read from uapi & rename the
variables as below:

max_uapi_value = (1 << 16) - 1;
max_hw_value = /* Read from the uapi. */

> 
> > +	uint32_t max_hw_value = (1 << 16) - 1;
> > +	unsigned int max_segment_value = 1 << 24;
> > +
> > +	lut = malloc(sizeof(struct drm_color_lut) * lut_size);
> > +
> > +	for (i = 0; i < lut_size; i++) {
> > +		double scaling_factor = (double)max_hw_value /
> (double)max_segment_value;
> > +		uint32_t r = MIN((gamma->coeffs[i].r * scaling_factor),
> max_hw_value);
> > +		uint32_t g = MIN((gamma->coeffs[i].g * scaling_factor),
> max_hw_value);
> > +		uint32_t b = MIN((gamma->coeffs[i].b * scaling_factor),
> max_hw_value);
> > +
> > +		lut[i].red = r;
> > +		lut[i].green = g;
> > +		lut[i].blue = b;
> > +	}
> > +
> > +	return lut;
> > +}
> > +
> >  void set_degamma(data_t *data,
> >  		 igt_pipe_t *pipe,
> >  		 const gamma_lut_t *gamma)
> > @@ -203,6 +230,15 @@ void set_degamma(data_t *data,
> >  	free(lut);
> >  }
> >
> > +void set_pipe_gamma(igt_pipe_t *pipe,
> > +		    uint64_t value,
> > +		    struct drm_color_lut *lut,
> > +		    uint32_t size)
> > +{
> > +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_MODE, value);
> > +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
> > +}
> > +
> >  void set_gamma(data_t *data,
> >  	       igt_pipe_t *pipe, const gamma_lut_t *gamma)
> >  {
> > @@ -241,6 +277,51 @@ void disable_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
> >  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
> >  }
> >
> > +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> > +					       enum igt_atomic_crtc_properties prop)
> > +{
> > +	igt_display_t *display = pipe->display;
> > +	uint32_t prop_id = pipe->props[prop];
> > +	drmModePropertyPtr drmProp;
> > +
> > +	igt_assert(prop_id);
> > +
> > +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> > +
> > +	igt_assert(drmProp);
> > +	igt_assert(drmProp->count_enums);
> > +
> > +	return drmProp;
> > +}
> > +
> > +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info)
> 
> Identity transformation?
> 
> > +{
> > +	uint32_t segment, entry, index = 0;
> > +	double val;
> > +	int i = 0;
> > +	gamma_lut_t *gamma = alloc_lut(info->entries_count);
> > +
> > +	igt_assert(gamma);
> > +
> > +	gamma->size = info->entries_count;
> > +	for (segment = 0; segment < info->segment_count; segment++) {
> > +		uint32_t entry_count = info->segment_data[segment].count;
> > +		uint32_t start = (segment == 0) ? 0 : (1 << (segment - 1));
> > +		uint32_t end = 1 << segment;
> > +
> > +		for (entry = 0; entry < entry_count; entry++) {
> > +			val = (index == 0) ? /* First entry is Zero. */
> > +				0 : start + entry *
> > +				((end - start) * 1.0 / entry_count);
> > +
> > +			set_rgb(&gamma->coeffs[i++], val);
> > +			index++;
> > +		}
> > +	}
> > +
> > +	return gamma;
> > +}
> > +
> >  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> >  				enum igt_atomic_plane_properties prop)
> >  {
> > @@ -331,6 +412,7 @@ segment_data_t *get_segment_data(data_t *data,
> >  	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info-
> >segment_count);
> >  	igt_assert(info->segment_data);
> >
> > +	info->entries_count = 0;
> 
> What's this?
> 
> >  	for (i = 0; i < info->segment_count; i++) {
> >  		info->entries_count += lut_range[i].count;
> >  		info->segment_data[i] = lut_range[i];
> > @@ -341,6 +423,51 @@ segment_data_t *get_segment_data(data_t *data,
> >  	return info;
> >  }
> >
> > +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type
> type)
> > +{
> > +	igt_display_t *display = &data->display;
> > +	gamma_lut_t *gamma_log;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	segment_data_t *segment_info = NULL;
> > +	struct drm_color_lut *lut = NULL;
> > +	int lut_size = 0;
> > +
> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
> 
> Is this how we are going to do cross-software DRM-master hand-over or
> switching compatibility in general?
> 
> Add a new client cap for every new KMS property, and if the KMS client
> does not set the property, the kernel will magically reset it to ensure
> the client's expectations are met? Is that how it works?
> 
> Or why does this exist?

Very good point. Need to explore on this.
I think the expectation is: Whoever sets this property should clear before
hand-over or switching the compatibility.

> 
> > +	gamma_mode = get_pipe_gamma_degamma_mode(pipe, IGT_CRTC_GAMMA_MODE);
> > +
> > +	for (int i = 0; i < gamma_mode->count_enums; i++) {
> > +		if (!strcmp(gamma_mode->enums[i].name, "logarithmic gamma")) {
> > +			segment_info = get_segment_data(data,
> > +							gamma_mode->enums[i].value,
> > +							gamma_mode->enums[i].name);
> > +			lut_size = sizeof(struct drm_color_lut) *
> > +					  segment_info->entries_count;
> > +			if (type == LINEAR_GAMMA) {
> > +				gamma_log = pipe_create_linear_lut(segment_info);
> > +				lut = coeffs_to_logarithmic_lut(data,
> > +								gamma_log,
> > +								data->color_depth,
> > +								0);
> > +			} else if (type == MAX_GAMMA) {
> > +				gamma_log = generate_table_max(segment_info-
> >entries_count);
> > +				gamma_log->size = segment_info->entries_count;
> > +				lut = coeffs_to_lut(data, gamma_log,
> > +						    data->color_depth, 0);
> > +			}
> > +			set_pipe_gamma(pipe, gamma_mode->enums[i].value,
> > +				       lut, lut_size);
> > +			igt_display_commit2(display, display->is_atomic
> > +					    ? COMMIT_ATOMIC : COMMIT_LEGACY);
> > +			break;
> > +		}
> > +	}
> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
> 
> I've never seen this done before. I did not know client caps could be
> reset.
> 
> > +	free(gamma_log);
> > +	free(lut);
> > +	clear_segment_data(segment_info);
> > +	drmModeFreeProperty(gamma_mode);
> > +}
> 
> 
> Thanks,
> pq
> 
> > +
> >  void set_plane_gamma(igt_plane_t *plane,
> >  		char *mode,
> >  		struct drm_color_lut_ext *lut,
> > diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> > index 5a35dcaac1..c863874f0c 100644
> > --- a/tests/kms_color_helper.h
> > +++ b/tests/kms_color_helper.h
> > @@ -70,6 +70,11 @@ typedef struct {
> >  	uint32_t entries_count;
> >  } segment_data_t;
> >
> > +enum gamma_type {
> > +	LINEAR_GAMMA,
> > +	MAX_GAMMA
> > +};
> > +
> >  #define MIN(a, b) ((a) < (b) ? (a) : (b))
> >
> >  void paint_gradient_rectangles(data_t *data,
> > @@ -89,6 +94,10 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
> >  				    const gamma_lut_t *gamma,
> >  				    uint32_t color_depth,
> >  				    int off);
> > +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> > +						const gamma_lut_t *gamma,
> > +						uint32_t color_depth,
> > +						int off);
> >  void set_degamma(data_t *data,
> >  		 igt_pipe_t *pipe,
> >  		 const gamma_lut_t *gamma);
> > @@ -98,12 +107,19 @@ void set_gamma(data_t *data,
> >  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
> >  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
> >
> > +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> > +					       enum igt_atomic_crtc_properties
> > +					       prop);
> >  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> >  	enum igt_atomic_plane_properties prop);
> >  void clear_segment_data(segment_data_t *info);
> > +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info);
> >  struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> >  struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> >  segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char
> *mode);
> > +void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
> > +		    struct drm_color_lut *lut, uint32_t size);
> > +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type
> type);
> >  void set_plane_gamma(igt_plane_t *plane,
> >  	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> >  void set_plane_degamma(igt_plane_t *plane,


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

* Re: [igt-dev] [i-g-t 12/14] kms_color_helper: Add helper functions to support logarithmic gamma mode
@ 2022-01-03  4:07       ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:07 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: igt-dev, Kumar, Mukunda Pramodh, dri-devel

> From: Pekka Paalanen <ppaalanen@gmail.com>
> Sent: Thursday, November 18, 2021 3:15 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>
> Cc: igt-dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org; Kumar,
> Mukunda Pramodh <mukunda.pramodh.kumar@intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 12/14] kms_color_helper: Add helper functions to support
> logarithmic gamma mode
> 
> On Mon, 15 Nov 2021 15:17:57 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
> > From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> >
> > Add helper functions to support logarithmic gamma mode
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color_helper.c | 127 +++++++++++++++++++++++++++++++++++++++
> >  tests/kms_color_helper.h |  16 +++++
> >  2 files changed, 143 insertions(+)
> >
> > diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> > index c65b7a0f50..7ea8282df3 100644
> > --- a/tests/kms_color_helper.c
> > +++ b/tests/kms_color_helper.c
> > @@ -190,6 +190,33 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
> >  	return lut;
> >  }
> >
> > +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> > +						const gamma_lut_t *gamma,
> > +						uint32_t color_depth,
> > +						int off)
> > +{
> > +	struct drm_color_lut *lut;
> > +	int i, lut_size = gamma->size;
> > +	/* This is the maximum value due to 16 bit precision in hardware. */
> 
> In whose hardware?
> 
> Are igt tests not supposed to be generic for everything that exposes
> the particular KMS properties?
> 
> This also hints that the UAPI design is lacking, because userspace
> needs to know hardware specific things out of thin air. Display servers
> are not going to have hardware-specific code. They specialise based on
> the existence of KMS properties instead.

Yeah, the comment is misleading and variable names also bit confusing.

As uapi supports U0.16 precision the max supported value would be (1 << 16) - 1
and Intel h/w supports max value of (1 << 24) so we need to scale the values
accordingly.

So, need to drop h/w specific hardcoded stuff and read from uapi & rename the
variables as below:

max_uapi_value = (1 << 16) - 1;
max_hw_value = /* Read from the uapi. */

> 
> > +	uint32_t max_hw_value = (1 << 16) - 1;
> > +	unsigned int max_segment_value = 1 << 24;
> > +
> > +	lut = malloc(sizeof(struct drm_color_lut) * lut_size);
> > +
> > +	for (i = 0; i < lut_size; i++) {
> > +		double scaling_factor = (double)max_hw_value /
> (double)max_segment_value;
> > +		uint32_t r = MIN((gamma->coeffs[i].r * scaling_factor),
> max_hw_value);
> > +		uint32_t g = MIN((gamma->coeffs[i].g * scaling_factor),
> max_hw_value);
> > +		uint32_t b = MIN((gamma->coeffs[i].b * scaling_factor),
> max_hw_value);
> > +
> > +		lut[i].red = r;
> > +		lut[i].green = g;
> > +		lut[i].blue = b;
> > +	}
> > +
> > +	return lut;
> > +}
> > +
> >  void set_degamma(data_t *data,
> >  		 igt_pipe_t *pipe,
> >  		 const gamma_lut_t *gamma)
> > @@ -203,6 +230,15 @@ void set_degamma(data_t *data,
> >  	free(lut);
> >  }
> >
> > +void set_pipe_gamma(igt_pipe_t *pipe,
> > +		    uint64_t value,
> > +		    struct drm_color_lut *lut,
> > +		    uint32_t size)
> > +{
> > +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_MODE, value);
> > +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
> > +}
> > +
> >  void set_gamma(data_t *data,
> >  	       igt_pipe_t *pipe, const gamma_lut_t *gamma)
> >  {
> > @@ -241,6 +277,51 @@ void disable_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
> >  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
> >  }
> >
> > +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> > +					       enum igt_atomic_crtc_properties prop)
> > +{
> > +	igt_display_t *display = pipe->display;
> > +	uint32_t prop_id = pipe->props[prop];
> > +	drmModePropertyPtr drmProp;
> > +
> > +	igt_assert(prop_id);
> > +
> > +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> > +
> > +	igt_assert(drmProp);
> > +	igt_assert(drmProp->count_enums);
> > +
> > +	return drmProp;
> > +}
> > +
> > +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info)
> 
> Identity transformation?
> 
> > +{
> > +	uint32_t segment, entry, index = 0;
> > +	double val;
> > +	int i = 0;
> > +	gamma_lut_t *gamma = alloc_lut(info->entries_count);
> > +
> > +	igt_assert(gamma);
> > +
> > +	gamma->size = info->entries_count;
> > +	for (segment = 0; segment < info->segment_count; segment++) {
> > +		uint32_t entry_count = info->segment_data[segment].count;
> > +		uint32_t start = (segment == 0) ? 0 : (1 << (segment - 1));
> > +		uint32_t end = 1 << segment;
> > +
> > +		for (entry = 0; entry < entry_count; entry++) {
> > +			val = (index == 0) ? /* First entry is Zero. */
> > +				0 : start + entry *
> > +				((end - start) * 1.0 / entry_count);
> > +
> > +			set_rgb(&gamma->coeffs[i++], val);
> > +			index++;
> > +		}
> > +	}
> > +
> > +	return gamma;
> > +}
> > +
> >  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> >  				enum igt_atomic_plane_properties prop)
> >  {
> > @@ -331,6 +412,7 @@ segment_data_t *get_segment_data(data_t *data,
> >  	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info-
> >segment_count);
> >  	igt_assert(info->segment_data);
> >
> > +	info->entries_count = 0;
> 
> What's this?
> 
> >  	for (i = 0; i < info->segment_count; i++) {
> >  		info->entries_count += lut_range[i].count;
> >  		info->segment_data[i] = lut_range[i];
> > @@ -341,6 +423,51 @@ segment_data_t *get_segment_data(data_t *data,
> >  	return info;
> >  }
> >
> > +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type
> type)
> > +{
> > +	igt_display_t *display = &data->display;
> > +	gamma_lut_t *gamma_log;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	segment_data_t *segment_info = NULL;
> > +	struct drm_color_lut *lut = NULL;
> > +	int lut_size = 0;
> > +
> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
> 
> Is this how we are going to do cross-software DRM-master hand-over or
> switching compatibility in general?
> 
> Add a new client cap for every new KMS property, and if the KMS client
> does not set the property, the kernel will magically reset it to ensure
> the client's expectations are met? Is that how it works?
> 
> Or why does this exist?

Very good point. Need to explore on this.
I think the expectation is: Whoever sets this property should clear before
hand-over or switching the compatibility.

> 
> > +	gamma_mode = get_pipe_gamma_degamma_mode(pipe, IGT_CRTC_GAMMA_MODE);
> > +
> > +	for (int i = 0; i < gamma_mode->count_enums; i++) {
> > +		if (!strcmp(gamma_mode->enums[i].name, "logarithmic gamma")) {
> > +			segment_info = get_segment_data(data,
> > +							gamma_mode->enums[i].value,
> > +							gamma_mode->enums[i].name);
> > +			lut_size = sizeof(struct drm_color_lut) *
> > +					  segment_info->entries_count;
> > +			if (type == LINEAR_GAMMA) {
> > +				gamma_log = pipe_create_linear_lut(segment_info);
> > +				lut = coeffs_to_logarithmic_lut(data,
> > +								gamma_log,
> > +								data->color_depth,
> > +								0);
> > +			} else if (type == MAX_GAMMA) {
> > +				gamma_log = generate_table_max(segment_info-
> >entries_count);
> > +				gamma_log->size = segment_info->entries_count;
> > +				lut = coeffs_to_lut(data, gamma_log,
> > +						    data->color_depth, 0);
> > +			}
> > +			set_pipe_gamma(pipe, gamma_mode->enums[i].value,
> > +				       lut, lut_size);
> > +			igt_display_commit2(display, display->is_atomic
> > +					    ? COMMIT_ATOMIC : COMMIT_LEGACY);
> > +			break;
> > +		}
> > +	}
> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
> 
> I've never seen this done before. I did not know client caps could be
> reset.
> 
> > +	free(gamma_log);
> > +	free(lut);
> > +	clear_segment_data(segment_info);
> > +	drmModeFreeProperty(gamma_mode);
> > +}
> 
> 
> Thanks,
> pq
> 
> > +
> >  void set_plane_gamma(igt_plane_t *plane,
> >  		char *mode,
> >  		struct drm_color_lut_ext *lut,
> > diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> > index 5a35dcaac1..c863874f0c 100644
> > --- a/tests/kms_color_helper.h
> > +++ b/tests/kms_color_helper.h
> > @@ -70,6 +70,11 @@ typedef struct {
> >  	uint32_t entries_count;
> >  } segment_data_t;
> >
> > +enum gamma_type {
> > +	LINEAR_GAMMA,
> > +	MAX_GAMMA
> > +};
> > +
> >  #define MIN(a, b) ((a) < (b) ? (a) : (b))
> >
> >  void paint_gradient_rectangles(data_t *data,
> > @@ -89,6 +94,10 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
> >  				    const gamma_lut_t *gamma,
> >  				    uint32_t color_depth,
> >  				    int off);
> > +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> > +						const gamma_lut_t *gamma,
> > +						uint32_t color_depth,
> > +						int off);
> >  void set_degamma(data_t *data,
> >  		 igt_pipe_t *pipe,
> >  		 const gamma_lut_t *gamma);
> > @@ -98,12 +107,19 @@ void set_gamma(data_t *data,
> >  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
> >  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
> >
> > +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> > +					       enum igt_atomic_crtc_properties
> > +					       prop);
> >  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> >  	enum igt_atomic_plane_properties prop);
> >  void clear_segment_data(segment_data_t *info);
> > +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info);
> >  struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> >  struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> >  segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char
> *mode);
> > +void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
> > +		    struct drm_color_lut *lut, uint32_t size);
> > +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type
> type);
> >  void set_plane_gamma(igt_plane_t *plane,
> >  	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> >  void set_plane_degamma(igt_plane_t *plane,


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

* RE: [i-g-t 12/14] kms_color_helper: Add helper functions to support logarithmic gamma mode
  2021-11-26 16:55     ` [igt-dev] " Harry Wentland
@ 2022-01-03  4:08       ` Modem, Bhanuprakash
  -1 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:08 UTC (permalink / raw)
  To: Harry Wentland, igt-dev, dri-devel; +Cc: Shankar, Uma, Kumar, Mukunda Pramodh

> From: Harry Wentland <harry.wentland@amd.com>
> Sent: Friday, November 26, 2021 10:25 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Kumar, Mukunda Pramodh <mukunda.pramodh.kumar@intel.com>; Ville Syrjälä
> <ville.syrjala@linux.intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 12/14] kms_color_helper: Add helper functions to support
> logarithmic gamma mode
> 
> On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> > From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> >
> > Add helper functions to support logarithmic gamma mode
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color_helper.c | 127 +++++++++++++++++++++++++++++++++++++++
> >  tests/kms_color_helper.h |  16 +++++
> >  2 files changed, 143 insertions(+)
> >
> > diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> > index c65b7a0f50..7ea8282df3 100644
> > --- a/tests/kms_color_helper.c
> > +++ b/tests/kms_color_helper.c
> > @@ -190,6 +190,33 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
> >  	return lut;
> >  }
> >
> > +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> > +						const gamma_lut_t *gamma,
> > +						uint32_t color_depth,
> > +						int off)
> 
> How does this create a logarithmic LUT? It seems to do the same
> as coeffs_to_lut (which is also full of intellisms) except that
> it also scales the values by max_hw_value / max_segment_value for
> reasons that are not obvious to me.

Yes, this is just an another version of coeffs_to_lut, I'll float
a new rev with this change.

> 
> > +{
> > +	struct drm_color_lut *lut;
> > +	int i, lut_size = gamma->size;
> > +	/* This is the maximum value due to 16 bit precision in hardware. */
> > +	uint32_t max_hw_value = (1 << 16) - 1;
> > +	unsigned int max_segment_value = 1 << 24;
> > +
> 
> 
> This looks like it is specific to Intel HW. Intel-specific things should
> not live in kms_ tests.
> 
> Shouldn't these be encoded in the drm_color_lut_range definitions?
> 
> To be honest I am not clear why max_hw_value and max_segment_value
> differ here.

Yeah, the comment is misleading and variable names also bit confusing.

As uapi supports U0.16 precision the max supported value would be (1 << 16) - 1
and Intel h/w supports max value of (1 << 24) so we need to scale the values
accordingly.

So, need to drop h/w specific hardcoded stuff and read from uapi & rename the
variables as below:

max_uapi_value = (1 << 16) - 1;
max_hw_value = /* Read from the uapi. */

> 
> Harry
> 
> > +	lut = malloc(sizeof(struct drm_color_lut) * lut_size);
> > +
> > +	for (i = 0; i < lut_size; i++) {
> > +		double scaling_factor = (double)max_hw_value /
> (double)max_segment_value;
> > +		uint32_t r = MIN((gamma->coeffs[i].r * scaling_factor),
> max_hw_value);
> > +		uint32_t g = MIN((gamma->coeffs[i].g * scaling_factor),
> max_hw_value);
> > +		uint32_t b = MIN((gamma->coeffs[i].b * scaling_factor),
> max_hw_value);
> > +
> > +		lut[i].red = r;
> > +		lut[i].green = g;
> > +		lut[i].blue = b;
> > +	}
> > +
> > +	return lut;
> > +}
> > +
> >  void set_degamma(data_t *data,
> >  		 igt_pipe_t *pipe,
> >  		 const gamma_lut_t *gamma)
> > @@ -203,6 +230,15 @@ void set_degamma(data_t *data,
> >  	free(lut);
> >  }
> >
> > +void set_pipe_gamma(igt_pipe_t *pipe,
> > +		    uint64_t value,
> > +		    struct drm_color_lut *lut,
> > +		    uint32_t size)
> > +{
> > +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_MODE, value);
> > +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
> > +}
> > +
> >  void set_gamma(data_t *data,
> >  	       igt_pipe_t *pipe, const gamma_lut_t *gamma)
> >  {
> > @@ -241,6 +277,51 @@ void disable_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
> >  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
> >  }
> >
> > +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> > +					       enum igt_atomic_crtc_properties prop)
> > +{
> > +	igt_display_t *display = pipe->display;
> > +	uint32_t prop_id = pipe->props[prop];
> > +	drmModePropertyPtr drmProp;
> > +
> > +	igt_assert(prop_id);
> > +
> > +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> > +
> > +	igt_assert(drmProp);
> > +	igt_assert(drmProp->count_enums);
> > +
> > +	return drmProp;
> > +}
> > +
> > +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info)
> > +{
> > +	uint32_t segment, entry, index = 0;
> > +	double val;
> > +	int i = 0;
> > +	gamma_lut_t *gamma = alloc_lut(info->entries_count);
> > +
> > +	igt_assert(gamma);
> > +
> > +	gamma->size = info->entries_count;
> > +	for (segment = 0; segment < info->segment_count; segment++) {
> > +		uint32_t entry_count = info->segment_data[segment].count;
> > +		uint32_t start = (segment == 0) ? 0 : (1 << (segment - 1));
> > +		uint32_t end = 1 << segment;
> > +
> > +		for (entry = 0; entry < entry_count; entry++) {
> > +			val = (index == 0) ? /* First entry is Zero. */
> > +				0 : start + entry *
> > +				((end - start) * 1.0 / entry_count);
> > +
> > +			set_rgb(&gamma->coeffs[i++], val);
> > +			index++;
> > +		}
> > +	}
> > +
> > +	return gamma;
> > +}
> > +
> >  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> >  				enum igt_atomic_plane_properties prop)
> >  {
> > @@ -331,6 +412,7 @@ segment_data_t *get_segment_data(data_t *data,
> >  	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info-
> >segment_count);
> >  	igt_assert(info->segment_data);
> >
> > +	info->entries_count = 0;
> >  	for (i = 0; i < info->segment_count; i++) {
> >  		info->entries_count += lut_range[i].count;
> >  		info->segment_data[i] = lut_range[i];
> > @@ -341,6 +423,51 @@ segment_data_t *get_segment_data(data_t *data,
> >  	return info;
> >  }
> >
> > +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type
> type)
> > +{
> > +	igt_display_t *display = &data->display;
> > +	gamma_lut_t *gamma_log;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	segment_data_t *segment_info = NULL;
> > +	struct drm_color_lut *lut = NULL;
> > +	int lut_size = 0;
> > +
> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
> > +	gamma_mode = get_pipe_gamma_degamma_mode(pipe, IGT_CRTC_GAMMA_MODE);
> > +
> > +	for (int i = 0; i < gamma_mode->count_enums; i++) {
> > +		if (!strcmp(gamma_mode->enums[i].name, "logarithmic gamma")) {
> > +			segment_info = get_segment_data(data,
> > +							gamma_mode->enums[i].value,
> > +							gamma_mode->enums[i].name);
> > +			lut_size = sizeof(struct drm_color_lut) *
> > +					  segment_info->entries_count;
> > +			if (type == LINEAR_GAMMA) {
> > +				gamma_log = pipe_create_linear_lut(segment_info);
> > +				lut = coeffs_to_logarithmic_lut(data,
> > +								gamma_log,
> > +								data->color_depth,
> > +								0);
> > +			} else if (type == MAX_GAMMA) {
> > +				gamma_log = generate_table_max(segment_info-
> >entries_count);
> > +				gamma_log->size = segment_info->entries_count;
> > +				lut = coeffs_to_lut(data, gamma_log,
> > +						    data->color_depth, 0);
> > +			}
> > +			set_pipe_gamma(pipe, gamma_mode->enums[i].value,
> > +				       lut, lut_size);
> > +			igt_display_commit2(display, display->is_atomic
> > +					    ? COMMIT_ATOMIC : COMMIT_LEGACY);
> > +			break;
> > +		}
> > +	}
> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
> > +	free(gamma_log);
> > +	free(lut);
> > +	clear_segment_data(segment_info);
> > +	drmModeFreeProperty(gamma_mode);
> > +}
> > +
> >  void set_plane_gamma(igt_plane_t *plane,
> >  		char *mode,
> >  		struct drm_color_lut_ext *lut,
> > diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> > index 5a35dcaac1..c863874f0c 100644
> > --- a/tests/kms_color_helper.h
> > +++ b/tests/kms_color_helper.h
> > @@ -70,6 +70,11 @@ typedef struct {
> >  	uint32_t entries_count;
> >  } segment_data_t;
> >
> > +enum gamma_type {
> > +	LINEAR_GAMMA,
> > +	MAX_GAMMA
> > +};
> > +
> >  #define MIN(a, b) ((a) < (b) ? (a) : (b))
> >
> >  void paint_gradient_rectangles(data_t *data,
> > @@ -89,6 +94,10 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
> >  				    const gamma_lut_t *gamma,
> >  				    uint32_t color_depth,
> >  				    int off);
> > +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> > +						const gamma_lut_t *gamma,
> > +						uint32_t color_depth,
> > +						int off);
> >  void set_degamma(data_t *data,
> >  		 igt_pipe_t *pipe,
> >  		 const gamma_lut_t *gamma);
> > @@ -98,12 +107,19 @@ void set_gamma(data_t *data,
> >  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
> >  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
> >
> > +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> > +					       enum igt_atomic_crtc_properties
> > +					       prop);
> >  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> >  	enum igt_atomic_plane_properties prop);
> >  void clear_segment_data(segment_data_t *info);
> > +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info);
> >  struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> >  struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> >  segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char
> *mode);
> > +void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
> > +		    struct drm_color_lut *lut, uint32_t size);
> > +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type
> type);
> >  void set_plane_gamma(igt_plane_t *plane,
> >  	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> >  void set_plane_degamma(igt_plane_t *plane,
> >


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

* Re: [igt-dev] [i-g-t 12/14] kms_color_helper: Add helper functions to support logarithmic gamma mode
@ 2022-01-03  4:08       ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:08 UTC (permalink / raw)
  To: Harry Wentland, igt-dev, dri-devel; +Cc: ppaalanen, Kumar, Mukunda Pramodh

> From: Harry Wentland <harry.wentland@amd.com>
> Sent: Friday, November 26, 2021 10:25 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Kumar, Mukunda Pramodh <mukunda.pramodh.kumar@intel.com>; Ville Syrjälä
> <ville.syrjala@linux.intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 12/14] kms_color_helper: Add helper functions to support
> logarithmic gamma mode
> 
> On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> > From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> >
> > Add helper functions to support logarithmic gamma mode
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color_helper.c | 127 +++++++++++++++++++++++++++++++++++++++
> >  tests/kms_color_helper.h |  16 +++++
> >  2 files changed, 143 insertions(+)
> >
> > diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
> > index c65b7a0f50..7ea8282df3 100644
> > --- a/tests/kms_color_helper.c
> > +++ b/tests/kms_color_helper.c
> > @@ -190,6 +190,33 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
> >  	return lut;
> >  }
> >
> > +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> > +						const gamma_lut_t *gamma,
> > +						uint32_t color_depth,
> > +						int off)
> 
> How does this create a logarithmic LUT? It seems to do the same
> as coeffs_to_lut (which is also full of intellisms) except that
> it also scales the values by max_hw_value / max_segment_value for
> reasons that are not obvious to me.

Yes, this is just an another version of coeffs_to_lut, I'll float
a new rev with this change.

> 
> > +{
> > +	struct drm_color_lut *lut;
> > +	int i, lut_size = gamma->size;
> > +	/* This is the maximum value due to 16 bit precision in hardware. */
> > +	uint32_t max_hw_value = (1 << 16) - 1;
> > +	unsigned int max_segment_value = 1 << 24;
> > +
> 
> 
> This looks like it is specific to Intel HW. Intel-specific things should
> not live in kms_ tests.
> 
> Shouldn't these be encoded in the drm_color_lut_range definitions?
> 
> To be honest I am not clear why max_hw_value and max_segment_value
> differ here.

Yeah, the comment is misleading and variable names also bit confusing.

As uapi supports U0.16 precision the max supported value would be (1 << 16) - 1
and Intel h/w supports max value of (1 << 24) so we need to scale the values
accordingly.

So, need to drop h/w specific hardcoded stuff and read from uapi & rename the
variables as below:

max_uapi_value = (1 << 16) - 1;
max_hw_value = /* Read from the uapi. */

> 
> Harry
> 
> > +	lut = malloc(sizeof(struct drm_color_lut) * lut_size);
> > +
> > +	for (i = 0; i < lut_size; i++) {
> > +		double scaling_factor = (double)max_hw_value /
> (double)max_segment_value;
> > +		uint32_t r = MIN((gamma->coeffs[i].r * scaling_factor),
> max_hw_value);
> > +		uint32_t g = MIN((gamma->coeffs[i].g * scaling_factor),
> max_hw_value);
> > +		uint32_t b = MIN((gamma->coeffs[i].b * scaling_factor),
> max_hw_value);
> > +
> > +		lut[i].red = r;
> > +		lut[i].green = g;
> > +		lut[i].blue = b;
> > +	}
> > +
> > +	return lut;
> > +}
> > +
> >  void set_degamma(data_t *data,
> >  		 igt_pipe_t *pipe,
> >  		 const gamma_lut_t *gamma)
> > @@ -203,6 +230,15 @@ void set_degamma(data_t *data,
> >  	free(lut);
> >  }
> >
> > +void set_pipe_gamma(igt_pipe_t *pipe,
> > +		    uint64_t value,
> > +		    struct drm_color_lut *lut,
> > +		    uint32_t size)
> > +{
> > +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_MODE, value);
> > +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
> > +}
> > +
> >  void set_gamma(data_t *data,
> >  	       igt_pipe_t *pipe, const gamma_lut_t *gamma)
> >  {
> > @@ -241,6 +277,51 @@ void disable_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
> >  		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
> >  }
> >
> > +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> > +					       enum igt_atomic_crtc_properties prop)
> > +{
> > +	igt_display_t *display = pipe->display;
> > +	uint32_t prop_id = pipe->props[prop];
> > +	drmModePropertyPtr drmProp;
> > +
> > +	igt_assert(prop_id);
> > +
> > +	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
> > +
> > +	igt_assert(drmProp);
> > +	igt_assert(drmProp->count_enums);
> > +
> > +	return drmProp;
> > +}
> > +
> > +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info)
> > +{
> > +	uint32_t segment, entry, index = 0;
> > +	double val;
> > +	int i = 0;
> > +	gamma_lut_t *gamma = alloc_lut(info->entries_count);
> > +
> > +	igt_assert(gamma);
> > +
> > +	gamma->size = info->entries_count;
> > +	for (segment = 0; segment < info->segment_count; segment++) {
> > +		uint32_t entry_count = info->segment_data[segment].count;
> > +		uint32_t start = (segment == 0) ? 0 : (1 << (segment - 1));
> > +		uint32_t end = 1 << segment;
> > +
> > +		for (entry = 0; entry < entry_count; entry++) {
> > +			val = (index == 0) ? /* First entry is Zero. */
> > +				0 : start + entry *
> > +				((end - start) * 1.0 / entry_count);
> > +
> > +			set_rgb(&gamma->coeffs[i++], val);
> > +			index++;
> > +		}
> > +	}
> > +
> > +	return gamma;
> > +}
> > +
> >  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> >  				enum igt_atomic_plane_properties prop)
> >  {
> > @@ -331,6 +412,7 @@ segment_data_t *get_segment_data(data_t *data,
> >  	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info-
> >segment_count);
> >  	igt_assert(info->segment_data);
> >
> > +	info->entries_count = 0;
> >  	for (i = 0; i < info->segment_count; i++) {
> >  		info->entries_count += lut_range[i].count;
> >  		info->segment_data[i] = lut_range[i];
> > @@ -341,6 +423,51 @@ segment_data_t *get_segment_data(data_t *data,
> >  	return info;
> >  }
> >
> > +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type
> type)
> > +{
> > +	igt_display_t *display = &data->display;
> > +	gamma_lut_t *gamma_log;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	segment_data_t *segment_info = NULL;
> > +	struct drm_color_lut *lut = NULL;
> > +	int lut_size = 0;
> > +
> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
> > +	gamma_mode = get_pipe_gamma_degamma_mode(pipe, IGT_CRTC_GAMMA_MODE);
> > +
> > +	for (int i = 0; i < gamma_mode->count_enums; i++) {
> > +		if (!strcmp(gamma_mode->enums[i].name, "logarithmic gamma")) {
> > +			segment_info = get_segment_data(data,
> > +							gamma_mode->enums[i].value,
> > +							gamma_mode->enums[i].name);
> > +			lut_size = sizeof(struct drm_color_lut) *
> > +					  segment_info->entries_count;
> > +			if (type == LINEAR_GAMMA) {
> > +				gamma_log = pipe_create_linear_lut(segment_info);
> > +				lut = coeffs_to_logarithmic_lut(data,
> > +								gamma_log,
> > +								data->color_depth,
> > +								0);
> > +			} else if (type == MAX_GAMMA) {
> > +				gamma_log = generate_table_max(segment_info-
> >entries_count);
> > +				gamma_log->size = segment_info->entries_count;
> > +				lut = coeffs_to_lut(data, gamma_log,
> > +						    data->color_depth, 0);
> > +			}
> > +			set_pipe_gamma(pipe, gamma_mode->enums[i].value,
> > +				       lut, lut_size);
> > +			igt_display_commit2(display, display->is_atomic
> > +					    ? COMMIT_ATOMIC : COMMIT_LEGACY);
> > +			break;
> > +		}
> > +	}
> > +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
> > +	free(gamma_log);
> > +	free(lut);
> > +	clear_segment_data(segment_info);
> > +	drmModeFreeProperty(gamma_mode);
> > +}
> > +
> >  void set_plane_gamma(igt_plane_t *plane,
> >  		char *mode,
> >  		struct drm_color_lut_ext *lut,
> > diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
> > index 5a35dcaac1..c863874f0c 100644
> > --- a/tests/kms_color_helper.h
> > +++ b/tests/kms_color_helper.h
> > @@ -70,6 +70,11 @@ typedef struct {
> >  	uint32_t entries_count;
> >  } segment_data_t;
> >
> > +enum gamma_type {
> > +	LINEAR_GAMMA,
> > +	MAX_GAMMA
> > +};
> > +
> >  #define MIN(a, b) ((a) < (b) ? (a) : (b))
> >
> >  void paint_gradient_rectangles(data_t *data,
> > @@ -89,6 +94,10 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
> >  				    const gamma_lut_t *gamma,
> >  				    uint32_t color_depth,
> >  				    int off);
> > +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> > +						const gamma_lut_t *gamma,
> > +						uint32_t color_depth,
> > +						int off);
> >  void set_degamma(data_t *data,
> >  		 igt_pipe_t *pipe,
> >  		 const gamma_lut_t *gamma);
> > @@ -98,12 +107,19 @@ void set_gamma(data_t *data,
> >  void set_ctm(igt_pipe_t *pipe, const double *coefficients);
> >  void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
> >
> > +drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
> > +					       enum igt_atomic_crtc_properties
> > +					       prop);
> >  drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
> >  	enum igt_atomic_plane_properties prop);
> >  void clear_segment_data(segment_data_t *info);
> > +gamma_lut_t *pipe_create_linear_lut(segment_data_t *info);
> >  struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
> >  struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
> >  segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char
> *mode);
> > +void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
> > +		    struct drm_color_lut *lut, uint32_t size);
> > +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type
> type);
> >  void set_plane_gamma(igt_plane_t *plane,
> >  	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
> >  void set_plane_degamma(igt_plane_t *plane,
> >


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

* RE: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
  2021-11-18  9:02     ` [igt-dev] " Pekka Paalanen
@ 2022-01-03  4:09       ` Modem, Bhanuprakash
  -1 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:09 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: igt-dev, Shankar, Uma, dri-devel

> From: Pekka Paalanen <ppaalanen@gmail.com>
> Sent: Thursday, November 18, 2021 2:33 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>
> Cc: igt-dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org; Juha-Pekka
> Heikkila <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
> 
> On Mon, 15 Nov 2021 15:17:49 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
> > To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> > with a maxed out gamma LUT and verify we have the same CRC as drawing solid
> > color rectangles.
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 178 insertions(+), 1 deletion(-)
> >
> > diff --git a/tests/kms_color.c b/tests/kms_color.c
> > index 775f35964f..b45d66762f 100644
> > --- a/tests/kms_color.c
> > +++ b/tests/kms_color.c
> > @@ -24,7 +24,34 @@
> >
> >  #include "kms_color_helper.h"
> >
> > -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
> > +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
> > +
> > +#define MAX_SUPPORTED_PLANES 7
> > +#define SDR_PLANE_BASE 3
> > +
> > +typedef bool (*test_t)(data_t*, igt_plane_t*);
> > +
> > +static bool is_hdr_plane(const igt_plane_t *plane)
> > +{
> > +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> 
> How can this be right for all KMS drivers?
> 
> What is a HDR plane?
> 
> > +}
> > +
> > +static bool is_valid_plane(igt_plane_t *plane)
> > +{
> > +	int index = plane->index;
> > +
> > +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> > +		return false;
> > +
> > +	/*
> > +	 * Test 1 HDR plane, 1 SDR plane.
> > +	 *
> > +	 * 0,1,2 HDR planes
> > +	 * 3,4,5,6 SDR planes
> 
> As above, where does this come from? Is this your hardware?

It is specific to Intel hardware, I'll make this generic in next rev.

Extended mode:
By default to optimize the CI, we can run these tests on first & last
planes only, If we want to cover all the planes, we need to pass an
argument in commandline

Example:
./kms_color --run-subtest pipe-A-plane-gamma
./kms_color --extend --run-subtest pipe-A-plane-gamma

> 
> > +	 *
> > +	 */
> > +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> > +}
> >
> >  static void test_pipe_degamma(data_t *data,
> >  			      igt_plane_t *primary)
> > @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t *data,
> >  }
> >  #endif
> >
> > +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> > +{
> > +	igt_output_t *output;
> > +	igt_display_t *display = &data->display;
> > +	drmModeModeInfo *mode;
> > +	struct igt_fb fb;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	uint32_t i;
> > +	bool ret = true;
> > +	igt_pipe_crc_t *pipe_crc = NULL;
> > +	color_t red_green_blue[] = {
> > +		{ 1.0, 0.0, 0.0 },
> > +		{ 0.0, 1.0, 0.0 },
> > +		{ 0.0, 0.0, 1.0 }
> > +	};
> > +
> > +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
> > +			kmstest_pipe_name(plane->pipe->pipe),
> > +			kmstest_plane_type_name(plane->type),
> > +			is_hdr_plane(plane) ? "hdr":"sdr");
> > +
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> > +
> > +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
> > +				  plane->pipe->pipe,
> > +				  INTEL_PIPE_CRC_SOURCE_AUTO);
> > +
> > +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
> > +	igt_assert(output);
> > +
> > +	igt_output_set_pipe(output, plane->pipe->pipe);
> > +	mode = igt_output_get_mode(output);
> > +
> > +	/* Create a framebuffer at the size of the output. */
> > +	igt_assert(igt_create_fb(data->drm_fd,
> > +			      mode->hdisplay,
> > +			      mode->vdisplay,
> > +			      DRM_FORMAT_XRGB8888,
> > +			      DRM_FORMAT_MOD_LINEAR,
> > +			      &fb));
> > +	igt_plane_set_fb(plane, &fb);
> > +
> > +	/* Disable Pipe color props. */
> > +	disable_ctm(plane->pipe);
> > +	disable_degamma(plane->pipe);
> > +	disable_gamma(plane->pipe);
> > +
> > +	disable_plane_ctm(plane);
> > +	disable_plane_degamma(plane);
> > +	igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +
> > +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> > +
> > +	/* Iterate all supported gamma modes. */
> > +	for (i = 0; i < gamma_mode->count_enums; i++) {
> > +		igt_crc_t crc_gamma, crc_fullcolors;
> > +		segment_data_t *segment_info = NULL;
> > +		struct drm_color_lut_ext *lut = NULL;
> > +		uint32_t lut_size = 0;
> > +
> > +		/* Ignore 'no gamma' from enum list. */
> > +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> > +			continue;
> > +
> > +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode-
> >enums[i].name);
> > +
> > +		/* Draw solid colors with no gamma transformation. */
> > +		disable_plane_gamma(plane);
> > +		paint_rectangles(data, mode, red_green_blue, &fb);
> > +		igt_plane_set_fb(plane, &fb);
> > +		igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +		igt_wait_for_vblank(data->drm_fd,
> > +			display->pipes[plane->pipe->pipe].crtc_offset);
> > +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
> > +
> > +		/* Draw gradient colors with gamma LUT to remap all
> > +		 * values to max red/green/blue.
> > +		 */
> > +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> > +				gamma_mode->enums[i].name);
> > +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
> >entries_count;
> > +		lut = create_max_lut(segment_info);
> 
> Using max LUT seems like a weak test. I recall seeing problem reports
> related to alpha blending where trying to display an alpha gradient
> essentially resulted in what max LUT would produce.

Due to the hardware roundups, we are getting crc mismatches for any LUTs.
So, by default we can compare
"gradient colors + max LUT" and "solid colors + No/unity LUT"

In extend mode (Please check above comments)
Other h/w vendors can extend the support for different LUTs

- Bhanu
 
> 
> 
> Thanks,
> pq
> 
> > +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
> > +
> > +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
> > +		igt_plane_set_fb(plane, &fb);
> > +		igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +		igt_wait_for_vblank(data->drm_fd,
> > +			display->pipes[plane->pipe->pipe].crtc_offset);
> > +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
> > +
> > +		/* Verify that the CRC of the software computed output is
> > +		 * equal to the CRC of the gamma LUT transformation output.
> > +		 */
> > +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
> > +
> > +		free(lut);
> > +		clear_segment_data(segment_info);
> > +	}
> > +
> > +	disable_plane_gamma(plane);
> > +	igt_plane_set_fb(plane, NULL);
> > +	igt_output_set_pipe(output, PIPE_NONE);
> > +	igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +
> > +	igt_pipe_crc_free(pipe_crc);
> > +	drmModeFreeProperty(gamma_mode);
> > +
> > +	return ret;
> > +}
> > +
> >  static void
> >  prep_pipe(data_t *data, enum pipe p)
> >  {
> > @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
> >  		invalid_ctm_matrix_sizes(data, p);
> >  }
> >
> > +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
> > +{
> > +	igt_plane_t *plane;
> > +	int count = 0;
> > +
> > +	for_each_plane_on_pipe(&data->display, pipe, plane) {
> > +		if (!is_valid_plane(plane))
> > +			continue;
> > +
> > +		igt_assert(test(data, plane));
> > +
> > +		count++;
> > +	}
> > +
> > +	igt_require_f(count, "No valid planes found.\n");
> > +}
> > +
> > +static void run_tests_for_plane(data_t *data, enum pipe pipe)
> > +{
> > +	igt_fixture {
> > +		igt_require_pipe(&data->display, pipe);
> > +		igt_require_pipe_crc(data->drm_fd);
> > +		igt_require(data->display.pipes[pipe].n_planes > 0);
> > +		igt_display_require_output_on_pipe(&data->display, pipe);
> > +	}
> > +
> > +	igt_describe("Compare maxed out plane gamma LUT and solid color linear
> LUT");
> > +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
> > +		run_plane_color_test(data, pipe, plane_gamma_test);
> > +}
> > +
> >  igt_main
> >  {
> >  	data_t data = {};
> > @@ -910,6 +1084,9 @@ igt_main
> >
> >  		igt_subtest_group
> >  			run_invalid_tests_for_pipe(&data, pipe);
> > +
> > +		igt_subtest_group
> > +			run_tests_for_plane(&data, pipe);
> >  	}
> >
> >  	igt_fixture {


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

* Re: [igt-dev] [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
@ 2022-01-03  4:09       ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:09 UTC (permalink / raw)
  To: Pekka Paalanen; +Cc: igt-dev, dri-devel

> From: Pekka Paalanen <ppaalanen@gmail.com>
> Sent: Thursday, November 18, 2021 2:33 PM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>
> Cc: igt-dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org; Juha-Pekka
> Heikkila <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
> 
> On Mon, 15 Nov 2021 15:17:49 +0530
> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> 
> > To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> > with a maxed out gamma LUT and verify we have the same CRC as drawing solid
> > color rectangles.
> >
> > Cc: Harry Wentland <harry.wentland@amd.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> > ---
> >  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 178 insertions(+), 1 deletion(-)
> >
> > diff --git a/tests/kms_color.c b/tests/kms_color.c
> > index 775f35964f..b45d66762f 100644
> > --- a/tests/kms_color.c
> > +++ b/tests/kms_color.c
> > @@ -24,7 +24,34 @@
> >
> >  #include "kms_color_helper.h"
> >
> > -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
> > +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
> > +
> > +#define MAX_SUPPORTED_PLANES 7
> > +#define SDR_PLANE_BASE 3
> > +
> > +typedef bool (*test_t)(data_t*, igt_plane_t*);
> > +
> > +static bool is_hdr_plane(const igt_plane_t *plane)
> > +{
> > +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> 
> How can this be right for all KMS drivers?
> 
> What is a HDR plane?
> 
> > +}
> > +
> > +static bool is_valid_plane(igt_plane_t *plane)
> > +{
> > +	int index = plane->index;
> > +
> > +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> > +		return false;
> > +
> > +	/*
> > +	 * Test 1 HDR plane, 1 SDR plane.
> > +	 *
> > +	 * 0,1,2 HDR planes
> > +	 * 3,4,5,6 SDR planes
> 
> As above, where does this come from? Is this your hardware?

It is specific to Intel hardware, I'll make this generic in next rev.

Extended mode:
By default to optimize the CI, we can run these tests on first & last
planes only, If we want to cover all the planes, we need to pass an
argument in commandline

Example:
./kms_color --run-subtest pipe-A-plane-gamma
./kms_color --extend --run-subtest pipe-A-plane-gamma

> 
> > +	 *
> > +	 */
> > +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> > +}
> >
> >  static void test_pipe_degamma(data_t *data,
> >  			      igt_plane_t *primary)
> > @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t *data,
> >  }
> >  #endif
> >
> > +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> > +{
> > +	igt_output_t *output;
> > +	igt_display_t *display = &data->display;
> > +	drmModeModeInfo *mode;
> > +	struct igt_fb fb;
> > +	drmModePropertyPtr gamma_mode = NULL;
> > +	uint32_t i;
> > +	bool ret = true;
> > +	igt_pipe_crc_t *pipe_crc = NULL;
> > +	color_t red_green_blue[] = {
> > +		{ 1.0, 0.0, 0.0 },
> > +		{ 0.0, 1.0, 0.0 },
> > +		{ 0.0, 0.0, 1.0 }
> > +	};
> > +
> > +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
> > +			kmstest_pipe_name(plane->pipe->pipe),
> > +			kmstest_plane_type_name(plane->type),
> > +			is_hdr_plane(plane) ? "hdr":"sdr");
> > +
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> > +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> > +
> > +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
> > +				  plane->pipe->pipe,
> > +				  INTEL_PIPE_CRC_SOURCE_AUTO);
> > +
> > +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
> > +	igt_assert(output);
> > +
> > +	igt_output_set_pipe(output, plane->pipe->pipe);
> > +	mode = igt_output_get_mode(output);
> > +
> > +	/* Create a framebuffer at the size of the output. */
> > +	igt_assert(igt_create_fb(data->drm_fd,
> > +			      mode->hdisplay,
> > +			      mode->vdisplay,
> > +			      DRM_FORMAT_XRGB8888,
> > +			      DRM_FORMAT_MOD_LINEAR,
> > +			      &fb));
> > +	igt_plane_set_fb(plane, &fb);
> > +
> > +	/* Disable Pipe color props. */
> > +	disable_ctm(plane->pipe);
> > +	disable_degamma(plane->pipe);
> > +	disable_gamma(plane->pipe);
> > +
> > +	disable_plane_ctm(plane);
> > +	disable_plane_degamma(plane);
> > +	igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +
> > +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> > +
> > +	/* Iterate all supported gamma modes. */
> > +	for (i = 0; i < gamma_mode->count_enums; i++) {
> > +		igt_crc_t crc_gamma, crc_fullcolors;
> > +		segment_data_t *segment_info = NULL;
> > +		struct drm_color_lut_ext *lut = NULL;
> > +		uint32_t lut_size = 0;
> > +
> > +		/* Ignore 'no gamma' from enum list. */
> > +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> > +			continue;
> > +
> > +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode-
> >enums[i].name);
> > +
> > +		/* Draw solid colors with no gamma transformation. */
> > +		disable_plane_gamma(plane);
> > +		paint_rectangles(data, mode, red_green_blue, &fb);
> > +		igt_plane_set_fb(plane, &fb);
> > +		igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +		igt_wait_for_vblank(data->drm_fd,
> > +			display->pipes[plane->pipe->pipe].crtc_offset);
> > +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
> > +
> > +		/* Draw gradient colors with gamma LUT to remap all
> > +		 * values to max red/green/blue.
> > +		 */
> > +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> > +				gamma_mode->enums[i].name);
> > +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
> >entries_count;
> > +		lut = create_max_lut(segment_info);
> 
> Using max LUT seems like a weak test. I recall seeing problem reports
> related to alpha blending where trying to display an alpha gradient
> essentially resulted in what max LUT would produce.

Due to the hardware roundups, we are getting crc mismatches for any LUTs.
So, by default we can compare
"gradient colors + max LUT" and "solid colors + No/unity LUT"

In extend mode (Please check above comments)
Other h/w vendors can extend the support for different LUTs

- Bhanu
 
> 
> 
> Thanks,
> pq
> 
> > +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
> > +
> > +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
> > +		igt_plane_set_fb(plane, &fb);
> > +		igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +		igt_wait_for_vblank(data->drm_fd,
> > +			display->pipes[plane->pipe->pipe].crtc_offset);
> > +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
> > +
> > +		/* Verify that the CRC of the software computed output is
> > +		 * equal to the CRC of the gamma LUT transformation output.
> > +		 */
> > +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
> > +
> > +		free(lut);
> > +		clear_segment_data(segment_info);
> > +	}
> > +
> > +	disable_plane_gamma(plane);
> > +	igt_plane_set_fb(plane, NULL);
> > +	igt_output_set_pipe(output, PIPE_NONE);
> > +	igt_display_commit2(display, display->is_atomic ?
> > +					COMMIT_ATOMIC : COMMIT_LEGACY);
> > +
> > +	igt_pipe_crc_free(pipe_crc);
> > +	drmModeFreeProperty(gamma_mode);
> > +
> > +	return ret;
> > +}
> > +
> >  static void
> >  prep_pipe(data_t *data, enum pipe p)
> >  {
> > @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
> >  		invalid_ctm_matrix_sizes(data, p);
> >  }
> >
> > +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
> > +{
> > +	igt_plane_t *plane;
> > +	int count = 0;
> > +
> > +	for_each_plane_on_pipe(&data->display, pipe, plane) {
> > +		if (!is_valid_plane(plane))
> > +			continue;
> > +
> > +		igt_assert(test(data, plane));
> > +
> > +		count++;
> > +	}
> > +
> > +	igt_require_f(count, "No valid planes found.\n");
> > +}
> > +
> > +static void run_tests_for_plane(data_t *data, enum pipe pipe)
> > +{
> > +	igt_fixture {
> > +		igt_require_pipe(&data->display, pipe);
> > +		igt_require_pipe_crc(data->drm_fd);
> > +		igt_require(data->display.pipes[pipe].n_planes > 0);
> > +		igt_display_require_output_on_pipe(&data->display, pipe);
> > +	}
> > +
> > +	igt_describe("Compare maxed out plane gamma LUT and solid color linear
> LUT");
> > +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
> > +		run_plane_color_test(data, pipe, plane_gamma_test);
> > +}
> > +
> >  igt_main
> >  {
> >  	data_t data = {};
> > @@ -910,6 +1084,9 @@ igt_main
> >
> >  		igt_subtest_group
> >  			run_invalid_tests_for_pipe(&data, pipe);
> > +
> > +		igt_subtest_group
> > +			run_tests_for_plane(&data, pipe);
> >  	}
> >
> >  	igt_fixture {


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

* RE: [i-g-t 00/14] Add IGT support for plane color management
  2021-11-29 15:20       ` Harry Wentland
@ 2022-01-03  4:11           ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:11 UTC (permalink / raw)
  To: Harry Wentland, Pekka Paalanen
  Cc: igt-dev, Shankar, Uma, Kumar,  Mukunda Pramodh, dri-devel

> From: Harry Wentland <harry.wentland@amd.com>
> Sent: Monday, November 29, 2021 8:50 PM
> To: Pekka Paalanen <ppaalanen@gmail.com>
> Cc: dri-devel@lists.freedesktop.org; Modem, Bhanuprakash
> <bhanuprakash.modem@intel.com>; igt-dev@lists.freedesktop.org; Kumar,
> Mukunda Pramodh <mukunda.pramodh.kumar@intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 00/14] Add IGT support for plane color management
> 
> On 2021-11-29 04:20, Pekka Paalanen wrote:
> > On Fri, 26 Nov 2021 11:54:55 -0500
> > Harry Wentland <harry.wentland@amd.com> wrote:
> >
> >> On 2021-11-18 04:50, Pekka Paalanen wrote:
> >>> On Mon, 15 Nov 2021 15:17:45 +0530
> >>> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> >>>
> >>>> From the Plane Color Management feature design, userspace can
> >>>> take the smart blending decisions based on hardware supported
> >>>> plane color features to obtain an accurate color profile.
> >>>>
> >>>> These IGT patches extend the existing pipe color management
> >>>> tests to the plane level.
> >>>>
> >>>> Kernel implementation:
> >>>> https://patchwork.freedesktop.org/series/90825/
> >
> > ...
> >
> >>> I also found some things that looked hardware-specific in this code
> >>> that to my understanding is supposed to be generic, and some concerns
> >>> about UAPI as well.
> >>>
> >>
> >> I left some comments on intellisms in these patches.
> >>
> >> Do you have any specifics about your concerns about UAPI?
> >
> > Yeah, the comments I left in the patches:
> >
> > patch 3:
> >
> >> Having to explicitly special-case index zero feels odd to me. Why does
> >> it need explicit special-casing?
> >>
> >> To me it's a hint that the definitions of .start and .end are somehow
> >> inconsistent.
> >
> > patch 4 and 8:
> >
> >>> +static bool is_hdr_plane(const igt_plane_t *plane)
> >>> +{
> >>> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> >>
> >> How can this be right for all KMS drivers?
> >>
> >> What is a HDR plane?
> >
> > patch 12:
> >
> >>> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> >>> +						const gamma_lut_t *gamma,
> >>> +						uint32_t color_depth,
> >>> +						int off)
> >>> +{
> >>> +	struct drm_color_lut *lut;
> >>> +	int i, lut_size = gamma->size;
> >>> +	/* This is the maximum value due to 16 bit precision in hardware. */
> >>
> >> In whose hardware?
> >>
> >> Are igt tests not supposed to be generic for everything that exposes
> >> the particular KMS properties?
> >>
> >> This also hints that the UAPI design is lacking, because userspace
> >> needs to know hardware specific things out of thin air. Display servers
> >> are not going to have hardware-specific code. They specialise based on
> >> the existence of KMS properties instead.
> >
> > ...
> >
> >>> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type
> type)
> >>> +{
> >>> +	igt_display_t *display = &data->display;
> >>> +	gamma_lut_t *gamma_log;
> >>> +	drmModePropertyPtr gamma_mode = NULL;
> >>> +	segment_data_t *segment_info = NULL;
> >>> +	struct drm_color_lut *lut = NULL;
> >>> +	int lut_size = 0;
> >>> +
> >>> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
> >>
> >> Is this how we are going to do cross-software DRM-master hand-over or
> >> switching compatibility in general?
> >>
> >> Add a new client cap for every new KMS property, and if the KMS client
> >> does not set the property, the kernel will magically reset it to ensure
> >> the client's expectations are met? Is that how it works?
> >>
> >> Or why does this exist?
> >
> > ...
> >
> >>> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
> >>
> >> I've never seen this done before. I did not know client caps could be
> >> reset.
> >
> >
> > So, patch 12 has the biggest UAPI questions, and patch 3 may need a
> > UAPI change as well. The comments in patches 4 and 8 could be addressed
> > with just removing that code since the concept of HDR/SDR planes does
> > not exist in UAPI. Or, if that concept is needed then it's another UAPI
> > problem.
> >
> 
> Thanks for reiterating your points. I missed your earlier replies and
> found them in my IGT folder just now.
> 
> Looks like we're on the same page.

Thanks Pekka & Harry for the review. Apologies for late response. I thought
that everyone is in holidays 😊. Now I am re-igniting this discussion.

I have gone through all review comments and it's make sense to remove hardware
specific stuff from the helper functions.

Patch 3:
Intel hardware is expecting first LUT value as 0, still we can remove this logic
from helper & handle in the subtest.

Patch 4 & 8:
In this context, for you HDR & SDR plane stuff is just a matter of plane index.
We are expecting to run tests on one HDR plane (index 0-3) & one SDR plane
(index 3-6). I think we can update the logic to run tests on first & last plane.
If you want to run on tests on all planes we need to pass an extra argument through
command line. Please refer tests/kms_flip.c for similar implementation.

Patch 12:
It seems there is some confusion with the IGT comments & variable names, I'll
refactor the logic & upload a new rev.

- Bhanu

> 
> Harry
> 
> >
> > Thanks,
> > pq
> >


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

* Re: [igt-dev] [i-g-t 00/14] Add IGT support for plane color management
@ 2022-01-03  4:11           ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-03  4:11 UTC (permalink / raw)
  To: Harry Wentland, Pekka Paalanen; +Cc: igt-dev, Kumar, Mukunda Pramodh, dri-devel

> From: Harry Wentland <harry.wentland@amd.com>
> Sent: Monday, November 29, 2021 8:50 PM
> To: Pekka Paalanen <ppaalanen@gmail.com>
> Cc: dri-devel@lists.freedesktop.org; Modem, Bhanuprakash
> <bhanuprakash.modem@intel.com>; igt-dev@lists.freedesktop.org; Kumar,
> Mukunda Pramodh <mukunda.pramodh.kumar@intel.com>; Juha-Pekka Heikkila
> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> Subject: Re: [i-g-t 00/14] Add IGT support for plane color management
> 
> On 2021-11-29 04:20, Pekka Paalanen wrote:
> > On Fri, 26 Nov 2021 11:54:55 -0500
> > Harry Wentland <harry.wentland@amd.com> wrote:
> >
> >> On 2021-11-18 04:50, Pekka Paalanen wrote:
> >>> On Mon, 15 Nov 2021 15:17:45 +0530
> >>> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
> >>>
> >>>> From the Plane Color Management feature design, userspace can
> >>>> take the smart blending decisions based on hardware supported
> >>>> plane color features to obtain an accurate color profile.
> >>>>
> >>>> These IGT patches extend the existing pipe color management
> >>>> tests to the plane level.
> >>>>
> >>>> Kernel implementation:
> >>>> https://patchwork.freedesktop.org/series/90825/
> >
> > ...
> >
> >>> I also found some things that looked hardware-specific in this code
> >>> that to my understanding is supposed to be generic, and some concerns
> >>> about UAPI as well.
> >>>
> >>
> >> I left some comments on intellisms in these patches.
> >>
> >> Do you have any specifics about your concerns about UAPI?
> >
> > Yeah, the comments I left in the patches:
> >
> > patch 3:
> >
> >> Having to explicitly special-case index zero feels odd to me. Why does
> >> it need explicit special-casing?
> >>
> >> To me it's a hint that the definitions of .start and .end are somehow
> >> inconsistent.
> >
> > patch 4 and 8:
> >
> >>> +static bool is_hdr_plane(const igt_plane_t *plane)
> >>> +{
> >>> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> >>
> >> How can this be right for all KMS drivers?
> >>
> >> What is a HDR plane?
> >
> > patch 12:
> >
> >>> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
> >>> +						const gamma_lut_t *gamma,
> >>> +						uint32_t color_depth,
> >>> +						int off)
> >>> +{
> >>> +	struct drm_color_lut *lut;
> >>> +	int i, lut_size = gamma->size;
> >>> +	/* This is the maximum value due to 16 bit precision in hardware. */
> >>
> >> In whose hardware?
> >>
> >> Are igt tests not supposed to be generic for everything that exposes
> >> the particular KMS properties?
> >>
> >> This also hints that the UAPI design is lacking, because userspace
> >> needs to know hardware specific things out of thin air. Display servers
> >> are not going to have hardware-specific code. They specialise based on
> >> the existence of KMS properties instead.
> >
> > ...
> >
> >>> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type
> type)
> >>> +{
> >>> +	igt_display_t *display = &data->display;
> >>> +	gamma_lut_t *gamma_log;
> >>> +	drmModePropertyPtr gamma_mode = NULL;
> >>> +	segment_data_t *segment_info = NULL;
> >>> +	struct drm_color_lut *lut = NULL;
> >>> +	int lut_size = 0;
> >>> +
> >>> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
> >>
> >> Is this how we are going to do cross-software DRM-master hand-over or
> >> switching compatibility in general?
> >>
> >> Add a new client cap for every new KMS property, and if the KMS client
> >> does not set the property, the kernel will magically reset it to ensure
> >> the client's expectations are met? Is that how it works?
> >>
> >> Or why does this exist?
> >
> > ...
> >
> >>> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
> >>
> >> I've never seen this done before. I did not know client caps could be
> >> reset.
> >
> >
> > So, patch 12 has the biggest UAPI questions, and patch 3 may need a
> > UAPI change as well. The comments in patches 4 and 8 could be addressed
> > with just removing that code since the concept of HDR/SDR planes does
> > not exist in UAPI. Or, if that concept is needed then it's another UAPI
> > problem.
> >
> 
> Thanks for reiterating your points. I missed your earlier replies and
> found them in my IGT folder just now.
> 
> Looks like we're on the same page.

Thanks Pekka & Harry for the review. Apologies for late response. I thought
that everyone is in holidays 😊. Now I am re-igniting this discussion.

I have gone through all review comments and it's make sense to remove hardware
specific stuff from the helper functions.

Patch 3:
Intel hardware is expecting first LUT value as 0, still we can remove this logic
from helper & handle in the subtest.

Patch 4 & 8:
In this context, for you HDR & SDR plane stuff is just a matter of plane index.
We are expecting to run tests on one HDR plane (index 0-3) & one SDR plane
(index 3-6). I think we can update the logic to run tests on first & last plane.
If you want to run on tests on all planes we need to pass an extra argument through
command line. Please refer tests/kms_flip.c for similar implementation.

Patch 12:
It seems there is some confusion with the IGT comments & variable names, I'll
refactor the logic & upload a new rev.

- Bhanu

> 
> Harry
> 
> >
> > Thanks,
> > pq
> >


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

* [igt-dev] [v2 i-g-t 00/15] Add IGT support for plane color management
  2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
                   ` (17 preceding siblings ...)
  (?)
@ 2022-01-04  7:57 ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 01/15] HAX: Get uapi headers to compile the IGT Bhanuprakash Modem
                     ` (14 more replies)
  -1 siblings, 15 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev

From the Plane Color Management feature design, userspace can
take the smart blending decisions based on hardware supported
plane color features to obtain an accurate color profile.

These IGT patches extend the existing pipe color management
tests to the plane level.

Kernel implementation:
https://patchwork.freedesktop.org/series/90825/

Bhanuprakash Modem (12):
  HAX: Get uapi headers to compile the IGT
  lib/igt_kms: Add plane color mgmt properties
  kms_color_helper: Add helper functions for plane color mgmt
  tests/kms_color: New subtests for Plane gamma
  tests/kms_color: New subtests for Plane degamma
  tests/kms_color: New subtests for Plane CTM
  tests/kms_color: New negative tests for plane level color mgmt
  tests/kms_color_chamelium: New subtests for Plane gamma
  tests/kms_color_chamelium: New subtests for Plane degamma
  tests/kms_color_chamelium: New subtests for Plane CTM
  tests/kms_color_chamelium: Extended IGT tests to support logarithmic
    gamma mode
  HAX: Add color mgmt tests to BAT

Mukunda Pramodh Kumar (3):
  lib/igt_kms: Add pipe color mgmt properties
  kms_color_helper: Add helper functions to support logarithmic gamma
    mode
  tests/kms_color: Extended IGT tests to support logarithmic gamma mode

 include/drm-uapi/drm.h                |  10 +
 include/drm-uapi/drm_mode.h           |  28 ++
 lib/igt_kms.c                         |   6 +
 lib/igt_kms.h                         |   6 +
 tests/intel-ci/fast-feedback.testlist | 112 +++++
 tests/kms_color.c                     | 663 +++++++++++++++++++++++++-
 tests/kms_color_chamelium.c           | 583 +++++++++++++++++++++-
 tests/kms_color_helper.c              | 301 +++++++++++-
 tests/kms_color_helper.h              |  44 ++
 9 files changed, 1736 insertions(+), 17 deletions(-)

--
2.32.0

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

* [igt-dev] [v2 i-g-t 01/15] HAX: Get uapi headers to compile the IGT
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 02/15] lib/igt_kms: Add plane color mgmt properties Bhanuprakash Modem
                     ` (13 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev

Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 include/drm-uapi/drm.h      | 10 ++++++++++
 include/drm-uapi/drm_mode.h | 28 ++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/include/drm-uapi/drm.h b/include/drm-uapi/drm.h
index 5e54c3aa4c..9ca3dbe8e5 100644
--- a/include/drm-uapi/drm.h
+++ b/include/drm-uapi/drm.h
@@ -830,6 +830,16 @@ struct drm_get_cap {
  */
 #define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS	5
 
+/**
+ * DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES
+ *
+ * Add support for advance gamma mode UAPI
+ * If set to 1, DRM will enable advance gamma mode
+ * UAPI to process the gamma mode based on extended
+ * range and segments.
+ */
+#define DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES     6
+
 /* DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
 struct drm_set_client_cap {
 	__u64 capability;
diff --git a/include/drm-uapi/drm_mode.h b/include/drm-uapi/drm_mode.h
index e4a2570a60..97198609a5 100644
--- a/include/drm-uapi/drm_mode.h
+++ b/include/drm-uapi/drm_mode.h
@@ -817,6 +817,34 @@ struct drm_color_lut {
 	__u16 reserved;
 };
 
+/*
+ * Creating 64 bit palette entries for better data
+ * precision. This will be required for HDR and
+ * similar color processing usecases.
+ */
+struct drm_color_lut_ext {
+    /*
+     * Data is U32.32 fixed point format.
+     */
+    __u64 red;
+    __u64 green;
+    __u64 blue;
+    __u64 reserved;
+};
+
+struct drm_color_lut_range {
+    /* DRM_MODE_LUT_* */
+    __u32 flags;
+    /* number of points on the curve */
+    __u16 count;
+    /* input/output bits per component */
+    __u8 input_bpc, output_bpc;
+    /* input start/end values */
+    __s32 start, end;
+    /* output min/max values */
+    __s32 min, max;
+};
+
 /**
  * struct hdr_metadata_infoframe - HDR Metadata Infoframe Data.
  *
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 02/15] lib/igt_kms: Add plane color mgmt properties
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 01/15] HAX: Get uapi headers to compile the IGT Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 03/15] kms_color_helper: Add helper functions for plane color mgmt Bhanuprakash Modem
                     ` (12 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Pekka Paalanen

Add support for Plane color management properties.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 lib/igt_kms.c | 5 +++++
 lib/igt_kms.h | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 34a2aa00ea..fdb83e0f91 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -581,6 +581,11 @@ const char * const igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
 	[IGT_PLANE_ALPHA] = "alpha",
 	[IGT_PLANE_ZPOS] = "zpos",
 	[IGT_PLANE_FB_DAMAGE_CLIPS] = "FB_DAMAGE_CLIPS",
+	[IGT_PLANE_CTM] = "PLANE_CTM",
+	[IGT_PLANE_GAMMA_MODE] = "PLANE_GAMMA_MODE",
+	[IGT_PLANE_GAMMA_LUT] = "PLANE_GAMMA_LUT",
+	[IGT_PLANE_DEGAMMA_MODE] = "PLANE_DEGAMMA_MODE",
+	[IGT_PLANE_DEGAMMA_LUT] = "PLANE_DEGAMMA_LUT",
 };
 
 const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index e9ecd21e98..3a1f7243ad 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -301,6 +301,11 @@ enum igt_atomic_plane_properties {
        IGT_PLANE_ALPHA,
        IGT_PLANE_ZPOS,
        IGT_PLANE_FB_DAMAGE_CLIPS,
+       IGT_PLANE_CTM,
+       IGT_PLANE_GAMMA_MODE,
+       IGT_PLANE_GAMMA_LUT,
+       IGT_PLANE_DEGAMMA_MODE,
+       IGT_PLANE_DEGAMMA_LUT,
        IGT_NUM_PLANE_PROPS
 };
 
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 03/15] kms_color_helper: Add helper functions for plane color mgmt
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 01/15] HAX: Get uapi headers to compile the IGT Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 02/15] lib/igt_kms: Add plane color mgmt properties Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 04/15] tests/kms_color: New subtests for Plane gamma Bhanuprakash Modem
                     ` (11 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Pekka Paalanen

Add helper functions to support Plane color management properties.

v2: (Pekka)
* Rename linear LUT to unity LUT
* Remove Intel specific logic from helper functions
* New function to fill ctm matrix
* Zero LUT for invalid lut_size tests

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_helper.c | 178 +++++++++++++++++++++++++++++++++++++--
 tests/kms_color_helper.h |  29 +++++++
 2 files changed, 201 insertions(+), 6 deletions(-)

diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
index d71e7bb2e6..e1d821f778 100644
--- a/tests/kms_color_helper.c
+++ b/tests/kms_color_helper.c
@@ -215,23 +215,31 @@ void set_gamma(data_t *data,
 	free(lut);
 }
 
-void set_ctm(igt_pipe_t *pipe, const double *coefficients)
+static void
+fill_ctm_matrix(struct drm_color_ctm *ctm, const double *coefficients)
 {
-	struct drm_color_ctm ctm;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
+	igt_assert(ctm && coefficients);
+
+	for (i = 0; i < ARRAY_SIZE(ctm->matrix); i++) {
 		if (coefficients[i] < 0) {
-			ctm.matrix[i] =
+			ctm->matrix[i] =
 				(int64_t) (-coefficients[i] *
 				((int64_t) 1L << 32));
-			ctm.matrix[i] |= 1ULL << 63;
+			ctm->matrix[i] |= 1ULL << 63;
 		} else
-			ctm.matrix[i] =
+			ctm->matrix[i] =
 				(int64_t) (coefficients[i] *
 				((int64_t) 1L << 32));
 	}
+}
+
+void set_ctm(igt_pipe_t *pipe, const double *coefficients)
+{
+	struct drm_color_ctm ctm;
 
+	fill_ctm_matrix(&ctm, coefficients);
 	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_CTM, &ctm, sizeof(ctm));
 }
 
@@ -241,6 +249,134 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
 		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
 }
 
+drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
+				enum igt_atomic_plane_properties prop)
+{
+	igt_display_t *display = plane->pipe->display;
+	uint32_t prop_id = plane->props[prop];
+	drmModePropertyPtr drmProp;
+
+	igt_assert(prop_id);
+
+	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
+
+	igt_assert(drmProp);
+	igt_assert(drmProp->count_enums);
+
+	return drmProp;
+}
+
+struct drm_color_lut_ext *create_unity_lut(segment_data_t *info)
+{
+	uint32_t val, segment, entry, index = 0;
+	uint32_t max_val = 0xffffffff;
+	struct drm_color_lut_ext *lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
+	igt_assert(lut);
+
+	for (segment = 0; segment < info->segment_count; segment++) {
+		uint32_t entry_count = info->segment_data[segment].count;
+		uint32_t start = info->segment_data[segment].start;
+		uint32_t end = info->segment_data[segment].end;
+
+		for (entry = 1; entry <= entry_count; entry++) {
+			val = start + entry * ((end - start) * 1.0 / entry_count);
+			lut[index].red = lut[index].green = lut[index].blue = MIN(val, max_val);
+
+			index++;
+		}
+	}
+
+	return lut;
+}
+
+struct drm_color_lut_ext *create_max_lut(segment_data_t *info)
+{
+	int i;
+	struct drm_color_lut_ext *lut;
+	uint32_t max_val = 0xffffffff;
+
+	lut = malloc(sizeof(struct drm_color_lut_ext) * info->entries_count);
+	igt_assert(lut);
+
+	for (i = 0; i < info->entries_count; i++)
+		lut[i].red = lut[i].green = lut[i].blue = max_val;
+
+	return lut;
+}
+
+void clear_segment_data(segment_data_t *info)
+{
+	if (!info)
+		return;
+
+	free(info->segment_data);
+	free(info);
+}
+
+segment_data_t *get_segment_data(data_t *data,
+				uint64_t blob_id, char *mode)
+{
+	drmModePropertyBlobPtr blob;
+	struct drm_color_lut_range *lut_range = NULL;
+	segment_data_t *info = NULL;
+	uint32_t i;
+
+	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
+	igt_assert(blob);
+	igt_assert(blob->length);
+
+	info = malloc(sizeof(segment_data_t));
+	igt_assert(info);
+
+	lut_range = (struct drm_color_lut_range *) blob->data;
+	info->segment_count = blob->length / sizeof(lut_range[0]);
+	igt_assert(info->segment_count);
+
+	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
+	igt_assert(info->segment_data);
+
+	for (i = 0; i < info->segment_count; i++) {
+		info->entries_count += lut_range[i].count;
+		info->segment_data[i] = lut_range[i];
+	}
+
+	drmModeFreePropertyBlob(blob);
+
+	return info;
+}
+
+void set_plane_gamma(igt_plane_t *plane,
+		char *mode,
+		struct drm_color_lut_ext *lut,
+		uint32_t size)
+{
+	igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, mode);
+	igt_plane_replace_prop_blob(plane, IGT_PLANE_GAMMA_LUT, lut, size);
+}
+
+void set_plane_degamma(igt_plane_t *plane,
+		char *mode,
+		struct drm_color_lut_ext *lut,
+		uint32_t size)
+{
+	igt_plane_set_prop_enum(plane, IGT_PLANE_DEGAMMA_MODE, mode);
+	igt_plane_replace_prop_blob(plane, IGT_PLANE_DEGAMMA_LUT, lut, size);
+}
+
+void set_plane_ctm(igt_plane_t *plane, const double *coefficients)
+{
+	struct drm_color_ctm ctm;
+
+	fill_ctm_matrix(&ctm, coefficients);
+	igt_plane_replace_prop_blob(plane, IGT_PLANE_CTM, &ctm, sizeof(ctm));
+}
+
+void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
+{
+	if (igt_plane_has_prop(plane, prop))
+		igt_plane_replace_prop_blob(plane, prop, NULL, 0);
+}
+
 drmModePropertyBlobPtr
 get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
 {
@@ -274,6 +410,19 @@ pipe_set_property_blob_id(igt_pipe_t *pipe,
 	return ret;
 }
 
+static int
+plane_set_property_blob(igt_display_t *display,
+			igt_plane_t *plane,
+			enum igt_atomic_plane_properties prop,
+			void *ptr, size_t length)
+{
+	igt_plane_replace_prop_blob(plane, prop, ptr, length);
+
+	return igt_display_try_commit2(display,
+				       display->is_atomic ?
+				       COMMIT_ATOMIC : COMMIT_LEGACY);
+}
+
 int
 pipe_set_property_blob(igt_pipe_t *pipe,
 		       enum igt_atomic_crtc_properties prop,
@@ -319,6 +468,23 @@ invalid_lut_sizes(data_t *data, enum pipe p,
 	free(lut);
 }
 
+void
+invalid_plane_lut_sizes(igt_display_t *display,
+			igt_plane_t *plane,
+			enum igt_atomic_plane_properties prop,
+			size_t lut_size)
+{
+	void *lut = malloc(lut_size * 2);
+	igt_assert(lut);
+
+	memset(lut, 0, (lut_size * 2));
+	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, 1), -EINVAL);
+	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size + 1), -EINVAL);
+	igt_assert_eq(plane_set_property_blob(display, plane, prop, lut, lut_size - 1), -EINVAL);
+
+	free(lut);
+}
+
 void
 invalid_gamma_lut_sizes(data_t *data, enum pipe p)
 {
diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
index bb6f0054f3..06c0dc22c4 100644
--- a/tests/kms_color_helper.h
+++ b/tests/kms_color_helper.h
@@ -64,6 +64,14 @@ typedef struct {
 	color_t coeffs[];
 } gamma_lut_t;
 
+typedef struct {
+	uint32_t segment_count;
+	struct drm_color_lut_range *segment_data;
+	uint32_t entries_count;
+} segment_data_t;
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
 void paint_gradient_rectangles(data_t *data,
 			       drmModeModeInfo *mode,
 			       color_t *colors,
@@ -90,10 +98,31 @@ void set_gamma(data_t *data,
 void set_ctm(igt_pipe_t *pipe, const double *coefficients);
 void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
 
+drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
+	enum igt_atomic_plane_properties prop);
+void clear_segment_data(segment_data_t *info);
+struct drm_color_lut_ext *create_unity_lut(segment_data_t *info);
+struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
+segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
+void set_plane_gamma(igt_plane_t *plane,
+	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
+void set_plane_degamma(igt_plane_t *plane,
+	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
+void set_plane_ctm(igt_plane_t *plane, const double *coefficients);
+void disable_plane_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop);
+void invalid_plane_lut_sizes(igt_display_t *display,
+			   igt_plane_t *plane,
+			   enum igt_atomic_plane_properties prop,
+			   size_t lut_size);
+
 #define disable_degamma(pipe) disable_prop(pipe, IGT_CRTC_DEGAMMA_LUT)
 #define disable_gamma(pipe) disable_prop(pipe, IGT_CRTC_GAMMA_LUT)
 #define disable_ctm(pipe) disable_prop(pipe, IGT_CRTC_CTM)
 
+#define disable_plane_degamma(plane) disable_plane_prop(plane, IGT_PLANE_DEGAMMA_LUT)
+#define disable_plane_gamma(plane) disable_plane_prop(plane, IGT_PLANE_GAMMA_LUT)
+#define disable_plane_ctm(plane) disable_plane_prop(plane, IGT_PLANE_CTM)
+
 drmModePropertyBlobPtr get_blob(data_t *data, igt_pipe_t *pipe,
 				enum igt_atomic_crtc_properties prop);
 bool crc_equal(igt_crc_t *a, igt_crc_t *b);
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 04/15] tests/kms_color: New subtests for Plane gamma
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (2 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 03/15] kms_color_helper: Add helper functions for plane color mgmt Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 05/15] tests/kms_color: New subtests for Plane degamma Bhanuprakash Modem
                     ` (10 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Pekka Paalanen

To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out gamma LUT and verify we have the same CRC as drawing solid
color rectangles.

v2:
* Drop Intel specific logic (Pekka)
* Add a support for extended mode (Bhanu)

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 175 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 173 insertions(+), 2 deletions(-)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index 854b8f3c31..58b0ae76ec 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -24,7 +24,10 @@
 
 #include "kms_color_helper.h"
 
-IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
+IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
+
+typedef bool (*test_t)(data_t*, igt_plane_t*);
+static bool extended = false;
 
 static void test_pipe_degamma(data_t *data,
 			      igt_plane_t *primary)
@@ -638,6 +641,123 @@ static void test_pipe_limited_range_ctm(data_t *data,
 }
 #endif
 
+static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb;
+	drmModePropertyPtr gamma_mode = NULL;
+	uint32_t i;
+	bool ret = true;
+	igt_pipe_crc_t *pipe_crc = NULL;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane gamma test is running on pipe-%s plane-%d(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe), plane->index,
+			kmstest_plane_type_name(plane->type));
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd,
+				  plane->pipe->pipe,
+				  INTEL_PIPE_CRC_SOURCE_AUTO);
+
+	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+	igt_plane_set_fb(plane, &fb);
+
+	/* Disable Pipe color props. */
+	disable_ctm(plane->pipe);
+	disable_degamma(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_ctm(plane);
+	disable_plane_degamma(plane);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
+
+	/* Iterate all supported gamma modes. */
+	for (i = 0; i < gamma_mode->count_enums; i++) {
+		igt_crc_t crc_gamma, crc_fullcolors;
+		segment_data_t *segment_info = NULL;
+		struct drm_color_lut_ext *lut = NULL;
+		uint32_t lut_size = 0;
+
+		/* Ignore 'no gamma' from enum list. */
+		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
+			continue;
+
+		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
+
+		/* Draw solid colors with no gamma transformation. */
+		disable_plane_gamma(plane);
+		paint_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
+
+		/* Draw gradient colors with gamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
+				gamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
+		lut = create_max_lut(segment_info);
+		if (is_i915_device(data->drm_fd))
+			lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is 0 for Intel h/w. */
+		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
+
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
+
+		/* Verify that the CRC of the software computed output is
+		 * equal to the CRC of the gamma LUT transformation output.
+		 */
+		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
+
+		free(lut);
+		clear_segment_data(segment_info);
+	}
+
+	disable_plane_gamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	igt_pipe_crc_free(pipe_crc);
+	drmModeFreeProperty(gamma_mode);
+
+	return ret;
+}
+
 static void
 prep_pipe(data_t *data, enum pipe p)
 {
@@ -896,7 +1016,55 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
 		invalid_ctm_matrix_sizes(data, p);
 }
 
-igt_main
+static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
+{
+	igt_plane_t *plane;
+	int count = 0;
+	int last_plane = (&data->display)->pipes[pipe].n_planes - 1;
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!extended && j__ != 0 && j__ != last_plane)
+			continue;
+
+		igt_assert(test(data, plane));
+
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
+static void run_tests_for_plane(data_t *data, enum pipe pipe)
+{
+	igt_fixture {
+		igt_require_pipe(&data->display, pipe);
+		igt_require_pipe_crc(data->drm_fd);
+		igt_require(data->display.pipes[pipe].n_planes > 0);
+		igt_display_require_output_on_pipe(&data->display, pipe);
+	}
+
+	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_gamma_test);
+}
+
+static int opt_handler(int opt, int opt_index, void *data)
+{
+	switch (opt) {
+		case 'e':
+			extended = true;
+			break;
+		default:
+			return IGT_OPT_HANDLER_ERROR;
+	}
+
+	return IGT_OPT_HANDLER_SUCCESS;
+}
+
+const char *help_str =
+	"  -e \tExtended plane tests.\n";
+
+igt_main_args("e", NULL, help_str, opt_handler, NULL)
 {
 	data_t data = {};
 	enum pipe pipe;
@@ -916,6 +1084,9 @@ igt_main
 
 		igt_subtest_group
 			run_invalid_tests_for_pipe(&data, pipe);
+
+		igt_subtest_group
+			run_tests_for_plane(&data, pipe);
 	}
 
 	igt_fixture {
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 05/15] tests/kms_color: New subtests for Plane degamma
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (3 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 04/15] tests/kms_color: New subtests for Plane gamma Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 06/15] tests/kms_color: New subtests for Plane CTM Bhanuprakash Modem
                     ` (9 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Pekka Paalanen

To verify Plane degamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out degamma LUT and verify we have the same CRC as drawing solid
color rectangles without degamma.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index 58b0ae76ec..2c971b011f 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -758,6 +758,126 @@ static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	drmModePropertyPtr degamma_mode;
+	struct igt_fb fb;
+	uint32_t i;
+	bool ret = true;
+	igt_pipe_crc_t *pipe_crc = NULL;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane degamma test is running on pipe-%s plane-%d(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe), plane->index,
+			kmstest_plane_type_name(plane->type));
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd,
+				    plane->pipe->pipe,
+				    INTEL_PIPE_CRC_SOURCE_AUTO);
+
+	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_plane_set_fb(plane, &fb);
+
+	/* Disable Pipe color props. */
+	disable_ctm(plane->pipe);
+	disable_degamma(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
+
+	/* Iterate all supported degamma modes. */
+	for (i = 0; i < degamma_mode->count_enums; i++) {
+		igt_crc_t crc_degamma, crc_fullcolors;
+		segment_data_t *segment_info = NULL;
+		struct drm_color_lut_ext *lut = NULL;
+		uint32_t lut_size = 0;
+
+		/* Ignore 'no degamma' from enum list. */
+		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
+			continue;
+
+		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
+
+		/* Draw solid colors with no degamma. */
+		disable_plane_degamma(plane);
+		paint_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+				display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
+
+		/* Draw gradient colors with degamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		segment_info = get_segment_data(data, degamma_mode->enums[i].value,
+						degamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
+		lut = create_max_lut(segment_info);
+		if (is_i915_device(data->drm_fd))
+			lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is 0 for Intel h/w. */
+
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		set_plane_degamma(plane, degamma_mode->enums[i].name,
+				  lut, lut_size);
+		igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+				display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_degamma);
+
+		/* Verify that the CRC of the software computed output
+		 * is equal to the CRC of the degamma LUT transformation
+		 * output.
+		 */
+		ret &= igt_check_crc_equal(&crc_degamma, &crc_fullcolors);
+
+		free(lut);
+		clear_segment_data(segment_info);
+	}
+
+	disable_plane_degamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	igt_pipe_crc_free(pipe_crc);
+	drmModeFreeProperty(degamma_mode);
+
+	return ret;
+}
+
 static void
 prep_pipe(data_t *data, enum pipe p)
 {
@@ -1046,6 +1166,11 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");
 	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_gamma_test);
+
+	igt_describe("Compare maxed out plane degamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-degamma",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_degamma_test);
 }
 
 static int opt_handler(int opt, int opt_index, void *data)
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 06/15] tests/kms_color: New subtests for Plane CTM
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (4 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 05/15] tests/kms_color: New subtests for Plane degamma Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 07/15] tests/kms_color: New negative tests for plane level color mgmt Bhanuprakash Modem
                     ` (8 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Pekka Paalanen

To verify plane CTM, draw 3 rectangles using before colors with the
ctm matrix applied and verify the CRC is equal to using after colors
with an identify ctm matrix.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 226 insertions(+)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index 2c971b011f..7f95916ee9 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -29,6 +29,77 @@ IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
 typedef bool (*test_t)(data_t*, igt_plane_t*);
 static bool extended = false;
 
+struct {
+	const char *test_name;
+	int iter;
+	color_t expected_colors[3];
+	double ctm[9];
+} ctm_tests[] = {
+	{"plane-ctm-red-to-blue", 0,
+					{{ 0.0, 0.0, 1.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 0.0, 0.0, 0.0,
+		  0.0, 1.0, 0.0,
+		  1.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-green-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 1.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 1.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0,
+		  0.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-blue-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 1.0, 0.0, 0.0 }},
+		{ 1.0, 0.0, 1.0,
+		  0.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0 },
+	},
+	{"plane-ctm-max", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 100.0, 0.0, 0.0,
+		  0.0, 100.0, 0.0,
+		  0.0, 0.0, 100.0 },
+	},
+	{"plane-ctm-negative", 0,
+					{{ 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 }},
+		{ -1.0, 0.0, 0.0,
+		   0.0, -1.0, 0.0,
+		   0.0, 0.0, -1.0 },
+	},
+	/* We tests a few values around the expected result because
+	 * it depends on the hardware we're dealing with, we can
+	 * either get clamped or rounded values and we also need to
+	 * account for odd number of items in the LUTs.
+	 */
+	{"plane-ctm-0-25", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.25, 0.0,  0.0,
+		  0.0,  0.25, 0.0,
+		  0.0,  0.0,  0.25 },
+	},
+	{"plane-ctm-0-50", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.5,  0.0,  0.0,
+		  0.0,  0.5,  0.0,
+		  0.0,  0.0,  0.5 },
+	},
+	{"plane-ctm-0-75", 7,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.75, 0.0,  0.0,
+		  0.0,  0.75, 0.0,
+		  0.0,  0.0,  0.75 },
+	},
+};
+
 static void test_pipe_degamma(data_t *data,
 			      igt_plane_t *primary)
 {
@@ -878,6 +949,98 @@ static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool test_plane_ctm(data_t *data,
+			  igt_plane_t *plane,
+			  color_t *before,
+			  color_t *after,
+			  double *ctm_matrix)
+{
+	const double ctm_identity[] = {
+		1.0, 0.0, 0.0,
+		0.0, 1.0, 0.0,
+		0.0, 0.0, 1.0
+	};
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb;
+	igt_crc_t crc_software, crc_hardware;
+	igt_pipe_crc_t *pipe_crc = NULL;
+	bool ret = true;
+
+	igt_info("Plane CTM test is running on pipe-%s plane-%d(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe), plane->index,
+			kmstest_plane_type_name(plane->type));
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd,
+				  plane->pipe->pipe,
+				  INTEL_PIPE_CRC_SOURCE_AUTO);
+
+	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_plane_set_fb(plane, &fb);
+
+	/* Disable Pipe color props. */
+	disable_degamma(plane->pipe);
+	disable_gamma(plane->pipe);
+	disable_ctm(plane->pipe);
+
+	disable_plane_gamma(plane);
+	disable_plane_degamma(plane);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Without CTM transformation. */
+	paint_rectangles(data, mode, after, &fb);
+	igt_plane_set_fb(plane, &fb);
+	set_plane_ctm(plane, ctm_identity);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+	igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+	igt_pipe_crc_collect_crc(pipe_crc, &crc_software);
+
+	/* With CTM transformation. */
+	paint_rectangles(data, mode, before, &fb);
+	igt_plane_set_fb(plane, &fb);
+	set_plane_ctm(plane, ctm_matrix);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+	igt_wait_for_vblank(data->drm_fd,
+			display->pipes[plane->pipe->pipe].crtc_offset);
+	igt_pipe_crc_collect_crc(pipe_crc, &crc_hardware);
+
+	/* Verify that the CRC of the software computed ouutput
+	 * is equal to the CRC of the CTM matrix transformation
+	 * output.
+	 */
+	ret = igt_check_crc_equal(&crc_software, &crc_hardware);
+
+	disable_plane_ctm(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	igt_pipe_crc_free(pipe_crc);
+
+	return ret;
+}
+
 static void
 prep_pipe(data_t *data, enum pipe p)
 {
@@ -1154,8 +1317,59 @@ static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 	igt_require_f(count, "No valid planes found.\n");
 }
 
+static void run_plane_ctm_test(data_t *data,
+				enum pipe pipe,
+				color_t *expected,
+				double *ctm,
+				int iter)
+{
+	igt_plane_t *plane;
+	bool result;
+	int i, count = 0;
+	double delta = 1.0 / (1 << 8);
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+	int last_plane = (&data->display)->pipes[pipe].n_planes - 1;
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!extended && j__ != 0 && j__ != last_plane)
+			continue;
+
+		result = false;
+
+		if (!iter)
+			result = test_plane_ctm(data, plane,
+						red_green_blue, expected,
+						ctm);
+
+		for (i = 0; i < iter; i++) {
+			expected[0].r =
+			expected[1].g =
+			expected[2].b =
+				ctm[0] + delta * (i - (iter/2));
+
+			if (test_plane_ctm(data, plane,
+					   red_green_blue, expected,
+					   ctm)) {
+				result = true;
+				break;
+			}
+		}
+
+		igt_assert(result);
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
 static void run_tests_for_plane(data_t *data, enum pipe pipe)
 {
+	int i;
+
 	igt_fixture {
 		igt_require_pipe(&data->display, pipe);
 		igt_require_pipe_crc(data->drm_fd);
@@ -1171,6 +1385,18 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_subtest_f("pipe-%s-plane-degamma",
 			kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_degamma_test);
+
+	for (i = 0; i < ARRAY_SIZE(ctm_tests); i++) {
+		igt_describe("Compare after applying ctm matrix & identity matrix");
+		igt_subtest_f("pipe-%s-%s",
+				kmstest_pipe_name(pipe),
+				ctm_tests[i].test_name) {
+			run_plane_ctm_test(data, pipe,
+					ctm_tests[i].expected_colors,
+					ctm_tests[i].ctm,
+					ctm_tests[i].iter);
+		}
+	}
 }
 
 static int opt_handler(int opt, int opt_index, void *data)
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 07/15] tests/kms_color: New negative tests for plane level color mgmt
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (5 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 06/15] tests/kms_color: New subtests for Plane CTM Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 08/15] tests/kms_color_chamelium: New subtests for Plane gamma Bhanuprakash Modem
                     ` (7 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Pekka Paalanen

Negative check for:
 * plane gamma lut sizes
 * plane degamma lut sizes
 * plane ctm matrix sizes

v2:
* Run subtests for all enums (Pekka)

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 118 insertions(+)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index 7f95916ee9..638d838757 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -712,6 +712,109 @@ static void test_pipe_limited_range_ctm(data_t *data,
 }
 #endif
 
+static bool invalid_plane_gamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_display_t *display = &data->display;
+	drmModePropertyPtr gamma_mode = NULL;
+	uint32_t i;
+
+	igt_info("Plane invalid gamma test is running on pipe-%s plane-%d(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe), plane->index,
+			kmstest_plane_type_name(plane->type));
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
+
+	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
+
+	/* Iterate all supported gamma modes. */
+	for (i = 0; i < gamma_mode->count_enums; i++) {
+		segment_data_t *segment_info = NULL;
+		size_t lut_size = 0;
+
+		/* Ignore 'no gamma' from enum list. */
+		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
+			continue;
+
+		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
+
+		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
+				gamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
+
+		igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, gamma_mode->enums[i].name);
+		invalid_plane_lut_sizes(display, plane,
+					IGT_PLANE_GAMMA_LUT,
+					lut_size);
+
+		clear_segment_data(segment_info);
+	}
+
+	drmModeFreeProperty(gamma_mode);
+
+	return true;
+}
+
+static bool invalid_plane_degamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_display_t *display = &data->display;
+	drmModePropertyPtr degamma_mode = NULL;
+	uint32_t i;
+
+	igt_info("Plane invalid degamma test is running on pipe-%s plane-%d(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe), plane->index,
+			kmstest_plane_type_name(plane->type));
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
+
+	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
+
+	/* Iterate all supported degamma modes. */
+	for (i = 0; i < degamma_mode->count_enums; i++) {
+		segment_data_t *segment_info = NULL;
+		size_t lut_size = 0;
+
+		/* Ignore 'no degamma' from enum list. */
+		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
+			continue;
+
+		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
+
+		segment_info = get_segment_data(data,
+						degamma_mode->enums[i].value,
+						degamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count * 2;
+
+		igt_plane_set_prop_enum(plane,
+					IGT_PLANE_DEGAMMA_MODE,
+					degamma_mode->enums[i].name);
+		invalid_plane_lut_sizes(display, plane,
+					IGT_PLANE_DEGAMMA_LUT,
+					lut_size);
+
+		clear_segment_data(segment_info);
+	}
+
+	drmModeFreeProperty(degamma_mode);
+
+	return true;
+}
+
+static bool invalid_plane_ctm_test(data_t *data, igt_plane_t *plane)
+{
+	igt_info("Plane invalid CTM test is running on pipe-%s plane-%d(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe), plane->index,
+			kmstest_plane_type_name(plane->type));
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
+	invalid_plane_lut_sizes(&data->display, plane,
+				IGT_PLANE_CTM,
+				sizeof(struct drm_color_ctm));
+
+	return true;
+}
+
 static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
 {
 	igt_output_t *output;
@@ -1397,6 +1500,21 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 					ctm_tests[i].iter);
 		}
 	}
+
+	igt_describe("Negative check for invalid plane gamma lut sizes");
+	igt_subtest_f("pipe-%s-invalid-plane-gamma-lut-sizes",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, invalid_plane_gamma_test);
+
+	igt_describe("Negative check for invalid plane degamma lut sizes");
+	igt_subtest_f("pipe-%s-invalid-plane-degamma-lut-sizes",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, invalid_plane_degamma_test);
+
+	igt_describe("Negative check for invalid plane ctm matrix sizes");
+	igt_subtest_f("pipe-%s-invalid-plane-ctm-matrix-sizes",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, invalid_plane_ctm_test);
 }
 
 static int opt_handler(int opt, int opt_index, void *data)
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 08/15] tests/kms_color_chamelium: New subtests for Plane gamma
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (6 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 07/15] tests/kms_color: New negative tests for plane level color mgmt Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 09/15] tests/kms_color_chamelium: New subtests for Plane degamma Bhanuprakash Modem
                     ` (6 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Kunal Joshi, Pekka Paalanen

To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out gamma LUT and verify we have the same frame dump as
drawing solid color rectangles.

v2:
* Drop Intel specific logic (Pekka)
* Add a support for extended mode (Bhanu)

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 184 +++++++++++++++++++++++++++++++++++-
 1 file changed, 182 insertions(+), 2 deletions(-)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index 76f82d6d35..c554e78436 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -24,7 +24,10 @@
 
 #include "kms_color_helper.h"
 
-IGT_TEST_DESCRIPTION("Test Color Features at Pipe level using Chamelium to verify instead of CRC");
+IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level using Chamelium to verify instead of CRC");
+
+typedef bool (*test_t)(data_t*, igt_plane_t*);
+static bool extended = false;
 
 /*
  * Draw 3 gradient rectangles in red, green and blue, with a maxed out
@@ -723,7 +726,180 @@ run_tests_for_pipe(data_t *data, enum pipe p)
 	}
 }
 
-igt_main
+static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb, fbref;
+	drmModePropertyPtr gamma_mode = NULL;
+	uint32_t i;
+	bool ret = true;
+	struct chamelium_port *port = NULL;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane gamma test is running on pipe-%s plane-%d(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe), plane->index,
+			kmstest_plane_type_name(plane->type));
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
+
+	for_each_valid_output_on_pipe(display, plane->pipe->pipe, output) {
+		for (i = 0; i < data->port_count; i++)
+			if (strcmp(output->name, chamelium_port_get_name(data->ports[i])) == 0) {
+				port = data->ports[i];
+				break;
+			}
+
+		if (port)
+			break;
+	}
+	igt_require(port);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fbref));
+
+	disable_degamma(plane->pipe);
+	disable_ctm(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_degamma(plane);
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+
+	igt_plane_set_fb(plane, &fbref);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Draw solid colors with no gamma transformation. */
+	paint_rectangles(data, mode, red_green_blue, &fbref);
+
+	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
+	/* Iterate all supported gamma modes. */
+	for (i = 0; i < gamma_mode->count_enums; i++) {
+		struct chamelium_frame_dump *frame_fullcolors;
+		segment_data_t *segment_info = NULL;
+		struct drm_color_lut_ext *lut = NULL;
+		uint32_t lut_size = 0;
+
+		/* Ignore 'no gamma' from enum list. */
+		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
+			continue;
+
+		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode->enums[i].name);
+
+		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
+				gamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
+		lut = create_max_lut(segment_info);
+		if (is_i915_device(data->drm_fd))
+			lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is 0 for Intel h/w. */
+		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
+
+		/* Draw a gradient with gamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+		chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 1);
+		frame_fullcolors =
+			chamelium_read_captured_frame(data->chamelium, 0);
+
+		/* Verify that the framebuffer reference of the software computed
+		 * output is equal to the frame dump of the gamma LUT
+		 * transformation output.
+		 */
+		ret &= chamelium_frame_match_or_dump(data->chamelium, port,
+					      frame_fullcolors, &fbref,
+					      CHAMELIUM_CHECK_ANALOG);
+		free(lut);
+		clear_segment_data(segment_info);
+	}
+
+	disable_plane_gamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	drmModeFreeProperty(gamma_mode);
+
+	return ret;
+}
+
+static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
+{
+	igt_plane_t *plane;
+	int count = 0;
+	int last_plane = (&data->display)->pipes[pipe].n_planes - 1;
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!extended && j__ != 0 && j__ != last_plane)
+			continue;
+
+		igt_assert(test(data, plane));
+
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
+static void run_tests_for_plane(data_t *data, enum pipe pipe)
+{
+	igt_fixture {
+		igt_require_pipe(&data->display, pipe);
+		igt_require(data->display.pipes[pipe].n_planes > 0);
+		igt_display_require_output_on_pipe(&data->display, pipe);
+	}
+
+	igt_describe("Compare maxed out plane gamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-gamma",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_gamma_test);
+}
+
+static int opt_handler(int opt, int opt_index, void *data)
+{
+	switch (opt) {
+		case 'e':
+			extended = true;
+			break;
+		default:
+			return IGT_OPT_HANDLER_ERROR;
+	}
+
+	return IGT_OPT_HANDLER_SUCCESS;
+}
+
+const char *help_str =
+	"  -e \tExtended plane tests.\n";
+
+igt_main_args("e", NULL, help_str, opt_handler, NULL)
 {
 	data_t data = {};
 	enum pipe pipe;
@@ -755,6 +931,10 @@ igt_main
 		igt_subtest_group
 			run_tests_for_pipe(&data, pipe);
 
+	for_each_pipe_static(pipe)
+		igt_subtest_group
+			run_tests_for_plane(&data, pipe);
+
 	igt_fixture {
 		igt_display_fini(&data.display);
 	}
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 09/15] tests/kms_color_chamelium: New subtests for Plane degamma
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (7 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 08/15] tests/kms_color_chamelium: New subtests for Plane gamma Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 10/15] tests/kms_color_chamelium: New subtests for Plane CTM Bhanuprakash Modem
                     ` (5 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Kunal Joshi, Pekka Paalanen

To verify Plane degamma, draw 3 gradient rectangles in red, green and blue,
with a maxed out degamma LUT and verify we have the same frame dump as
drawing solid color rectangles with linear gamma LUT.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 131 ++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index c554e78436..76d80e39ba 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -851,6 +851,132 @@ static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	drmModePropertyPtr degamma_mode;
+	struct igt_fb fb, fbref;
+	struct chamelium_port *port;
+	uint32_t i;
+	bool ret = true;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane degamma test is running on pipe-%s plane-%d(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe), plane->index,
+			kmstest_plane_type_name(plane->type));
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
+
+	for_each_valid_output_on_pipe(display, plane->pipe->pipe, output) {
+		for (i = 0; i < data->port_count; i++)
+			if (strcmp(output->name, chamelium_port_get_name(data->ports[i])) == 0) {
+				port = data->ports[i];
+				break;
+			}
+
+		if (port)
+			break;
+	}
+	igt_require(port);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fbref));
+
+	disable_degamma(plane->pipe);
+	disable_ctm(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_degamma(plane);
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+
+	igt_plane_set_fb(plane, &fbref);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Draw solid colors with no degamma. */
+	paint_rectangles(data, mode, red_green_blue, &fbref);
+
+	degamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_DEGAMMA_MODE);
+	/* Iterate all supported degamma modes. */
+	for (i = 0; i < degamma_mode->count_enums; i++) {
+		struct chamelium_frame_dump *frame_fullcolors;
+		segment_data_t *segment_info = NULL;
+		struct drm_color_lut_ext *lut = NULL;
+		uint32_t lut_size = 0;
+
+		/* Ignore 'no degamma' from enum list. */
+		if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
+			continue;
+
+		igt_info("Trying to use degamma mode: \'%s\'\n", degamma_mode->enums[i].name);
+
+		segment_info = get_segment_data(data, degamma_mode->enums[i].value,
+						degamma_mode->enums[i].name);
+		lut_size = sizeof(struct drm_color_lut_ext) * segment_info->entries_count;
+		lut = create_max_lut(segment_info);
+		if (is_i915_device(data->drm_fd))
+			lut[0].red = lut[0].green = lut[0].blue = 0; /* First entry is 0 for Intel h/w. */
+		set_plane_degamma(plane, degamma_mode->enums[i].name, lut, lut_size);
+
+		/* Draw a gradient with degamma LUT to remap all
+		 * values to max red/green/blue.
+		 */
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+		chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 1);
+		frame_fullcolors =
+			chamelium_read_captured_frame(data->chamelium, 0);
+
+		/* Verify that the framebuffer reference of the software computed
+		 * output is equal to the frame dump of the gamma LUT
+		 * transformation output.
+		 */
+		ret &= chamelium_frame_match_or_dump(data->chamelium, port,
+				frame_fullcolors, &fbref,
+				CHAMELIUM_CHECK_ANALOG);
+
+		free(lut);
+		clear_segment_data(segment_info);
+	}
+
+	disable_plane_degamma(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	drmModeFreeProperty(degamma_mode);
+
+	return ret;
+}
+
 static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 {
 	igt_plane_t *plane;
@@ -881,6 +1007,11 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_subtest_f("pipe-%s-plane-gamma",
 			kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_gamma_test);
+
+	igt_describe("Compare maxed out plane degamma LUT and solid color linear LUT");
+	igt_subtest_f("pipe-%s-plane-degamma",
+			kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_degamma_test);
 }
 
 static int opt_handler(int opt, int opt_index, void *data)
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 10/15] tests/kms_color_chamelium: New subtests for Plane CTM
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (8 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 09/15] tests/kms_color_chamelium: New subtests for Plane degamma Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 11/15] lib/igt_kms: Add pipe color mgmt properties Bhanuprakash Modem
                     ` (4 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Kunal Joshi, Pekka Paalanen

To verify plane CTM, draw 3 rectangles using before colors with the
ctm matrix applied and verify the frame dump is equal to using after
colors with an identify ctm matrix.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 228 ++++++++++++++++++++++++++++++++++++
 1 file changed, 228 insertions(+)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index 76d80e39ba..a9469f9827 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -29,6 +29,77 @@ IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level using Chamelium
 typedef bool (*test_t)(data_t*, igt_plane_t*);
 static bool extended = false;
 
+struct {
+	const char *test_name;
+	int iter;
+	color_t expected_colors[3];
+	double ctm[9];
+} ctm_tests[] = {
+	{"plane-ctm-red-to-blue", 0,
+					{{ 0.0, 0.0, 1.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 0.0, 0.0, 0.0,
+		  0.0, 1.0, 0.0,
+		  1.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-green-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 1.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 1.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0,
+		  0.0, 0.0, 1.0 },
+	},
+	{"plane-ctm-blue-to-red", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 1.0, 0.0, 0.0 }},
+		{ 1.0, 0.0, 1.0,
+		  0.0, 1.0, 0.0,
+		  0.0, 0.0, 0.0 },
+	},
+	{"plane-ctm-max", 0,
+					{{ 1.0, 0.0, 0.0 },
+					 { 0.0, 1.0, 0.0 },
+					 { 0.0, 0.0, 1.0 }},
+		{ 100.0, 0.0, 0.0,
+		  0.0, 100.0, 0.0,
+		  0.0, 0.0, 100.0 },
+	},
+	{"plane-ctm-negative", 0,
+					{{ 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 },
+					 { 0.0, 0.0, 0.0 }},
+		{ -1.0, 0.0, 0.0,
+		   0.0, -1.0, 0.0,
+		   0.0, 0.0, -1.0 },
+	},
+	/* We tests a few values around the expected result because
+	 * it depends on the hardware we're dealing with, we can
+	 * either get clamped or rounded values and we also need to
+	 * account for odd number of items in the LUTs.
+	 */
+	{"plane-ctm-0-25", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.25, 0.0,  0.0,
+		  0.0,  0.25, 0.0,
+		  0.0,  0.0,  0.25 },
+	},
+	{"plane-ctm-0-50", 5,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.5,  0.0,  0.0,
+		  0.0,  0.5,  0.0,
+		  0.0,  0.0,  0.5 },
+	},
+	{"plane-ctm-0-75", 7,
+					{{ 0.0, }, { 0.0, }, { 0.0, }},
+		{ 0.75, 0.0,  0.0,
+		  0.0,  0.75, 0.0,
+		  0.0,  0.0,  0.75 },
+	},
+};
+
 /*
  * Draw 3 gradient rectangles in red, green and blue, with a maxed out
  * degamma LUT and verify we have the same frame dump as drawing solid color
@@ -977,6 +1048,102 @@ static bool plane_degamma_test(data_t *data, igt_plane_t *plane)
 	return ret;
 }
 
+static bool test_plane_ctm(data_t *data,
+			  igt_plane_t *plane,
+			  color_t *before,
+			  color_t *after,
+			  double *ctm_matrix)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	struct igt_fb fb, fbref;
+	struct chamelium_port *port;
+	struct chamelium_frame_dump *frame_hardware;
+	uint32_t i;
+	bool ret = true;
+
+	igt_info("Plane CTM test is running on pipe-%s plane-%d(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe), plane->index,
+			kmstest_plane_type_name(plane->type));
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_CTM));
+
+	for_each_valid_output_on_pipe(display, plane->pipe->pipe, output) {
+		for (i = 0; i < data->port_count; i++)
+			if (strcmp(output->name, chamelium_port_get_name(data->ports[i])) == 0) {
+				port = data->ports[i];
+				break;
+			}
+
+		if (port)
+			break;
+	}
+	igt_require(port);
+	igt_assert(output);
+
+	igt_output_set_pipe(output, plane->pipe->pipe);
+	mode = igt_output_get_mode(output);
+
+	/* Create a framebuffer at the size of the output. */
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_assert(igt_create_fb(data->drm_fd,
+			      mode->hdisplay,
+			      mode->vdisplay,
+			      DRM_FORMAT_XRGB8888,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fbref));
+
+	disable_degamma(plane->pipe);
+	disable_ctm(plane->pipe);
+	disable_gamma(plane->pipe);
+
+	disable_plane_degamma(plane);
+	disable_plane_ctm(plane);
+	disable_plane_gamma(plane);
+
+	igt_plane_set_fb(plane, &fbref);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	/* Without CTM transformation. */
+	paint_rectangles(data, mode, after, &fbref);
+
+	/* With CTM transformation. */
+	paint_rectangles(data, mode, before, &fb);
+	igt_plane_set_fb(plane, &fb);
+	set_plane_ctm(plane, ctm_matrix);
+	igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 1);
+	frame_hardware =
+		chamelium_read_captured_frame(data->chamelium, 0);
+
+	/* Verify that the framebuffer reference of the software
+	 * computed output is equal to the frame dump of the CTM
+	 * matrix transformation output.
+	 */
+	ret = chamelium_frame_match_or_dump(data->chamelium, port,
+					     frame_hardware,
+					     &fbref,
+					     CHAMELIUM_CHECK_ANALOG);
+
+	disable_plane_ctm(plane);
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, display->is_atomic ?
+					COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	return ret;
+}
+
 static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 {
 	igt_plane_t *plane;
@@ -995,8 +1162,57 @@ static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
 	igt_require_f(count, "No valid planes found.\n");
 }
 
+static void run_plane_ctm_test(data_t *data,
+				enum pipe pipe,
+				color_t *expected,
+				double *ctm,
+				int iter)
+{
+	igt_plane_t *plane;
+	bool result;
+	int i, count = 0;
+	double delta = 1.0 / (1 << 8);
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+	int last_plane = (&data->display)->pipes[pipe].n_planes - 1;
+
+	for_each_plane_on_pipe(&data->display, pipe, plane) {
+		if (!extended && j__ != 0 && j__ != last_plane)
+			continue;
+
+		result = false;
+
+		if (!iter)
+			result = test_plane_ctm(data, plane, red_green_blue,
+						expected, ctm);
+
+		for (i = 0; i < iter; i++) {
+			expected[0].r =
+			expected[1].g =
+			expected[2].b =
+				ctm[0] + delta * (i - (iter/2));
+
+			if (test_plane_ctm(data, plane, red_green_blue,
+						expected, ctm)) {
+				result = true;
+				break;
+			}
+		}
+
+		igt_assert(result);
+		count++;
+	}
+
+	igt_require_f(count, "No valid planes found.\n");
+}
+
 static void run_tests_for_plane(data_t *data, enum pipe pipe)
 {
+	int i;
+
 	igt_fixture {
 		igt_require_pipe(&data->display, pipe);
 		igt_require(data->display.pipes[pipe].n_planes > 0);
@@ -1012,6 +1228,18 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_subtest_f("pipe-%s-plane-degamma",
 			kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_degamma_test);
+
+	for (i = 0; i < ARRAY_SIZE(ctm_tests); i++) {
+		igt_describe("Compare after applying ctm matrix & identity matrix");
+		igt_subtest_f("pipe-%s-%s",
+				kmstest_pipe_name(pipe),
+				ctm_tests[i].test_name) {
+			run_plane_ctm_test(data, pipe,
+					ctm_tests[i].expected_colors,
+					ctm_tests[i].ctm,
+					ctm_tests[i].iter);
+		}
+	}
 }
 
 static int opt_handler(int opt, int opt_index, void *data)
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 11/15] lib/igt_kms: Add pipe color mgmt properties
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (9 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 10/15] tests/kms_color_chamelium: New subtests for Plane CTM Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 12/15] kms_color_helper: Add helper functions to support logarithmic gamma mode Bhanuprakash Modem
                     ` (3 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Mukunda Pramodh Kumar, Pekka Paalanen

From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>

Add IGT support to read CRTC GAMMA_MODE property.

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 lib/igt_kms.c | 1 +
 lib/igt_kms.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index fdb83e0f91..677d26fedb 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -592,6 +592,7 @@ const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
 	[IGT_CRTC_CTM] = "CTM",
 	[IGT_CRTC_GAMMA_LUT] = "GAMMA_LUT",
 	[IGT_CRTC_GAMMA_LUT_SIZE] = "GAMMA_LUT_SIZE",
+	[IGT_CRTC_GAMMA_MODE] = "GAMMA_MODE",
 	[IGT_CRTC_DEGAMMA_LUT] = "DEGAMMA_LUT",
 	[IGT_CRTC_DEGAMMA_LUT_SIZE] = "DEGAMMA_LUT_SIZE",
 	[IGT_CRTC_MODE_ID] = "MODE_ID",
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 3a1f7243ad..5fac651fa3 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -119,6 +119,7 @@ enum igt_atomic_crtc_properties {
        IGT_CRTC_CTM = 0,
        IGT_CRTC_GAMMA_LUT,
        IGT_CRTC_GAMMA_LUT_SIZE,
+       IGT_CRTC_GAMMA_MODE,
        IGT_CRTC_DEGAMMA_LUT,
        IGT_CRTC_DEGAMMA_LUT_SIZE,
        IGT_CRTC_MODE_ID,
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 12/15] kms_color_helper: Add helper functions to support logarithmic gamma mode
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (10 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 11/15] lib/igt_kms: Add pipe color mgmt properties Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 13/15] tests/kms_color: Extended IGT tests " Bhanuprakash Modem
                     ` (2 subsequent siblings)
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Mukunda Pramodh Kumar, Pekka Paalanen

From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>

Add helper functions to support logarithmic gamma mode

v2:
* Refactor the logic (Bhanu)

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_helper.c | 123 +++++++++++++++++++++++++++++++++++++++
 tests/kms_color_helper.h |  15 +++++
 2 files changed, 138 insertions(+)

diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
index e1d821f778..636eb33164 100644
--- a/tests/kms_color_helper.c
+++ b/tests/kms_color_helper.c
@@ -120,6 +120,30 @@ gamma_lut_t *generate_table(int lut_size, double exp)
 	return gamma;
 }
 
+gamma_lut_t *generate_table_unity(segment_data_t *info)
+{
+	uint32_t segment, entry, index = 0;
+	double val;
+	int i = 0;
+	gamma_lut_t *gamma = alloc_lut(info->entries_count);
+	igt_assert(gamma);
+
+	for (segment = 0; segment < info->segment_count; segment++) {
+		uint32_t entry_count = info->segment_data[segment].count;
+		uint32_t start = (segment == 0) ? 0 : (1 << (segment - 1));
+		uint32_t end = 1 << segment;
+
+		for (entry = 0; entry < entry_count; entry++) {
+			val = start + entry * ((end - start) * 1.0 / entry_count);
+
+			set_rgb(&gamma->coeffs[i++], val);
+			index++;
+		}
+	}
+
+	return gamma;
+}
+
 gamma_lut_t *generate_table_max(int lut_size)
 {
 	gamma_lut_t *gamma = alloc_lut(lut_size);
@@ -190,6 +214,31 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
 	return lut;
 }
 
+struct drm_color_lut *coeffs_to_lut_adv(data_t *data,
+					const gamma_lut_t *gamma,
+					int max_hw_value)
+{
+	struct drm_color_lut *lut;
+	int i, lut_size = gamma->size;
+	uint32_t max_value = (1 << 16) - 1;
+
+	lut = malloc(sizeof(struct drm_color_lut) * lut_size);
+	igt_assert(lut);
+
+	for (i = 0; i < lut_size; i++) {
+		double scaling_factor = (double)max_value / (double)max_hw_value;
+		uint32_t r = MIN((gamma->coeffs[i].r * scaling_factor), max_value);
+		uint32_t g = MIN((gamma->coeffs[i].g * scaling_factor), max_value);
+		uint32_t b = MIN((gamma->coeffs[i].b * scaling_factor), max_value);
+
+		lut[i].red = r;
+		lut[i].green = g;
+		lut[i].blue = b;
+	}
+
+	return lut;
+}
+
 void set_degamma(data_t *data,
 		 igt_pipe_t *pipe,
 		 const gamma_lut_t *gamma)
@@ -203,6 +252,15 @@ void set_degamma(data_t *data,
 	free(lut);
 }
 
+void set_pipe_gamma(igt_pipe_t *pipe,
+		    uint64_t value,
+		    struct drm_color_lut *lut,
+		    uint32_t size)
+{
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_GAMMA_MODE, value);
+	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
+}
+
 void set_gamma(data_t *data,
 	       igt_pipe_t *pipe, const gamma_lut_t *gamma)
 {
@@ -249,6 +307,23 @@ void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
 		igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
 }
 
+drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
+					       enum igt_atomic_crtc_properties prop)
+{
+	igt_display_t *display = pipe->display;
+	uint32_t prop_id = pipe->props[prop];
+	drmModePropertyPtr drmProp;
+
+	igt_assert(prop_id);
+
+	drmProp = drmModeGetProperty(display->drm_fd, prop_id);
+
+	igt_assert(drmProp);
+	igt_assert(drmProp->count_enums);
+
+	return drmProp;
+}
+
 drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
 				enum igt_atomic_plane_properties prop)
 {
@@ -335,6 +410,7 @@ segment_data_t *get_segment_data(data_t *data,
 	info->segment_data = malloc(sizeof(struct drm_color_lut_range) * info->segment_count);
 	igt_assert(info->segment_data);
 
+	info->entries_count = 0;
 	for (i = 0; i < info->segment_count; i++) {
 		info->entries_count += lut_range[i].count;
 		info->segment_data[i] = lut_range[i];
@@ -345,6 +421,53 @@ segment_data_t *get_segment_data(data_t *data,
 	return info;
 }
 
+void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type)
+{
+	igt_display_t *display = &data->display;
+	gamma_lut_t *gamma_log;
+	drmModePropertyPtr gamma_mode = NULL;
+	segment_data_t *segment_info = NULL;
+	struct drm_color_lut *lut = NULL;
+	int lut_size = 0;
+	int max_hw_value = 0;
+
+	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
+	gamma_mode = get_pipe_gamma_degamma_mode(pipe, IGT_CRTC_GAMMA_MODE);
+
+	for (int i = 0; i < gamma_mode->count_enums; i++) {
+		if (!strcmp(gamma_mode->enums[i].name, "logarithmic gamma")) {
+			segment_info = get_segment_data(data,
+							gamma_mode->enums[i].value,
+							gamma_mode->enums[i].name);
+			lut_size = sizeof(struct drm_color_lut) *
+					  segment_info->entries_count;
+			max_hw_value = segment_info->segment_data[segment_info->segment_count - 1].end;
+			gamma_log->size = segment_info->entries_count;
+
+			if (type == UNITY_GAMMA) {
+				gamma_log = generate_table_unity(segment_info);
+				lut = coeffs_to_lut_adv(data, gamma_log, max_hw_value);
+			} else if (type == MAX_GAMMA) {
+				gamma_log = generate_table_max(segment_info->entries_count);
+				lut = coeffs_to_lut(data, gamma_log, data->color_depth, 0);
+			}
+			if (is_i915_device(data->drm_fd))
+				lut[0].red = lut[0].green = lut[0].blue = 0;
+
+			set_pipe_gamma(pipe, gamma_mode->enums[i].value,
+				       lut, lut_size);
+			igt_display_commit2(display, display->is_atomic
+					    ? COMMIT_ATOMIC : COMMIT_LEGACY);
+			break;
+		}
+	}
+	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
+	free(gamma_log);
+	free(lut);
+	clear_segment_data(segment_info);
+	drmModeFreeProperty(gamma_mode);
+}
+
 void set_plane_gamma(igt_plane_t *plane,
 		char *mode,
 		struct drm_color_lut_ext *lut,
diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
index 06c0dc22c4..3bb4076957 100644
--- a/tests/kms_color_helper.h
+++ b/tests/kms_color_helper.h
@@ -70,6 +70,11 @@ typedef struct {
 	uint32_t entries_count;
 } segment_data_t;
 
+enum gamma_type {
+	UNITY_GAMMA,
+	MAX_GAMMA
+};
+
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 
 void paint_gradient_rectangles(data_t *data,
@@ -85,10 +90,14 @@ void free_lut(gamma_lut_t *gamma);
 gamma_lut_t *generate_table(int lut_size, double exp);
 gamma_lut_t *generate_table_max(int lut_size);
 gamma_lut_t *generate_table_zero(int lut_size);
+gamma_lut_t *generate_table_unity(segment_data_t *info);
 struct drm_color_lut *coeffs_to_lut(data_t *data,
 				    const gamma_lut_t *gamma,
 				    uint32_t color_depth,
 				    int off);
+struct drm_color_lut *coeffs_to_lut_adv(data_t *data,
+						const gamma_lut_t *gamma,
+						int max_hw_value);
 void set_degamma(data_t *data,
 		 igt_pipe_t *pipe,
 		 const gamma_lut_t *gamma);
@@ -98,12 +107,18 @@ void set_gamma(data_t *data,
 void set_ctm(igt_pipe_t *pipe, const double *coefficients);
 void disable_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
 
+drmModePropertyPtr get_pipe_gamma_degamma_mode(igt_pipe_t *pipe,
+					       enum igt_atomic_crtc_properties
+					       prop);
 drmModePropertyPtr get_plane_gamma_degamma_mode(igt_plane_t *plane,
 	enum igt_atomic_plane_properties prop);
 void clear_segment_data(segment_data_t *info);
 struct drm_color_lut_ext *create_unity_lut(segment_data_t *info);
 struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
 segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
+void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
+		    struct drm_color_lut *lut, uint32_t size);
+void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type type);
 void set_plane_gamma(igt_plane_t *plane,
 	char *mode, struct drm_color_lut_ext *lut, uint32_t size);
 void set_plane_degamma(igt_plane_t *plane,
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 13/15] tests/kms_color: Extended IGT tests to support logarithmic gamma mode
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (11 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 12/15] kms_color_helper: Add helper functions to support logarithmic gamma mode Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 14/15] tests/kms_color_chamelium: " Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 15/15] HAX: Add color mgmt tests to BAT Bhanuprakash Modem
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Mukunda Pramodh Kumar, Pekka Paalanen

From: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>

Extended IGT tests to support logarithmic gamma mode on pipe

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index 638d838757..430868f922 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -208,8 +208,6 @@ static void test_pipe_gamma(data_t *data,
 
 	igt_require(igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_LUT));
 
-	gamma_full = generate_table_max(data->gamma_lut_size);
-
 	output = igt_get_single_output_for_pipe(&data->display, primary->pipe->pipe);
 	igt_require(output);
 
@@ -234,10 +232,13 @@ static void test_pipe_gamma(data_t *data,
 	igt_assert(fb_modeset_id);
 
 	igt_plane_set_fb(primary, &fb_modeset);
+	/* Reset Color properties */
 	disable_ctm(primary->pipe);
 	disable_degamma(primary->pipe);
-	set_gamma(data, primary->pipe, gamma_full);
+	disable_gamma(primary->pipe);
 	igt_display_commit(&data->display);
+	igt_wait_for_vblank(data->drm_fd,
+			    display->pipes[primary->pipe->pipe].crtc_offset);
 
 	/* Draw solid colors with no gamma transformation. */
 	paint_rectangles(data, mode, red_green_blue, &fb);
@@ -250,6 +251,13 @@ static void test_pipe_gamma(data_t *data,
 	/* Draw a gradient with gamma LUT to remap all values
 	 * to max red/green/blue.
 	 */
+	if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE)) {
+		set_advance_gamma(data, primary->pipe, MAX_GAMMA);
+	} else {
+		gamma_full = generate_table_max(data->gamma_lut_size);
+		set_gamma(data, primary->pipe, gamma_full);
+		igt_display_commit(&data->display);
+	}
 	paint_gradient_rectangles(data, mode, red_green_blue, &fb);
 	igt_plane_set_fb(primary, &fb);
 	igt_display_commit(&data->display);
@@ -557,7 +565,10 @@ static bool test_pipe_ctm(data_t *data,
 	 */
 	if (memcmp(before, after, sizeof(color_t))) {
 		set_degamma(data, primary->pipe, degamma_linear);
-		set_gamma(data, primary->pipe, gamma_linear);
+		if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE))
+			disable_gamma(primary->pipe);
+		else
+			set_gamma(data, primary->pipe, gamma_linear);
 	} else {
 		/* Disable Degamma and Gamma for ctm max test */
 		disable_degamma(primary->pipe);
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 14/15] tests/kms_color_chamelium: Extended IGT tests to support logarithmic gamma mode
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (12 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 13/15] tests/kms_color: Extended IGT tests " Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 15/15] HAX: Add color mgmt tests to BAT Bhanuprakash Modem
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Kunal Joshi, Mukunda Pramodh Kumar, Pekka Paalanen

Extended IGT tests to support logarithmic gamma mode on pipe

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Mukunda Pramodh Kumar <mukunda.pramodh.kumar@intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/kms_color_chamelium.c | 40 ++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index a9469f9827..c6cd568c29 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -293,10 +293,21 @@ static void test_pipe_gamma(data_t *data,
 		igt_assert(fbref_id);
 
 		igt_plane_set_fb(primary, &fb_modeset);
+
+		/* Reset the color properties */
 		disable_ctm(primary->pipe);
 		disable_degamma(primary->pipe);
-		set_gamma(data, primary->pipe, gamma_full);
+		disable_gamma(primary->pipe);
 		igt_display_commit(&data->display);
+		igt_wait_for_vblank(data->drm_fd,
+				    data->display.pipes[primary->pipe->pipe].crtc_offset);
+
+		if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE)) {
+			set_advance_gamma(data, primary->pipe, MAX_GAMMA);
+		} else {
+			set_gamma(data, primary->pipe, gamma_full);
+			igt_display_commit(&data->display);
+		}
 
 		/* Draw solid colors with no gamma transformation. */
 		paint_rectangles(data, mode, red_green_blue, &fbref);
@@ -319,6 +330,7 @@ static void test_pipe_gamma(data_t *data,
 					      frame_fullcolors, &fbref,
 					      CHAMELIUM_CHECK_ANALOG);
 
+		/* Cleanup */
 		disable_gamma(primary->pipe);
 		igt_plane_set_fb(primary, NULL);
 		igt_output_set_pipe(output, PIPE_NONE);
@@ -407,7 +419,10 @@ static bool test_pipe_ctm(data_t *data,
 
 		if (memcmp(before, after, sizeof(color_t))) {
 			set_degamma(data, primary->pipe, degamma_linear);
-			set_gamma(data, primary->pipe, gamma_linear);
+			if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE))
+				disable_gamma(primary->pipe);
+			else
+				set_gamma(data, primary->pipe, gamma_linear);
 		} else {
 			/* Disable Degamma and Gamma for ctm max test */
 			disable_degamma(primary->pipe);
@@ -441,6 +456,12 @@ static bool test_pipe_ctm(data_t *data,
 		igt_output_set_pipe(output, PIPE_NONE);
 	}
 
+	/* Cleanup */
+	disable_gamma(primary->pipe);
+	disable_degamma(primary->pipe);
+	disable_ctm(primary->pipe);
+	igt_display_commit(&data->display);
+
 	free_lut(degamma_linear);
 	free_lut(gamma_linear);
 
@@ -537,7 +558,14 @@ static void test_pipe_limited_range_ctm(data_t *data,
 		igt_plane_set_fb(primary, &fb_modeset);
 
 		set_degamma(data, primary->pipe, degamma_linear);
-		set_gamma(data, primary->pipe, gamma_linear);
+		/*
+		 * No need of linear gamma for limited range ctm test
+		 * Not extending for new API interface.
+		 */
+		if (igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_MODE))
+			disable_gamma(primary->pipe);
+		else
+			set_gamma(data, primary->pipe, gamma_linear);
 		set_ctm(primary->pipe, ctm);
 
 		igt_output_set_prop_value(output,
@@ -574,6 +602,12 @@ static void test_pipe_limited_range_ctm(data_t *data,
 
 	}
 
+	/* Cleanup */
+	disable_gamma(primary->pipe);
+	disable_degamma(primary->pipe);
+	disable_ctm(primary->pipe);
+	igt_display_commit(&data->display);
+
 	free_lut(gamma_linear);
 	free_lut(degamma_linear);
 
-- 
2.32.0

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

* [igt-dev] [v2 i-g-t 15/15] HAX: Add color mgmt tests to BAT
  2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
                     ` (13 preceding siblings ...)
  2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 14/15] tests/kms_color_chamelium: " Bhanuprakash Modem
@ 2022-01-04  7:57   ` Bhanuprakash Modem
  14 siblings, 0 replies; 96+ messages in thread
From: Bhanuprakash Modem @ 2022-01-04  7:57 UTC (permalink / raw)
  To: igt-dev

Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
---
 tests/intel-ci/fast-feedback.testlist | 112 ++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)

diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist
index de1c6cb46c..0bdd82f9bc 100644
--- a/tests/intel-ci/fast-feedback.testlist
+++ b/tests/intel-ci/fast-feedback.testlist
@@ -102,6 +102,118 @@ igt@kms_chamelium@hdmi-crc-fast
 igt@kms_chamelium@vga-hpd-fast
 igt@kms_chamelium@vga-edid-read
 igt@kms_chamelium@common-hpd-after-suspend
+igt@kms_color@pipe-A-ctm-red-to-blue
+igt@kms_color@pipe-A-ctm-green-to-red
+igt@kms_color@pipe-A-ctm-blue-to-red
+igt@kms_color@pipe-A-ctm-0-25
+igt@kms_color@pipe-A-ctm-0-5
+igt@kms_color@pipe-A-ctm-0-75
+igt@kms_color@pipe-A-ctm-max
+igt@kms_color@pipe-A-ctm-negative
+igt@kms_color@pipe-A-degamma
+igt@kms_color@pipe-A-gamma
+igt@kms_color@pipe-A-legacy-gamma
+igt@kms_color@pipe-A-legacy-gamma-reset
+igt@kms_color@pipe-A-invalid-gamma-lut-sizes
+igt@kms_color@pipe-A-invalid-degamma-lut-sizes
+igt@kms_color@pipe-A-invalid-ctm-matrix-sizes
+igt@kms_color@pipe-A-plane-gamma
+igt@kms_color@pipe-A-plane-degamma
+igt@kms_color@pipe-A-plane-ctm-red-to-blue
+igt@kms_color@pipe-A-plane-ctm-green-to-red
+igt@kms_color@pipe-A-plane-ctm-blue-to-red
+igt@kms_color@pipe-A-plane-ctm-max
+igt@kms_color@pipe-A-plane-ctm-negative
+igt@kms_color@pipe-A-plane-ctm-0-25
+igt@kms_color@pipe-A-plane-ctm-0-50
+igt@kms_color@pipe-A-plane-ctm-0-75
+igt@kms_color@pipe-A-invalid-plane-gamma-lut-sizes
+igt@kms_color@pipe-A-invalid-plane-degamma-lut-sizes
+igt@kms_color@pipe-A-invalid-plane-ctm-matrix-sizes
+igt@kms_color@pipe-B-ctm-red-to-blue
+igt@kms_color@pipe-B-ctm-green-to-red
+igt@kms_color@pipe-B-ctm-blue-to-red
+igt@kms_color@pipe-B-ctm-0-25
+igt@kms_color@pipe-B-ctm-0-5
+igt@kms_color@pipe-B-ctm-0-75
+igt@kms_color@pipe-B-ctm-max
+igt@kms_color@pipe-B-ctm-negative
+igt@kms_color@pipe-B-degamma
+igt@kms_color@pipe-B-gamma
+igt@kms_color@pipe-B-legacy-gamma
+igt@kms_color@pipe-B-legacy-gamma-reset
+igt@kms_color@pipe-B-invalid-gamma-lut-sizes
+igt@kms_color@pipe-B-invalid-degamma-lut-sizes
+igt@kms_color@pipe-B-invalid-ctm-matrix-sizes
+igt@kms_color@pipe-B-plane-gamma
+igt@kms_color@pipe-B-plane-degamma
+igt@kms_color@pipe-B-plane-ctm-red-to-blue
+igt@kms_color@pipe-B-plane-ctm-green-to-red
+igt@kms_color@pipe-B-plane-ctm-blue-to-red
+igt@kms_color@pipe-B-plane-ctm-max
+igt@kms_color@pipe-B-plane-ctm-negative
+igt@kms_color@pipe-B-plane-ctm-0-25
+igt@kms_color@pipe-B-plane-ctm-0-50
+igt@kms_color@pipe-B-plane-ctm-0-75
+igt@kms_color@pipe-B-invalid-plane-gamma-lut-sizes
+igt@kms_color@pipe-B-invalid-plane-degamma-lut-sizes
+igt@kms_color@pipe-B-invalid-plane-ctm-matrix-sizes
+igt@kms_color@pipe-C-ctm-red-to-blue
+igt@kms_color@pipe-C-ctm-green-to-red
+igt@kms_color@pipe-C-ctm-blue-to-red
+igt@kms_color@pipe-C-ctm-0-25
+igt@kms_color@pipe-C-ctm-0-5
+igt@kms_color@pipe-C-ctm-0-75
+igt@kms_color@pipe-C-ctm-max
+igt@kms_color@pipe-C-ctm-negative
+igt@kms_color@pipe-C-degamma
+igt@kms_color@pipe-C-gamma
+igt@kms_color@pipe-C-legacy-gamma
+igt@kms_color@pipe-C-legacy-gamma-reset
+igt@kms_color@pipe-C-invalid-gamma-lut-sizes
+igt@kms_color@pipe-C-invalid-degamma-lut-sizes
+igt@kms_color@pipe-C-invalid-ctm-matrix-sizes
+igt@kms_color@pipe-C-plane-gamma
+igt@kms_color@pipe-C-plane-degamma
+igt@kms_color@pipe-C-plane-ctm-red-to-blue
+igt@kms_color@pipe-C-plane-ctm-green-to-red
+igt@kms_color@pipe-C-plane-ctm-blue-to-red
+igt@kms_color@pipe-C-plane-ctm-max
+igt@kms_color@pipe-C-plane-ctm-negative
+igt@kms_color@pipe-C-plane-ctm-0-25
+igt@kms_color@pipe-C-plane-ctm-0-50
+igt@kms_color@pipe-C-plane-ctm-0-75
+igt@kms_color@pipe-C-invalid-plane-gamma-lut-sizes
+igt@kms_color@pipe-C-invalid-plane-degamma-lut-sizes
+igt@kms_color@pipe-C-invalid-plane-ctm-matrix-sizes
+igt@kms_color@pipe-D-ctm-red-to-blue
+igt@kms_color@pipe-D-ctm-green-to-red
+igt@kms_color@pipe-D-ctm-blue-to-red
+igt@kms_color@pipe-D-ctm-0-25
+igt@kms_color@pipe-D-ctm-0-5
+igt@kms_color@pipe-D-ctm-0-75
+igt@kms_color@pipe-D-ctm-max
+igt@kms_color@pipe-D-ctm-negative
+igt@kms_color@pipe-D-degamma
+igt@kms_color@pipe-D-gamma
+igt@kms_color@pipe-D-legacy-gamma
+igt@kms_color@pipe-D-legacy-gamma-reset
+igt@kms_color@pipe-D-invalid-gamma-lut-sizes
+igt@kms_color@pipe-D-invalid-degamma-lut-sizes
+igt@kms_color@pipe-D-invalid-ctm-matrix-sizes
+igt@kms_color@pipe-D-plane-gamma
+igt@kms_color@pipe-D-plane-degamma
+igt@kms_color@pipe-D-plane-ctm-red-to-blue
+igt@kms_color@pipe-D-plane-ctm-green-to-red
+igt@kms_color@pipe-D-plane-ctm-blue-to-red
+igt@kms_color@pipe-D-plane-ctm-max
+igt@kms_color@pipe-D-plane-ctm-negative
+igt@kms_color@pipe-D-plane-ctm-0-25
+igt@kms_color@pipe-D-plane-ctm-0-50
+igt@kms_color@pipe-D-plane-ctm-0-75
+igt@kms_color@pipe-D-invalid-plane-gamma-lut-sizes
+igt@kms_color@pipe-D-invalid-plane-degamma-lut-sizes
+igt@kms_color@pipe-D-invalid-plane-ctm-matrix-sizes
 igt@kms_prop_blob@basic
 igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic
 igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy
-- 
2.32.0

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

* Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
  2022-01-03  4:05       ` [igt-dev] " Modem, Bhanuprakash
  (?)
@ 2022-01-04 21:19       ` Harry Wentland
  2022-01-05 11:21           ` [igt-dev] " Modem, Bhanuprakash
  -1 siblings, 1 reply; 96+ messages in thread
From: Harry Wentland @ 2022-01-04 21:19 UTC (permalink / raw)
  To: Modem, Bhanuprakash, igt-dev, dri-devel; +Cc: Shankar, Uma



On 2022-01-02 23:05, Modem, Bhanuprakash wrote:
>> From: Harry Wentland <harry.wentland@amd.com>
>> Sent: Friday, November 26, 2021 10:25 PM
>> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
>> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Juha-Pekka Heikkila
>> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
>> Subject: Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
>>
>> On 2021-11-15 04:47, Bhanuprakash Modem wrote:
>>> To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
>>> with a maxed out gamma LUT and verify we have the same CRC as drawing solid
>>> color rectangles.
>>>
>>> Cc: Harry Wentland <harry.wentland@amd.com>
>>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>>> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
>>> Cc: Uma Shankar <uma.shankar@intel.com>
>>> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
>>> ---
>>>  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
>>>  1 file changed, 178 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/tests/kms_color.c b/tests/kms_color.c
>>> index 775f35964f..b45d66762f 100644
>>> --- a/tests/kms_color.c
>>> +++ b/tests/kms_color.c
>>> @@ -24,7 +24,34 @@
>>>
>>>  #include "kms_color_helper.h"
>>>
>>> -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
>>> +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
>>> +
>>> +#define MAX_SUPPORTED_PLANES 7
>>> +#define SDR_PLANE_BASE 3
>>> +
>>> +typedef bool (*test_t)(data_t*, igt_plane_t*);
>>> +
>>> +static bool is_hdr_plane(const igt_plane_t *plane)
>>> +{
>>> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
>>> +}
>>> +
>>> +static bool is_valid_plane(igt_plane_t *plane)
>>> +{
>>> +	int index = plane->index;
>>> +
>>> +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
>>> +		return false;
>>> +
>>> +	/*
>>> +	 * Test 1 HDR plane, 1 SDR plane.
>>> +	 *
>>> +	 * 0,1,2 HDR planes
>>> +	 * 3,4,5,6 SDR planes
>>> +	 *
>>> +	 */
>>
>> This seems to be about Intel HW. AMD HW for example does
>> not have HDR or SDR planes, only one generic plane.
>>
>>> +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
>>> +}
>>>
>>>  static void test_pipe_degamma(data_t *data,
>>>  			      igt_plane_t *primary)
>>> @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t *data,
>>>  }
>>>  #endif
>>>
>>> +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
>>> +{
>>> +	igt_output_t *output;
>>> +	igt_display_t *display = &data->display;
>>> +	drmModeModeInfo *mode;
>>> +	struct igt_fb fb;
>>> +	drmModePropertyPtr gamma_mode = NULL;
>>> +	uint32_t i;
>>> +	bool ret = true;
>>> +	igt_pipe_crc_t *pipe_crc = NULL;
>>> +	color_t red_green_blue[] = {
>>> +		{ 1.0, 0.0, 0.0 },
>>> +		{ 0.0, 1.0, 0.0 },
>>> +		{ 0.0, 0.0, 1.0 }
>>> +	};
>>> +
>>> +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
>>> +			kmstest_pipe_name(plane->pipe->pipe),
>>> +			kmstest_plane_type_name(plane->type),
>>> +			is_hdr_plane(plane) ? "hdr":"sdr");
>>> +
>>
>> is_hdr_plane is Intel-specific.
>>
>>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
>>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
>>> +
>>> +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
>>> +				  plane->pipe->pipe,
>>> +				  INTEL_PIPE_CRC_SOURCE_AUTO);
>>> +
>>> +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
>>> +	igt_assert(output);
>>> +
>>> +	igt_output_set_pipe(output, plane->pipe->pipe);
>>> +	mode = igt_output_get_mode(output);
>>> +
>>> +	/* Create a framebuffer at the size of the output. */
>>> +	igt_assert(igt_create_fb(data->drm_fd,
>>> +			      mode->hdisplay,
>>> +			      mode->vdisplay,
>>> +			      DRM_FORMAT_XRGB8888,
>>> +			      DRM_FORMAT_MOD_LINEAR,
>>> +			      &fb));
>>> +	igt_plane_set_fb(plane, &fb);
>>> +
>>> +	/* Disable Pipe color props. */
>>> +	disable_ctm(plane->pipe);
>>> +	disable_degamma(plane->pipe);
>>> +	disable_gamma(plane->pipe);
>>> +
>>> +	disable_plane_ctm(plane);
>>> +	disable_plane_degamma(plane);
>>> +	igt_display_commit2(display, display->is_atomic ?
>>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
>>> +
>>> +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
>>> +
>>> +	/* Iterate all supported gamma modes. */
>>> +	for (i = 0; i < gamma_mode->count_enums; i++) {
>>> +		igt_crc_t crc_gamma, crc_fullcolors;
>>> +		segment_data_t *segment_info = NULL;
>>> +		struct drm_color_lut_ext *lut = NULL;
>>> +		uint32_t lut_size = 0;
>>> +
>>> +		/* Ignore 'no gamma' from enum list. */
>>> +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
>>> +			continue;
>>> +
>>
>> It might still make sense to test that this is doing bypass.
> 
> As we know gamma_mode->enum[i].name represents the name of the
> gamma mode and gamma_mode->enum[i].value would be the LUT blob
> address of that particular gamma_mode.
> 
> For "no gamma" case the blob address is NULL, so we can't commit
> this mode. Hence skipping this mode.
> 

I was thinking it'd be good to test the "no gamma" case as well
here, i.e. the case were we set a NULL blob. I'm not sure what
you mean when you say "we can't commit this mode."

Harry

>>
>>> +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode-
>>> enums[i].name);
>>> +
>>> +		/* Draw solid colors with no gamma transformation. */
>>> +		disable_plane_gamma(plane);
>>> +		paint_rectangles(data, mode, red_green_blue, &fb);
>>> +		igt_plane_set_fb(plane, &fb);
>>> +		igt_display_commit2(display, display->is_atomic ?
>>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
>>> +		igt_wait_for_vblank(data->drm_fd,
>>> +			display->pipes[plane->pipe->pipe].crtc_offset);
>>> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
>>> +
>>> +		/* Draw gradient colors with gamma LUT to remap all
>>> +		 * values to max red/green/blue.
>>> +		 */
>>> +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
>>> +				gamma_mode->enums[i].name);
>>> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
>>> entries_count;
>>> +		lut = create_max_lut(segment_info);
>>> +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
>>> +
>>> +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
>>> +		igt_plane_set_fb(plane, &fb);
>>> +		igt_display_commit2(display, display->is_atomic ?
>>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
>>> +		igt_wait_for_vblank(data->drm_fd,
>>> +			display->pipes[plane->pipe->pipe].crtc_offset);
>>> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
>>> +
>>> +		/* Verify that the CRC of the software computed output is
>>> +		 * equal to the CRC of the gamma LUT transformation output.
>>> +		 */
>>> +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
>>> +
>>> +		free(lut);
>>> +		clear_segment_data(segment_info);
>>> +	}
>>> +
>>> +	disable_plane_gamma(plane);
>>> +	igt_plane_set_fb(plane, NULL);
>>> +	igt_output_set_pipe(output, PIPE_NONE);
>>> +	igt_display_commit2(display, display->is_atomic ?
>>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
>>> +
>>> +	igt_pipe_crc_free(pipe_crc);
>>> +	drmModeFreeProperty(gamma_mode);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>>  static void
>>>  prep_pipe(data_t *data, enum pipe p)
>>>  {
>>> @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe p)
>>>  		invalid_ctm_matrix_sizes(data, p);
>>>  }
>>>
>>> +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t test)
>>> +{
>>> +	igt_plane_t *plane;
>>> +	int count = 0;
>>> +
>>> +	for_each_plane_on_pipe(&data->display, pipe, plane) {
>>> +		if (!is_valid_plane(plane))
>>> +			continue;
>>> +
>>> +		igt_assert(test(data, plane));
>>> +
>>> +		count++;
>>> +	}
>>> +
>>> +	igt_require_f(count, "No valid planes found.\n");
>>> +}
>>> +
>>> +static void run_tests_for_plane(data_t *data, enum pipe pipe)
>>> +{
>>> +	igt_fixture {
>>> +		igt_require_pipe(&data->display, pipe);
>>> +		igt_require_pipe_crc(data->drm_fd);
>>> +		igt_require(data->display.pipes[pipe].n_planes > 0);
>>> +		igt_display_require_output_on_pipe(&data->display, pipe);
>>> +	}
>>> +
>>> +	igt_describe("Compare maxed out plane gamma LUT and solid color linear
>> LUT");
>>
>> I can't seem to see the linear LUT test. This only seems to test
>> the max LUT.
>>
>> Harry
>>
>>> +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
>>> +		run_plane_color_test(data, pipe, plane_gamma_test);
>>> +}
>>> +
>>>  igt_main
>>>  {
>>>  	data_t data = {};
>>> @@ -910,6 +1084,9 @@ igt_main
>>>
>>>  		igt_subtest_group
>>>  			run_invalid_tests_for_pipe(&data, pipe);
>>> +
>>> +		igt_subtest_group
>>> +			run_tests_for_plane(&data, pipe);
>>>  	}
>>>
>>>  	igt_fixture {
>>>
> 

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

* Re: [i-g-t 00/14] Add IGT support for plane color management
  2022-01-03  4:11           ` [igt-dev] " Modem, Bhanuprakash
  (?)
@ 2022-01-04 22:01           ` Harry Wentland
  -1 siblings, 0 replies; 96+ messages in thread
From: Harry Wentland @ 2022-01-04 22:01 UTC (permalink / raw)
  To: Modem, Bhanuprakash, Pekka Paalanen
  Cc: igt-dev, Shankar, Uma, Kumar, Mukunda Pramodh, dri-devel



On 2022-01-02 23:11, Modem, Bhanuprakash wrote:
>> From: Harry Wentland <harry.wentland@amd.com>
>> Sent: Monday, November 29, 2021 8:50 PM
>> To: Pekka Paalanen <ppaalanen@gmail.com>
>> Cc: dri-devel@lists.freedesktop.org; Modem, Bhanuprakash
>> <bhanuprakash.modem@intel.com>; igt-dev@lists.freedesktop.org; Kumar,
>> Mukunda Pramodh <mukunda.pramodh.kumar@intel.com>; Juha-Pekka Heikkila
>> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
>> Subject: Re: [i-g-t 00/14] Add IGT support for plane color management
>>
>> On 2021-11-29 04:20, Pekka Paalanen wrote:
>>> On Fri, 26 Nov 2021 11:54:55 -0500
>>> Harry Wentland <harry.wentland@amd.com> wrote:
>>>
>>>> On 2021-11-18 04:50, Pekka Paalanen wrote:
>>>>> On Mon, 15 Nov 2021 15:17:45 +0530
>>>>> Bhanuprakash Modem <bhanuprakash.modem@intel.com> wrote:
>>>>>
>>>>>> From the Plane Color Management feature design, userspace can
>>>>>> take the smart blending decisions based on hardware supported
>>>>>> plane color features to obtain an accurate color profile.
>>>>>>
>>>>>> These IGT patches extend the existing pipe color management
>>>>>> tests to the plane level.
>>>>>>
>>>>>> Kernel implementation:
>>>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatchwork.freedesktop.org%2Fseries%2F90825%2F&amp;data=04%7C01%7Charry.wentland%40amd.com%7C6d85b55209204b9b1e6108d9ce6f30f6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637767799222764784%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=j%2BkGUD45bTIke%2FIeCO7GGAM1n%2FCrF2oy6CKfLc6jhzk%3D&amp;reserved=0
>>>
>>> ...
>>>
>>>>> I also found some things that looked hardware-specific in this code
>>>>> that to my understanding is supposed to be generic, and some concerns
>>>>> about UAPI as well.
>>>>>
>>>>
>>>> I left some comments on intellisms in these patches.
>>>>
>>>> Do you have any specifics about your concerns about UAPI?
>>>
>>> Yeah, the comments I left in the patches:
>>>
>>> patch 3:
>>>
>>>> Having to explicitly special-case index zero feels odd to me. Why does
>>>> it need explicit special-casing?
>>>>
>>>> To me it's a hint that the definitions of .start and .end are somehow
>>>> inconsistent.
>>>
>>> patch 4 and 8:
>>>
>>>>> +static bool is_hdr_plane(const igt_plane_t *plane)
>>>>> +{
>>>>> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
>>>>
>>>> How can this be right for all KMS drivers?
>>>>
>>>> What is a HDR plane?
>>>
>>> patch 12:
>>>
>>>>> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
>>>>> +						const gamma_lut_t *gamma,
>>>>> +						uint32_t color_depth,
>>>>> +						int off)
>>>>> +{
>>>>> +	struct drm_color_lut *lut;
>>>>> +	int i, lut_size = gamma->size;
>>>>> +	/* This is the maximum value due to 16 bit precision in hardware. */
>>>>
>>>> In whose hardware?
>>>>
>>>> Are igt tests not supposed to be generic for everything that exposes
>>>> the particular KMS properties?
>>>>
>>>> This also hints that the UAPI design is lacking, because userspace
>>>> needs to know hardware specific things out of thin air. Display servers
>>>> are not going to have hardware-specific code. They specialise based on
>>>> the existence of KMS properties instead.
>>>
>>> ...
>>>
>>>>> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type
>> type)
>>>>> +{
>>>>> +	igt_display_t *display = &data->display;
>>>>> +	gamma_lut_t *gamma_log;
>>>>> +	drmModePropertyPtr gamma_mode = NULL;
>>>>> +	segment_data_t *segment_info = NULL;
>>>>> +	struct drm_color_lut *lut = NULL;
>>>>> +	int lut_size = 0;
>>>>> +
>>>>> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);
>>>>
>>>> Is this how we are going to do cross-software DRM-master hand-over or
>>>> switching compatibility in general?
>>>>
>>>> Add a new client cap for every new KMS property, and if the KMS client
>>>> does not set the property, the kernel will magically reset it to ensure
>>>> the client's expectations are met? Is that how it works?
>>>>
>>>> Or why does this exist?
>>>
>>> ...
>>>
>>>>> +	drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);
>>>>
>>>> I've never seen this done before. I did not know client caps could be
>>>> reset.
>>>
>>>
>>> So, patch 12 has the biggest UAPI questions, and patch 3 may need a
>>> UAPI change as well. The comments in patches 4 and 8 could be addressed
>>> with just removing that code since the concept of HDR/SDR planes does
>>> not exist in UAPI. Or, if that concept is needed then it's another UAPI
>>> problem.
>>>
>>
>> Thanks for reiterating your points. I missed your earlier replies and
>> found them in my IGT folder just now.
>>
>> Looks like we're on the same page.
> 
> Thanks Pekka & Harry for the review. Apologies for late response. I thought
> that everyone is in holidays 😊. Now I am re-igniting this discussion.
> 

No worries.

> I have gone through all review comments and it's make sense to remove hardware
> specific stuff from the helper functions.
> 
> Patch 3:
> Intel hardware is expecting first LUT value as 0, still we can remove this logic
> from helper & handle in the subtest.
> 
> Patch 4 & 8:
> In this context, for you HDR & SDR plane stuff is just a matter of plane index.
> We are expecting to run tests on one HDR plane (index 0-3) & one SDR plane
> (index 3-6). I think we can update the logic to run tests on first & last plane.
> If you want to run on tests on all planes we need to pass an extra argument through
> command line. Please refer tests/kms_flip.c for similar implementation.
> 

I think that's fine for AMD HW. For us all planes are the same.

Harry

> Patch 12:
> It seems there is some confusion with the IGT comments & variable names, I'll
> refactor the logic & upload a new rev.
> 
> - Bhanu
> 
>>
>> Harry
>>
>>>
>>> Thanks,
>>> pq
>>>
> 

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

* RE: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
  2022-01-04 21:19       ` Harry Wentland
@ 2022-01-05 11:21           ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-05 11:21 UTC (permalink / raw)
  To: Harry Wentland, igt-dev, dri-devel; +Cc: Shankar, Uma

> From: Harry Wentland <harry.wentland@amd.com>
> Sent: Wednesday, January 5, 2022 2:49 AM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; ppaalanen@gmail.com
> Subject: Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
> 
> On 2022-01-02 23:05, Modem, Bhanuprakash wrote:
> >> From: Harry Wentland <harry.wentland@amd.com>
> >> Sent: Friday, November 26, 2021 10:25 PM
> >> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
> >> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Juha-Pekka Heikkila
> >> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> >> Subject: Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
> >>
> >> On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> >>> To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> >>> with a maxed out gamma LUT and verify we have the same CRC as drawing
> solid
> >>> color rectangles.
> >>>
> >>> Cc: Harry Wentland <harry.wentland@amd.com>
> >>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >>> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> >>> Cc: Uma Shankar <uma.shankar@intel.com>
> >>> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> >>> ---
> >>>  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
> >>>  1 file changed, 178 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/tests/kms_color.c b/tests/kms_color.c
> >>> index 775f35964f..b45d66762f 100644
> >>> --- a/tests/kms_color.c
> >>> +++ b/tests/kms_color.c
> >>> @@ -24,7 +24,34 @@
> >>>
> >>>  #include "kms_color_helper.h"
> >>>
> >>> -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
> >>> +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
> >>> +
> >>> +#define MAX_SUPPORTED_PLANES 7
> >>> +#define SDR_PLANE_BASE 3
> >>> +
> >>> +typedef bool (*test_t)(data_t*, igt_plane_t*);
> >>> +
> >>> +static bool is_hdr_plane(const igt_plane_t *plane)
> >>> +{
> >>> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> >>> +}
> >>> +
> >>> +static bool is_valid_plane(igt_plane_t *plane)
> >>> +{
> >>> +	int index = plane->index;
> >>> +
> >>> +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> >>> +		return false;
> >>> +
> >>> +	/*
> >>> +	 * Test 1 HDR plane, 1 SDR plane.
> >>> +	 *
> >>> +	 * 0,1,2 HDR planes
> >>> +	 * 3,4,5,6 SDR planes
> >>> +	 *
> >>> +	 */
> >>
> >> This seems to be about Intel HW. AMD HW for example does
> >> not have HDR or SDR planes, only one generic plane.
> >>
> >>> +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> >>> +}
> >>>
> >>>  static void test_pipe_degamma(data_t *data,
> >>>  			      igt_plane_t *primary)
> >>> @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t
> *data,
> >>>  }
> >>>  #endif
> >>>
> >>> +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> >>> +{
> >>> +	igt_output_t *output;
> >>> +	igt_display_t *display = &data->display;
> >>> +	drmModeModeInfo *mode;
> >>> +	struct igt_fb fb;
> >>> +	drmModePropertyPtr gamma_mode = NULL;
> >>> +	uint32_t i;
> >>> +	bool ret = true;
> >>> +	igt_pipe_crc_t *pipe_crc = NULL;
> >>> +	color_t red_green_blue[] = {
> >>> +		{ 1.0, 0.0, 0.0 },
> >>> +		{ 0.0, 1.0, 0.0 },
> >>> +		{ 0.0, 0.0, 1.0 }
> >>> +	};
> >>> +
> >>> +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
> >>> +			kmstest_pipe_name(plane->pipe->pipe),
> >>> +			kmstest_plane_type_name(plane->type),
> >>> +			is_hdr_plane(plane) ? "hdr":"sdr");
> >>> +
> >>
> >> is_hdr_plane is Intel-specific.
> >>
> >>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> >>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> >>> +
> >>> +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
> >>> +				  plane->pipe->pipe,
> >>> +				  INTEL_PIPE_CRC_SOURCE_AUTO);
> >>> +
> >>> +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
> >>> +	igt_assert(output);
> >>> +
> >>> +	igt_output_set_pipe(output, plane->pipe->pipe);
> >>> +	mode = igt_output_get_mode(output);
> >>> +
> >>> +	/* Create a framebuffer at the size of the output. */
> >>> +	igt_assert(igt_create_fb(data->drm_fd,
> >>> +			      mode->hdisplay,
> >>> +			      mode->vdisplay,
> >>> +			      DRM_FORMAT_XRGB8888,
> >>> +			      DRM_FORMAT_MOD_LINEAR,
> >>> +			      &fb));
> >>> +	igt_plane_set_fb(plane, &fb);
> >>> +
> >>> +	/* Disable Pipe color props. */
> >>> +	disable_ctm(plane->pipe);
> >>> +	disable_degamma(plane->pipe);
> >>> +	disable_gamma(plane->pipe);
> >>> +
> >>> +	disable_plane_ctm(plane);
> >>> +	disable_plane_degamma(plane);
> >>> +	igt_display_commit2(display, display->is_atomic ?
> >>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> >>> +
> >>> +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> >>> +
> >>> +	/* Iterate all supported gamma modes. */
> >>> +	for (i = 0; i < gamma_mode->count_enums; i++) {
> >>> +		igt_crc_t crc_gamma, crc_fullcolors;
> >>> +		segment_data_t *segment_info = NULL;
> >>> +		struct drm_color_lut_ext *lut = NULL;
> >>> +		uint32_t lut_size = 0;
> >>> +
> >>> +		/* Ignore 'no gamma' from enum list. */
> >>> +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> >>> +			continue;
> >>> +
> >>
> >> It might still make sense to test that this is doing bypass.
> >
> > As we know gamma_mode->enum[i].name represents the name of the
> > gamma mode and gamma_mode->enum[i].value would be the LUT blob
> > address of that particular gamma_mode.
> >
> > For "no gamma" case the blob address is NULL, so we can't commit
> > this mode. Hence skipping this mode.
> >
> 
> I was thinking it'd be good to test the "no gamma" case as well
> here, i.e. the case were we set a NULL blob. I'm not sure what
> you mean when you say "we can't commit this mode."

Sorry for the confusion, "no gamma" is intentional to disable the gamma.
I think, we just need to check that we can able to flip with this mode.
So, we need to update disable_plane_gamma() to use this mode.

Or are you thinking any specific usecase for this?

- Bhanu
 
> 
> Harry
> 
> >>
> >>> +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode-
> >>> enums[i].name);
> >>> +
> >>> +		/* Draw solid colors with no gamma transformation. */
> >>> +		disable_plane_gamma(plane);
> >>> +		paint_rectangles(data, mode, red_green_blue, &fb);
> >>> +		igt_plane_set_fb(plane, &fb);
> >>> +		igt_display_commit2(display, display->is_atomic ?
> >>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> >>> +		igt_wait_for_vblank(data->drm_fd,
> >>> +			display->pipes[plane->pipe->pipe].crtc_offset);
> >>> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
> >>> +
> >>> +		/* Draw gradient colors with gamma LUT to remap all
> >>> +		 * values to max red/green/blue.
> >>> +		 */
> >>> +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> >>> +				gamma_mode->enums[i].name);
> >>> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
> >>> entries_count;
> >>> +		lut = create_max_lut(segment_info);
> >>> +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
> >>> +
> >>> +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
> >>> +		igt_plane_set_fb(plane, &fb);
> >>> +		igt_display_commit2(display, display->is_atomic ?
> >>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> >>> +		igt_wait_for_vblank(data->drm_fd,
> >>> +			display->pipes[plane->pipe->pipe].crtc_offset);
> >>> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
> >>> +
> >>> +		/* Verify that the CRC of the software computed output is
> >>> +		 * equal to the CRC of the gamma LUT transformation output.
> >>> +		 */
> >>> +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
> >>> +
> >>> +		free(lut);
> >>> +		clear_segment_data(segment_info);
> >>> +	}
> >>> +
> >>> +	disable_plane_gamma(plane);
> >>> +	igt_plane_set_fb(plane, NULL);
> >>> +	igt_output_set_pipe(output, PIPE_NONE);
> >>> +	igt_display_commit2(display, display->is_atomic ?
> >>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> >>> +
> >>> +	igt_pipe_crc_free(pipe_crc);
> >>> +	drmModeFreeProperty(gamma_mode);
> >>> +
> >>> +	return ret;
> >>> +}
> >>> +
> >>>  static void
> >>>  prep_pipe(data_t *data, enum pipe p)
> >>>  {
> >>> @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe
> p)
> >>>  		invalid_ctm_matrix_sizes(data, p);
> >>>  }
> >>>
> >>> +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t
> test)
> >>> +{
> >>> +	igt_plane_t *plane;
> >>> +	int count = 0;
> >>> +
> >>> +	for_each_plane_on_pipe(&data->display, pipe, plane) {
> >>> +		if (!is_valid_plane(plane))
> >>> +			continue;
> >>> +
> >>> +		igt_assert(test(data, plane));
> >>> +
> >>> +		count++;
> >>> +	}
> >>> +
> >>> +	igt_require_f(count, "No valid planes found.\n");
> >>> +}
> >>> +
> >>> +static void run_tests_for_plane(data_t *data, enum pipe pipe)
> >>> +{
> >>> +	igt_fixture {
> >>> +		igt_require_pipe(&data->display, pipe);
> >>> +		igt_require_pipe_crc(data->drm_fd);
> >>> +		igt_require(data->display.pipes[pipe].n_planes > 0);
> >>> +		igt_display_require_output_on_pipe(&data->display, pipe);
> >>> +	}
> >>> +
> >>> +	igt_describe("Compare maxed out plane gamma LUT and solid color linear
> >> LUT");
> >>
> >> I can't seem to see the linear LUT test. This only seems to test
> >> the max LUT.
> >>
> >> Harry
> >>
> >>> +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
> >>> +		run_plane_color_test(data, pipe, plane_gamma_test);
> >>> +}
> >>> +
> >>>  igt_main
> >>>  {
> >>>  	data_t data = {};
> >>> @@ -910,6 +1084,9 @@ igt_main
> >>>
> >>>  		igt_subtest_group
> >>>  			run_invalid_tests_for_pipe(&data, pipe);
> >>> +
> >>> +		igt_subtest_group
> >>> +			run_tests_for_plane(&data, pipe);
> >>>  	}
> >>>
> >>>  	igt_fixture {
> >>>
> >

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

* Re: [igt-dev] [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
@ 2022-01-05 11:21           ` Modem, Bhanuprakash
  0 siblings, 0 replies; 96+ messages in thread
From: Modem, Bhanuprakash @ 2022-01-05 11:21 UTC (permalink / raw)
  To: Harry Wentland, igt-dev, dri-devel; +Cc: ppaalanen

> From: Harry Wentland <harry.wentland@amd.com>
> Sent: Wednesday, January 5, 2022 2:49 AM
> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Shankar, Uma
> <uma.shankar@intel.com>; ppaalanen@gmail.com
> Subject: Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
> 
> On 2022-01-02 23:05, Modem, Bhanuprakash wrote:
> >> From: Harry Wentland <harry.wentland@amd.com>
> >> Sent: Friday, November 26, 2021 10:25 PM
> >> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
> >> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Juha-Pekka Heikkila
> >> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
> >> Subject: Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
> >>
> >> On 2021-11-15 04:47, Bhanuprakash Modem wrote:
> >>> To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
> >>> with a maxed out gamma LUT and verify we have the same CRC as drawing
> solid
> >>> color rectangles.
> >>>
> >>> Cc: Harry Wentland <harry.wentland@amd.com>
> >>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >>> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
> >>> Cc: Uma Shankar <uma.shankar@intel.com>
> >>> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
> >>> ---
> >>>  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
> >>>  1 file changed, 178 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/tests/kms_color.c b/tests/kms_color.c
> >>> index 775f35964f..b45d66762f 100644
> >>> --- a/tests/kms_color.c
> >>> +++ b/tests/kms_color.c
> >>> @@ -24,7 +24,34 @@
> >>>
> >>>  #include "kms_color_helper.h"
> >>>
> >>> -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
> >>> +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
> >>> +
> >>> +#define MAX_SUPPORTED_PLANES 7
> >>> +#define SDR_PLANE_BASE 3
> >>> +
> >>> +typedef bool (*test_t)(data_t*, igt_plane_t*);
> >>> +
> >>> +static bool is_hdr_plane(const igt_plane_t *plane)
> >>> +{
> >>> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
> >>> +}
> >>> +
> >>> +static bool is_valid_plane(igt_plane_t *plane)
> >>> +{
> >>> +	int index = plane->index;
> >>> +
> >>> +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> >>> +		return false;
> >>> +
> >>> +	/*
> >>> +	 * Test 1 HDR plane, 1 SDR plane.
> >>> +	 *
> >>> +	 * 0,1,2 HDR planes
> >>> +	 * 3,4,5,6 SDR planes
> >>> +	 *
> >>> +	 */
> >>
> >> This seems to be about Intel HW. AMD HW for example does
> >> not have HDR or SDR planes, only one generic plane.
> >>
> >>> +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
> >>> +}
> >>>
> >>>  static void test_pipe_degamma(data_t *data,
> >>>  			      igt_plane_t *primary)
> >>> @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t
> *data,
> >>>  }
> >>>  #endif
> >>>
> >>> +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
> >>> +{
> >>> +	igt_output_t *output;
> >>> +	igt_display_t *display = &data->display;
> >>> +	drmModeModeInfo *mode;
> >>> +	struct igt_fb fb;
> >>> +	drmModePropertyPtr gamma_mode = NULL;
> >>> +	uint32_t i;
> >>> +	bool ret = true;
> >>> +	igt_pipe_crc_t *pipe_crc = NULL;
> >>> +	color_t red_green_blue[] = {
> >>> +		{ 1.0, 0.0, 0.0 },
> >>> +		{ 0.0, 1.0, 0.0 },
> >>> +		{ 0.0, 0.0, 1.0 }
> >>> +	};
> >>> +
> >>> +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
> >>> +			kmstest_pipe_name(plane->pipe->pipe),
> >>> +			kmstest_plane_type_name(plane->type),
> >>> +			is_hdr_plane(plane) ? "hdr":"sdr");
> >>> +
> >>
> >> is_hdr_plane is Intel-specific.
> >>
> >>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
> >>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
> >>> +
> >>> +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
> >>> +				  plane->pipe->pipe,
> >>> +				  INTEL_PIPE_CRC_SOURCE_AUTO);
> >>> +
> >>> +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
> >>> +	igt_assert(output);
> >>> +
> >>> +	igt_output_set_pipe(output, plane->pipe->pipe);
> >>> +	mode = igt_output_get_mode(output);
> >>> +
> >>> +	/* Create a framebuffer at the size of the output. */
> >>> +	igt_assert(igt_create_fb(data->drm_fd,
> >>> +			      mode->hdisplay,
> >>> +			      mode->vdisplay,
> >>> +			      DRM_FORMAT_XRGB8888,
> >>> +			      DRM_FORMAT_MOD_LINEAR,
> >>> +			      &fb));
> >>> +	igt_plane_set_fb(plane, &fb);
> >>> +
> >>> +	/* Disable Pipe color props. */
> >>> +	disable_ctm(plane->pipe);
> >>> +	disable_degamma(plane->pipe);
> >>> +	disable_gamma(plane->pipe);
> >>> +
> >>> +	disable_plane_ctm(plane);
> >>> +	disable_plane_degamma(plane);
> >>> +	igt_display_commit2(display, display->is_atomic ?
> >>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> >>> +
> >>> +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
> >>> +
> >>> +	/* Iterate all supported gamma modes. */
> >>> +	for (i = 0; i < gamma_mode->count_enums; i++) {
> >>> +		igt_crc_t crc_gamma, crc_fullcolors;
> >>> +		segment_data_t *segment_info = NULL;
> >>> +		struct drm_color_lut_ext *lut = NULL;
> >>> +		uint32_t lut_size = 0;
> >>> +
> >>> +		/* Ignore 'no gamma' from enum list. */
> >>> +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
> >>> +			continue;
> >>> +
> >>
> >> It might still make sense to test that this is doing bypass.
> >
> > As we know gamma_mode->enum[i].name represents the name of the
> > gamma mode and gamma_mode->enum[i].value would be the LUT blob
> > address of that particular gamma_mode.
> >
> > For "no gamma" case the blob address is NULL, so we can't commit
> > this mode. Hence skipping this mode.
> >
> 
> I was thinking it'd be good to test the "no gamma" case as well
> here, i.e. the case were we set a NULL blob. I'm not sure what
> you mean when you say "we can't commit this mode."

Sorry for the confusion, "no gamma" is intentional to disable the gamma.
I think, we just need to check that we can able to flip with this mode.
So, we need to update disable_plane_gamma() to use this mode.

Or are you thinking any specific usecase for this?

- Bhanu
 
> 
> Harry
> 
> >>
> >>> +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode-
> >>> enums[i].name);
> >>> +
> >>> +		/* Draw solid colors with no gamma transformation. */
> >>> +		disable_plane_gamma(plane);
> >>> +		paint_rectangles(data, mode, red_green_blue, &fb);
> >>> +		igt_plane_set_fb(plane, &fb);
> >>> +		igt_display_commit2(display, display->is_atomic ?
> >>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> >>> +		igt_wait_for_vblank(data->drm_fd,
> >>> +			display->pipes[plane->pipe->pipe].crtc_offset);
> >>> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
> >>> +
> >>> +		/* Draw gradient colors with gamma LUT to remap all
> >>> +		 * values to max red/green/blue.
> >>> +		 */
> >>> +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
> >>> +				gamma_mode->enums[i].name);
> >>> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
> >>> entries_count;
> >>> +		lut = create_max_lut(segment_info);
> >>> +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
> >>> +
> >>> +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
> >>> +		igt_plane_set_fb(plane, &fb);
> >>> +		igt_display_commit2(display, display->is_atomic ?
> >>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> >>> +		igt_wait_for_vblank(data->drm_fd,
> >>> +			display->pipes[plane->pipe->pipe].crtc_offset);
> >>> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
> >>> +
> >>> +		/* Verify that the CRC of the software computed output is
> >>> +		 * equal to the CRC of the gamma LUT transformation output.
> >>> +		 */
> >>> +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
> >>> +
> >>> +		free(lut);
> >>> +		clear_segment_data(segment_info);
> >>> +	}
> >>> +
> >>> +	disable_plane_gamma(plane);
> >>> +	igt_plane_set_fb(plane, NULL);
> >>> +	igt_output_set_pipe(output, PIPE_NONE);
> >>> +	igt_display_commit2(display, display->is_atomic ?
> >>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
> >>> +
> >>> +	igt_pipe_crc_free(pipe_crc);
> >>> +	drmModeFreeProperty(gamma_mode);
> >>> +
> >>> +	return ret;
> >>> +}
> >>> +
> >>>  static void
> >>>  prep_pipe(data_t *data, enum pipe p)
> >>>  {
> >>> @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe
> p)
> >>>  		invalid_ctm_matrix_sizes(data, p);
> >>>  }
> >>>
> >>> +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t
> test)
> >>> +{
> >>> +	igt_plane_t *plane;
> >>> +	int count = 0;
> >>> +
> >>> +	for_each_plane_on_pipe(&data->display, pipe, plane) {
> >>> +		if (!is_valid_plane(plane))
> >>> +			continue;
> >>> +
> >>> +		igt_assert(test(data, plane));
> >>> +
> >>> +		count++;
> >>> +	}
> >>> +
> >>> +	igt_require_f(count, "No valid planes found.\n");
> >>> +}
> >>> +
> >>> +static void run_tests_for_plane(data_t *data, enum pipe pipe)
> >>> +{
> >>> +	igt_fixture {
> >>> +		igt_require_pipe(&data->display, pipe);
> >>> +		igt_require_pipe_crc(data->drm_fd);
> >>> +		igt_require(data->display.pipes[pipe].n_planes > 0);
> >>> +		igt_display_require_output_on_pipe(&data->display, pipe);
> >>> +	}
> >>> +
> >>> +	igt_describe("Compare maxed out plane gamma LUT and solid color linear
> >> LUT");
> >>
> >> I can't seem to see the linear LUT test. This only seems to test
> >> the max LUT.
> >>
> >> Harry
> >>
> >>> +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
> >>> +		run_plane_color_test(data, pipe, plane_gamma_test);
> >>> +}
> >>> +
> >>>  igt_main
> >>>  {
> >>>  	data_t data = {};
> >>> @@ -910,6 +1084,9 @@ igt_main
> >>>
> >>>  		igt_subtest_group
> >>>  			run_invalid_tests_for_pipe(&data, pipe);
> >>> +
> >>> +		igt_subtest_group
> >>> +			run_tests_for_plane(&data, pipe);
> >>>  	}
> >>>
> >>>  	igt_fixture {
> >>>
> >

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

* Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
  2022-01-05 11:21           ` [igt-dev] " Modem, Bhanuprakash
  (?)
@ 2022-01-05 22:13           ` Harry Wentland
  -1 siblings, 0 replies; 96+ messages in thread
From: Harry Wentland @ 2022-01-05 22:13 UTC (permalink / raw)
  To: Modem, Bhanuprakash, igt-dev, dri-devel; +Cc: Shankar, Uma



On 2022-01-05 06:21, Modem, Bhanuprakash wrote:
>> From: Harry Wentland <harry.wentland@amd.com>
>> Sent: Wednesday, January 5, 2022 2:49 AM
>> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
>> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Shankar, Uma
>> <uma.shankar@intel.com>; ppaalanen@gmail.com
>> Subject: Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
>>
>> On 2022-01-02 23:05, Modem, Bhanuprakash wrote:
>>>> From: Harry Wentland <harry.wentland@amd.com>
>>>> Sent: Friday, November 26, 2021 10:25 PM
>>>> To: Modem, Bhanuprakash <bhanuprakash.modem@intel.com>; igt-
>>>> dev@lists.freedesktop.org; dri-devel@lists.freedesktop.org
>>>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Juha-Pekka Heikkila
>>>> <juhapekka.heikkila@gmail.com>; Shankar, Uma <uma.shankar@intel.com>
>>>> Subject: Re: [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma
>>>>
>>>> On 2021-11-15 04:47, Bhanuprakash Modem wrote:
>>>>> To verify Plane gamma, draw 3 gradient rectangles in red, green and blue,
>>>>> with a maxed out gamma LUT and verify we have the same CRC as drawing
>> solid
>>>>> color rectangles.
>>>>>
>>>>> Cc: Harry Wentland <harry.wentland@amd.com>
>>>>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>>>>> Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
>>>>> Cc: Uma Shankar <uma.shankar@intel.com>
>>>>> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com>
>>>>> ---
>>>>>  tests/kms_color.c | 179 +++++++++++++++++++++++++++++++++++++++++++++-
>>>>>  1 file changed, 178 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/tests/kms_color.c b/tests/kms_color.c
>>>>> index 775f35964f..b45d66762f 100644
>>>>> --- a/tests/kms_color.c
>>>>> +++ b/tests/kms_color.c
>>>>> @@ -24,7 +24,34 @@
>>>>>
>>>>>  #include "kms_color_helper.h"
>>>>>
>>>>> -IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
>>>>> +IGT_TEST_DESCRIPTION("Test Color Features at Pipe & Plane level");
>>>>> +
>>>>> +#define MAX_SUPPORTED_PLANES 7
>>>>> +#define SDR_PLANE_BASE 3
>>>>> +
>>>>> +typedef bool (*test_t)(data_t*, igt_plane_t*);
>>>>> +
>>>>> +static bool is_hdr_plane(const igt_plane_t *plane)
>>>>> +{
>>>>> +	return plane->index >= 0 && plane->index < SDR_PLANE_BASE;
>>>>> +}
>>>>> +
>>>>> +static bool is_valid_plane(igt_plane_t *plane)
>>>>> +{
>>>>> +	int index = plane->index;
>>>>> +
>>>>> +	if (plane->type != DRM_PLANE_TYPE_PRIMARY)
>>>>> +		return false;
>>>>> +
>>>>> +	/*
>>>>> +	 * Test 1 HDR plane, 1 SDR plane.
>>>>> +	 *
>>>>> +	 * 0,1,2 HDR planes
>>>>> +	 * 3,4,5,6 SDR planes
>>>>> +	 *
>>>>> +	 */
>>>>
>>>> This seems to be about Intel HW. AMD HW for example does
>>>> not have HDR or SDR planes, only one generic plane.
>>>>
>>>>> +	return index >= 0 && index < MAX_SUPPORTED_PLANES;
>>>>> +}
>>>>>
>>>>>  static void test_pipe_degamma(data_t *data,
>>>>>  			      igt_plane_t *primary)
>>>>> @@ -638,6 +665,122 @@ static void test_pipe_limited_range_ctm(data_t
>> *data,
>>>>>  }
>>>>>  #endif
>>>>>
>>>>> +static bool plane_gamma_test(data_t *data, igt_plane_t *plane)
>>>>> +{
>>>>> +	igt_output_t *output;
>>>>> +	igt_display_t *display = &data->display;
>>>>> +	drmModeModeInfo *mode;
>>>>> +	struct igt_fb fb;
>>>>> +	drmModePropertyPtr gamma_mode = NULL;
>>>>> +	uint32_t i;
>>>>> +	bool ret = true;
>>>>> +	igt_pipe_crc_t *pipe_crc = NULL;
>>>>> +	color_t red_green_blue[] = {
>>>>> +		{ 1.0, 0.0, 0.0 },
>>>>> +		{ 0.0, 1.0, 0.0 },
>>>>> +		{ 0.0, 0.0, 1.0 }
>>>>> +	};
>>>>> +
>>>>> +	igt_info("Plane gamma test is running on pipe-%s plane-%s(%s)\n",
>>>>> +			kmstest_pipe_name(plane->pipe->pipe),
>>>>> +			kmstest_plane_type_name(plane->type),
>>>>> +			is_hdr_plane(plane) ? "hdr":"sdr");
>>>>> +
>>>>
>>>> is_hdr_plane is Intel-specific.
>>>>
>>>>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
>>>>> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
>>>>> +
>>>>> +	pipe_crc = igt_pipe_crc_new(data->drm_fd,
>>>>> +				  plane->pipe->pipe,
>>>>> +				  INTEL_PIPE_CRC_SOURCE_AUTO);
>>>>> +
>>>>> +	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
>>>>> +	igt_assert(output);
>>>>> +
>>>>> +	igt_output_set_pipe(output, plane->pipe->pipe);
>>>>> +	mode = igt_output_get_mode(output);
>>>>> +
>>>>> +	/* Create a framebuffer at the size of the output. */
>>>>> +	igt_assert(igt_create_fb(data->drm_fd,
>>>>> +			      mode->hdisplay,
>>>>> +			      mode->vdisplay,
>>>>> +			      DRM_FORMAT_XRGB8888,
>>>>> +			      DRM_FORMAT_MOD_LINEAR,
>>>>> +			      &fb));
>>>>> +	igt_plane_set_fb(plane, &fb);
>>>>> +
>>>>> +	/* Disable Pipe color props. */
>>>>> +	disable_ctm(plane->pipe);
>>>>> +	disable_degamma(plane->pipe);
>>>>> +	disable_gamma(plane->pipe);
>>>>> +
>>>>> +	disable_plane_ctm(plane);
>>>>> +	disable_plane_degamma(plane);
>>>>> +	igt_display_commit2(display, display->is_atomic ?
>>>>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
>>>>> +
>>>>> +	gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
>>>>> +
>>>>> +	/* Iterate all supported gamma modes. */
>>>>> +	for (i = 0; i < gamma_mode->count_enums; i++) {
>>>>> +		igt_crc_t crc_gamma, crc_fullcolors;
>>>>> +		segment_data_t *segment_info = NULL;
>>>>> +		struct drm_color_lut_ext *lut = NULL;
>>>>> +		uint32_t lut_size = 0;
>>>>> +
>>>>> +		/* Ignore 'no gamma' from enum list. */
>>>>> +		if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
>>>>> +			continue;
>>>>> +
>>>>
>>>> It might still make sense to test that this is doing bypass.
>>>
>>> As we know gamma_mode->enum[i].name represents the name of the
>>> gamma mode and gamma_mode->enum[i].value would be the LUT blob
>>> address of that particular gamma_mode.
>>>
>>> For "no gamma" case the blob address is NULL, so we can't commit
>>> this mode. Hence skipping this mode.
>>>
>>
>> I was thinking it'd be good to test the "no gamma" case as well
>> here, i.e. the case were we set a NULL blob. I'm not sure what
>> you mean when you say "we can't commit this mode."
> 
> Sorry for the confusion, "no gamma" is intentional to disable the gamma.
> I think, we just need to check that we can able to flip with this mode.
> So, we need to update disable_plane_gamma() to use this mode.
> 
> Or are you thinking any specific usecase for this?
> 

I understand that "no gamma" is used to disable the gamma block
but where do we test that the driver disables it correctly?

I'm fine to skip it here if we test it elsewhere but it almost
makes sense to test this here as just another gamma mode.

Harry

> - Bhanu
>  
>>
>> Harry
>>
>>>>
>>>>> +		igt_info("Trying to use gamma mode: \'%s\'\n", gamma_mode-
>>>>> enums[i].name);
>>>>> +
>>>>> +		/* Draw solid colors with no gamma transformation. */
>>>>> +		disable_plane_gamma(plane);
>>>>> +		paint_rectangles(data, mode, red_green_blue, &fb);
>>>>> +		igt_plane_set_fb(plane, &fb);
>>>>> +		igt_display_commit2(display, display->is_atomic ?
>>>>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
>>>>> +		igt_wait_for_vblank(data->drm_fd,
>>>>> +			display->pipes[plane->pipe->pipe].crtc_offset);
>>>>> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
>>>>> +
>>>>> +		/* Draw gradient colors with gamma LUT to remap all
>>>>> +		 * values to max red/green/blue.
>>>>> +		 */
>>>>> +		segment_info = get_segment_data(data, gamma_mode->enums[i].value,
>>>>> +				gamma_mode->enums[i].name);
>>>>> +		lut_size = sizeof(struct drm_color_lut_ext) * segment_info-
>>>>> entries_count;
>>>>> +		lut = create_max_lut(segment_info);
>>>>> +		set_plane_gamma(plane, gamma_mode->enums[i].name, lut, lut_size);
>>>>> +
>>>>> +		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
>>>>> +		igt_plane_set_fb(plane, &fb);
>>>>> +		igt_display_commit2(display, display->is_atomic ?
>>>>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
>>>>> +		igt_wait_for_vblank(data->drm_fd,
>>>>> +			display->pipes[plane->pipe->pipe].crtc_offset);
>>>>> +		igt_pipe_crc_collect_crc(pipe_crc, &crc_gamma);
>>>>> +
>>>>> +		/* Verify that the CRC of the software computed output is
>>>>> +		 * equal to the CRC of the gamma LUT transformation output.
>>>>> +		 */
>>>>> +		ret &= igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
>>>>> +
>>>>> +		free(lut);
>>>>> +		clear_segment_data(segment_info);
>>>>> +	}
>>>>> +
>>>>> +	disable_plane_gamma(plane);
>>>>> +	igt_plane_set_fb(plane, NULL);
>>>>> +	igt_output_set_pipe(output, PIPE_NONE);
>>>>> +	igt_display_commit2(display, display->is_atomic ?
>>>>> +					COMMIT_ATOMIC : COMMIT_LEGACY);
>>>>> +
>>>>> +	igt_pipe_crc_free(pipe_crc);
>>>>> +	drmModeFreeProperty(gamma_mode);
>>>>> +
>>>>> +	return ret;
>>>>> +}
>>>>> +
>>>>>  static void
>>>>>  prep_pipe(data_t *data, enum pipe p)
>>>>>  {
>>>>> @@ -890,6 +1033,37 @@ run_invalid_tests_for_pipe(data_t *data, enum pipe
>> p)
>>>>>  		invalid_ctm_matrix_sizes(data, p);
>>>>>  }
>>>>>
>>>>> +static void run_plane_color_test(data_t *data, enum pipe pipe, test_t
>> test)
>>>>> +{
>>>>> +	igt_plane_t *plane;
>>>>> +	int count = 0;
>>>>> +
>>>>> +	for_each_plane_on_pipe(&data->display, pipe, plane) {
>>>>> +		if (!is_valid_plane(plane))
>>>>> +			continue;
>>>>> +
>>>>> +		igt_assert(test(data, plane));
>>>>> +
>>>>> +		count++;
>>>>> +	}
>>>>> +
>>>>> +	igt_require_f(count, "No valid planes found.\n");
>>>>> +}
>>>>> +
>>>>> +static void run_tests_for_plane(data_t *data, enum pipe pipe)
>>>>> +{
>>>>> +	igt_fixture {
>>>>> +		igt_require_pipe(&data->display, pipe);
>>>>> +		igt_require_pipe_crc(data->drm_fd);
>>>>> +		igt_require(data->display.pipes[pipe].n_planes > 0);
>>>>> +		igt_display_require_output_on_pipe(&data->display, pipe);
>>>>> +	}
>>>>> +
>>>>> +	igt_describe("Compare maxed out plane gamma LUT and solid color linear
>>>> LUT");
>>>>
>>>> I can't seem to see the linear LUT test. This only seems to test
>>>> the max LUT.
>>>>
>>>> Harry
>>>>
>>>>> +	igt_subtest_f("pipe-%s-plane-gamma", kmstest_pipe_name(pipe))
>>>>> +		run_plane_color_test(data, pipe, plane_gamma_test);
>>>>> +}
>>>>> +
>>>>>  igt_main
>>>>>  {
>>>>>  	data_t data = {};
>>>>> @@ -910,6 +1084,9 @@ igt_main
>>>>>
>>>>>  		igt_subtest_group
>>>>>  			run_invalid_tests_for_pipe(&data, pipe);
>>>>> +
>>>>> +		igt_subtest_group
>>>>> +			run_tests_for_plane(&data, pipe);
>>>>>  	}
>>>>>
>>>>>  	igt_fixture {
>>>>>
>>>


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

end of thread, other threads:[~2022-01-05 22:13 UTC | newest]

Thread overview: 96+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-15  9:47 [i-g-t 00/14] Add IGT support for plane color management Bhanuprakash Modem
2021-11-15  9:47 ` [igt-dev] " Bhanuprakash Modem
2021-11-15  9:47 ` [i-g-t 01/14] HAX: Get uapi headers to compile the IGT Bhanuprakash Modem
2021-11-15  9:47 ` [i-g-t 02/14] lib/igt_kms: Add plane color mgmt properties Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-15  9:47 ` [i-g-t 03/14] kms_color_helper: Add helper functions for plane color mgmt Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-18  8:41   ` Pekka Paalanen
2021-11-18  8:41     ` [igt-dev] " Pekka Paalanen
2022-01-03  4:02     ` Modem, Bhanuprakash
2022-01-03  4:02       ` [igt-dev] " Modem, Bhanuprakash
2021-11-26 16:54   ` Harry Wentland
2021-11-26 16:54     ` [igt-dev] " Harry Wentland
2022-01-03  4:02     ` Modem, Bhanuprakash
2022-01-03  4:02       ` [igt-dev] " Modem, Bhanuprakash
2021-11-15  9:47 ` [i-g-t 04/14] tests/kms_color: New subtests for Plane gamma Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-18  9:02   ` Pekka Paalanen
2021-11-18  9:02     ` [igt-dev] " Pekka Paalanen
2022-01-03  4:09     ` Modem, Bhanuprakash
2022-01-03  4:09       ` [igt-dev] " Modem, Bhanuprakash
2021-11-26 16:55   ` Harry Wentland
2021-11-26 16:55     ` [igt-dev] " Harry Wentland
2022-01-03  4:05     ` Modem, Bhanuprakash
2022-01-03  4:05       ` [igt-dev] " Modem, Bhanuprakash
2022-01-04 21:19       ` Harry Wentland
2022-01-05 11:21         ` Modem, Bhanuprakash
2022-01-05 11:21           ` [igt-dev] " Modem, Bhanuprakash
2022-01-05 22:13           ` Harry Wentland
2021-11-15  9:47 ` [i-g-t 05/14] tests/kms_color: New subtests for Plane degamma Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-15  9:47 ` [i-g-t 06/14] tests/kms_color: New subtests for Plane CTM Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-26 16:55   ` Harry Wentland
2021-11-15  9:47 ` [i-g-t 07/14] tests/kms_color: New negative tests for plane level color mgmt Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-18  9:19   ` Pekka Paalanen
2021-11-18  9:19     ` [igt-dev] " Pekka Paalanen
2021-11-29 14:56     ` Harry Wentland
2022-01-03  4:05     ` Modem, Bhanuprakash
2022-01-03  4:05       ` [igt-dev] " Modem, Bhanuprakash
2021-11-15  9:47 ` [i-g-t 08/14] tests/kms_color_chamelium: New subtests for Plane gamma Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-18  9:32   ` Pekka Paalanen
2021-11-18  9:32     ` [igt-dev] " Pekka Paalanen
2022-01-03  4:06     ` Modem, Bhanuprakash
2022-01-03  4:06       ` [igt-dev] " Modem, Bhanuprakash
2021-11-15  9:47 ` [i-g-t 09/14] tests/kms_color_chamelium: New subtests for Plane degamma Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-15  9:47 ` [i-g-t 10/14] tests/kms_color_chamelium: New subtests for Plane CTM Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-15  9:47 ` [i-g-t 11/14] lib/igt_kms: Add pipe color mgmt properties Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-18  9:34   ` Pekka Paalanen
2021-11-18  9:34     ` [igt-dev] " Pekka Paalanen
2021-11-15  9:47 ` [i-g-t 12/14] kms_color_helper: Add helper functions to support logarithmic gamma mode Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-18  9:45   ` Pekka Paalanen
2021-11-18  9:45     ` [igt-dev] " Pekka Paalanen
2022-01-03  4:07     ` Modem, Bhanuprakash
2022-01-03  4:07       ` [igt-dev] " Modem, Bhanuprakash
2021-11-26 16:55   ` Harry Wentland
2021-11-26 16:55     ` [igt-dev] " Harry Wentland
2022-01-03  4:08     ` Modem, Bhanuprakash
2022-01-03  4:08       ` [igt-dev] " Modem, Bhanuprakash
2021-11-15  9:47 ` [i-g-t 13/14] tests/kms_color: Extended IGT tests " Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-15  9:47 ` [i-g-t 14/14] tests/kms_color_chamelium: " Bhanuprakash Modem
2021-11-15  9:47   ` [igt-dev] " Bhanuprakash Modem
2021-11-15 11:14 ` [igt-dev] ✓ Fi.CI.BAT: success for Add IGT support for plane color management Patchwork
2021-11-15 13:36 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
2021-11-18  9:50 ` [i-g-t 00/14] " Pekka Paalanen
2021-11-18  9:50   ` [igt-dev] " Pekka Paalanen
2021-11-26 16:54   ` Harry Wentland
2021-11-29  9:20     ` Pekka Paalanen
2021-11-29  9:20       ` [igt-dev] " Pekka Paalanen
2021-11-29 15:20       ` Harry Wentland
2022-01-03  4:11         ` Modem, Bhanuprakash
2022-01-03  4:11           ` [igt-dev] " Modem, Bhanuprakash
2022-01-04 22:01           ` Harry Wentland
2022-01-04  7:57 ` [igt-dev] [v2 i-g-t 00/15] " Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 01/15] HAX: Get uapi headers to compile the IGT Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 02/15] lib/igt_kms: Add plane color mgmt properties Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 03/15] kms_color_helper: Add helper functions for plane color mgmt Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 04/15] tests/kms_color: New subtests for Plane gamma Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 05/15] tests/kms_color: New subtests for Plane degamma Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 06/15] tests/kms_color: New subtests for Plane CTM Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 07/15] tests/kms_color: New negative tests for plane level color mgmt Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 08/15] tests/kms_color_chamelium: New subtests for Plane gamma Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 09/15] tests/kms_color_chamelium: New subtests for Plane degamma Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 10/15] tests/kms_color_chamelium: New subtests for Plane CTM Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 11/15] lib/igt_kms: Add pipe color mgmt properties Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 12/15] kms_color_helper: Add helper functions to support logarithmic gamma mode Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 13/15] tests/kms_color: Extended IGT tests " Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 14/15] tests/kms_color_chamelium: " Bhanuprakash Modem
2022-01-04  7:57   ` [igt-dev] [v2 i-g-t 15/15] HAX: Add color mgmt tests to BAT Bhanuprakash Modem

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.