[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