[PATCH i-g-t 1/3] lib: Introduce blitter verifier
Karolina Stolarek
karolina.stolarek at intel.com
Fri Mar 31 13:41:04 UTC 2023
Add an initial version of intel_blt_verifier, a library that checks if
the blit operation used the expected tiling format.
Signed-off-by: Karolina Stolarek <karolina.stolarek at intel.com>
---
lib/intel_blt_verifier.c | 265 +++++++++++++++++++++++++++++++++++++++
lib/intel_blt_verifier.h | 33 +++++
lib/meson.build | 1 +
3 files changed, 299 insertions(+)
create mode 100644 lib/intel_blt_verifier.c
create mode 100644 lib/intel_blt_verifier.h
diff --git a/lib/intel_blt_verifier.c b/lib/intel_blt_verifier.c
new file mode 100644
index 00000000..b9116433
--- /dev/null
+++ b/lib/intel_blt_verifier.c
@@ -0,0 +1,265 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include "intel_blt_verifier.h"
+
+/*
+ * As for now, only a subsection of tiling formats is supported by intel_bufops
+ * operations. Verifier checks if it can copy to a requested format before
+ * trying to verify intel_cmds_info entry.
+ */
+#define SUPPORTED_TILING_FORMATS (BIT(T_LINEAR) | BIT(T_XMAJOR) | BIT(T_YMAJOR) | BIT(T_YFMAJOR))
+
+static void generate_reference(struct intel_blt_verifier *verifier)
+{
+ cairo_surface_t *surface;
+ cairo_pattern_t *pat;
+ cairo_t *cr;
+
+ struct intel_buf *buf;
+ void *linear;
+ int width = 512, height = 512;
+ int bpp = 32;
+
+ buf = verifier->ref;
+
+ intel_buf_init(verifier->bops, buf, width, height, bpp, 0,
+ I915_TILING_NONE, I915_COMPRESSION_NONE);
+
+ width = intel_buf_width(buf);
+ height = intel_buf_height(buf);
+
+ linear = gem_mmap__device_coherent(verifier->fd, buf->handle, 0,
+ buf->surface[0].size,
+ PROT_READ | PROT_WRITE);
+
+ surface = cairo_image_surface_create_for_data(linear,
+ CAIRO_FORMAT_RGB24,
+ width, height,
+ buf->surface[0].stride);
+ cr = cairo_create(surface);
+
+ cairo_rectangle(cr, 0, 0, width, height);
+ cairo_clip(cr);
+
+ pat = cairo_pattern_create_mesh();
+ cairo_mesh_pattern_begin_patch(pat);
+ cairo_mesh_pattern_move_to(pat, 0, 0);
+ cairo_mesh_pattern_line_to(pat, width, 0);
+ cairo_mesh_pattern_line_to(pat, width, height);
+ cairo_mesh_pattern_line_to(pat, 0, height);
+ 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, 0, 0, width, height);
+ cairo_set_source(cr, pat);
+ cairo_fill(cr);
+ cairo_pattern_destroy(pat);
+
+ cairo_destroy(cr);
+
+ cairo_surface_destroy(surface);
+
+ linear_to_intel_buf(verifier->bops, buf, linear);
+
+ munmap(linear, buf->surface[0].size);
+}
+
+static void software_blit(struct intel_blt_verifier *verifier,
+ enum blt_tiling_type tiling)
+{
+ struct intel_buf *ref, *dst;
+ int width, height;
+ void *linear;
+ int bpp = 32;
+
+ ref = verifier->ref;
+ dst = verifier->software_dst;
+
+ width = intel_buf_width(ref);
+ height = intel_buf_height(ref);
+
+ intel_buf_init(verifier->bops, dst, width, height, bpp, 0,
+ tiling, I915_COMPRESSION_NONE);
+
+ gem_set_domain(verifier->fd, ref->handle, I915_GEM_DOMAIN_CPU, 0);
+ linear = gem_mmap__device_coherent(verifier->fd, ref->handle, 0,
+ ref->size, PROT_READ);
+ if (!ref->ptr)
+ intel_buf_cpu_map(ref, false);
+
+ linear_to_intel_buf(verifier->bops, dst, linear);
+
+ munmap(linear, ref->size);
+}
+
+static void copy_from_ref(int fd, struct intel_buf *ref,
+ struct blt_copy_object *src)
+{
+ void *map = src->ptr;
+
+ map = gem_mmap__device_coherent(fd, src->handle, 0,
+ src->size, PROT_READ | PROT_WRITE);
+
+ memcpy(map, ref->ptr, ref->surface[0].size);
+ munmap(map, ref->surface[0].size);
+}
+
+static void blit(struct intel_blt_verifier *verifier,
+ enum blt_cmd_type command,
+ enum blt_tiling_type tiling)
+{
+ struct blt_copy_data blt = {};
+ struct blt_block_copy_data_ext ext = {}, *pext = &ext;
+ struct blt_copy_object *src, *dst;
+ struct intel_execution_engine2 *e;
+ const uint32_t bpp = 32;
+ uint64_t bb_size = 4096;
+ int fd = verifier->fd;
+
+ uint64_t ahnd = intel_allocator_open_full(fd, verifier->ctx->id, 0, 0,
+ INTEL_ALLOCATOR_SIMPLE,
+ ALLOC_STRATEGY_LOW_TO_HIGH, 0);
+ uint32_t bb;
+ int width, height;
+
+ igt_assert(__gem_create_in_memory_regions(fd, &bb, &bb_size, I915_SYSTEM_MEMORY) == 0);
+
+ width = intel_buf_width(verifier->ref);
+ height = intel_buf_height(verifier->ref);
+
+ src = blt_create_object(fd, I915_SYSTEM_MEMORY, width, height, bpp, 0,
+ T_LINEAR, COMPRESSION_DISABLED, 0, true);
+ dst = blt_create_object(fd, I915_SYSTEM_MEMORY, width, height, bpp, 0,
+ tiling, COMPRESSION_DISABLED, 0, true);
+ igt_assert(src->size == dst->size);
+
+ copy_from_ref(fd, verifier->ref, src);
+
+ for_each_ctx_engine(fd, verifier->ctx, e) {
+ if (e->class == I915_ENGINE_CLASS_COPY)
+ break;
+ }
+
+ memset(&blt, 0, sizeof(blt));
+ blt.color_depth = CD_32bit;
+ blt_set_batch(&blt.bb, bb, bb_size, I915_SYSTEM_MEMORY);
+ blt_set_copy_object(&blt.src, src);
+ blt_set_copy_object(&blt.dst, dst);
+
+ /* block-copy doesn't have a bit to set Yf-Major, test all but this format */
+ if (command == XY_BLOCK_COPY && tiling != T_YFMAJOR) {
+ if (!blt_uses_extended_block_copy(fd))
+ pext = NULL;
+
+ /* block-copy requires additional setup */
+ blt_set_object_ext(&ext.src, 0, width, height, SURFACE_TYPE_2D);
+ blt_set_object_ext(&ext.dst, 0, width, height, SURFACE_TYPE_2D);
+
+ blt_block_copy(fd, verifier->ctx, e, ahnd, &blt, pext);
+ } else if (command == XY_FAST_COPY) {
+ blt_fast_copy(fd, verifier->ctx, e, ahnd, &blt);
+ }
+
+ gem_sync(fd, blt.dst.handle);
+ verifier->blitter_dst = dst;
+
+ blt_destroy_object(fd, src);
+ gem_close(fd, bb);
+ put_ahnd(ahnd);
+ munmap(&bb, bb_size);
+}
+
+struct intel_blt_verifier *blt_verifier_init(int fd)
+{
+ struct intel_blt_verifier *verifier;
+ int devid = intel_get_drm_devid(fd);
+
+ verifier = calloc(1, sizeof(*verifier));
+ igt_assert(verifier);
+
+ verifier->fd = fd;
+ verifier->cmds_info = intel_get_cmds_info(devid);
+ verifier->bops = buf_ops_create(fd);
+ verifier->ctx = intel_ctx_create_all_physical(fd);
+
+ verifier->ref = calloc(1, sizeof(struct intel_buf *));
+ verifier->software_dst = calloc(1, sizeof(struct intel_buf *));
+
+ generate_reference(verifier);
+
+ return verifier;
+}
+
+bool verifier_supports_blt_tiling(enum blt_tiling_type tiling)
+{
+ return SUPPORTED_TILING_FORMATS & BIT(tiling);
+}
+
+static bool compare_results(struct intel_blt_verifier *verifier)
+{
+ void *soft_dst, *blt_dst;
+ int ret;
+ int fd = verifier->fd;
+ uint64_t size = verifier->software_dst->size;
+
+ igt_assert(verifier->blitter_dst->size == size);
+
+ soft_dst = gem_mmap__device_coherent(fd, verifier->software_dst->handle,
+ 0, size, PROT_READ);
+ blt_dst = gem_mmap__device_coherent(fd, verifier->blitter_dst->handle,
+ 0, size, PROT_READ);
+ ret = memcmp(soft_dst, blt_dst, size);
+
+ munmap(soft_dst, size);
+ munmap(blt_dst, size);
+
+ return ret == 0;
+}
+
+int blt_verify_support(struct intel_blt_verifier *verifier,
+ enum blt_cmd_type command,
+ enum blt_tiling_type tiling)
+{
+ bool same_results;
+ bool intel_cmds_support;
+
+ if (!verifier_supports_blt_tiling(tiling)) {
+ igt_warn("Tiling %s not supported by the verifier\n",
+ blt_tiling_name(tiling));
+ return -EINVAL;
+ }
+
+ software_blit(verifier, tiling);
+ blit(verifier, command, tiling);
+
+ same_results = compare_results(verifier);
+ intel_cmds_support = blt_cmd_supports_tiling(verifier->cmds_info,
+ command, tiling);
+
+ /* platform supports the tiling, but didn't know about it */
+ if (same_results && !intel_cmds_support)
+ return -1;
+
+ /* intel_cmds_info falsely claims support for the tiling format */
+ if (!same_results && intel_cmds_support)
+ return 1;
+
+ return 0;
+}
+
+void blt_verifier_destroy(struct intel_blt_verifier *verifier)
+{
+ intel_buf_close(verifier->bops, verifier->ref);
+ intel_buf_unmap(verifier->ref);
+
+ buf_ops_destroy(verifier->bops);
+ blt_destroy_object(verifier->fd, verifier->blitter_dst);
+
+ free(verifier);
+}
diff --git a/lib/intel_blt_verifier.h b/lib/intel_blt_verifier.h
new file mode 100644
index 00000000..424a2bc0
--- /dev/null
+++ b/lib/intel_blt_verifier.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef INTEL_BLT_VERIFIER_H
+#define INTEL_BLT_VERIFIER_H
+
+#include "i915/i915_blt.h"
+#include "intel_bufops.h"
+
+struct intel_blt_verifier {
+ int fd;
+ const intel_ctx_t *ctx;
+ const struct intel_cmds_info *cmds_info;
+
+ struct buf_ops *bops;
+ struct intel_buf *ref;
+ struct intel_buf *software_dst;
+ struct blt_copy_object *blitter_dst;
+};
+
+bool verifier_supports_blt_tiling(enum blt_tiling_type tiling);
+
+int blt_verify_support(struct intel_blt_verifier *verifier,
+ enum blt_cmd_type command,
+ enum blt_tiling_type tiling);
+// bool blt_verify_support_with_ref(struct intel_buf *ref); <-- later
+
+void blt_verifier_destroy(struct intel_blt_verifier *verifier);
+struct intel_blt_verifier *blt_verifier_init(int fd);
+
+#endif // INTEL_BLT_VERIFIER_H
diff --git a/lib/meson.build b/lib/meson.build
index ad9e2abe..905d49af 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -54,6 +54,7 @@ lib_sources = [
'intel_allocator_reloc.c',
'intel_allocator_simple.c',
'intel_batchbuffer.c',
+ 'intel_blt_verifier.c',
'intel_bufops.c',
'intel_chipset.c',
'intel_ctx.c',
--
2.25.1
More information about the Intel-gfx-trybot
mailing list