[Intel-gfx] [PATCH 1/1] kms_blend: tests blending of sprite planes using drm_property "blend".

sagar.a.kamble at intel.com sagar.a.kamble at intel.com
Tue Mar 25 15:38:12 CET 2014


From: arsharma <ankitprasad.r.sharma at intel.com>

v1: This test currently tests constant alpha setting of sprite planes.
It verifies alpha setting of 0 and 255 with CRC.

Signed-off-by: Sharma, Ankitprasad R <ankitprasad.r.sharma at intel.com>
Signed-off-by: Sagar Kamble <sagar.a.kamble at intel.com>
---
 tests/Makefile.sources |   1 +
 tests/kms_blend.c      | 560 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 561 insertions(+)
 create mode 100644 tests/kms_blend.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 88866ac..b8a19cd 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -55,6 +55,7 @@ TESTS_progs_M = \
 	gem_tiled_partial_pwrite_pread \
 	gem_write_read_ring_switch \
 	kms_addfb \
+	kms_blend \
 	kms_cursor_crc \
 	kms_fbc_crc \
 	kms_flip \
diff --git a/tests/kms_blend.c b/tests/kms_blend.c
new file mode 100644
index 0000000..1990c52
--- /dev/null
+++ b/tests/kms_blend.c
@@ -0,0 +1,560 @@
+/*
+ * Copyright © 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.
+ *
+ * Author:
+ *     Ankitprasad Sharma <ankitprasad.r.sharma at intel.com>
+ *     Sagar Kamble <sagar.a.kamble at intel.com>
+ */
+
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <cairo.h>
+#include <math.h>
+#include "drm_fourcc.h"
+#include "drmtest.h"
+#include "igt_debugfs.h"
+#include "igt_kms.h"
+
+#define DRM_BLEND_NUM			24
+#define DRM_BLEND_PROP_SRC_COLOR 	2
+#define DRM_BLEND_PROP_CONST_ALPHA 	12
+#define BIT(x)				(1 << x)
+
+typedef struct {
+	struct kmstest_connector_config config;
+	drmModeModeInfo mode;
+	struct kmstest_fb fb[DRM_BLEND_NUM];
+	struct kmstest_fb sprite_fb[DRM_BLEND_NUM]
+} connector_t;
+
+typedef struct {
+	int drm_fd;
+	igt_debugfs_t debugfs;
+	drmModeRes *resources;
+	igt_crc_t ref_crtc_crc[DRM_BLEND_NUM];
+	igt_crc_t ref_sprite_crc[DRM_BLEND_NUM];
+	igt_pipe_crc_t **pipe_crc;
+	uint32_t crtc_id;
+	uint32_t sprite_id;
+	uint32_t crtc_idx;
+	uint32_t crtc_fb_id[DRM_BLEND_NUM];
+	uint32_t sprite_fb_id[DRM_BLEND_NUM];
+} data_t;
+
+static void set_blend(int drm_fd, uint32_t plane_id, uint64_t blend_prop, double blend_val)
+{
+	int i = 0, j = 0, ret = 0;
+	uint64_t prop_blend;
+	uint64_t value, blend_val_int;
+	double blend_val_ex;
+	drmModeObjectPropertiesPtr props = NULL;
+
+	props = drmModeObjectGetProperties(drm_fd, plane_id, DRM_MODE_OBJECT_PLANE);
+
+	switch(blend_prop)
+	{
+		case BIT(DRM_BLEND_PROP_CONST_ALPHA):
+			blend_val_ex = blend_val * 255;
+			blend_val_int = (uint64_t) blend_val_ex;
+			value = (blend_val_int << 32);
+			prop_blend = value | blend_prop;
+			fprintf(stdout, "blend_val_ex = %f, blend_val_int = %d, value = %016llx, blend_prop = %016llx\n",
+				blend_val_ex, blend_val_int, value, blend_prop);
+			break;
+		case BIT(DRM_BLEND_PROP_SRC_COLOR):
+			prop_blend = blend_prop;
+			break;
+		default:
+			fprintf(stdout, "Blend Type not supported\n");
+			return;
+	}
+
+	for (i = 0; i < props->count_props; i++)
+	{
+		drmModePropertyPtr prop = drmModeGetProperty(drm_fd, props->props[i]);
+		fprintf(stdout, "\nProp->name=%s ", prop->name);
+
+		if (strcmp(prop->name, "blend") == 0)
+		{
+			igt_assert(prop->flags & (DRM_MODE_PROP_BITMASK | DRM_MODE_PROP_32BIT_PAIR));
+			fprintf(stdout, "\nBlending property enum count %d", prop->count_enums);
+			fprintf(stdout, "\nBlending type\tValue");
+			for (j = 0; j < prop->count_enums; j++)
+				fprintf(stdout, "\n%s: 0x%x", prop->enums[j].name, prop->enums[j].value);
+
+			ret = drmModeObjectSetProperty(drm_fd, plane_id, DRM_MODE_OBJECT_PLANE,
+								(uint32_t)prop->prop_id, (uint64_t)prop_blend);
+			if (ret)
+			{
+				fprintf(stdout, "\nAlpha blending \(0x%016llx\) failed returning -- %d !!!", prop_blend, ret);
+				return;
+			}
+			else
+				fprintf(stdout, "\nPlane with id 0x%x is blended with setting 0x%016llx", plane_id, prop_blend);
+		}
+		drmModeFreeProperty(prop);
+	}
+	drmModeFreeObjectProperties(props);
+}
+
+static uint32_t create_crtc_fb(data_t *data,
+			  uint16_t w,
+			  uint16_t h,
+			  uint64_t blend_prop,
+			  struct kmstest_fb *fb)
+{
+	uint32_t fb_id = 0, fb_id_0 = 0;
+	cairo_t *cr, *cr_0;
+	struct kmstest_fb fb_0;
+	cairo_surface_t *image_0;
+
+	fb_id_0 = kmstest_create_fb(data->drm_fd,
+				  w, h,
+				  32 /* bpp */, 24 /* depth */,
+				  false /* tiling */,
+				  &fb_0);
+	igt_assert(fb_id_0);
+
+	cr_0 = kmstest_get_cairo_ctx(data->drm_fd, &fb_0);
+
+	kmstest_paint_color(cr_0, 0, 0, w, h, 0.0, 0.0, 0.0);
+
+	image_0 = fb_0.cairo_surface;
+
+	fb_id = kmstest_create_fb(data->drm_fd,
+					  w, h,
+					  32 /* bpp */, 24 /* depth */,
+					  false /* tiling */,
+					  fb);
+
+	igt_assert(fb_id);
+	cr = kmstest_get_cairo_ctx(data->drm_fd, fb);
+
+	cairo_set_source_surface (cr, image_0, 0, 0);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+	cairo_paint (cr);
+
+	igt_assert(cairo_status(cr) == 0);
+	cairo_destroy(cr);
+	cairo_destroy(cr_0);
+
+	return fb_id;
+}
+
+static uint32_t create_sprite_fb(data_t *data,
+			  uint16_t w,
+			  uint16_t h,
+			  uint64_t blend_prop,
+			  struct kmstest_fb *fb, double blend_val)
+{
+	uint32_t fb_id = 0, fb_id_0 = 0;
+	cairo_t *cr, *cr_0;
+	struct kmstest_fb fb_0;
+	cairo_surface_t *image_0;
+
+	fb_id_0 = kmstest_create_fb2(data->drm_fd, w, h,
+					   DRM_FORMAT_XRGB8888, false, &fb_0);
+
+	igt_assert(fb_id_0);
+
+	cr_0 = kmstest_get_cairo_ctx(data->drm_fd, &fb_0);
+
+	kmstest_paint_color(cr_0, 0, 0, w, h, 1.0, 1.0, 1.0);
+
+	image_0 = fb_0.cairo_surface;
+
+	fb_id = kmstest_create_fb2(data->drm_fd, w, h,
+				   DRM_FORMAT_XRGB8888, false, fb);
+
+	igt_assert(fb_id);
+	cr = kmstest_get_cairo_ctx(data->drm_fd, fb);
+	cairo_set_source_surface (cr, image_0, 0, 0);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+	cairo_paint (cr);
+
+	igt_assert(cairo_status(cr) == 0);
+	cairo_destroy(cr);
+	cairo_destroy(cr_0);
+
+	return fb_id;
+}
+
+static int connector_find_plane(int gfx_fd, uint32_t pipe)
+{
+	drmModePlaneRes *plane_resources;
+	drmModePlane *ovr;
+	uint32_t id = 0;
+	int i;
+
+	plane_resources = drmModeGetPlaneResources(gfx_fd);
+	if (!plane_resources) {
+		printf("drmModeGetPlaneResources failed: %s\n",
+			strerror(errno));
+		return 0;
+	}
+
+	for (i = 0; i < plane_resources->count_planes; i++) {
+		ovr = drmModeGetPlane(gfx_fd, plane_resources->planes[i]);
+		if (!ovr) {
+			printf("drmModeGetPlane failed: %s\n",
+				strerror(errno));
+			continue;
+		}
+
+		if (ovr->possible_crtcs & (1 << pipe)) {
+			id = ovr->plane_id;
+			drmModeFreePlane(ovr);
+			break;
+		}
+		drmModeFreePlane(ovr);
+	}
+
+	return id;
+}
+
+static void sprite_set_mode(data_t *data, connector_t *connector,
+				 uint16_t w, uint16_t h, uint32_t sprite_fb_id)
+{
+	struct drm_intel_sprite_colorkey    set;
+	struct kmstest_connector_config *config = &connector->config;
+	int ret = 0;
+	uint16_t out_w = 0, out_h = 0, sprite_x = 0, sprite_y = 0;
+	uint32_t plane_flags = 0;
+
+	// Set the sprite colorkey state
+	set.plane_id = data->sprite_id;
+	set.min_value = 0;
+	set.max_value = 0;
+	set.flags = I915_SET_COLORKEY_NONE;
+	ret = drmCommandWrite(data->drm_fd, DRM_I915_SET_SPRITE_COLORKEY, &set, sizeof(set));
+	assert(ret == 0);
+
+	// Set up sprite output dimensions, initial position, etc.
+	out_w = w;
+	out_h = h;
+
+	sprite_x = w - w/2;
+	sprite_y = h - h/2;
+
+	/* i915 Set Mode */
+	if (drmModeSetPlane(data->drm_fd, data->sprite_id, config->crtc->crtc_id,
+			    sprite_fb_id, plane_flags,
+			    sprite_x, sprite_y,
+			    out_w, out_h,
+			    0, 0,
+			    out_w << 16, out_h << 16))
+		printf("Failed to enable sprite plane: %s\n", strerror(errno));
+}
+
+static bool
+connector_set_mode(data_t *data, connector_t *connector,
+		   drmModeModeInfo *mode, uint32_t fb_id)
+{
+	struct kmstest_connector_config *config = &connector->config;
+	int ret;
+
+	ret = drmModeSetCrtc(data->drm_fd,
+			     config->crtc->crtc_id,
+			     fb_id,
+			     0, 0, /* x, y */
+			     &config->connector->connector_id,
+			     1,
+			     mode);
+	igt_assert(ret == 0);
+
+	return 0;
+}
+
+static void display_init(data_t *data)
+{
+	data->resources = drmModeGetResources(data->drm_fd);
+	igt_assert(data->resources);
+
+	data->pipe_crc = calloc(data->resources->count_crtcs, sizeof(data->pipe_crc[0]));
+}
+
+static void display_fini(data_t *data)
+{
+	free(data->pipe_crc);
+}
+
+static void test_crtc_crc(data_t *data, uint64_t blend_prop)
+{
+	igt_pipe_crc_t *pipe_crc = data->pipe_crc[data->crtc_idx];
+	igt_crc_t *crcs = NULL;
+
+	usleep(200000);
+
+	igt_wait_for_vblank(data->drm_fd, data->crtc_idx);
+
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_get_crcs(pipe_crc, 1, &crcs);
+	igt_pipe_crc_stop(pipe_crc);
+	fprintf(stdout, "\n Output CRCS: %u %s ", crcs[0].frame, igt_crc_to_string(&crcs[0]));
+	fprintf(stdout, "\n Reference CRCS: %u %s ", data->ref_crtc_crc[blend_prop].frame, igt_crc_to_string(&data->ref_crtc_crc[blend_prop]));
+
+	igt_assert(!igt_crc_equal(&crcs[0], &data->ref_crtc_crc[blend_prop]));
+	free(crcs);
+}
+
+static void test_sprite_crc(data_t *data, uint64_t blend_prop, double blend_val)
+{
+	igt_pipe_crc_t *pipe_crc = data->pipe_crc[data->crtc_idx];
+	igt_crc_t *crcs = NULL;
+
+	set_blend(data->drm_fd, data->sprite_id, BIT(blend_prop), blend_val);
+
+	usleep(200000);
+
+	igt_wait_for_vblank(data->drm_fd, data->crtc_idx);
+
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_get_crcs(pipe_crc, 1, &crcs);
+	igt_pipe_crc_stop(pipe_crc);
+
+	if (blend_val == 1.0)
+	{
+		fprintf(stdout, "\n Output CRCS: %u %s ", crcs[0].frame, igt_crc_to_string(&crcs[0]));
+		fprintf(stdout, "\n Reference CRCS: %u %s ", data->ref_sprite_crc[blend_prop].frame, igt_crc_to_string(&data->ref_sprite_crc[blend_prop]));
+
+		igt_assert(!igt_crc_equal(&crcs[0], &data->ref_sprite_crc[blend_prop]));
+	}
+
+	free(crcs);
+}
+
+static void get_ref_crtc_crcs(data_t *data, connector_t connector,
+				igt_pipe_crc_t *pipe_crc, uint64_t blend_prop)
+{
+	igt_crc_t *crcs = NULL;
+
+	igt_assert(blend_prop < DRM_BLEND_NUM);
+
+	data->crtc_fb_id[blend_prop] = create_crtc_fb(data,
+				   connector.config.default_mode.hdisplay,
+				   connector.config.default_mode.vdisplay,
+				   blend_prop, &connector.fb[blend_prop]);
+
+	igt_assert(data->crtc_fb_id[blend_prop]);
+
+	/* scanout = fb[blend_prop] */
+	connector_set_mode(data, &connector, &connector.config.default_mode,
+			   data->crtc_fb_id[blend_prop]);
+	usleep(200000);
+
+	igt_wait_for_vblank(data->drm_fd, data->crtc_idx);
+
+	/* get reference crc for fb[blend_prop] */
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_get_crcs(pipe_crc, 1, &crcs);
+	data->ref_crtc_crc[blend_prop] = crcs[0];
+	igt_pipe_crc_stop(pipe_crc);
+	free(crcs);
+}
+
+static void get_ref_sprite_crcs(data_t *data, connector_t connector,
+				igt_pipe_crc_t *pipe_crc, uint64_t blend_prop, double blend_val)
+{
+	igt_crc_t *crcs = NULL;
+	uint16_t w = 0, h = 0;
+
+	igt_assert(blend_prop < DRM_BLEND_NUM);
+
+	w = connector.config.default_mode.hdisplay / 2;
+	h = connector.config.default_mode.vdisplay / 2;
+
+	data->sprite_fb_id[blend_prop] = create_sprite_fb(data, w, h,
+				   blend_prop, &connector.fb[blend_prop], blend_val);
+
+	igt_assert(data->sprite_fb_id[blend_prop]);
+
+	/* scanout = fb[blend_prop] */
+	sprite_set_mode(data, &connector, w, h, data->sprite_fb_id[blend_prop]);
+	usleep(200000);
+
+	igt_wait_for_vblank(data->drm_fd, data->crtc_idx);
+
+	/* get reference crc for fb[blend_prop] */
+	igt_pipe_crc_start(pipe_crc);
+	igt_pipe_crc_get_crcs(pipe_crc, 1, &crcs);
+	data->ref_sprite_crc[blend_prop] = crcs[0];
+	igt_pipe_crc_stop(pipe_crc);
+	free(crcs);
+}
+
+static bool prepare_sprite(data_t *data, uint32_t connector_id,
+				double blend_val, uint64_t blend_prop)
+{
+	uint32_t sprite_plane_id;
+	connector_t connector;
+	igt_pipe_crc_t *pipe_crc;
+	int ret;
+
+	ret = kmstest_get_connector_config(data->drm_fd,
+					   connector_id,
+					   1 << data->crtc_idx,
+					   &connector.config);
+	if (ret)
+		return false;
+
+	igt_pipe_crc_free(data->pipe_crc[data->crtc_idx]);
+	data->pipe_crc[data->crtc_idx] = NULL;
+
+	pipe_crc = igt_pipe_crc_new(&data->debugfs,
+				    data->drm_fd, data->crtc_idx,
+				    INTEL_PIPE_CRC_SOURCE_AUTO);
+	if (!pipe_crc) {
+		fprintf(stdout, "auto crc not supported on this connector with crtc %i\n",
+		       data->crtc_idx);
+		return false;
+	}
+
+	data->pipe_crc[data->crtc_idx] = pipe_crc;
+
+	// Determine if sprite hardware is available on pipe
+	// associated with this connector.
+	sprite_plane_id = connector_find_plane(data->drm_fd, data->crtc_idx);
+	if (!sprite_plane_id) {
+		printf("Failed to find sprite plane on crtc\n");
+		return false;
+	}
+	data->sprite_id = sprite_plane_id;
+
+	get_ref_sprite_crcs(data, connector, pipe_crc, blend_prop, blend_val);
+
+	kmstest_free_connector_config(&connector.config);
+
+	return true;
+}
+
+static bool prepare_crtc(data_t *data, uint32_t connector_id, uint64_t blend_prop)
+{
+	connector_t connector;
+	igt_pipe_crc_t *pipe_crc;
+	int ret;
+
+	ret = kmstest_get_connector_config(data->drm_fd,
+					   connector_id,
+					   1 << data->crtc_idx,
+					   &connector.config);
+	if (ret)
+		return false;
+
+	if (!connector.config.crtc->mode_valid)
+		return false;
+
+	igt_pipe_crc_free(data->pipe_crc[data->crtc_idx]);
+	data->pipe_crc[data->crtc_idx] = NULL;
+
+	pipe_crc = igt_pipe_crc_new(&data->debugfs,
+				    data->drm_fd, data->crtc_idx,
+				    INTEL_PIPE_CRC_SOURCE_AUTO);
+	if (!pipe_crc) {
+		fprintf(stdout, "auto crc not supported on this connector with crtc %i\n",
+		       data->crtc_idx);
+		return false;
+	}
+
+	data->pipe_crc[data->crtc_idx] = pipe_crc;
+
+	get_ref_crtc_crcs(data, connector, pipe_crc, blend_prop);
+
+	kmstest_free_connector_config(&connector.config);
+
+	return true;
+}
+
+static void finish_crtc(data_t *data)
+{
+	igt_pipe_crc_free(data->pipe_crc[data->crtc_idx]);
+	data->pipe_crc[data->crtc_idx] = NULL;
+}
+
+static void run_test(data_t *data, double blend_val, uint64_t blend_prop)
+{
+	int i, n;
+
+	for (i = 0; i < data->resources->count_connectors; i++) {
+		uint32_t connector_id = data->resources->connectors[i];
+
+		for (n = 0; n < data->resources->count_crtcs; n++) {
+			data->crtc_idx = n;
+			data->crtc_id = data->resources->crtcs[n];
+
+			if (!prepare_crtc(data, connector_id, blend_prop))
+				continue;
+
+			fprintf(stdout, "\nBeginning blending test type(%08llx) on crtc %d, connector %d\n",
+				blend_prop, data->crtc_id, connector_id);
+
+			if (!prepare_sprite(data, connector_id, blend_val, blend_prop))
+				continue;
+
+			test_sprite_crc(data, blend_prop, blend_val);
+			if (blend_val == 0.0)
+			{
+				test_crtc_crc(data, blend_prop);
+			}
+
+			fprintf(stdout, "\nBlending test type(%08llx) on crtc %d, connector %d: PASSED\n\n",
+				blend_prop, data->crtc_id, connector_id);
+
+			finish_crtc(data);
+		}
+	}
+}
+
+data_t data = {0, };
+
+igt_main
+{
+	double i = 0.0;
+	igt_skip_on_simulation();
+
+	igt_fixture {
+		data.drm_fd = drm_open_any();
+		igt_set_vt_graphics_mode();
+
+		igt_debugfs_init(&data.debugfs);
+		igt_pipe_crc_check(&data.debugfs);
+
+		display_init(&data);
+	}
+
+	for(i = 0; i <= 1.01; i += 0.025)
+	{
+		igt_subtest("sprite-constant-alpha")
+			run_test(&data, i, DRM_BLEND_PROP_CONST_ALPHA);
+	}
+
+
+	igt_subtest("sprite-src-color")
+                        run_test(&data, i, DRM_BLEND_PROP_SRC_COLOR);
+
+	igt_fixture {
+		display_fini(&data);
+	}
+
+}
-- 
1.8.5




More information about the Intel-gfx mailing list