diff mbox

tests/kms_color:Color IGT

Message ID FF3DDC77922A8A4BB08A3BC48A1EA8CB099570C1@BGSMSX101.gar.corp.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sharma, Shashank July 13, 2015, 4:01 a.m. UTC
My comments inline.

Regards
Shashank
-----Original Message-----
From: R, Dhanya p 
Sent: Monday, July 13, 2015 9:25 AM
To: intel-gfx@lists.freedesktop.org
Cc: Palleti, Avinash Reddy; Malladi, Kausal; Sharma, Shashank; Suresh, Anitha; R, Dhanya p
Subject: [PATCH] tests/kms_color:Color IGT

From: Dhanya <dhanya.p.r@intel.com>

This patch will verify color correction capability of a display driver.
Gamma/CSC/De-gamma supported.

Signed-off-by: Dhanya <dhanya.p.r@intel.com>
---
 tests/Makefile.sources |   3 +
 tests/kms_color.c      | 639 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 642 insertions(+)
 create mode 100644 tests/kms_color.c

+	igt_subtest_f("Enable_De-gamma") {
+		test_pipe_color(&data, "degamma_property", RANDOM);
+	}
+	igt_subtest_f("Enable_De-gamma") {
+		test_pipe_color(&data, "degamma_property", DEFAULT);
+	}
+	igt_subtest_f("Enable_CSC") {
+		test_pipe_color(&data, "csc_property", RANDOM);
+	}
+
+	igt_fixture{
+		igt_display_fini(&data.display);
+	}
+}
+
--
1.9.1
diff mbox

Patch

diff --git a/tests/Makefile.sources b/tests/Makefile.sources index 994c31b..f49c396 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -77,9 +77,12 @@  TESTS_progs_M = \
 	kms_setmode \
 	kms_universal_plane \
 	kms_vblank \
+	kms_color \
+	color-correction	\
 	kms_crtc_background_color \
 	kms_plane_scaling \
 	kms_panel_fitting \
+	kms_render_compression \
Why are we adding render compression API here ?
 	pm_lpsp \
 	pm_rpm \
 	pm_rps \
diff --git a/tests/kms_color.c b/tests/kms_color.c new file mode 100644 index 0000000..48fad7a
--- /dev/null
+++ b/tests/kms_color.c
@@ -0,0 +1,639 @@ 
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person 
+obtaining a
+ * copy of this software and associated documentation files (the 
+"Software"),
+ * to deal in the Software without restriction, including without 
+limitation
+ * the rights to use, copy, modify, merge, publish, distribute, 
+sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom 
+the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the 
+next
+ * paragraph) shall be included in all copies or substantial portions 
+of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT 
+SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
+OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include <math.h>
+#include "drmtest.h"
+#include "igt_debugfs.h"
+#include "igt_kms.h"
+#include "igt_core.h"
+#include "intel_chipset.h"
+#include "igt_aux.h"
+#include<unistd.h>
+#include<stdlib.h>
+IGT_TEST_DESCRIPTION("Test Color Features at Plane/Pipe level");
+
+
+#define CHV_CSC_VALS    9
+#define I915_PIPE_CSC           (1<<0)
+#define I915_PLANE_CSC  (1<<1)
+
+#define CSC_MANTISSA_MAX_BITS    1
+#define CSC_MANTISSA_MAX_VALUE   ((1 << CSC_MANTISSA_MAX_BITS) - 1)
+#define CSC_FRACTION_MAX_BITS    10
+#define GAMMA_RED_SHIFT	16
+#define GAMMA_GREEN_SHIFT	8
+#define STANDARD_GAMMA				2.2
+#define I915_GAMMA_FLAG_DEGAMMA		(1<<0)
+#define I915_PIPE_GAMMA		(1<<0)
+#define I915_PLANE_GAMMA	(1<<1)
+#define I915_GAMMA_PRECISION_UNKNOWN	0
+#define I915_GAMMA_PRECISION_CURRENT	0xFFFFFFFF
+#define I915_GAMMA_PRECISION_LEGACY	(1<<0)
+#define I915_GAMMA_PRECISION_10BIT	(1<<1)
+#define I915_GAMMA_PRECISION_12BIT	(1<<2)
+#define I915_GAMMA_PRECISION_14BIT	(1<<3)
+#define I915_GAMMA_PRECISION_16BIT	(1<<4)
+#define CHV_DEGAMMA_MAX_INDEX	64
+#define CHV_DEGAMMA_VALS	65
+#define CHV_8BIT_GAMMA_MAX_INDEX	256
+#define CHV_8BIT_GAMMA_MAX_VALS	CHV_8BIT_GAMMA_MAX_INDEX
+#define CHV_10BIT_GAMMA_MAX_INDEX	256
+#define CHV_10BIT_GAMMA_MAX_VALS	(CHV_10BIT_GAMMA_MAX_INDEX + 1)
+#define DEFAULT 0
+#define RANDOM 1
+#define DRM_IOCTL_MODE_CREATEPROPBLOB	\
+	DRM_IOWR(0xBD, struct drm_mode_create_blob)
Why are we adding these definitions here ? We should reuse whatever is available in the UAPI layer, link to appropriate header files, and then hardcode whatever is not accessible. 
I don’t see a reason to add IOCTL nos here.
+
+struct drm_intel_csc {
+	uint32_t version;
+	int csc_matrix[9];
+
+};
Same here, this should be available in drm headers. 
+
+struct CURVE_SLIDER_VALUES {
+	int32_t brightness;
+	int32_t contrast;
+	float gamma;
+};
+
+struct rgb_pixel {
+	uint32_t red;
+	uint32_t green;
+	uint32_t blue;
+};
+
+struct drm_intel_gamma {
+	uint32_t version;
+	uint32_t num_samples;
+	struct rgb_pixel gamma_values[257];
+};
+struct drm_intel_degamma {
+	uint32_t version;
+	uint32_t num_samples;
+	struct rgb_pixel degamma_values[65];
+};
+
+static struct drm_mode_create_blob {
+	uint64_t data;
+	uint32_t length;
+	uint32_t blob_id;
+};
Same here, this should be available in drm headers.
+
+
+struct data_t {
+	int fb_initial;
+	int drm_fd;
+	int w, h;
+	igt_display_t display;
+	struct igt_fb fb_prep;
+	struct igt_fb fb, fb1;
+};
+
+	static void
+paint_color(struct data_t *d, struct igt_fb *fb, uint16_t w, uint16_t 
+h) {
+	cairo_t *cr;
+
+	cr = igt_get_cairo_ctx(d->drm_fd, fb);
+	igt_paint_test_pattern(cr, w, h);
+	cairo_destroy(cr);
+}
+
+int create_blob(int fd, uint64_t *data, int length) {
+	struct drm_mode_create_blob blob;
+	int ret = -1;
+
+	blob.data = (uint64_t)data;
+	blob.length = length;
+	blob.blob_id = -1;
+	ret = ioctl(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &blob);
+	if (!ret)
+		return blob.blob_id;
+	printf("Blob creation ioctl failed");
+	return ret;
+}
+
+static void prepare_crtc(struct data_t *data, igt_output_t *output,
+		enum pipe pipe, igt_plane_t *plane, drmModeModeInfo *mode,
+		enum igt_commit_style s)
+{
+	igt_display_t *display = &data->display;
+
+	igt_output_set_pipe(output, pipe);
+
+
+	/* before allocating, free if any older fb */
+	if (data->fb_initial) {
+		igt_remove_fb(data->drm_fd, &data->fb_prep);
+		data->fb_initial = 0;
+	}
+
+	/* allocate fb for plane 1 */
+	data->fb_initial = igt_create_color_fb(data->drm_fd,
+			mode->hdisplay, mode->vdisplay,
+			DRM_FORMAT_XRGB8888,
+			LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
+			0, 0, 1.0,
+			&data->fb_prep);
+	igt_assert(data->fb_initial);
+
+	igt_plane_set_fb(plane, &data->fb_prep);
+	if (s == COMMIT_LEGACY) {
+		int ret;
+
+		ret = drmModeSetCrtc(data->drm_fd,
+				output->config.crtc->crtc_id,
+				data->fb_initial,
+				plane->pan_x, plane->pan_y,
+				&output->id,
+				1,
+				mode);
+		igt_assert(ret == 0);
+	} else {
+		igt_display_commit2(display, s);
+	}
+}
+static void cleanup_fb(struct data_t *data) {
+	igt_display_t *display = &data->display;
+
+	if (data->fb_initial) {
+		igt_remove_fb(data->drm_fd, &data->fb_prep);
+		data->fb_initial = 0;
+	}
+	if (data->fb.fb_id)
+		igt_remove_fb(data->drm_fd, &data->fb);
+	if (data->fb1.fb_id)
+		igt_remove_fb(data->drm_fd, &data->fb1);
+
+}
+static void cleanup_crtc(struct data_t *data, igt_output_t *output,
+		igt_plane_t *plane)
+{
+	igt_display_t *display = &data->display;
+
+	if (!plane->is_primary) {
+		igt_plane_t *primary;
+
+		primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
+		igt_plane_set_fb(primary, NULL);
+	}
+
+	igt_plane_set_fb(plane, NULL);
+	igt_output_set_pipe(output, PIPE_ANY);
+	igt_display_commit2(display, COMMIT_LEGACY); }
+
+int convertToBinarySigned(float value)
+{
+	int mantissa = 0;
+	int fraction = 0;
+	int sign = 0;
+	int loop;
+	float ftmp;
+	int ret = 0;
+
+	if (value < 0) {
+		sign = 1;
+		value *= (-1);
+	}
+	mantissa = (int) value / 1;
+	mantissa &= CSC_MANTISSA_MAX_VALUE;
+	ftmp = value - mantissa;
+	for (loop = 0; loop < CSC_FRACTION_MAX_BITS; loop++) {
+		ftmp = ftmp * 2;
+		if (ftmp >= 1) {
+			fraction |= 0x1;
+			ftmp -= 1.0;
+		}
+		if (loop == (CSC_FRACTION_MAX_BITS - 1))
+			break;
+		fraction <<= 1;
+
+	}
+	fraction &= 0x3FF;
+	ret = (fraction | (mantissa << CSC_FRACTION_MAX_BITS));
+	if (sign)
+		ret = (~ret) + 1;
+	ret |= (sign << 11);
+	ret &= 0xFFF;
+	return ret;
+}
+void cscWrite(float *csc_val, int *csc_matrix) {
+	for (int i = 0; i < CHV_CSC_VALS; i++)
+		csc_matrix[i] = (uint64_t)convertToBinarySigned(csc_val[i]);
+}
+
+void generateCurveFromSlider(struct CURVE_SLIDER_VALUES *pSlider,
+		uint32_t *pCurve, uint32_t num_samples) {
+	double dGamma = (double)pSlider->gamma;
+	double dBrightness = (double)pSlider->brightness * 256;
+	double dContrast = (double)pSlider->contrast;
+	double dSlope, dOutput, outVal;
+	uint32_t input, index, i;
+	int maxVal = 65535;
+
+	for (i = 0; i < num_samples*2; i++) {
+		outVal = (double)(255 * pow(((double)i / 255.0),
+					(STANDARD_GAMMA / dGamma)));
+		outVal += 0.5;
+		if (maxVal < outVal)
+			outVal = maxVal;
+		pCurve[i] = outVal;
+	}
+	dSlope = 1.0 + dContrast / 100.0;
+	for (input = 0; input < num_samples*2; input++) {
+		dOutput = dSlope * pCurve[input];
+		dOutput += dBrightness + 0.5;
+		if (dOutput > maxVal)
+			dOutput = maxVal;
+		if (dOutput < 0)
+			dOutput = 0;
+		pCurve[input] = dOutput;
+	}
+}
+void writeCurveCsv(uint32_t *pCurveData, uint32_t num_samples,
+		struct rgb_pixel *gamma_ptr)
What does Csv stand for ?
+{
+	uint32_t *pRed, *pGreen, *pBlue;
+	uint64_t i, index;
+
+	pRed = pCurveData;
+	pGreen = pCurveData;
+	pBlue = pCurveData;
+	for (i = 0; i < num_samples; i++) {
+		index = i * 2;
+		gamma_ptr[i].red = pRed[index];
+		gamma_ptr[i].green = pGreen[index];
+		gamma_ptr[i].blue = pBlue[index];
+	}
+}
+
+void gammaPipe(int brightness, int contrast, float gamma,
+		uint32_t num_samples, struct rgb_pixel *gamma_ptr) {
+	struct CURVE_SLIDER_VALUES sSlideData;
+	uint32_t pCurve[2*num_samples];
+
+	sSlideData.brightness = brightness;
+	sSlideData.contrast = contrast;
+	sSlideData.gamma = gamma;
+	generateCurveFromSlider(&sSlideData, pCurve, num_samples);
+	writeCurveCsv(pCurve, num_samples, gamma_ptr); } static int 
+get_color_property(int drm_fd, int id, int object,
+		char *prop_name, int blob_id)
+{
+	int i = 0, ret = 0;
+	uint64_t value = 0;
+	struct drm_intel_gamma *gamma_data = NULL;
+	drmModeObjectPropertiesPtr props = NULL;
+
+	if (id < 0 || ((object != DRM_MODE_OBJECT_CRTC) &&
+				(object != DRM_MODE_OBJECT_PLANE)))
+		return -1;
+	value = blob_id;
+
+	/* Get all the properties from object */
+	props = drmModeObjectGetProperties(drm_fd, id, object);
+	if (!props)
Its good to add a print for failure case.
+		return -1;
+	for (i = 0; i < props->count_props; i++) {
+		drmModePropertyPtr prop = drmModeGetProperty(drm_fd,
+				props->props[i]);
+		if (strcmp(prop->name, prop_name) == 0) {
+			/* Found property, now set the values */
+			blob_id = props->prop_values[i];
+			break;
+		}
+		drmModeFreeProperty(prop);
+	}
+
+	ret = blob_id;
+	/* Free the allocated property */
+	drmModeFreeObjectProperties(props);
+	if (i == props->count_props) {
+		/* Property not found */
+		return -1;
+	}
+	return ret;
+}
+
+
+int set_color_property(int drm_fd, int id, int object, char *prop_name,
+			 int blob_id)
+{
+	int i = 0, res;
+
+	drmModeObjectPropertiesPtr props = NULL;
+
+	if (id < 0 || ((object != DRM_MODE_OBJECT_CRTC) &&
+			(object != DRM_MODE_OBJECT_PLANE))) {
Same here, an error message will do good.
+		return -1;
+	}
+
+	props = drmModeObjectGetProperties(drm_fd, id, object);
+	if (!props)
+		return -1;
+	for (i = 0; i < props->count_props; i++) {
+		drmModePropertyPtr prop = drmModeGetProperty(drm_fd,
+							 props->props[i]);
+		if (strcmp(prop->name, prop_name) == 0) {
+			/* Found property, now set the values */
+			res = drmModeObjectSetProperty(drm_fd, id, object,
+					 (uint32_t)prop->prop_id, blob_id);
+
+			if (res) {
+				drmModeFreeProperty(prop);
+				drmModeFreeObjectProperties(props);
+			} else {
+				drmModeFreeProperty(prop);
+				break;
+			}
+		}
+
+		drmModeFreeProperty(prop);
+	}
+	drmModeFreeObjectProperties(props);
+	if (i == props->count_props) {
+		/* Property not found */
+		return -1;
+	}
+	return 0;
+}
+void test_pipe_csc(igt_display_t *display, igt_output_t *output,
+				 igt_plane_t *plane, int value)
+{
+	struct drm_intel_csc *csc_data = NULL;
+
+	csc_data = (struct drm_intel_csc *)
+		 malloc(sizeof(struct drm_intel_csc));
+	int csc_matrix[CHV_CSC_VALS];
+	float  csc_val[CHV_CSC_VALS];
+	int csc_random[CHV_CSC_VALS] = {1, 1, 1, 0, 0, 0, 0, 0, 0};
+	int csc_default[CHV_CSC_VALS] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
+	int i, res;
+
+	csc_data->version = 1;
+	if (value == DEFAULT)
+		memcpy(csc_val, csc_default, sizeof(csc_val));
+	else
+		memcpy(csc_val, csc_random, sizeof(csc_val));
+
+	cscWrite(csc_val, csc_matrix);
+
+	for (i = 0; i < CHV_CSC_VALS; i++)
+		csc_data->csc_matrix[i] = csc_matrix[i];
+
+	int blob_id = create_blob(display->drm_fd,
+			 (int *)(csc_data), sizeof(struct drm_intel_csc));
+
+	igt_assert(blob_id > 0);
+
	We should not call this function, if the blob creation is not successful.
+	res = set_color_property(display->drm_fd, output->config.crtc->crtc_id,
+		 DRM_MODE_OBJECT_CRTC, "CTM", blob_id);
+	if (res < 0)
+		printf("Setting CSC failed!");
+	free(csc_data);
+
+
+}
+void test_pipe_degamma(igt_display_t *display, igt_output_t *output,
+	 igt_plane_t *plane, float degamma, int brightness, int contrast,
+			 uint32_t gamma_precision, uint32_t num_samples) {
+	struct drm_intel_degamma *degamma_data =  NULL;
+	int res, ret;
+
+	degamma_data = malloc(sizeof(struct drm_intel_degamma) +
+			 (num_samples * sizeof(struct rgb_pixel)));
+	degamma_data->version = 1;
+	degamma_data->num_samples = num_samples;
+	struct rgb_pixel degamma_ptr[num_samples];
+
+	gammaPipe(brightness, contrast, degamma, num_samples, degamma_ptr);
+	for (int i = 0; i < num_samples; i++)
+		degamma_data->degamma_values[i] = degamma_ptr[i];
+
+	int blob_id = create_blob(display->drm_fd, (uint64_t *)(degamma_data),
+		 sizeof(struct drm_intel_degamma) + (num_samples *
+			 sizeof(struct rgb_pixel)));
+
+	igt_assert(blob_id > 0);
Same for gamma.
+	res = set_color_property(display->drm_fd, output->config.crtc->crtc_id,
+			 DRM_MODE_OBJECT_CRTC, "PALETTE_BEFORE_CTM", blob_id);
+	ret = get_color_property(display->drm_fd, output->config.crtc->crtc_id,
+			 DRM_MODE_OBJECT_CRTC, "PALETTE_BEFORE_CTM", blob_id);
+	if (ret < 0)
+		return -1;
+	if (res < 0)
+		printf("Setting Gamma failed!");
+	free(degamma_data);
+}
+void test_pipe_gamma(igt_display_t *display, igt_output_t *output,
+			 igt_plane_t *plane, float gamma, int brightness,
+			 int contrast, uint32_t gamma_precision,
+				 uint32_t num_samples)
+{
+	struct drm_intel_gamma *gamma_data =  NULL;
+	int res, ret;
+
+	gamma_data = malloc(sizeof(struct drm_intel_gamma) +
+			 (num_samples * sizeof(struct rgb_pixel)));
+	gamma_data->version = 1;
+	gamma_data->num_samples = num_samples;
+	struct rgb_pixel gamma_ptr[num_samples];
+
+	gammaPipe(brightness, contrast, gamma, num_samples, gamma_ptr);
+	for (int i = 0; i < num_samples; i++)
+		gamma_data->gamma_values[i] = gamma_ptr[i];
+
+
+	int blob_id = create_blob(display->drm_fd, (uint64_t *)(gamma_data),
+			 sizeof(struct drm_intel_gamma) + (num_samples *
+					sizeof(struct rgb_pixel)));
+
+	igt_assert(blob_id > 0);
Same for set color property.
+	res = set_color_property(display->drm_fd, output->config.crtc->crtc_id,
+			 DRM_MODE_OBJECT_CRTC, "PALETTE_AFTER_CTM", blob_id);
+	ret = get_color_property(display->drm_fd, output->config.crtc->crtc_id,
+			DRM_MODE_OBJECT_CRTC, "PALETTE_AFTER_CTM", blob_id);
+	if (ret < 0)
Shouldn't we check this before doing a get_color_prop first ?
+		return -1;
+	if (res < 0)
+		printf("Setting Gamma failed!");
+
+	free(gamma_data);
+}
+void test_pipe_color(struct data_t *data, char *prop_name, int value) {
+	igt_display_t *display = &data->display;
+	igt_output_t *output;
+	igt_plane_t *plane;
+	enum pipe pipe;
+	enum igt_commit_style commit = COMMIT_LEGACY;
+	int res, i;
+	int fb_id, fb_id1;
+	int width, height;
+	uint32_t pixelformat = DRM_FORMAT_XRGB8888;
+
+	for_each_connected_output(display, output) {
+		drmModeModeInfo *mode;
+
+		pipe = output->config.pipe;
+
+		igt_output_set_pipe(output, pipe);
+		mode = igt_output_get_mode(output);
+		/*Draw the initial primary plane*/
+		plane = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
+
+		prepare_crtc(data, output, pipe, plane, mode, commit);
+		width = 600;
+		height = 600;
+
+		plane = igt_output_get_plane(output, IGT_PLANE_2);
+		fb_id = igt_create_color_fb(data->drm_fd,
+				width, height,
+				pixelformat,
+				LOCAL_DRM_FORMAT_MOD_NONE,
+				1.0,
+				0.0,
+				0.0,
+				&data->fb);
+		plane->crtc_x = 100;
+		plane->crtc_y = 100;
+		plane->fb_changed = true;
+		igt_plane_set_fb(plane, &data->fb);
+		/* set the width and height for sprite plane 2. */
+		width = 200;
+		height = 200;
+		plane = igt_output_get_plane(output, IGT_PLANE_3);
+		fb_id1 = igt_create_color_fb(data->drm_fd,
+				width, height,
+				pixelformat,
+				LOCAL_DRM_FORMAT_MOD_NONE,
+				1.0,
+				1.0,
+				0.0,
+				&data->fb1);
+		igt_assert(fb_id1);
+
+		plane->crtc_x = 30;
+		plane->crtc_y = 30;
+		plane->fb_changed = true;
+		igt_plane_set_fb(plane, &data->fb1);
+
+		igt_display_commit2(display, commit);
+		usleep(2000000);
+		if ((strcmp(prop_name, "gamma_property_8bit") == 0) &&
+					value == RANDOM){
+			test_pipe_gamma(display, output, plane, 1, 50, 50,
+					 I915_GAMMA_PRECISION_LEGACY,
+						 CHV_8BIT_GAMMA_MAX_VALS);
+		} else  if ((strcmp(prop_name, "gamma_property_8bit") == 0) &&
+						value == DEFAULT) {
+			test_pipe_gamma(display, output, plane, 1, 50, 50,
+					 I915_GAMMA_PRECISION_10BIT, 0);
+		} else  if ((strcmp(prop_name, "gamma_property_10bit") == 0) &&
+					value == DEFAULT) {
+			test_pipe_gamma(display, output, plane, 1, 50, 50,
+					 I915_GAMMA_PRECISION_10BIT, 0);
+		} else  if ((strcmp(prop_name, "gamma_property_10bit") == 0) &&
+					 value == RANDOM) {
+			test_pipe_gamma(display, output, plane, 1, 50, 50,
+					 I915_GAMMA_PRECISION_10BIT,
+						CHV_10BIT_GAMMA_MAX_VALS);
+
+		} else  if ((strcmp(prop_name, "csc_property") == 0)) {
+			test_pipe_csc(display, output, plane, value);
+		} else  if ((strcmp(prop_name, "degamma_property") == 0) &&
+					value == RANDOM) {
+			test_pipe_degamma(display, output, plane, 1, 50, 50,
+					 I915_GAMMA_PRECISION_10BIT, 65);
+		} else  if ((strcmp(prop_name, "degamma_property") == 0) &&
+					value == DEFAULT) {
+			test_pipe_degamma(display, output, plane, 1, 50, 50,
+					 I915_GAMMA_PRECISION_10BIT, 0);
+
+		} else {
+			printf("Invalid Test\n");
+		}
+
+		usleep(2000000);
+		cleanup_fb(data);
+		plane = igt_output_get_plane(output, IGT_PLANE_3);
+		cleanup_crtc(data, output, plane);
+		plane = igt_output_get_plane(output, IGT_PLANE_2);
+		cleanup_crtc(data, output, plane);
+		break;
+
+	}
+}
+
+igt_main
+{
+	struct data_t data = {};
+	int gen = 0;
+	int plane_it = 0, it_rotation = 0, it_tiling = 0;
+
+	igt_skip_on_simulation();
+
+	igt_fixture{
+		data.drm_fd = drm_open_any_master();
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_display_init(&data.display, data.drm_fd);
+	}
+	igt_subtest_f("Enable_Gamma_8bit") {
+		test_pipe_color(&data, "gamma_property_8bit", RANDOM);
+	}
+	igt_subtest_f("Disable_Gamma_8bit") {
+		test_pipe_color(&data, "gamma_property_8bit", DEFAULT);
+	}
+	igt_subtest_f("Enable_Gamma_10bit") {
+		test_pipe_color(&data, "gamma_property_10bit", RANDOM);
+	}
+	igt_subtest_f("Disable_Gamma_10bit") {
+		test_pipe_color(&data, "gamma_property_10bit", DEFAULT);
+	}
+