This makes it easier to see corruption which e.g. occurs when using the userptr functionality to copy buffers allocated via plain malloc. One of the reasons why this is currently just used with GEM buffer mode.
Signed-off-by: Tobias Jakobi tjakobi@math.uni-bielefeld.de --- tests/exynos/exynos_fimg2d_test.c | 117 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+)
diff --git a/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c index c6bd558..41fb869 100644 --- a/tests/exynos/exynos_fimg2d_test.c +++ b/tests/exynos/exynos_fimg2d_test.c @@ -55,6 +55,9 @@ struct fimg2d_test_case { int (*blend)(struct exynos_device *dev, struct exynos_bo *src, struct exynos_bo *dst, enum e_g2d_buf_type); + int (*checkerboard)(struct exynos_device *dev, + struct exynos_bo *src, struct exynos_bo *dst, + enum e_g2d_buf_type); };
struct connector { @@ -207,6 +210,33 @@ static struct exynos_bo *exynos_create_buffer(struct exynos_device *dev, return bo; }
+/* Allocate buffer and fill it with checkerboard pattern, where the tiles * + * have a random color. The caller has to free the buffer. */ +void *create_checkerboard_pattern(unsigned int num_tiles_x, + unsigned int num_tiles_y, unsigned int tile_size) +{ + unsigned int *buf; + unsigned int x, y, i, j; + const unsigned int stride = num_tiles_x * tile_size; + + if (posix_memalign((void*)&buf, 64, num_tiles_y * tile_size * stride * 4) != 0) + return NULL; + + for (x = 0; x < num_tiles_x; ++x) { + for (y = 0; y < num_tiles_y; ++y) { + const unsigned int color = 0xff000000 + (random() & 0xffffff); + + for (i = 0; i < tile_size; ++i) { + for (j = 0; j < tile_size; ++j) { + buf[x * tile_size + y * stride * tile_size + i + j * stride] = color; + } + } + } + } + + return buf; +} + static void exynos_destroy_buffer(struct exynos_bo *bo) { exynos_bo_destroy(bo); @@ -533,11 +563,90 @@ err_free_userptr: return 0; }
+static int g2d_checkerboard_test(struct exynos_device *dev, + struct exynos_bo *src, + struct exynos_bo *dst, + enum e_g2d_buf_type type) +{ + struct g2d_context *ctx; + struct g2d_image src_img = {0}, dst_img = {0}; + unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h; + void *checkerboard = NULL; + int ret; + + ctx = g2d_init(dev->fd); + if (!ctx) + return -EFAULT; + + dst_img.bo[0] = dst->handle; + + src_x = 0; + src_y = 0; + dst_x = 0; + dst_y = 0; + + checkerboard = create_checkerboard_pattern(screen_width / 32, screen_height / 32, 32); + if (checkerboard == NULL) { + ret = -1; + goto fail; + } + + img_w = screen_width - (screen_width % 32); + img_h = screen_height - (screen_height % 32); + + switch (type) { + case G2D_IMGBUF_GEM: + memcpy(src->vaddr, checkerboard, img_w * img_h * 4); + src_img.bo[0] = src->handle; + break; + case G2D_IMGBUF_USERPTR: + src_img.user_ptr[0].userptr = (unsigned long)checkerboard; + src_img.user_ptr[0].size = img_w * img_h * 4; + break; + default: + ret = -EFAULT; + goto fail; + } + + printf("checkerboard test with %s.\n", + type == G2D_IMGBUF_GEM ? "gem" : "userptr"); + + src_img.width = img_w; + src_img.height = img_h; + src_img.stride = src_img.width * 4; + src_img.buf_type = type; + src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB; + + dst_img.width = screen_width; + dst_img.height = screen_height; + dst_img.stride = dst_img.width * 4; + dst_img.buf_type = G2D_IMGBUF_GEM; + dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB; + src_img.color = 0xff000000; + ret = g2d_solid_fill(ctx, &dst_img, src_x, src_y, screen_width, screen_height); + if (ret < 0) + goto fail; + + ret = g2d_copy(ctx, &src_img, &dst_img, src_x, src_y, dst_x, dst_y, + img_w, img_h); + if (ret < 0) + goto fail; + + g2d_exec(ctx); + +fail: + free(checkerboard); + g2d_fini(ctx); + + return ret; +} + static struct fimg2d_test_case test_case = { .solid_fill = &g2d_solid_fill_test, .copy = &g2d_copy_test, .copy_with_scale = &g2d_copy_with_scale_test, .blend = &g2d_blend_test, + .checkerboard = &g2d_checkerboard_test, };
static void usage(char *name) @@ -671,6 +780,14 @@ int main(int argc, char **argv)
getchar();
+ ret = test_case.checkerboard(dev, src, bo, G2D_IMGBUF_GEM); + if (ret < 0) { + fprintf(stderr, "failed to issue checkerboard test.\n"); + goto err_free_src; + } + + getchar(); + ret = test_case.blend(dev, src, bo, G2D_IMGBUF_USERPTR); if (ret < 0) fprintf(stderr, "failed to test blend operation.\n");
This also avoids the floating point conversion steps and just uses pure integer arithmetic. Also the G2D hardware scaling factor is a bit unintuitive, so explain it in the function.
Signed-off-by: Tobias Jakobi tjakobi@math.uni-bielefeld.de --- exynos/exynos_fimg2d.c | 19 ++++++++++++++----- exynos/fimg2d.h | 2 -- 2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/exynos/exynos_fimg2d.c b/exynos/exynos_fimg2d.c index fc281b6..435a88d 100644 --- a/exynos/exynos_fimg2d.c +++ b/exynos/exynos_fimg2d.c @@ -40,6 +40,15 @@
#define MIN(a, b) ((a) < (b) ? (a) : (b))
+static unsigned int g2d_get_scaling(unsigned int src, unsigned int dst) +{ + /* The G2D hw scaling factor is a normalized inverse of the scaling factor. * + * For example: When source width is 100 and destination width is 200 * + * (scaling of 2x), then the hw factor is NORMALIZE_CONSTANT * 100 / 200. */ + + return ((src << 16) / dst); +} + static unsigned int g2d_get_blend_op(enum e_g2d_op op) { union g2d_blend_func_val val; @@ -424,7 +433,7 @@ int g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src, union g2d_rop4_val rop4; union g2d_point_val pt; unsigned int scale; - double scale_x = 0.0f, scale_y = 0.0f; + unsigned int scale_x, scale_y;
g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR); g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode); @@ -450,8 +459,8 @@ int g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src, scale = 0; else { scale = 1; - scale_x = (double)src_w / (double)dst_w; - scale_y = (double)src_h / (double)dst_h; + scale_x = g2d_get_scaling(src_w, dst_w); + scale_y = g2d_get_scaling(src_h, dst_h); }
if (src_x + src_w > src->width) @@ -483,8 +492,8 @@ int g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src,
if (scale) { g2d_add_cmd(ctx, SRC_SCALE_CTRL_REG, G2D_SCALE_MODE_BILINEAR); - g2d_add_cmd(ctx, SRC_XSCALE_REG, G2D_DOUBLE_TO_FIXED(scale_x)); - g2d_add_cmd(ctx, SRC_YSCALE_REG, G2D_DOUBLE_TO_FIXED(scale_y)); + g2d_add_cmd(ctx, SRC_XSCALE_REG, scale_x); + g2d_add_cmd(ctx, SRC_YSCALE_REG, scale_y); }
pt.val = 0; diff --git a/exynos/fimg2d.h b/exynos/fimg2d.h index 4785e2f..8e0321c 100644 --- a/exynos/fimg2d.h +++ b/exynos/fimg2d.h @@ -25,8 +25,6 @@ #define G2D_MAX_CMD_LIST_NR 64 #define G2D_PLANE_MAX_NR 2
-#define G2D_DOUBLE_TO_FIXED(d) ((unsigned int)((d) * 65536.0)) - enum e_g2d_color_mode { /* COLOR FORMAT */ G2D_COLOR_FMT_XRGB8888,
No functional changes.
Signed-off-by: Tobias Jakobi tjakobi@math.uni-bielefeld.de --- exynos/exynos_fimg2d.c | 8 ++++---- tests/exynos/exynos_fimg2d_test.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/exynos/exynos_fimg2d.c b/exynos/exynos_fimg2d.c index 435a88d..61b4f94 100644 --- a/exynos/exynos_fimg2d.c +++ b/exynos/exynos_fimg2d.c @@ -144,13 +144,13 @@ static void g2d_reset(struct g2d_context *ctx) }
/* - * g2d_flush - summit all commands and values in user side command buffer + * g2d_flush - submit all commands and values in user side command buffer * to command queue aware of fimg2d dma. * * @ctx: a pointer to g2d_context structure. * * This function should be called after all commands and values to user - * side command buffer is set to summit that buffer to kernel side driver. + * side command buffer are set. It submits that buffer to the kernel side driver. */ static int g2d_flush(struct g2d_context *ctx) { @@ -191,7 +191,7 @@ static int g2d_flush(struct g2d_context *ctx) /** * g2d_init - create a new g2d context and get hardware version. * - * fd: a file descriptor to drm device driver opened. + * fd: a file descriptor to an opened drm device. */ struct g2d_context *g2d_init(int fd) { @@ -520,7 +520,7 @@ int g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src, }
/** - * g2d_blend - blend image data in source and destion buffers + * g2d_blend - blend image data in source and destination buffers. * * @ctx: a pointer to g2d_context structure. * @src: a pointer to g2d_image structure including image and buffer diff --git a/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c index 41fb869..aa140e5 100644 --- a/tests/exynos/exynos_fimg2d_test.c +++ b/tests/exynos/exynos_fimg2d_test.c @@ -39,7 +39,7 @@ static unsigned int screen_width, screen_height; /* * A structure to test fimg2d hw. * - * @solid_fild: fill given color data to source buffer. + * @solid_fill: fill given color data to source buffer. * @copy: copy source to destination buffer. * @copy_with_scale: copy source to destination buffer scaling up or * down properly. @@ -256,7 +256,7 @@ static int g2d_solid_fill_test(struct exynos_device *dev, struct exynos_bo *dst) memset(&img, 0, sizeof(struct g2d_image)); img.bo[0] = dst->handle;
- printf("soild fill test.\n"); + printf("solid fill test.\n");
srand(time(NULL)); img_w = screen_width;
dri-devel@lists.freedesktop.org