summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
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();