[i-g-t V6 39/41] lib/colorops: Add support for Custom 1D LUT

Bhanuprakash Modem bhanuprakash.modem at intel.com
Wed Apr 24 10:26:47 UTC 2024


Add helpers to support custom 1D LUT.

v2:
 - Rebase

Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem at intel.com>
---
 lib/igt_kms.c            |   1 +
 lib/igt_kms.h            |   1 +
 tests/kms_color_helper.c | 100 +++++++++++++++++++++++++++++++++++++++
 tests/kms_color_helper.h |  31 +++++++++++-
 4 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 99d198870..9813bb24d 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -696,6 +696,7 @@ const char * const igt_colorop_prop_names[IGT_NUM_COLOROP_PROPS] = {
 	[IGT_COLOROP_BYPASS] = "BYPASS",
 	[IGT_COLOROP_CURVE_1D_TYPE] = "CURVE_1D_TYPE",
 	[IGT_COLOROP_SIZE] = "SIZE",
+	[IGT_COLOROP_HW_CAPS] = "HW_CAPS",
 	[IGT_COLOROP_DATA] = "DATA",
 	[IGT_COLOROP_MULTIPLIER] = "MULTIPLIER",
 	[IGT_COLOROP_NEXT] = "NEXT",
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 55ef1934f..b887aea8a 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -354,6 +354,7 @@ enum igt_atomic_colorop_properties {
        IGT_COLOROP_BYPASS,
        IGT_COLOROP_CURVE_1D_TYPE,
        IGT_COLOROP_SIZE,
+       IGT_COLOROP_HW_CAPS,
        IGT_COLOROP_DATA,
        IGT_COLOROP_MULTIPLIER,
        IGT_COLOROP_NEXT,
diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
index a325b04a4..ccfde7ba8 100644
--- a/tests/kms_color_helper.c
+++ b/tests/kms_color_helper.c
@@ -24,6 +24,8 @@
 
 #include "kms_color_helper.h"
 
+#define MIN(a, b)	((a) < (b) ? (a) : (b))
+
 bool pipe_output_combo_valid(data_t *data, enum pipe pipe)
 {
 	bool ret = true;
@@ -405,6 +407,10 @@ static bool can_use_colorop(igt_display_t *display, igt_colorop_t *colorop, kms_
 		if (igt_colorop_get_prop(display, colorop, IGT_COLOROP_TYPE) == DRM_COLOROP_1D_LUT)
 			return true;
 		return false;
+	case KMS_COLOROP_MULTSEG_LUT1D:
+		if (igt_colorop_get_prop(display, colorop, IGT_COLOROP_TYPE) == DRM_COLOROP_1D_LUT_MULTSEG)
+			return true;
+		return false;
 	case KMS_COLOROP_MULTIPLIER:
 		return (igt_colorop_get_prop(display, colorop, IGT_COLOROP_TYPE) == DRM_COLOROP_MULTIPLIER);
 	case KMS_COLOROP_LUT3D:
@@ -519,6 +525,9 @@ void set_colorop(igt_display_t *display, kms_colorop_t *colorop)
 		lut_size = igt_colorop_get_prop(display, colorop->colorop, IGT_COLOROP_SIZE);
 		igt_colorop_set_custom_1dlut(display, colorop->colorop, colorop->lut1d, lut_size * sizeof(struct drm_color_lut));
 		break;
+	case KMS_COLOROP_MULTSEG_LUT1D:
+		igt_colorop_set_multseg_1dlut(display, colorop->colorop, colorop->multseg_lut1d_info);
+		break;
 	case KMS_COLOROP_MULTIPLIER:
 		mult = colorop->multiplier * (mult << 32);	/* convert double to fixed number */
 		igt_colorop_set_prop_value(colorop->colorop, IGT_COLOROP_MULTIPLIER, mult);
@@ -558,6 +567,97 @@ void set_color_pipeline(igt_display_t *display,
 	}
 }
 
+void create_zero_lut(segment_data_t *info, struct drm_color_lut_ext *lut)
+{
+	int i;
+
+	for (i = 0; i < info->entries_count; i++)
+		lut[i].red = lut[i].green = lut[i].blue = 0;
+}
+
+void create_unity_lut(segment_data_t *info, struct drm_color_lut_ext *lut)
+{
+	uint32_t val, segment, entry, index = 0;
+	uint32_t max_val = 0xffffffff;
+
+	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 =
+				(index == 0) ? 0 : MIN(val, max_val);
+
+			index++;
+		}
+	}
+}
+
+void create_max_lut(segment_data_t *info, struct drm_color_lut_ext *lut)
+{
+	int i;
+	uint32_t max_val = 0xffffffff;
+
+	for (i = 0; i < info->entries_count; i++)
+		lut[i].red = lut[i].green = lut[i].blue = (i == 0) ? 0 : max_val;
+}
+
+void clear_segment_data(segment_data_t *info)
+{
+	if (!info)
+		return;
+
+	free(info->segment_data);
+	free(info);
+}
+
+segment_data_t *get_segment_data(int drm_fd, uint64_t blob_id)
+{
+	drmModePropertyBlobPtr blob;
+	struct drm_color_lut_range *lut_range = NULL;
+	segment_data_t *info = NULL;
+	uint32_t i;
+
+	blob = drmModeGetPropertyBlob(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);
+
+	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];
+	}
+
+	drmModeFreePropertyBlob(blob);
+
+	return info;
+}
+
+void igt_colorop_set_multseg_1dlut(igt_display_t *display,
+				   igt_colorop_t *colorop,
+				   const kms_colorop_multseg_lut1d_info_t lut_info)
+{
+	/* set blob property */
+	for (int i = 0; i < lut_info.lut_size; i++)
+		igt_debug("Lut[%d]: 0x%llx 0x%llx 0x%llx\n",
+			 i, lut_info.lut[i].red, lut_info.lut[i].green, lut_info.lut[i].blue);
+
+	igt_colorop_replace_prop_blob(colorop, IGT_COLOROP_DATA,
+			lut_info.lut, sizeof(struct drm_color_lut_ext) * lut_info.lut_size);
+}
+
 void igt_colorop_set_ctm_3x3(igt_display_t *display,
 			     igt_colorop_t *colorop,
 			     const struct drm_color_ctm *matrix)
diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
index 0d691af14..e925bc1bd 100644
--- a/tests/kms_color_helper.h
+++ b/tests/kms_color_helper.h
@@ -122,10 +122,23 @@ void invalid_gamma_lut_sizes(data_t *data, enum pipe p);
 void invalid_degamma_lut_sizes(data_t *data, enum pipe p);
 void invalid_ctm_matrix_sizes(data_t *data, enum pipe p);
 
-/* Test version definitions */
+typedef struct {
+	uint32_t segment_count;
+	struct drm_color_lut_range *segment_data;
+	uint32_t entries_count;
+} segment_data_t;
+
+void create_zero_lut(segment_data_t *info, struct drm_color_lut_ext *lut);
+void create_unity_lut(segment_data_t *info, struct drm_color_lut_ext *lut);
+void create_max_lut(segment_data_t *info, struct drm_color_lut_ext *lut);
+void clear_segment_data(segment_data_t *info);
+segment_data_t *get_segment_data(int drm_fd, uint64_t blob_id);
+
+/* Colorops Test version definitions */
 typedef enum kms_colorop_type {
 	KMS_COLOROP_ENUMERATED_LUT1D,
 	KMS_COLOROP_CUSTOM_LUT1D,
+	KMS_COLOROP_MULTSEG_LUT1D,
 	KMS_COLOROP_CTM_3X3,
 	KMS_COLOROP_CTM_3X4,
 	KMS_COLOROP_MULTIPLIER,
@@ -136,12 +149,25 @@ typedef struct kms_colorop_enumerated_lut1d_info {
 	kms_colorop_lut1d_tf_t tf;
 } kms_colorop_enumerated_lut1d_info_t;
 
+typedef enum kms_colorop_multseg_lut1d_tf {
+       KMS_COLOROP_MULTSEG_LUT1D_ZERO,
+       KMS_COLOROP_MULTSEG_LUT1D_LINEAR,
+       KMS_COLOROP_MULTSEG_LUT1D_MAX,
+} kms_colorop_multseg_lut1d_tf_t;
+
+typedef struct kms_colorop_multseg_lut1d_info {
+	uint32_t lut_size;
+	kms_colorop_multseg_lut1d_tf_t lut_type;
+	struct drm_color_lut_ext *lut;
+} kms_colorop_multseg_lut1d_info_t;
+
 typedef struct kms_colorop {
 	kms_colorop_type_t type;
 
 	union {
 		kms_colorop_enumerated_lut1d_info_t enumerated_lut1d_info;
 		igt_1dlut_t *lut1d;
+		kms_colorop_multseg_lut1d_info_t multseg_lut1d_info;
 		const struct drm_color_ctm *matrix_3x3;
 		const igt_matrix_3x4_t *matrix_3x4;
 		double multiplier;
@@ -172,6 +198,9 @@ void igt_colorop_set_custom_1dlut(igt_display_t *display,
 				  igt_colorop_t *colorop,
 				  const igt_1dlut_t *lut1d,
 				  const size_t lut_size);
+void igt_colorop_set_multseg_1dlut(igt_display_t *display,
+				   igt_colorop_t *colorop,
+				   const kms_colorop_multseg_lut1d_info_t custom_lut1d_info);
 
 #define set_color_pipeline_bypass(plane)  igt_plane_set_prop_enum((plane), IGT_PLANE_COLOR_PIPELINE, "Bypass")
 
-- 
2.43.2



More information about the Intel-gfx-trybot mailing list