All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] tests/kms_color:Color IGT
@ 2015-07-10 10:32 Dhanya Pillai
  2015-07-10 10:41 ` David Weinehall
  0 siblings, 1 reply; 11+ messages in thread
From: Dhanya Pillai @ 2015-07-10 10:32 UTC (permalink / raw)
  To: intel-gfx; +Cc: Dhanya

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

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 \
 	pm_lpsp \
 	pm_rpm \
 	pm_rps \
diff --git a/tests/kms_color.c b/tests/kms_color.c
new file mode 100644
index 0000000..4f6e157
--- /dev/null
+++ b/tests/kms_color.c
@@ -0,0 +1,639 @@
+/*
+ * Copyeight © 2013,2014 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)
+
+struct drm_intel_csc {
+	uint32_t version;
+	int csc_matrix[9];
+
+};
+
+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;
+};
+
+
+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)
+{
+	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)
+		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))) {
+		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);
+
+	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);
+	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);
+	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)
+		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);
+	}
+
+	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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread
* [PATCH] tests/kms_color:Color IGT
@ 2015-07-13  3:54 Dhanya Pillai
  2015-07-13  4:01 ` Sharma, Shashank
  0 siblings, 1 reply; 11+ messages in thread
From: Dhanya Pillai @ 2015-07-13  3:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Dhanya

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

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 \
 	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)
+
+struct drm_intel_csc {
+	uint32_t version;
+	int csc_matrix[9];
+
+};
+
+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;
+};
+
+
+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)
+{
+	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)
+		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))) {
+		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);
+
+	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);
+	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);
+	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)
+		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);
+	}
+
+	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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread
* [PATCH] tests/kms_color:Color IGT
@ 2015-11-20 10:27 Dhanya Pillai
  2015-11-24 16:36 ` Thomas Wood
  2015-11-24 17:08 ` Daniel Vetter
  0 siblings, 2 replies; 11+ messages in thread
From: Dhanya Pillai @ 2015-11-20 10:27 UTC (permalink / raw)
  To: intel-gfx
  Cc: annie.j.matheson, yann.argotti, alex.crisan, nathan.d.ciobanu, Dhanya

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

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

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

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 8fb2de8..906c14f 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -64,6 +64,7 @@ TESTS_progs_M = \
 	gem_write_read_ring_switch \
 	kms_addfb_basic \
 	kms_atomic \
+	kms_color \
 	kms_cursor_crc \
 	kms_draw_crc \
 	kms_fbc_crc \
diff --git a/tests/kms_color.c b/tests/kms_color.c
new file mode 100644
index 0000000..c261c3f
--- /dev/null
+++ b/tests/kms_color.c
@@ -0,0 +1,1070 @@
+/*
+ * 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 "drm.h"
+#include "igt_debugfs.h"
+#include "igt_kms.h"
+#include "igt_core.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
+#include "igt_aux.h"
+#include<unistd.h>
+#include<stdlib.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+
+
+IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
+typedef unsigned char u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+
+#define CSC_MAX_VALS    9
+
+#define GEN9_SPLITGAMMA_MAX_VALS                512
+#define GEN9_8BIT_GAMMA_MAX_VALS                256
+#define GEN9_10BIT_GAMMA_MAX_VALS               1024
+#define GEN9_12BIT_GAMMA_MAX_VALS               513
+#define BDW_MAX_GAMMA                         ((1 << 24) - 1)
+
+
+#define CSC_COEFF_MAX   0x3FE000000
+#define CSC_COEFF_MIN   0xFFFFFFFC00000000
+
+#define VAR_LEN 100
+/*OFFSETS*/
+
+#define _PIPE_A_CSC_COEFF 0x49010
+#define _PIPE_B_CSC_COEFF 0x49110
+#define GAMMA_8BIT_PIPEA  0x4A000
+#define GAMMA_8BIT_PIPEB  0x4A800
+#define GAMMA_8BIT_PIPEC  0x4B000
+
+#define GAMMA_10BIT_PIPEA  0x4A404
+#define GAMMA_10BIT_PIPEB  0x4AC04
+#define GAMMA_10BIT_PIPEC  0x4B404
+
+#define CSC_TEST 0
+#define GAMMA_TEST 1
+#define DEGAMMA_TEST 2
+#define ENABLE 0
+#define DISABLE 1
+#define RED 0
+#define GREEN 1
+#define BLUE 2
+#define UNITY 3
+#define GAMMA_1 0
+#define GAMMA_2 1
+#define GAMMA_2_2 2
+#define PRIMARY 0
+#define SECONDARY 1
+
+#define CSC_COEFF_UNITY 0x100000000
+
+#define GET_BIT_MASK(n) ((1 << n) - 1)
+#define GET_BITS(x, start, nbits) ((x >> start) & GET_BIT_MASK(nbits))
+#define GET_BITS_ROUNDOFF(x, start, nbits) \
+	((GET_BITS(x, start, (nbits + 1)) + 1) >> 1)
+
+/*Structure defination will be removed once intergrated in libdrm */
+struct drm_r32g32b32 {
+	__u32 r32;
+	__u32 g32;
+	__u32 b32;
+	__u32 reserved;
+};
+
+struct drm_palette {
+	struct drm_r32g32b32 lut[0];
+};
+
+struct drm_ctm {
+	__s64 ctm_coeff[9];
+};
+
+float ctm_red[9] = {1, 1, 1, 0, 0, 0, 0, 0, 0};
+float ctm_green[9] = {0, 0, 0, 1, 1, 1, 0, 0, 0};
+float ctm_blue[9] = {0, 0, 0, 0, 0, 0, 1, 1, 1};
+float ctm_unity[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
+
+struct data_t {
+	int fb_initial;
+	int drm_fd;
+	int gen;
+	int w, h;
+	igt_display_t display;
+	struct igt_fb fb_prep;
+	struct igt_fb fb, fb1;
+};
+
+
+static 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;
+	igt_info("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);
+
+		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);
+
+}
+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_UNIVERSAL);
+
+}
+
+
+
+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_palette *gamma_data = NULL;
+	drmModeObjectPropertiesPtr props = NULL;
+
+	if (id < 0 || ((object != DRM_MODE_OBJECT_CRTC) &&
+				(object != DRM_MODE_OBJECT_PLANE))) {
+		igt_warn("Invalid input to get color property %d", id);
+		return -1;
+	}
+	value = blob_id;
+
+	props = drmModeObjectGetProperties(drm_fd, id, object);
+	if (!props) {
+		igt_warn("\nNo property for object id=%d\n", id);
+		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) {
+			blob_id = props->prop_values[i];
+			break;
+		}
+		drmModeFreeProperty(prop);
+	}
+
+	ret = blob_id;
+	drmModeFreeObjectProperties(props);
+	if (i == props->count_props) {
+		igt_warn("%s No such property\n", prop_name);
+		return -1;
+	}
+	return ret;
+}
+
+
+static 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))) {
+		igt_warn("Invalid input to set color property %d", id);
+		return -1;
+	}
+
+	props = drmModeObjectGetProperties(drm_fd, id, object);
+	if (!props) {
+		igt_warn("\nNo property for object id=%d\n", id);
+		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) {
+			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) {
+		igt_warn("%s No such property\n", prop_name);
+		return -1;
+	}
+	return 0;
+}
+static int64_t  convertFloatToBinary(double input)
+{
+
+	int integer_part, count = 0;
+	uint32_t temp_ip, frac_val = 0x00000000;
+	uint64_t integer_val = 0x00000000;
+	int64_t  value = 0x0000000000000000;
+	float fractional_part, ip;
+	integer_part = (int)input;
+	fractional_part = input - integer_part;
+	while (fractional_part != 0.000000) {
+		ip = fractional_part * 16;
+		temp_ip = (int)(fractional_part * 16);
+		frac_val = frac_val | (temp_ip << (28 - count * 4));
+		count++;
+		fractional_part = ip - temp_ip;
+	}
+	integer_val = integer_part;
+	value = value | (integer_val << 32);
+	value = value | frac_val;
+	return value;
+
+
+}
+static void write_gamma_lut(int brightness, int contrast, int gamma, uint32_t num_samples,
+		struct drm_r32g32b32 *gamma_ptr)
+{
+	unsigned short Red, Green, Blue;
+	uint32_t r32, b32, g32;
+	uint64_t i, index, val;
+	uint32_t data[num_samples];
+
+	for (i = 0; i < num_samples; i++) {
+		data[i] = (brightness +  contrast * pow((double)i, (double)gamma)) * num_samples;
+		Blue = data[i];
+		Green = data[i] >> 8;
+		Red = data[i] >> 16;
+		r32 = Red  << 16;
+		b32 = Blue ;
+		g32 = Green << 8;
+		gamma_ptr[i].r32 = r32;
+		gamma_ptr[i].g32 = g32;
+		gamma_ptr[i].b32 = b32;
+		val = 0;
+		val = r32;
+		val <<= 8;
+		val = val | g32;
+		val <<= 8;
+		val = val | b32;
+	}
+}
+static uint64_t get_blob(int fd, int blob_id, int length)
+{
+	struct drm_mode_get_blob blob;
+	int ret = 0;
+	int count = 0;
+
+	blob.blob_id = blob_id;
+	blob.length = length;
+	blob.data = (uint64_t) malloc(blob.length);
+	ret = ioctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob);
+
+	if (ret)
+		igt_info("GET BLOB Failed\n");
+
+	return blob.data;
+}
+
+static uint32_t csc_coeff(int64_t coeff)
+{
+	uint32_t reg_val, ls_bit_pos, exponent_bits, sign_bit = 0;
+	int32_t mantissa;
+	uint64_t abs_coeff;
+
+	abs_coeff = coeff;
+	if (abs_coeff < (CSC_COEFF_UNITY >> 3)) {
+		exponent_bits = 3;
+		ls_bit_pos = 19;
+	} else if (abs_coeff >= (CSC_COEFF_UNITY >> 3) &&
+			abs_coeff < (CSC_COEFF_UNITY >> 2)) {
+		exponent_bits = 2;
+		ls_bit_pos = 20;
+	} else if (abs_coeff >= (CSC_COEFF_UNITY >> 2)
+			&& abs_coeff < (CSC_COEFF_UNITY >> 1)) {
+		exponent_bits = 1;
+		ls_bit_pos = 21;
+	} else if (abs_coeff >= (CSC_COEFF_UNITY >> 1)
+			&& abs_coeff < CSC_COEFF_UNITY) {
+		exponent_bits = 0;
+		ls_bit_pos = 22;
+	} else if (abs_coeff >= CSC_COEFF_UNITY &&
+			abs_coeff < (CSC_COEFF_UNITY << 1)) {
+		exponent_bits = 7;
+		ls_bit_pos = 23;
+	} else {
+		exponent_bits = 6;
+		ls_bit_pos = 24;
+	}
+	mantissa = GET_BITS_ROUNDOFF(abs_coeff, ls_bit_pos, CSC_MAX_VALS);
+	if (coeff < 0)
+		sign_bit = 1;
+
+	reg_val = 0;
+	reg_val |= (exponent_bits << 12);
+	reg_val |= mantissa << 3;
+	reg_val |= sign_bit << 15;
+	return reg_val;
+}
+
+static bool validate_ctm_registers(int display, int64_t value[CSC_MAX_VALS])
+{
+	uint32_t temp_reg_val = 0, RValue = 0, OFFSET;
+	uint32_t tmp_val, tmp2_val;
+	bool result = false;
+	uint32_t RY_Val = 0, GY_Val = 0, BY_Val = 0;
+	uint32_t RU_Val = 0, GU_Val = 0, BU_Val = 0;
+	uint32_t RV_Val = 0, GV_Val = 0, BV_Val = 0;
+	char register_to_validate[VAR_LEN];
+	intel_register_access_init(intel_get_pci_device(), 0);
+
+	if (display == PRIMARY)
+		OFFSET = _PIPE_A_CSC_COEFF;
+	else
+		OFFSET = _PIPE_B_CSC_COEFF;
+
+	temp_reg_val = INREG(OFFSET);
+	GY_Val = temp_reg_val & 0xFFFF;
+	tmp_val = csc_coeff(value[1]);
+	if (GY_Val != tmp_val) {
+		igt_warn("reading register is failed - Reg:%x Val:%x Expected:%x\n", GY_Val, tmp_val, value[1]);
+		return result;
+	}
+	RY_Val = (temp_reg_val >> 16) & 0xFFFF;
+	tmp_val = csc_coeff(value[0]);
+	if (RY_Val != tmp_val) {
+		igt_warn("reading register is failed - Reg:%x Val:%x Expected:%x\n", temp_reg_val, tmp_val, value[0]);
+		return result;
+	}
+	OFFSET += 4;
+	temp_reg_val = INREG(OFFSET);
+	BY_Val = (temp_reg_val >> 16) & 0xFFFF;
+	tmp_val = csc_coeff(value[2]);
+	if (BY_Val != tmp_val) {
+		igt_warn("reading register is failed - Reg:%x Val:%x Expected:%x\n", temp_reg_val, tmp_val, value[2]);
+		return result;
+	}
+	OFFSET += 4;
+	temp_reg_val = INREG(OFFSET);
+	RU_Val = (temp_reg_val  >> 16) & 0xFFFF;
+	tmp_val = csc_coeff(value[3]);
+	if (RU_Val != tmp_val) {
+		igt_warn("reading register is failed - Reg:%x Val:%x Expected:%x\n", temp_reg_val, tmp_val, value[3]);
+		return result;
+	}
+	GU_Val = temp_reg_val & 0xFFFF;
+	tmp_val = csc_coeff(value[4]);
+	if (GU_Val != tmp_val) {
+		igt_warn("reading register is failed - Reg:%x Val:%x Expected:%x\n", temp_reg_val, tmp_val, value[4]);
+		return result;
+	}
+	OFFSET += 4;
+	temp_reg_val = INREG(OFFSET);
+	BU_Val = (temp_reg_val >> 16) & 0xFFFF;
+	tmp_val = csc_coeff(value[5]);
+	if (BU_Val != tmp_val) {
+		igt_warn("reading register is failed - Reg:%x Val:%x Expected:%x\n", temp_reg_val, tmp_val, value[5]);
+		return result;
+	}
+	OFFSET += 4;
+	temp_reg_val = INREG(OFFSET);
+	RV_Val = (temp_reg_val >> 16) & 0xFFFF;
+	tmp_val = csc_coeff(value[6]);
+	if (RV_Val != tmp_val) {
+		igt_warn("reading register is failed - Reg:%x Val:%x Expected:%x\n", temp_reg_val, tmp_val, value[6]);
+		return result;
+	}
+	GV_Val = temp_reg_val  & 0xFFFF;
+	tmp_val = csc_coeff(value[7]);
+	if (GV_Val != tmp_val) {
+		igt_warn("reading register is failed - Reg:%x Val:%x Expected:%x\n", temp_reg_val, tmp_val, value[7]);
+		return result;
+	}
+	OFFSET += 4;
+	temp_reg_val = INREG(OFFSET);
+	BV_Val = (temp_reg_val >> 16) & 0xFFFF;
+	tmp_val = csc_coeff(value[8]);
+	if (BV_Val != tmp_val) {
+		igt_warn("reading register is failed - Reg:%x Val:%x Expected:%x\n", temp_reg_val, tmp_val, value[8]);
+		return result;
+	}
+
+	igt_info("CTM Register test for Coefficient is PASS \n");
+	intel_register_access_fini();
+
+	return true;
+}
+static void enable_plane(struct data_t *data, igt_display_t *display, igt_output_t *output, int pipe1)
+{
+	enum igt_commit_style commit;
+	int res, i;
+	int fb_id, fb_id1;
+	int width, height;
+	uint32_t pixelformat = DRM_FORMAT_XRGB8888;
+	commit = COMMIT_UNIVERSAL;
+	enum pipe pipe;
+	for_each_connected_output(display, output) {
+		drmModeModeInfo *mode;
+		pipe = output->config.pipe;
+
+		if (pipe != pipe1)
+			break;
+		igt_plane_t *plane;
+		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);
+		/*Random Size  Buffer Creation */
+		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,
+				0.0,
+				1.0,
+				0.0,
+				&data->fb);
+		igt_plane_set_position(plane, 100, 100);
+
+		igt_plane_set_fb(plane, &data->fb);
+		igt_display_commit2(display, commit);
+	}
+
+}
+static void test_pipe_csc(struct data_t *data, igt_display_t *display, igt_output_t *output,
+		igt_plane_t *plane, int enable, int value, int pipe1)
+{
+	struct drm_ctm *ctm_data = NULL;
+	bool ret = false;
+	ctm_data = (struct drm_ctm *)
+		malloc(sizeof(struct drm_ctm));
+	enum igt_commit_style commit;
+	int res, i;
+	int fb_id, fb_id1;
+	int width, height;
+	uint32_t pixelformat = DRM_FORMAT_XRGB8888;
+	commit = COMMIT_UNIVERSAL;
+	float *ctm;
+	enum pipe pipe;
+	if (!enable)
+		ctm = ctm_unity;
+	else {
+		if (value == RED) {
+			ctm = ctm_red;
+		} else if (value == GREEN) {
+			ctm = ctm_green;
+		} else if (value == BLUE) {
+			ctm = ctm_blue;
+		} else{
+			ctm = ctm_unity;
+		} }
+	for (i = 0; i < CSC_MAX_VALS; i++) {
+		ctm_data->ctm_coeff[i] = convertFloatToBinary(*(ctm + i));
+	}
+
+	int blob_id = create_blob(display->drm_fd,
+			(int *)(ctm_data), sizeof(struct drm_ctm));
+	if (blob_id < 0) {
+		igt_warn("CTM:BLOB IOCTL Fail\n");
+	}
+	igt_assert_lte(0, blob_id);
+	res = set_color_property(display->drm_fd, output->config.crtc->crtc_id,
+			DRM_MODE_OBJECT_CRTC, "CTM", blob_id);
+	if (res < 0)
+		igt_warn("CTM:Set Property Failed\n");
+	igt_assert_lte(0, res);
+	res = get_color_property(display->drm_fd, output->config.crtc->crtc_id, DRM_MODE_OBJECT_CRTC, "CTM", blob_id);
+	if (res < 0)
+		igt_warn("CTM:Get Property Failed\n");
+	igt_assert_lte(0, res);
+	uint64_t blob_address = get_blob(display->drm_fd, res, sizeof(struct drm_ctm));
+	ctm_data = (struct drm_ctm *) (intptr_t) blob_address;
+	i = 0;
+	enable_plane(data, display, output, pipe1);
+	/*Register Verification*/
+	ret = validate_ctm_registers(pipe1, ctm_data->ctm_coeff);
+	if (!ret)
+		igt_warn("Register Verification Failed for CTM");
+	free(ctm_data);
+	igt_assert(ret);
+
+
+}
+
+static bool gamma_register_validation(int pipe, int mode, struct drm_r32g32b32 gamma_lut[mode])
+{
+	uint16_t blue_fract, green_fract, red_fract, blue_fract1, green_fract1, red_fract1, blue_fract2, green_fract2, red_fract2;
+	int ret, count, num_samples, length;
+	uint32_t blue, green, red, word, index, odd_word, even_word;
+	uint32_t offset, gamma;
+	intel_register_access_init(intel_get_pci_device(), 0);
+
+	if (pipe == PRIMARY) {
+		if (mode == GEN9_8BIT_GAMMA_MAX_VALS)
+			offset = GAMMA_8BIT_PIPEA;
+		else
+			offset = GAMMA_10BIT_PIPEA;
+	} else {
+		if (mode == GEN9_8BIT_GAMMA_MAX_VALS)
+			offset = GAMMA_8BIT_PIPEB;
+		else
+			offset = GAMMA_10BIT_PIPEB;
+	}
+
+	switch (mode) {
+	case 0:
+		return true;
+	case GEN9_8BIT_GAMMA_MAX_VALS:
+		count = 0;
+		while (count < GEN9_8BIT_GAMMA_MAX_VALS) {
+			blue = gamma_lut[count].b32;
+			green = gamma_lut[count].g32;
+			red = gamma_lut[count].r32;
+			if (blue >= BDW_MAX_GAMMA)
+				blue = BDW_MAX_GAMMA;
+			if (green >= BDW_MAX_GAMMA)
+				green = BDW_MAX_GAMMA;
+			if (red >= BDW_MAX_GAMMA)
+				red = BDW_MAX_GAMMA;
+
+			blue_fract = (blue >> 16) & 0xFF;
+			green_fract = (green >> 16) & 0xFF;
+			red_fract = (red >> 16) & 0xFF;
+			/* Red (23:16) Green (15:8) and Blue (7:0) */
+			word = red_fract << 16 ;
+			word = word | (green_fract << 8);
+			word = word | blue_fract;
+			gamma = INREG(offset);
+			if (gamma != word) {
+				igt_warn("Register Values not proper read value =%x \t  written = %x \t ", gamma, word);
+				return false;
+			}
+			offset += 4;
+			count++;
+		}
+		break;
+	case GEN9_10BIT_GAMMA_MAX_VALS:
+		count = 0;
+		while (count < GEN9_10BIT_GAMMA_MAX_VALS) {
+			blue = gamma_lut[count].b32;
+			green = gamma_lut[count].g32;
+			red = gamma_lut[count].r32;
+			if (blue >= BDW_MAX_GAMMA)
+				blue = BDW_MAX_GAMMA;
+			if (green >= BDW_MAX_GAMMA)
+				green = BDW_MAX_GAMMA;
+			if (red >= BDW_MAX_GAMMA)
+				red = BDW_MAX_GAMMA;
+
+			blue_fract = (blue >> 14) & 0x3FF ;
+			green_fract = (green >> 14) & 0x3FF;
+			red_fract = (red >> 14) & 0x3FF;
+			word = red_fract << 20;
+			word = word | (green_fract << 10);
+			word = word | blue_fract;
+			gamma = INREG(offset);
+			if (gamma != word) {
+				igt_warn("Register Values not proper read value =%x \t  written = %x \t ", gamma, word);
+				return false;
+			}
+			count++;
+		}
+		break;
+	case GEN9_SPLITGAMMA_MAX_VALS:
+		count = 0;
+		while (count < GEN9_10BIT_GAMMA_MAX_VALS) {
+			blue = gamma_lut[count].b32;
+			green = gamma_lut[count].g32;
+			red = gamma_lut[count].r32;
+			if (blue >= BDW_MAX_GAMMA)
+				blue = BDW_MAX_GAMMA;
+			if (green >= BDW_MAX_GAMMA)
+				green = BDW_MAX_GAMMA;
+			if (red >= BDW_MAX_GAMMA)
+				red = BDW_MAX_GAMMA;
+			blue_fract = (blue >> 14) & 0x3FF ;
+			green_fract = (green >> 14) & 0x3FF;
+			red_fract = (red >> 14) & 0x3FF;
+			word = red_fract << 20;
+			word = word | (green_fract << 10);
+			word = word | blue_fract;
+			gamma = INREG(offset);
+			if (gamma != word) {
+				igt_warn("Register Values not proper read value =%x \t  written = %x \t ", gamma, word);
+				return false;
+			}
+			count++;
+		}
+		break;
+
+	case GEN9_12BIT_GAMMA_MAX_VALS:
+		count = 0;
+		even_word = 0x0;
+		odd_word = 0x0;
+		while (count < GEN9_12BIT_GAMMA_MAX_VALS - 1) {
+			blue = gamma_lut[count].b32;
+			green = gamma_lut[count].g32;
+			red = gamma_lut[count].r32;
+			if (blue >= BDW_MAX_GAMMA)
+				blue = BDW_MAX_GAMMA;
+			if (green >= BDW_MAX_GAMMA)
+				green = BDW_MAX_GAMMA;
+			if (red >= BDW_MAX_GAMMA)
+				red = BDW_MAX_GAMMA;
+
+			red_fract = (red >> 8) & 0xFFFF ;
+			green_fract = (green >> 8) & 0xFFFF;
+			blue_fract = (blue >> 8) & 0xFFFF;
+
+			red_fract1 = red_fract & 0x3F ;
+			green_fract1 = green_fract & 0x3F ;
+			blue_fract1 = blue_fract & 0x3F ;
+			even_word = red_fract1 << 24;
+			even_word = even_word | (green_fract1  << 14) ;
+			even_word = even_word | (blue_fract1  << 4);
+			even_word = even_word & 0xFF0FC3F0 ;
+
+			gamma = INREG(offset);
+			if (gamma != even_word) {
+				igt_warn("EVEN:Register Values not proper read value =%x \t  written = %x \t count = %d ", gamma, even_word, count);
+				return false;
+			}
+			gamma = 0x0;
+			red_fract2 =  ((red_fract >> 6) & 0x3FF);
+			green_fract2 = ((green_fract >> 6) & 0x3FF);
+			blue_fract2 = ((blue_fract >> 6) & 0x3FF);
+
+			odd_word = (red_fract2 << 20);
+			odd_word = odd_word | (green_fract2  << 10) ;
+			odd_word = odd_word | blue_fract2 ;
+
+			gamma = INREG(offset);
+
+			if (gamma != odd_word) {
+				igt_warn("ODD:Register Values not proper read value =%x \t  written = %x \t ", gamma, odd_word);
+				return false;
+			}
+			count++;
+		}
+		break;
+	}
+
+	intel_register_access_fini();
+
+	igt_info("Gamma Values Are Programmed Correctly\n");
+	return true;
+}
+static void test_pipe_degamma(struct data_t *data, igt_display_t *display, igt_output_t *output,
+			igt_plane_t *plane, uint32_t num_samples, int values, int pipe1)
+{
+	struct drm_palette *degamma_data =  NULL;
+	int res, ret;
+	float degamma;
+	enum pipe pipe;
+	enum igt_commit_style commit;
+	int  i;
+	int fb_id, fb_id1;
+	int width, height;
+	uint32_t pixelformat = DRM_FORMAT_XRGB8888;
+	bool status = false;
+	commit = COMMIT_UNIVERSAL;
+
+	int brightness = 50, contrast = 50, blob_length;
+	if (values == GAMMA_1)
+		degamma = 1.0;
+	else if (values == GAMMA_2)
+		degamma = 2.0;
+	else
+		degamma = 2.2;
+	if (num_samples == 0)
+		blob_length = 1;
+	else
+		blob_length = (sizeof(struct drm_palette) + (num_samples * sizeof(struct drm_r32g32b32)));
+
+	degamma_data = malloc(blob_length);
+	struct drm_r32g32b32 degamma_ptr[num_samples];
+	write_gamma_lut(brightness, contrast, degamma, num_samples, degamma_ptr);
+	for (int i = 0; i < num_samples; i++)
+		degamma_data->lut[i] = degamma_ptr[i];
+	int blob_id = create_blob(display->drm_fd, (uint64_t *)(degamma_data), blob_length);
+	if (blob_id < 0) {
+		igt_warn("Set blob IOCTL failed\n");
+	}
+	igt_assert_lte(0, blob_id);
+	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);
+	igt_assert_lte(0, res);
+	igt_assert_lte(0, ret);
+	enable_plane(data, display, output, pipe1);
+	if (num_samples != 0) {
+		status = gamma_register_validation(pipe1, num_samples, degamma_data->lut);
+		free(degamma_data);
+	}
+	igt_assert(status);
+
+
+}
+
+static void test_pipe_gamma(struct data_t *data, igt_display_t *display, igt_output_t *output,
+		uint32_t num_samples, int values, int pipe1)
+{
+	enum igt_commit_style commit;
+	int res, i;
+	int fb_id, fb_id1;
+	int width, height;
+	igt_plane_t *plane;
+	uint32_t pixelformat = DRM_FORMAT_XRGB8888;
+	commit = COMMIT_UNIVERSAL;
+	enum pipe pipe;
+	struct drm_palette *gamma_data =  NULL;
+	int  ret;
+	bool status = false;
+	float gamma;
+	int brightness = 50, contrast = 50, blob_length;
+	if (values == GAMMA_1)
+		gamma = 1.0;
+	else if (values == GAMMA_2)
+		gamma = 2.0;
+	else if (values == GAMMA_2_2)
+		gamma = 2.2;
+	else
+		gamma = values;
+	if (num_samples == 0)
+		blob_length = 1;
+	else
+		blob_length = (sizeof(struct drm_palette) + (num_samples * sizeof(struct drm_r32g32b32)));
+
+	gamma_data = malloc(blob_length);
+	struct drm_r32g32b32 gamma_ptr[num_samples];
+	write_gamma_lut(brightness, contrast, gamma, num_samples, gamma_ptr);
+
+	for (int i = 0; i < num_samples; i++)
+		gamma_data->lut[i] = gamma_ptr[i];
+
+
+	int blob_id = create_blob(display->drm_fd, (uint64_t *)(gamma_data), blob_length);
+	if (blob_id < 0) {
+		igt_warn("Set blob IOCTL failed\n");
+	}
+	igt_assert_lte(0, blob_id);
+
+
+	res = set_color_property(display->drm_fd, output->config.crtc->crtc_id,
+			DRM_MODE_OBJECT_CRTC, "PALETTE_AFTER_CTM", blob_id);
+	if (res < 0) {
+		igt_info("Setting Gamma failed!");
+
+		free(gamma_data);
+	}
+	igt_assert_lte(0, res);
+
+	ret = get_color_property(display->drm_fd, output->config.crtc->crtc_id,
+			DRM_MODE_OBJECT_CRTC, "PALETTE_AFTER_CTM", blob_id);
+	if (ret < 0) {
+		igt_info("Getting Gamma failed!");
+		free(gamma_data);
+	}
+	igt_assert_lte(0, ret);
+	enable_plane(data, display, output, pipe1);
+	if (num_samples != 0) {
+
+		status = gamma_register_validation(pipe1, num_samples, gamma_data->lut);
+
+		igt_assert(status);
+	}
+
+	free(gamma_data);
+}
+static void test_pipe_color(struct data_t *data, char *prop_name, int enable, int display_in, int value)
+{
+	igt_display_t *display = &data->display;
+	igt_output_t *output;
+	igt_plane_t *plane;
+	enum pipe pipe;
+	enum igt_commit_style commit;
+	int res, i;
+	int fb_id, fb_id1;
+	int width, height;
+	uint32_t pixelformat = DRM_FORMAT_XRGB8888;
+	commit = COMMIT_UNIVERSAL;
+	for_each_connected_output(display, output) {
+		drmModeModeInfo *mode;
+		pipe = output->config.pipe;
+		if (display_in != 2 && pipe != display_in)
+				break;
+		igt_plane_t *plane;
+		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);
+		/*Random sized Frame buffer creation */
+		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,
+				0.0,
+				1.0,
+				0.0,
+				&data->fb);
+		plane->crtc_x = 100;
+		plane->crtc_y = 100;
+		plane->fb_changed = true;
+		igt_plane_set_fb(plane, &data->fb);
+		igt_display_commit2(display, commit);
+
+		if ((strcmp(prop_name, "gamma_property_8bit") == 0) &&
+				enable == ENABLE){
+			test_pipe_gamma(data, display, output,
+					GEN9_8BIT_GAMMA_MAX_VALS, value, pipe);
+		} else  if ((strcmp(prop_name, "gamma_property_8bit") == 0) &&
+				enable == DISABLE) {
+			test_pipe_gamma(data, display, output,  0, value, pipe);
+		} else  if ((strcmp(prop_name, "gamma_property_10bit") == 0) &&
+				enable == ENABLE) {
+			test_pipe_gamma(data, display, output, GEN9_10BIT_GAMMA_MAX_VALS, value, pipe);
+		} else  if ((strcmp(prop_name, "csc_property") == 0)) {
+			test_pipe_csc(data, display, output, plane, enable, value, pipe);
+		} else  if ((strcmp(prop_name, "degamma_property") == 0) &&
+				enable == ENABLE) {
+			test_pipe_degamma(data, display, output, plane, GEN9_SPLITGAMMA_MAX_VALS, value, pipe);
+		} else  if ((strcmp(prop_name, "degamma_property") == 0) &&
+			enable == DISABLE) {
+			test_pipe_degamma(data, display, output, plane, 0, value, pipe);
+		} else  if ((strcmp(prop_name, "gamma_property_split") == 0) &&
+				enable == ENABLE) {
+			test_pipe_gamma(data, display, output,
+					GEN9_SPLITGAMMA_MAX_VALS, value, pipe);
+		} else  if ((strcmp(prop_name, "gamma_property_12bit") == 0) && enable == ENABLE) {
+			test_pipe_gamma(data, display, output,
+					GEN9_12BIT_GAMMA_MAX_VALS, value, pipe);
+
+		} else {
+			igt_info("Invalid Test\n");
+		}
+
+		cleanup_fb(data);
+		plane = igt_output_get_plane(output, IGT_PLANE_2);
+		usleep(2000000);
+		cleanup_crtc(data, output, plane);
+
+	}
+}
+
+static void print_usage(void)
+{
+	igt_info("Usage: ./kms_color \n");
+	igt_info("\t-d\t<display>           \t0->primary\t1->Secondary \n");
+	igt_info("\t-t\t<test>              \t0->csc    \t1->gamma\t2->degamma\n");
+	igt_info("\t-e\t<enable/disable>    \t0->enable \t1->disable\n");
+	igt_info("\t-v\t<Values>            \tFor csc values:  \t0->Red \t1->Green\t2->Blue \t3->Unity \n");
+	igt_info("                          \tFor Gamma values:\t0->1.0 \t1->2.0  \t2->2.2  \tx-> Any Gamma Custom Values\n");
+	igt_info("\t-m\t<Mode>              \tOnly For Gamma   \t0->8bit\t1->10bit\t2->12bit\t3->SplitLevel\n");
+}
+
+main(int argc, char *argv[])
+{
+	struct data_t data = {};
+	int gen = 0;
+	int display_id = 0;
+	int option = 0, count = -1;
+	int display = -1, test = -1, values = -1, enable_in = -1, mode = 0;
+	while ((option = getopt(argc, argv, "d:t:e:v:m:")) != -1) {
+		switch (option) {
+		case 'd':
+			 display = atoi(optarg);
+			 break;
+		case 't':
+			 test = atoi(optarg);
+			 break;
+		case 'v':
+			 values = atoi(optarg);
+			 break;
+		case 'e':
+			 enable_in = atoi(optarg);
+			 break;
+		case 'm':
+			 mode = atoi(optarg);
+			 break;
+		default:
+			 print_usage();
+			 return -1;
+		}
+	}
+	count =  argc;
+	igt_skip_on_simulation();
+	igt_subtest_init(argc, argv);
+	igt_fixture{
+		data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
+		kmstest_set_vt_graphics_mode();
+		igt_display_init(&data.display, data.drm_fd);
+		data.gen = intel_gen(intel_get_drm_devid(data.drm_fd));
+	}
+	igt_require(data.gen >= 9);
+	if (count == 1) {
+	igt_info("Color Generic Tests\n");
+	display = 2;
+	values = 1;
+	igt_subtest_f("Enable_Gamma_8bit")
+		test_pipe_color(&data, "gamma_property_8bit", ENABLE, display, values);
+	igt_subtest_f("Enable_Gamma_10bit")
+		test_pipe_color(&data, "gamma_property_10bit", ENABLE, display, values);
+	igt_subtest_f("Enable_Gamma_12bit")
+		test_pipe_color(&data, "gamma_property_12bit", ENABLE, display, values);
+	igt_subtest_f("Enable_SPLIT_GAMMA")
+		test_pipe_color(&data, "gamma_property_split", ENABLE, display, values);
+	igt_subtest_f("Disable_Gamma_8bit")
+		test_pipe_color(&data, "gamma_property_8bit", DISABLE, display, values);
+	igt_subtest_f("CSC_ENABLE")
+		test_pipe_color(&data, "csc_property", ENABLE, display, values);
+	igt_subtest_f("CSC_DISABLE")
+		test_pipe_color(&data, "csc_property", ENABLE, display, values);
+	igt_subtest_f("Enable_De-gamma")
+		test_pipe_color(&data, "degamma_property", ENABLE, display, values);
+	igt_subtest_f("Disable_De-gamma")
+		test_pipe_color(&data, "degamma_property", DISABLE, display, values);
+	} else {
+		if (((count < 7) || (display == -1) || (test == -1) || (values == -1) || (enable_in == -1))) {
+			print_usage();
+			return -1;
+		} else {
+			igt_info("Color Customised Tests\n");
+
+			if (test == CSC_TEST) {
+				igt_subtest_f("CSC")
+					test_pipe_color(&data, "csc_property", enable_in, display, values);
+			} else if (test == GAMMA_TEST) {
+				if (enable_in == ENABLE) {
+					if (mode == 0) {
+						igt_subtest_f("Enable_Gamma_8bit")
+							test_pipe_color(&data, "gamma_property_8bit", ENABLE, display, values);
+					} else if (mode == 1) {
+						igt_subtest_f("Enable_Gamma_10bit")
+							test_pipe_color(&data, "gamma_property_10bit", ENABLE, display, values);
+
+					} else if (mode == 2) {
+						igt_subtest_f("Enable_Gamma_12bit")
+							test_pipe_color(&data, "gamma_property_12bit", ENABLE, display, values);
+
+					} else if (mode == 3) {
+						igt_subtest_f("Enable_SPLIT_GAMMA")
+							test_pipe_color(&data, "gamma_property_split", ENABLE, display, values);
+					}
+				} else {
+					igt_subtest_f("Disable_Gamma_8bit")
+						test_pipe_color(&data, "gamma_property_8bit", DISABLE, display, values);
+
+				}
+			} else if (test == DEGAMMA_TEST) {
+				if (enable_in == ENABLE) {
+					igt_subtest_f("Enable_De-gamma")
+						test_pipe_color(&data, "degamma_property", ENABLE, display, values);
+				} else {
+					igt_subtest_f("Disable_De-gamma")
+						test_pipe_color(&data, "degamma_property", DISABLE, display, values);
+
+				} } else {
+					print_usage();
+				}
+		}
+
+	}
+	igt_fixture{
+		igt_display_fini(&data.display);
+	}
+	igt_exit();
+}
+
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 11+ messages in thread
* [PATCH] tests/kms_color:Color IGT
@ 2015-12-11 10:31 Dhanya Pillai
  2015-12-11 15:35 ` Rob Bradford
  0 siblings, 1 reply; 11+ messages in thread
From: Dhanya Pillai @ 2015-12-11 10:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: jesse.barnes, Dhanya

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 22312 bytes --]

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

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

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

diff --git a/tests/.gitignore b/tests/.gitignore
index 80af9a7..58c79e2 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -127,6 +127,7 @@ gen7_forcewake_mt
 kms_3d
 kms_addfb_basic
 kms_atomic
+kms_color
 kms_crtc_background_color
 kms_cursor_crc
 kms_draw_crc
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 8fb2de8..906c14f 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -64,6 +64,7 @@ TESTS_progs_M = \
 	gem_write_read_ring_switch \
 	kms_addfb_basic \
 	kms_atomic \
+	kms_color \
 	kms_cursor_crc \
 	kms_draw_crc \
 	kms_fbc_crc \
diff --git a/tests/kms_color.c b/tests/kms_color.c
new file mode 100644
index 0000000..b5d199b
--- /dev/null
+++ b/tests/kms_color.c
@@ -0,0 +1,684 @@
+/*
+ * 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 "drm.h"
+#include "igt_debugfs.h"
+#include "igt_kms.h"
+#include "igt_core.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
+#include "igt_aux.h"
+#include<unistd.h>
+#include<stdlib.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+
+
+IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
+/*
+This tool tests the following color features:
+	1.csc-red
+	2.csc-green
+	3.csc-blue
+	4.gamma-legacy
+	5.gamma-8bit
+	6.gamma-10bit
+	7.gamma-12bit
+	8.gamma-split
+
+Verification is done by CRC checks.
+
+*/
+
+#define CSC_MAX_VALS    9
+#define GEN9_SPLITGAMMA_MAX_VALS                512
+#define GEN9_8BIT_GAMMA_MAX_VALS                256
+#define GEN9_10BIT_GAMMA_MAX_VALS               1024
+#define GEN9_12BIT_GAMMA_MAX_VALS               513
+#define GEN9_MAX_GAMMA                         ((1 << 24) - 1)
+#define GEN9_MIN_GAMMA				0
+#define RED_CSC 0
+#define GREEN_CSC 1
+#define BLUE_CSC 2
+#define RED_FB 0
+#define GREEN_FB 1
+#define BLUE_FB 2
+
+struct _drm_r32g32b32 {
+	__u32 r32;
+	__u32 g32;
+	__u32 b32;
+	__u32 reserved;
+};
+
+struct _drm_palette {
+	struct _drm_r32g32b32 lut[0];
+};
+
+struct _drm_ctm {
+	__s64 ctm_coeff[9];
+};
+
+float ctm_red[9] = {1, 1, 1, 0, 0, 0, 0, 0, 0};
+float ctm_green[9] = {0, 0, 0, 1, 1, 1, 0, 0, 0};
+float ctm_blue[9] = {0, 0, 0, 0, 0, 0, 1, 1, 1};
+float ctm_unity[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
+
+struct framebuffer_color {
+	int red;
+	int green;
+	int blue;
+};
+struct framebuffer_color fb_color = {0,0,0};
+
+igt_crc_t crc_reference, crc_reference_black, crc_reference_white;
+igt_crc_t crc_black, crc_white, crc_current;
+
+struct data_t {
+	int fb_initial;
+	int drm_fd;
+	int gen;
+	int w, h;
+	igt_display_t display;
+	struct igt_fb fb_prep;
+	struct igt_fb fb, fb1;
+        igt_pipe_crc_t *pipe_crc;
+	enum pipe pipe;
+
+};
+
+
+static 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;
+	igt_fail(IGT_EXIT_FAILURE);
+	return ret;
+}
+
+static void prepare_crtc(struct data_t *data, igt_output_t *output,
+			 enum pipe pipe1, igt_plane_t *plane, drmModeModeInfo *mode,
+			 enum igt_commit_style s)
+{
+	igt_display_t *display = &data->display;
+
+	igt_output_set_pipe(output, pipe1);
+	
+	igt_pipe_crc_free(data->pipe_crc);
+        data->pipe_crc = igt_pipe_crc_new(pipe1, INTEL_PIPE_CRC_SOURCE_AUTO);
+	
+	/* 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 */
+					       fb_color.red, fb_color.green, fb_color.blue,
+					       &data->fb_prep);
+	igt_assert(data->fb_initial);
+
+	igt_plane_set_fb(plane, &data->fb_prep);
+
+	igt_display_commit2(display, s);
+}
+
+static void cleanup_fb(struct data_t *data)
+{
+
+	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);
+
+}
+
+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_UNIVERSAL);
+
+}
+
+static int get_color_property(int drm_fd, int id, int object,const char *prop_name,
+			      int blob_id)
+{
+	int i = 0, ret = 0;
+	drmModeObjectPropertiesPtr props = NULL;
+	igt_fail_on_f(id < 0 || ((object != DRM_MODE_OBJECT_CRTC) &&
+		      (object != DRM_MODE_OBJECT_PLANE)),
+		      "Invalid input to get color property %d", id);
+
+	props = drmModeObjectGetProperties(drm_fd, id, object);
+	igt_fail_on_f(!props,
+		     "\nNo property for object id=%d\n", id);
+	for (i = 0; i < props->count_props; i++) {
+		drmModePropertyPtr prop = drmModeGetProperty(drm_fd,
+							     props->props[i]);
+		if (strcmp(prop->name, prop_name) == 0) {
+			blob_id = props->prop_values[i];
+			break;
+		}
+		drmModeFreeProperty(prop);
+	}
+
+	ret = blob_id;
+	drmModeFreeObjectProperties(props);
+	igt_fail_on_f(i == props->count_props,
+		      "%s No such property\n", prop_name);
+	return ret;
+}
+
+
+static int set_color_property(int drm_fd, int id, int object, const char *prop_name, int blob_id)
+{
+	int i = 0, res;
+
+	drmModeObjectPropertiesPtr props = NULL;
+	igt_fail_on_f(id < 0 || ((object != DRM_MODE_OBJECT_CRTC) &&
+                      (object != DRM_MODE_OBJECT_PLANE)),
+                      "Invalid input to get color property %d", id);
+
+
+	props = drmModeObjectGetProperties(drm_fd, id, object);
+        igt_fail_on_f(!props,
+                     "\nNo property for object id=%d\n", id);
+	for (i = 0; i < props->count_props; i++) {
+		drmModePropertyPtr prop = drmModeGetProperty(drm_fd,
+							     props->props[i]);
+		if (strcmp(prop->name, prop_name) == 0) {
+			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);
+        igt_fail_on_f(i == props->count_props,
+                      "%s No such property\n", prop_name);
+	return 0;
+}
+
+static int64_t  convertFloatToBinary(double input)
+{
+
+	int integer_part, count = 0;
+	uint32_t temp_ip, frac_val = 0x00000000;
+	uint64_t integer_val = 0x00000000;
+	int64_t  value = 0x0000000000000000;
+	float fractional_part, ip;
+	integer_part = (int)input;
+	fractional_part = input - integer_part;
+	while (fractional_part != 0.000000) {
+		ip = fractional_part * 16;
+		temp_ip = (int)(fractional_part * 16);
+		frac_val = frac_val | (temp_ip << (28 - count * 4));
+		count++;
+		fractional_part = ip - temp_ip;
+	}
+	integer_val = integer_part;
+	value = value | (integer_val << 32);
+	value = value | frac_val;
+	return value;
+
+
+}
+
+static void write_gamma_lut( uint32_t num_samples, struct _drm_r32g32b32 *gamma_ptr, int unit_gamma )
+{
+	unsigned short Red, Green, Blue;
+	uint32_t r32, b32, g32;
+	uint64_t i,  val;
+
+	for (i = 0; i < num_samples; i++) {
+		if(unit_gamma == 0) {
+		Blue = GEN9_MAX_GAMMA;
+		Green = GEN9_MAX_GAMMA;
+		Red = GEN9_MAX_GAMMA;
+		} else {
+		Blue = GEN9_MIN_GAMMA;
+		Green = GEN9_MIN_GAMMA;
+		Red = GEN9_MIN_GAMMA;
+		}
+		r32 = Red;
+		g32 = Green;
+		b32 = Blue;
+		r32 <<=8;
+		g32 <<=8;
+		b32 <<=8;
+		gamma_ptr[i].r32 = r32;
+		gamma_ptr[i].g32 = g32;
+		gamma_ptr[i].b32 = b32;
+	}
+}
+
+static uint64_t get_blob(int fd, int blob_id, int length)
+{
+	struct drm_mode_get_blob blob;
+	int ret = 0;
+
+	blob.blob_id = blob_id;
+	blob.length = length;
+	blob.data =  (uint64_t)malloc(blob.length);
+	ret = ioctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob);
+
+	if (ret)
+		igt_info("GET BLOB Failed\n");
+
+	return blob.data;
+}
+
+static void enable_plane(struct data_t *data, igt_display_t *display, igt_output_t *output , int pipe1)
+{
+	enum igt_commit_style commit;
+	enum pipe pipe2;
+        int width, height;
+        uint32_t pixelformat = DRM_FORMAT_XRGB8888;
+
+	commit = COMMIT_UNIVERSAL;
+	for_each_connected_output(display, output) {
+		drmModeModeInfo *mode;
+		igt_plane_t *plane;
+		pipe2 = output->config.pipe;
+
+		if (pipe2 != pipe1)
+			break;
+		igt_output_set_pipe(output, pipe2);
+		mode = igt_output_get_mode(output);
+		/*Draw the initial primary plane*/
+		plane = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
+
+		prepare_crtc(data, output, pipe2, plane, mode, commit);
+		/*Random Size  Buffer Creation */
+		width = 600;
+		height = 600;
+
+		plane = igt_output_get_plane(output, IGT_PLANE_2);
+		igt_create_color_fb(data->drm_fd,
+					    width, height,
+					    pixelformat,
+					    LOCAL_DRM_FORMAT_MOD_NONE,
+					    fb_color.red,fb_color.green,fb_color.blue,
+					    &data->fb);
+		igt_plane_set_position(plane, 100, 100);
+
+		igt_plane_set_fb(plane, &data->fb);
+		igt_display_commit2(display, commit);
+	}
+
+}
+/*
+This function verify csc feature using both CRC check.
+Steps followed are:
+	1.Enable plane for capturing reference CRC
+	2.Capture Reference CRC
+	3.Apply CSC on Pipe
+	4.Enable Plane .CSC will be applied on this planes.
+	5.Capture CRC and compare with reference CRC
+	6. Register Validation for CRC
+*/
+static void test_pipe_csc(struct data_t *data, igt_display_t *display, igt_output_t *output,
+			  igt_plane_t *plane, bool enable, int value, int pipe1)
+{
+
+	struct _drm_ctm *ctm_data = NULL;
+	bool ret = false;
+	int res, i, blob_id;
+	float *ctm;
+	uint64_t blob_address;
+	ctm_data = (struct _drm_ctm *)
+		malloc(sizeof(struct _drm_ctm));
+	if (!enable) {
+		ctm = ctm_unity;
+	} else {
+		if (value == RED_CSC) {
+			ctm = ctm_red;
+		} else if (value == GREEN_CSC) {
+			ctm = ctm_green;
+		} else if (value == BLUE_CSC) {
+			ctm = ctm_blue;
+		} else{
+			ctm = ctm_unity;
+		} }
+	if(value == RED_FB) {
+		fb_color.red = 1;
+		fb_color.green =0;
+		fb_color.blue = 0;
+	} else  if(value == GREEN_FB) {
+		fb_color.red = 0;
+		fb_color.green = 1;
+		fb_color.blue = 0;
+	} else if(value == BLUE_FB) {
+		fb_color.red = 0;
+		fb_color.green = 0;
+		fb_color.blue = 1;
+	} else {
+		fb_color.red = 1;
+		fb_color.green = 1;
+		fb_color.blue = 1;
+	}
+	/*Enable planes and capture reference crc*/
+	enable_plane(data, display, output, pipe1);
+	igt_pipe_crc_collect_crc(data->pipe_crc, &crc_reference);
+
+	fb_color.red = 1;
+	fb_color.green = 1;
+	fb_color.blue = 1;
+
+	enable_plane(data, display, output, pipe1);
+
+	for (i = 0; i < CSC_MAX_VALS; i++) {
+		ctm_data->ctm_coeff[i] = convertFloatToBinary(*(ctm + i));
+	}
+
+	blob_id = create_blob(display->drm_fd,
+			(int *)(ctm_data), sizeof(struct _drm_ctm));
+	igt_fail_on_f (blob_id < 0, "CTM:BLOB IOCTL Fail\n");
+	res = set_color_property(display->drm_fd, output->config.crtc->crtc_id,
+			DRM_MODE_OBJECT_CRTC, "CTM", blob_id);
+	igt_fail_on_f (res < 0, "CTM:Set Property Failed\n");
+	res = get_color_property(display->drm_fd, output->config.crtc->crtc_id, DRM_MODE_OBJECT_CRTC, "CTM", blob_id);
+	igt_fail_on_f (res < 0, "CTM:Get Property Failed\n");
+	
+	blob_address = get_blob(display->drm_fd, res, sizeof(struct _drm_ctm));
+	ctm_data = (struct _drm_ctm *) (intptr_t) blob_address;
+
+	enable_plane(data, display, output, pipe1);
+	igt_pipe_crc_collect_crc(data->pipe_crc, &crc_current);
+	igt_assert_crc_equal(&crc_reference, &crc_current);
+	/*Restoring the Unit CSC*/
+	ctm = ctm_unity;
+	for (i = 0; i < CSC_MAX_VALS; i++) {
+		ctm_data->ctm_coeff[i] = convertFloatToBinary(*(ctm + i));
+	}
+
+	blob_id = create_blob(display->drm_fd,
+			(int *)(ctm_data), sizeof(struct _drm_ctm));
+        igt_fail_on_f (blob_id < 0, "CTM:BLOB IOCTL Fail\n");
+
+	res = set_color_property(display->drm_fd, output->config.crtc->crtc_id,
+			DRM_MODE_OBJECT_CRTC, "CTM", blob_id);
+        igt_fail_on_f (res < 0, "CTM:Set Property Failed\n");
+
+	free(ctm_data);
+
+}
+
+
+static void apply_gamma(struct data_t *data, igt_display_t *display, igt_output_t *output, int pipe1, uint32_t num_samples, int unit_gamma) 
+{
+	struct _drm_palette *gamma_data =  NULL;
+	int  ret, res, blob_id, blob_length;
+	bool status = false;
+
+
+	if (num_samples == 0)
+		blob_length = 1;
+	else
+		blob_length = (sizeof(struct _drm_palette) + (num_samples * sizeof(struct _drm_r32g32b32)));
+
+	gamma_data = malloc(blob_length);
+	write_gamma_lut(num_samples, gamma_data->lut, unit_gamma);
+	blob_id = create_blob(display->drm_fd, (uint64_t *)(gamma_data), blob_length);
+	if (blob_id < 0)
+		free(gamma_data);
+
+        igt_fail_on_f (blob_id < 0, "GAMMA:BLOB IOCTL Fail\n");
+	/*Disabling degamma*/
+	if(unit_gamma == 2 ) {
+		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);
+                igt_fail_on_f (res < 0, "PALETTE_BEFORE_CTM:Set Property Failed\n");
+                igt_fail_on_f (ret < 0, "PALETTE_BEFORE_CTM:Set Property Failed\n");
+
+	}
+
+	if (num_samples == GEN9_SPLITGAMMA_MAX_VALS) {
+		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 (res < 0)
+			free(gamma_data);
+	        igt_fail_on_f (res < 0, "PALETTE_BEFORE_CTM:Set Property Failed\n");
+                igt_fail_on_f (ret < 0, "PALETTE_BEFORE_CTM:Set Property Failed\n");
+
+	}
+
+	res = set_color_property(display->drm_fd, output->config.crtc->crtc_id,
+			DRM_MODE_OBJECT_CRTC, "PALETTE_AFTER_CTM", blob_id);
+	if (res < 0) {
+		free(gamma_data);
+	}
+        igt_fail_on_f (res < 0, "PALETTE_AFTER_CTM:Set Property Failed\n");
+
+	ret = get_color_property(display->drm_fd, output->config.crtc->crtc_id,
+			DRM_MODE_OBJECT_CRTC, "PALETTE_AFTER_CTM", blob_id);
+	if (ret < 0) {
+		free(gamma_data);
+	}
+        igt_fail_on_f (ret < 0, "PALETTE_BEFORE_CTM:Set Property Failed\n");
+
+	free(gamma_data);
+
+
+}
+/*
+This function verify csc feature using both CRC check.
+Steps followed are:
+        1.Enable Black plane and capture CRC_REFERENCE_BLACK.
+	2.Enable White plane and capture CRS_REFERENCE_WHITE
+        3.Enable Red plane.
+        4.Apply LOW Gamma.
+        5.Capture CRC_Black.
+        6.Apply High Gamma and capture CRC_White.
+        7.CRC_Black should be equivalent to CRC_REFERENCE_BLACK
+        8.CRC_White should be equivalent to CRC_REFERENCE_WHite.
+
+
+*/
+static void test_pipe_gamma(struct data_t *data, igt_display_t *display, igt_output_t *output,
+		            uint32_t num_samples, int values, int pipe1)
+{
+	int unit_gamma, disable_gamma;
+	igt_plane_t *plane;
+
+	/*Enable black planes and capture reference crc*/
+
+	fb_color.red = 0;
+	fb_color.green =0;
+	fb_color.blue = 0;
+	enable_plane(data, display, output, pipe1);
+	igt_pipe_crc_collect_crc(data->pipe_crc, &crc_reference_black);
+	/*Enable white plane and capture refernce crc*/
+	fb_color.red = 1;
+	fb_color.green =1;
+	fb_color.blue = 1;
+	enable_plane(data, display, output, pipe1);
+	igt_pipe_crc_collect_crc(data->pipe_crc, &crc_reference_white);
+
+	/*Enable red planes and apply unit gamma*/
+	fb_color.red = 1;
+	fb_color.green =0;
+	fb_color.blue = 0;
+	unit_gamma = 0; /*0 -> white 1->black*/
+	apply_gamma(data, display, output, pipe1, num_samples, unit_gamma);
+	enable_plane(data, display, output, pipe1);
+	igt_pipe_crc_collect_crc(data->pipe_crc, &crc_white);
+
+	/* Apply 0x0 gamma */
+	unit_gamma =  1;
+
+	apply_gamma(data, display, output, pipe1, num_samples, unit_gamma);
+	enable_plane(data, display, output, pipe1);
+	igt_pipe_crc_collect_crc(data->pipe_crc, &crc_black);
+	igt_assert_crc_equal(&crc_reference_black, &crc_black);
+	igt_assert_crc_equal(&crc_reference_white, &crc_white);
+
+	/*Disabling gamma*/
+	if( num_samples == GEN9_SPLITGAMMA_MAX_VALS) {
+		disable_gamma = 2;
+		apply_gamma(data, display, output, pipe1, 0, disable_gamma);
+	} else {
+                apply_gamma(data, display, output, pipe1, 0, unit_gamma);
+	}
+	
+
+
+
+}
+
+static void test_legacy_gamma (struct data_t *data, igt_display_t *display, igt_output_t *output, int pipe1)
+{
+	int fd,ret,i;
+
+	uint32_t crtc;
+	uint16_t *val = malloc(sizeof(uint16_t) * 256);
+        igt_plane_t *plane;
+
+        fb_color.red = 1;
+        fb_color.green =1;
+        fb_color.blue = 1;
+        enable_plane(data, display, output, pipe1);
+	float gamma1 = 1.0;
+	for(i = 0; i < 256 ; i++) {
+		val[i] = 0xffff * pow((i/255), gamma1);
+
+	}
+	for_each_connected_output (display, output) {
+		ret = drmModeCrtcSetGamma (display->drm_fd, output->config.crtc->crtc_id, 256, val, val, val);
+	        igt_assert_lte(0, ret);
+
+	}
+}
+
+static void test_pipe_color(struct data_t *data, const  char *prop_name, int enable, int value)
+{
+	igt_display_t *display = &data->display;
+	igt_output_t *output;
+	igt_plane_t *plane;
+	enum pipe pipe1;
+
+	for_each_connected_output(display, output) {
+		pipe1 = output->config.pipe;
+		igt_output_set_pipe(output,pipe1);
+		if ((strcmp(prop_name, "gamma_property_8bit") == 0) &&
+				enable == true){
+			test_pipe_gamma(data, display, output,
+					GEN9_8BIT_GAMMA_MAX_VALS, value, pipe1);
+		} else if ((strcmp(prop_name, "legacy_gamma") == 0)){
+			test_legacy_gamma(data, display, output, pipe1);
+		} else  if ((strcmp(prop_name, "gamma_property_10bit") == 0) &&
+				enable == true) {
+			test_pipe_gamma(data, display, output, GEN9_10BIT_GAMMA_MAX_VALS, value, pipe1);
+		} else  if ((strcmp(prop_name, "csc_property") == 0)) {
+			test_pipe_csc(data, display, output, plane, enable, value, pipe1);
+		} else  if ((strcmp(prop_name, "gamma_property_split") == 0) &&
+				enable == true) {
+			test_pipe_gamma(data, display, output,
+					GEN9_SPLITGAMMA_MAX_VALS, value, pipe1);
+		} else  if ((strcmp(prop_name, "gamma_property_12bit") == 0) && enable == true) {
+			test_pipe_gamma(data, display, output,
+					GEN9_12BIT_GAMMA_MAX_VALS, value, pipe1);
+		} else {
+			igt_info("Invalid Test\n");
+		}
+		cleanup_fb(data);
+		plane = igt_output_get_plane(output, IGT_PLANE_2);
+		cleanup_crtc(data, output, plane);
+	}
+}
+
+igt_main
+{
+	struct data_t data = {};
+	int values = 1;
+	igt_skip_on_simulation();
+	igt_fixture{
+		//                data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
+		data.drm_fd = drm_open_any_master();
+		kmstest_set_vt_graphics_mode();
+		igt_display_init(&data.display, data.drm_fd);
+		data.gen = intel_gen(intel_get_drm_devid(data.drm_fd));
+		igt_require(data.gen >= 9);
+	}
+	igt_subtest_f("csc-red")
+		test_pipe_color(&data, "csc_property", true, RED_CSC);
+	igt_subtest_f("csc-green")
+		test_pipe_color(&data, "csc_property", true, GREEN_CSC);
+	igt_subtest_f("csc-blue")
+		test_pipe_color(&data, "csc_property", true, BLUE_CSC);
+	igt_subtest_f("gamma-legacy")
+                test_pipe_color(&data, "legacy_gamma", true, values);
+
+	igt_subtest_f("gamma-8bit")
+		test_pipe_color(&data, "gamma_property_8bit", true, values);
+	igt_subtest_f("gamma-10bit")
+		test_pipe_color(&data, "gamma_property_10bit", true, values);
+	igt_subtest_f("gamma-12bit")
+		test_pipe_color(&data, "gamma_property_12bit", true,  values);
+	igt_subtest_f("gamma-split")
+		test_pipe_color(&data, "gamma_property_split", true,  values);
+
+	igt_fixture{
+		igt_display_fini(&data.display);
+	}
+}
+
-- 
1.9.1


[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2015-12-14  7:43 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-10 10:32 [PATCH] tests/kms_color:Color IGT Dhanya Pillai
2015-07-10 10:41 ` David Weinehall
2015-07-13  3:54 Dhanya Pillai
2015-07-13  4:01 ` Sharma, Shashank
2015-11-20 10:27 Dhanya Pillai
2015-11-24 16:36 ` Thomas Wood
2015-11-24 17:08 ` Daniel Vetter
2015-12-11 10:31 Dhanya Pillai
2015-12-11 15:35 ` Rob Bradford
2015-12-11 18:51   ` Daniel Vetter
2015-12-14  7:43   ` R, Dhanya p

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.