[PATCH i-g-t v2 14/14] tests/gem_draw: Test igt_draw without kms
Ville Syrjala
ville.syrjala at linux.intel.com
Fri Oct 11 10:43:54 UTC 2024
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
kms_draw_crc is our only way to confirm that igt_draw
linear<->tiled conversion routines are correct. That may
not cover every case as we could be hitting display
specific limitations that prevent testing everything.
Introduce a new gem_draw test case that compares igt_draw
mmap/pwrite methods against GTT mmaps. This will verify that
the software conversion routines match the hardware (de)tiling
peformed via the fenced region.
TODO: could verify against blt/rendercopy
when gtt mmaps are not available...
v2: Drop the "driver requirement: i915" to make it past
the documentation build scripts
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
tests/intel/gem_draw.c | 233 +++++++++++++++++++++++++++++++++++++++++
tests/meson.build | 1 +
2 files changed, 234 insertions(+)
create mode 100644 tests/intel/gem_draw.c
diff --git a/tests/intel/gem_draw.c b/tests/intel/gem_draw.c
new file mode 100644
index 000000000000..86df7c33ff2d
--- /dev/null
+++ b/tests/intel/gem_draw.c
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+/**
+ * TEST: gem draw
+ * Category: GEM
+ * Description: Tests whether the igt_draw library actually works.
+ * Functionality: tiling
+ * Test category: functionality test
+ */
+
+/**
+ * SUBTEST: draw-method-%s
+ * Description: Verify that igt draw library works for the %arg[1] method with
+ * different tilings and color depths.
+ *
+ * arg[1]:
+ *
+ * @mmap-cpu: MMAP-CPU
+ * @mmap-wc: MMAP-WC
+ * @pwrite: PWRITE
+ */
+
+#include "i915/gem.h"
+#include "i915/gem_create.h"
+#include "igt.h"
+#include "igt_halffloat.h"
+#include "igt_primes.h"
+
+int drm_fd;
+struct buf_ops *bops;
+
+static const enum igt_draw_method draw_methods[] = {
+ IGT_DRAW_MMAP_CPU,
+ IGT_DRAW_MMAP_WC,
+ IGT_DRAW_PWRITE,
+};
+
+static const uint32_t tilings[] = {
+ I915_TILING_NONE,
+ I915_TILING_X,
+ I915_TILING_Y,
+};
+
+static uint64_t read_pixel(const void *ptr, int stride, int x, int y, int bpp)
+{
+ ptr += y * stride + x * bpp / 8;
+
+ switch (bpp) {
+ case 8:
+ return *(const uint8_t*)ptr;
+ case 16:
+ return *(const uint16_t*)ptr;
+ case 32:
+ return *(const uint32_t*)ptr;
+ case 64:
+ return *(const uint64_t*)ptr;
+ default:
+ return 0;
+ }
+}
+
+static void check_rect(const void *ptr, int stride,
+ int x0, int y0, int w, int h,
+ uint64_t color, int bpp)
+{
+ int x1 = x0 + w - 1;
+ int y1 = y0 + h - 1;
+
+ if (bpp < 64)
+ color &= (1ull << bpp) - 1;
+
+ /* only check the corners to speed this up a bit */
+ igt_assert_eq(read_pixel(ptr, stride, x0, y0, bpp), color);
+ igt_assert_eq(read_pixel(ptr, stride, x0, y1, bpp), color);
+ igt_assert_eq(read_pixel(ptr, stride, x1, y0, bpp), color);
+ igt_assert_eq(read_pixel(ptr, stride, x1, y1, bpp), color);
+}
+
+static void draw(enum igt_draw_method method,
+ int width, int height,
+ uint32_t stride, int bpp, uint32_t tiling)
+{
+ uint64_t size = stride * height;
+ uint64_t color;
+ uint32_t handle;
+ void *ptr;
+
+ igt_require(buf_ops_has_tiling_support(bops, tiling));
+
+ handle = gem_create(drm_fd, size);
+ gem_set_tiling(drm_fd, handle, tiling, stride);
+
+ color = 0x0123456789abcdef;
+ for (int y = 0 ; y < height;) {
+ int y_next = min(height, (int)igt_next_prime_number(y));
+ int h = y_next - y;
+
+ for (int x = 0; x < width; ) {
+ int x_next = min(width, (int)igt_next_prime_number(x));
+ int w = x_next - x;
+
+ igt_draw_rect(drm_fd, bops, 0, handle, size, stride,
+ width, height, tiling, method,
+ x, y, w, h, color, bpp);
+
+ color = igt_ror(color, 1, 64);
+
+ x = x_next;
+ }
+
+ y = y_next;
+ }
+
+ gem_set_domain(drm_fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+ ptr = gem_mmap__gtt(drm_fd, handle, size, PROT_READ);
+
+ color = 0x0123456789abcdef;
+ for (int y = 0 ; y < height;) {
+ int y_next = min(height, (int)igt_next_prime_number(y));
+ int h = y_next - y;
+
+ for (int x = 0; x < width; ) {
+ int x_next = min(width, (int)igt_next_prime_number(x));
+ int w = x_next - x;
+
+ check_rect(ptr, stride, x, y, w, h, color, bpp);
+
+ color = igt_ror(color, 1, 64);
+
+ x = x_next;
+ }
+
+ y = y_next;
+ }
+
+ munmap(ptr, size);
+
+ gem_close(drm_fd, handle);
+}
+
+static void draw_method_subtest(enum igt_draw_method method,
+ int bpp, uint32_t tiling)
+{
+ const struct intel_device_info *info =
+ intel_get_device_info(intel_get_drm_devid(drm_fd));
+ int width, height, stride;
+ int tile_w, tile_h;
+
+ if (info->graphics_ver == 2) {
+ tile_w = 128;
+ tile_h = 16;
+ } else if (tiling == I915_TILING_X ||
+ info->is_grantsdale || info->is_alviso) {
+ tile_w = 512;
+ tile_h = 8;
+ } else {
+ tile_w = 128;
+ tile_h = 32;
+ }
+
+ stride = 4 * tile_w;
+ width = stride * 8 / bpp;
+ height = 4 * tile_h;
+
+ draw(method, width, height, stride, bpp, tiling);
+}
+
+static void setup_environment(void)
+{
+ drm_fd = drm_open_driver_master(DRIVER_INTEL | DRIVER_XE);
+ igt_require(drm_fd >= 0);
+ bops = buf_ops_create(drm_fd);
+
+ /* need hardware to untile for verification */
+ gem_require_mappable_ggtt(drm_fd);
+}
+
+static void teardown_environment(void)
+{
+ buf_ops_destroy(bops);
+ drm_close_driver(drm_fd);
+}
+
+static const char *tiling_str(uint32_t tiling)
+{
+ switch (tiling) {
+ case I915_TILING_NONE :
+ return "untiled";
+ case I915_TILING_X :
+ return "xtiled";
+ case I915_TILING_Y :
+ return "ytiled";
+ default:
+ igt_assert(false);
+ }
+}
+
+igt_main
+{
+ int method_idx, tiling_idx;
+
+ igt_fixture
+ setup_environment();
+
+ for (method_idx = 0; method_idx < ARRAY_SIZE(draw_methods); method_idx++) {
+ enum igt_draw_method method = draw_methods[method_idx];
+
+ igt_describe_f("Verify that igt draw library works for the draw "
+ "method (%s) with different tilings and color depths.",
+ igt_draw_get_method_name(method));
+
+ igt_subtest_with_dynamic_f("draw-method-%s", igt_draw_get_method_name(method)) {
+ if (!igt_draw_supports_method(drm_fd, method))
+ continue;
+
+ for (tiling_idx = 0; tiling_idx < ARRAY_SIZE(tilings); tiling_idx++) {
+ uint32_t tiling = tilings[tiling_idx];
+
+ for (int bpp = 8; bpp <= 64; bpp *= 2) {
+ igt_dynamic_f("%dbpp-%s", bpp, tiling_str(tiling))
+ draw_method_subtest(method, bpp, tiling);
+ }
+ }
+ }
+ }
+
+ igt_fixture
+ teardown_environment();
+}
diff --git a/tests/meson.build b/tests/meson.build
index 2d8cb87d5dfd..853f1e17ad79 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -118,6 +118,7 @@ intel_i915_progs = [
'gem_ctx_shared',
'gem_ctx_sseu',
'gem_ctx_switch',
+ 'gem_draw',
'gem_eio',
'gem_evict_alignment',
'gem_evict_everything',
--
2.45.2
More information about the igt-dev
mailing list