summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2018-06-29 16:25:57 +0300
committerVille Syrjälä <ville.syrjala@linux.intel.com>2018-07-04 19:10:00 +0300
commitaaa23eff21a148809beb22e928f3cd72530ea3de (patch)
treee11da7bd690af98b5dd6460661e8df9c7df33acc /tests
parent20f4aee0fbc5f5a0b375a512d340e4c453b67de9 (diff)
tests/gem_render_copy: Use a more elaborate pattern of pixels
Checking whether we can copy solid rectangles isn't particularly robust. Eg. errors in texture coordinates/interpolation wouldn't necessarily show up at all because all texels are identical. Let's switch to a more elaborate pattern that should catch such errors. And we'll also change the test to not start the copy from position 0,0 in the texture. We'll generate the reference image (against which the rendercopy results are compared) by peforming an identical copy using the cpu. v2: Use gtt mmap instead of pread/pwrite (Chris) Offset the dst coordinates by -1,-1 to make sure the copy doesn't go past the intended region Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'tests')
-rw-r--r--tests/gem_render_copy.c248
1 files changed, 202 insertions, 46 deletions
diff --git a/tests/gem_render_copy.c b/tests/gem_render_copy.c
index a036a924..2efec078 100644
--- a/tests/gem_render_copy.c
+++ b/tests/gem_render_copy.c
@@ -30,6 +30,7 @@
*/
#include "igt.h"
+#include "igt_x86.h"
#include <stdbool.h>
#include <unistd.h>
#include <cairo.h>
@@ -52,16 +53,11 @@ IGT_TEST_DESCRIPTION("Basic test for the render_copy() function.");
#define WIDTH 512
#define STRIDE (WIDTH*4)
#define HEIGHT 512
-#define SIZE (HEIGHT*STRIDE)
-
-#define SRC_COLOR 0xffff00ff
-#define DST_COLOR 0xfff0ff00
typedef struct {
int drm_fd;
uint32_t devid;
drm_intel_bufmgr *bufmgr;
- uint32_t linear[WIDTH * HEIGHT];
} data_t;
static int opt_dump_png = false;
static int check_all_pixels = false;
@@ -83,36 +79,198 @@ static void scratch_buf_write_to_png(struct igt_buf *buf, const char *filename)
drm_intel_bo_unmap(buf->bo);
}
+static void *linear_copy(data_t *data, struct igt_buf *buf)
+{
+ void *map, *linear;
+
+ igt_assert_eq(posix_memalign(&linear, 16, buf->bo->size), 0);
+
+ gem_set_domain(data->drm_fd, buf->bo->handle,
+ I915_GEM_DOMAIN_GTT, 0);
+
+ map = gem_mmap__gtt(data->drm_fd, buf->bo->handle,
+ buf->bo->size, PROT_READ);
+
+ igt_memcpy_from_wc(linear, map, buf->bo->size);
+
+ munmap(map, buf->bo->size);
+
+ return linear;
+}
+
+static void scratch_buf_draw_pattern(data_t *data, struct igt_buf *buf,
+ int x, int y, int w, int h,
+ int cx, int cy, int cw, int ch,
+ bool use_alternate_colors)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *pat;
+ cairo_t *cr;
+ void *map, *linear;
+
+ linear = linear_copy(data, buf);
+
+ surface = cairo_image_surface_create_for_data(linear,
+ CAIRO_FORMAT_RGB24,
+ igt_buf_width(buf),
+ igt_buf_height(buf),
+ buf->stride);
+
+ cr = cairo_create(surface);
+
+ cairo_rectangle(cr, cx, cy, cw, ch);
+ cairo_clip(cr);
+
+ pat = cairo_pattern_create_mesh();
+ cairo_mesh_pattern_begin_patch(pat);
+ cairo_mesh_pattern_move_to(pat, x, y);
+ cairo_mesh_pattern_line_to(pat, x+w, y);
+ cairo_mesh_pattern_line_to(pat, x+w, y+h);
+ cairo_mesh_pattern_line_to(pat, x, y+h);
+ if (use_alternate_colors) {
+ cairo_mesh_pattern_set_corner_color_rgb(pat, 0, 0.0, 1.0, 1.0);
+ cairo_mesh_pattern_set_corner_color_rgb(pat, 1, 1.0, 0.0, 1.0);
+ cairo_mesh_pattern_set_corner_color_rgb(pat, 2, 1.0, 1.0, 0.0);
+ cairo_mesh_pattern_set_corner_color_rgb(pat, 3, 0.0, 0.0, 0.0);
+ } else {
+ cairo_mesh_pattern_set_corner_color_rgb(pat, 0, 1.0, 0.0, 0.0);
+ cairo_mesh_pattern_set_corner_color_rgb(pat, 1, 0.0, 1.0, 0.0);
+ cairo_mesh_pattern_set_corner_color_rgb(pat, 2, 0.0, 0.0, 1.0);
+ cairo_mesh_pattern_set_corner_color_rgb(pat, 3, 1.0, 1.0, 1.0);
+ }
+ cairo_mesh_pattern_end_patch(pat);
+
+ cairo_rectangle(cr, x, y, w, h);
+ cairo_set_source(cr, pat);
+ cairo_fill(cr);
+ cairo_pattern_destroy(pat);
+
+ cairo_destroy(cr);
+
+ cairo_surface_destroy(surface);
+
+ gem_set_domain(data->drm_fd, buf->bo->handle,
+ I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+ map = gem_mmap__gtt(data->drm_fd, buf->bo->handle,
+ buf->bo->size, PROT_READ | PROT_WRITE);
+
+ memcpy(map, linear, buf->bo->size);
+
+ munmap(map, buf->bo->size);
+
+ free(linear);
+}
+
+static void
+scratch_buf_copy(data_t *data,
+ struct igt_buf *src, int sx, int sy, int w, int h,
+ struct igt_buf *dst, int dx, int dy)
+{
+ int width = igt_buf_width(dst);
+ int height = igt_buf_height(dst);
+ uint32_t *linear_dst, *linear_src;
+
+ igt_assert_eq(igt_buf_width(dst), igt_buf_width(src));
+ igt_assert_eq(igt_buf_height(dst), igt_buf_height(src));
+ igt_assert_eq(dst->bo->size, src->bo->size);
+
+ gem_set_domain(data->drm_fd, dst->bo->handle,
+ I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+ gem_set_domain(data->drm_fd, src->bo->handle,
+ I915_GEM_DOMAIN_GTT, 0);
+
+ linear_dst = gem_mmap__gtt(data->drm_fd, dst->bo->handle,
+ dst->bo->size, PROT_WRITE);
+ linear_src = gem_mmap__gtt(data->drm_fd, src->bo->handle,
+ src->bo->size, PROT_READ);
+
+ w = min(w, min(width - sx, width - dx));
+ w = min(h, min(height - sy, height - dy));
+
+ for (int y = 0; y < h; y++) {
+ igt_memcpy_from_wc(&linear_dst[(dy+y) * width + dx],
+ &linear_src[(sy+y) * width + sx],
+ w * 4);
+ }
+
+ munmap(linear_dst, dst->bo->size);
+ munmap(linear_src, src->bo->size);
+}
+
static void scratch_buf_init(data_t *data, struct igt_buf *buf,
- int width, int height, int stride, uint32_t color)
+ int width, int height, int stride)
{
drm_intel_bo *bo;
- int i;
+ int size = height * stride;
- bo = drm_intel_bo_alloc(data->bufmgr, "", SIZE, 4096);
- for (i = 0; i < width * height; i++)
- data->linear[i] = color;
- gem_write(data->drm_fd, bo->handle, 0, data->linear,
- sizeof(data->linear));
+ bo = drm_intel_bo_alloc(data->bufmgr, "", size, 4096);
buf->bo = bo;
buf->stride = stride;
buf->tiling = I915_TILING_NONE;
- buf->size = SIZE;
+ buf->size = size;
+
+ igt_assert(igt_buf_width(buf) == width);
+ igt_assert(igt_buf_height(buf) == height);
}
static void
-scratch_buf_check(data_t *data, struct igt_buf *buf, int x, int y,
- uint32_t color)
+scratch_buf_check(data_t *data,
+ struct igt_buf *buf,
+ struct igt_buf *ref,
+ int x, int y)
{
- uint32_t val;
+ int width = igt_buf_width(buf);
+ uint32_t buf_val, ref_val;
+ uint32_t *linear;
+
+ igt_assert_eq(igt_buf_width(buf), igt_buf_width(ref));
+ igt_assert_eq(igt_buf_height(buf), igt_buf_height(ref));
+ igt_assert_eq(buf->bo->size, ref->bo->size);
+
+ linear = linear_copy(data, buf);
+ buf_val = linear[y * width + x];
+ free(linear);
+
+ linear = linear_copy(data, ref);
+ ref_val = linear[y * width + x];
+ free(linear);
- gem_read(data->drm_fd, buf->bo->handle, 0,
- data->linear, sizeof(data->linear));
- val = data->linear[y * WIDTH + x];
- igt_assert_f(val == color,
+ igt_assert_f(buf_val == ref_val,
"Expected 0x%08x, found 0x%08x at (%d,%d)\n",
- color, val, x, y);
+ ref_val, buf_val, x, y);
+}
+
+static void
+scratch_buf_check_all(data_t *data,
+ struct igt_buf *buf,
+ struct igt_buf *ref)
+{
+ int width = igt_buf_width(buf);
+ int height = igt_buf_height(buf);
+ uint32_t *linear_buf, *linear_ref;
+
+ igt_assert_eq(igt_buf_width(buf), igt_buf_width(ref));
+ igt_assert_eq(igt_buf_height(buf), igt_buf_height(ref));
+ igt_assert_eq(buf->bo->size, ref->bo->size);
+
+ linear_buf = linear_copy(data, buf);
+ linear_ref = linear_copy(data, ref);
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ uint32_t buf_val = linear_buf[y * width + x];
+ uint32_t ref_val = linear_ref[y * width + x];
+
+ igt_assert_f(buf_val == ref_val,
+ "Expected 0x%08x, found 0x%08x at (%d,%d)\n",
+ ref_val, buf_val, x, y);
+ }
+ }
+
+ free(linear_ref);
+ free(linear_buf);
}
static int opt_handler(int opt, int opt_index, void *data)
@@ -132,7 +290,7 @@ int main(int argc, char **argv)
{
data_t data = {0, };
struct intel_batchbuffer *batch = NULL;
- struct igt_buf src, dst;
+ struct igt_buf src, dst, ref;
igt_render_copyfunc_t render_copy = NULL;
int opt_dump_aub = igt_aub_dump_enabled();
@@ -154,15 +312,28 @@ int main(int argc, char **argv)
igt_assert(batch);
}
- scratch_buf_init(&data, &src, WIDTH, HEIGHT, STRIDE, SRC_COLOR);
- scratch_buf_init(&data, &dst, WIDTH, HEIGHT, STRIDE, DST_COLOR);
+ scratch_buf_init(&data, &src, WIDTH, HEIGHT, STRIDE);
+ scratch_buf_init(&data, &dst, WIDTH, HEIGHT, STRIDE);
+ scratch_buf_init(&data, &ref, WIDTH, HEIGHT, STRIDE);
+
+ scratch_buf_draw_pattern(&data, &src,
+ 0, 0, WIDTH, HEIGHT,
+ 0, 0, WIDTH, HEIGHT, true);
+ scratch_buf_draw_pattern(&data, &dst,
+ 0, 0, WIDTH, HEIGHT,
+ 0, 0, WIDTH, HEIGHT, false);
- scratch_buf_check(&data, &src, WIDTH / 2, HEIGHT / 2, SRC_COLOR);
- scratch_buf_check(&data, &dst, WIDTH / 2, HEIGHT / 2, DST_COLOR);
+ scratch_buf_copy(&data,
+ &dst, 0, 0, WIDTH, HEIGHT,
+ &ref, 0, 0);
+ scratch_buf_copy(&data,
+ &src, WIDTH/4, WIDTH/4, WIDTH/2, HEIGHT/2,
+ &ref, WIDTH/2-1, WIDTH/2-1);
if (opt_dump_png) {
scratch_buf_write_to_png(&src, "source.png");
scratch_buf_write_to_png(&dst, "destination.png");
+ scratch_buf_write_to_png(&ref, "reference.png");
}
if (opt_dump_aub) {
@@ -180,8 +351,8 @@ int main(int argc, char **argv)
* -------
*/
render_copy(batch, NULL,
- &src, 0, 0, WIDTH, HEIGHT,
- &dst, WIDTH / 2, HEIGHT / 2);
+ &src, WIDTH/4, HEIGHT/4, WIDTH/2, HEIGHT/2,
+ &dst, WIDTH/2-1, HEIGHT/2-1);
if (opt_dump_png)
scratch_buf_write_to_png(&dst, "result.png");
@@ -193,25 +364,10 @@ int main(int argc, char **argv)
STRIDE, 0);
drm_intel_bufmgr_gem_set_aub_dump(data.bufmgr, false);
} else if (check_all_pixels) {
- uint32_t val;
- int i, j;
- gem_read(data.drm_fd, dst.bo->handle, 0,
- data.linear, sizeof(data.linear));
- for (i = 0; i < WIDTH; i++) {
- for (j = 0; j < HEIGHT; j++) {
- uint32_t color = DST_COLOR;
- val = data.linear[j * WIDTH + i];
- if (j >= HEIGHT/2 && i >= WIDTH/2)
- color = SRC_COLOR;
-
- igt_assert_f(val == color,
- "Expected 0x%08x, found 0x%08x at (%d,%d)\n",
- color, val, i, j);
- }
- }
+ scratch_buf_check_all(&data, &dst, &ref);
} else {
- scratch_buf_check(&data, &dst, 10, 10, DST_COLOR);
- scratch_buf_check(&data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR);
+ scratch_buf_check(&data, &dst, &ref, 10, 10);
+ scratch_buf_check(&data, &dst, &ref, WIDTH - 10, HEIGHT - 10);
}
igt_exit();