From: arsharma <ankitprasad.r.sha...@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.sha...@intel.com>
Signed-off-by: Sagar Kamble <sagar.a.kam...@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.kam...@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

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

Reply via email to