[igt-dev] [PATCH i-g-t v27 12/30] tests/api_intel_bb: add render tests

Zbigniew Kempczyński
2020-08-10T09:48:06Z

Check render / render-ccs tests works fine on all supported gens.

Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Cc: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
tests/i915/api_intel_bb.c | 267 +++++++++++++++++++++++++++++++++++++-
1 file changed, 265 insertions(+), 2 deletions(-)

diff --git a/tests/i915/api_intel_bb.c b/tests/i915/api_intel_bb.c
index a4b57b7c..376021de 100644
--- a/tests/i915/api_intel_bb.c
+++ b/tests/i915/api_intel_bb.c
@@ -32,6 +32,8 @@
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
+#include <glib.h>
+#include <zlib.h>
#include "intel_bufops.h"

#define PAGE_SIZE 4096
@@ -58,6 +60,7 @@ enum obj_cache_ops {
static bool debug_bb = false;
static bool write_png = false;
static bool buf_info = false;
+static bool print_base64 = false;

static void *alloc_aligned(uint64_t size)
{
@@ -575,6 +578,54 @@ static int compare_bufs(struct intel_buf *buf1, struct intel_buf *buf2,
return ret;
}

+#define LINELEN 76
+static int dump_base64(const char *name, struct intel_buf *buf)
+{
+ void *ptr;
+ int fd, ret;
+ uLongf outsize = buf->surface[0].size * 3 / 2;
+ Bytef *destbuf = malloc(outsize);
+ gchar *str, *pos;
+
+ fd = buf_ops_get_fd(buf->bops);
+
+ ptr = gem_mmap__device_coherent(fd, buf->handle, 0,
+ buf->surface[0].size, PROT_READ);
+
+ ret = compress2(destbuf, &outsize, ptr, buf->surface[0].size,
+ Z_BEST_COMPRESSION);
+ if (ret != Z_OK) {
+ igt_warn("error compressing, ret: %d\n", ret);
+ } else {
+ igt_info("compressed %u -> %lu\n",
+ buf->surface[0].size, outsize);
+
+ igt_info("--- %s ---\n", name);
+ pos = str = g_base64_encode(destbuf, outsize);
+ outsize = strlen(str);
+ while (pos) {
+ char line[LINELEN + 1];
+ int to_copy = min(LINELEN, outsize);
+
+ memcpy(line, pos, to_copy);
+ line[to_copy] = 0;
+ igt_info("%s\n", line);
+ pos += LINELEN;
+ outsize -= to_copy;
+
+ if (outsize == 0)
+ break;
+ }
+ free(str);
+ }
+
+ munmap(ptr, buf->surface[0].size);
+ free(destbuf);
+
+ return ret;
+}
+
+
static int __do_intel_bb_blit(struct buf_ops *bops, uint32_t tiling)
{
struct intel_bb *ibb;
@@ -753,6 +804,180 @@ static void full_batch(struct buf_ops *bops)
intel_bb_destroy(ibb);
}

+static int render(struct buf_ops *bops, uint32_t tiling, bool do_reloc,
+ uint32_t width, uint32_t height)
+{
+ struct intel_bb *ibb;
+ struct intel_buf src, dst, final;
+ int i915 = buf_ops_get_fd(bops);
+ uint32_t fails = 0;
+ char name[128];
+ uint32_t devid = intel_get_drm_devid(i915);
+ igt_render_copyfunc_t render_copy = NULL;
+
+ igt_debug("%s() gen: %d\n", __func__, intel_gen(devid));
+
+ /* Don't use relocations on gen12+ */
+ igt_require((do_reloc && intel_gen(devid) < 12) ||
+ !do_reloc);
+
+ if (do_reloc)
+ ibb = intel_bb_create_with_relocs(i915, PAGE_SIZE);
+ else
+ ibb = intel_bb_create(i915, PAGE_SIZE);
+
+ if (debug_bb)
+ intel_bb_set_debug(ibb, true);
+
+ if (print_base64)
+ intel_bb_set_dump_base64(ibb, true);
+
+ scratch_buf_init(bops, &src, width, height, I915_TILING_NONE,
+ I915_COMPRESSION_NONE);
+ scratch_buf_init(bops, &dst, width, height, tiling,
+ I915_COMPRESSION_NONE);
+ scratch_buf_init(bops, &final, width, height, I915_TILING_NONE,
+ I915_COMPRESSION_NONE);
+
+ scratch_buf_draw_pattern(bops, &src,
+ 0, 0, width, height,
+ 0, 0, width, height, 0);
+
+ render_copy = igt_get_render_copyfunc(devid);
+ igt_assert(render_copy);
+
+ render_copy(ibb, 0,
+ &src,
+ 0, 0, width, height,
+ &dst,
+ 0, 0);
+
+ render_copy(ibb, 0,
+ &dst,
+ 0, 0, width, height,
+ &final,
+ 0, 0);
+
+ intel_bb_sync(ibb);
+ intel_bb_destroy(ibb);
+
+ if (write_png) {
+ snprintf(name, sizeof(name) - 1,
+ "render_dst_tiling_%d.png", tiling);
+ intel_buf_write_to_png(&src, "render_src_tiling_none.png");
+ intel_buf_write_to_png(&dst, name);
+ intel_buf_write_to_png(&final, "render_final_tiling_none.png");
+ }
+
+ /* We'll fail on src <-> final compare so just warn */
+ if (tiling == I915_TILING_NONE) {
+ if (compare_bufs(&src, &dst, false) > 0)
+ igt_warn("%s: none->none failed!\n", __func__);
+ } else {
+ if (compare_bufs(&src, &dst, false) == 0)
+ igt_warn("%s: none->tiled failed!\n", __func__);
+ }
+
+ fails = compare_bufs(&src, &final, true);
+
+ if (fails && print_base64) {
+ dump_base64("src", &src);
+ dump_base64("dst", &dst);
+ dump_base64("final", &final);
+ }
+
+ intel_buf_close(bops, &src);
+ intel_buf_close(bops, &dst);
+ intel_buf_close(bops, &final);
+
+ igt_assert_f(fails == 0, "%s: (tiling: %d) fails: %d\n",
+ __func__, tiling, fails);
+
+ return fails;
+}
+
+static uint32_t count_compressed(int gen, struct intel_buf *buf)
+{
+ int ccs_size = intel_buf_ccs_width(gen, buf) * intel_buf_ccs_height(gen, buf);
+ uint8_t *ptr = intel_buf_device_map(buf, false);
+ uint32_t compressed = 0;
+ int i;
+
+ for (i = 0; i < ccs_size; i++)
+ if (ptr[buf->ccs[0].offset + i])
+ compressed++;
+
+ intel_buf_unmap(buf);
+
+ return compressed;
+}
+
+#define IMGSIZE (512 * 512 * 4)
+#define CCSIMGSIZE (IMGSIZE + 4096)
+static void render_ccs(struct buf_ops *bops)
+{
+ struct intel_bb *ibb;
+ const int width = 1024;
+ const int height = 1024;
+ struct intel_buf src, dst, final;
+ int i915 = buf_ops_get_fd(bops);
+ uint32_t fails = 0;
+ uint32_t compressed = 0;
+ uint32_t devid = intel_get_drm_devid(i915);
+ igt_render_copyfunc_t render_copy = NULL;
+
+ ibb = intel_bb_create(i915, PAGE_SIZE);
+ if (debug_bb)
+ intel_bb_set_debug(ibb, true);
+
+ scratch_buf_init(bops, &src, width, height, I915_TILING_NONE,
+ I915_COMPRESSION_NONE);
+ scratch_buf_init(bops, &dst, width, height, I915_TILING_Y,
+ I915_COMPRESSION_RENDER);
+ scratch_buf_init(bops, &final, width, height, I915_TILING_NONE,
+ I915_COMPRESSION_NONE);
+
+ render_copy = igt_get_render_copyfunc(devid);
+ igt_assert(render_copy);
+
+ scratch_buf_draw_pattern(bops, &src,
+ 0, 0, width, height,
+ 0, 0, width, height, 0);
+
+ render_copy(ibb, 0,
+ &src,
+ 0, 0, width, height,
+ &dst,
+ 0, 0);
+
+ render_copy(ibb, 0,
+ &dst,
+ 0, 0, width, height,
+ &final,
+ 0, 0);
+
+ intel_bb_sync(ibb);
+ intel_bb_destroy(ibb);
+
+ fails = compare_bufs(&src, &final, true);
+ compressed = count_compressed(ibb->gen, &dst);
+
+ igt_debug("fails: %u, compressed: %u\n", fails, compressed);
+
+ if (write_png) {
+ intel_buf_write_to_png(&src, "render-ccs-src.png");
+ intel_buf_write_to_png(&dst, "render-ccs-dst.png");
+ intel_buf_write_aux_to_png(&dst, "render-ccs-dst-aux.png");
+ intel_buf_write_to_png(&final, "render-ccs-final.png");
+ }
+
+ intel_buf_close(bops, &src);
+ intel_buf_close(bops, &dst);
+ intel_buf_close(bops, &final);
+
+ igt_assert_f(fails == 0, "render-ccs fails: %d\n", fails);
+}
+
static int opt_handler(int opt, int opt_index, void *data)
{
switch (opt) {
@@ -765,6 +990,9 @@ static int opt_handler(int opt, int opt_index, void *data)
case 'i':
buf_info = true;
break;
+ case 'b':
+ print_base64 = true;
+ break;
default:
return IGT_OPT_HANDLER_ERROR;
}
@@ -776,16 +1004,28 @@ const char *help_str =
" -d\tDebug bb\n"
" -p\tWrite surfaces to png\n"
" -i\tPrint buffer info\n"
+ " -b\tDump to base64 (bb and images)\n"
;

-igt_main_args("dpi", NULL, help_str, opt_handler, NULL)
+igt_main_args("dpib", NULL, help_str, opt_handler, NULL)
{
- int i915;
+ int i915, i, gen;
struct buf_ops *bops;
+ uint32_t width;
+
+ struct test {
+ uint32_t tiling;
+ const char *tiling_name;
+ } tests[] = {
+ { I915_TILING_NONE, "none" },
+ { I915_TILING_X, "x" },
+ { I915_TILING_Y, "y" },
+ };

igt_fixture {
i915 = drm_open_driver(DRIVER_INTEL);
bops = buf_ops_create(i915);
+ gen = intel_gen(intel_get_drm_devid(i915));
}

igt_subtest("simple-bb")
@@ -829,6 +1069,29 @@ igt_main_args("dpi", NULL, help_str, opt_handler, NULL)
igt_subtest("full-batch")
full_batch(bops);

+ igt_subtest_with_dynamic("render") {
+ for (i = 0; i < ARRAY_SIZE(tests); i++) {
+ const struct test *t = &tests[i];
+
+ for (width = 512; width <= 1024; width += 512) {
+ igt_dynamic_f("render-%s-%u", t->tiling_name, width) {
+ render(bops, t->tiling, false, width, width);
+ }
+
+ /* No relocs for gen12+ */
+ if (gen >= 12)
+ continue;
+
+ igt_dynamic_f("render-%s-reloc-%u", t->tiling_name, width) {
+ render(bops, t->tiling, true, width, width);
+ }
+ }
+ }
+ }
+
+ igt_subtest("render-ccs")
+ render_ccs(bops);
+
igt_fixture {
buf_ops_destroy(bops);
close(i915);