diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/gem_render_copy.c | 248 |
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(); |
