[Intel-gfx] [PATCH i-g-t v3] igt/gem_pipe_control_store_loop: Add qword write tests

Michał Winiarski michal.winiarski at intel.com
Thu Mar 17 16:15:39 UTC 2016


Test description suggested that all platforms were testing qword writes,
while in fact only gen4-gen5 did.

v2: Test dword/qword writes for all available platforms.
v3: Rewrite, drop libdrm/intel_batchbuffer dependencies,
    drop brw_emit_post_sync_nonzero_flush WA for gen6/gen7,
    drop WC_FLUSH/TC_FLUSH on gen4/gen5,
    drop preuse tests, use gem_wait instead of set_domain.

Cc: Chris Wilson <chris at chris-wilson.co.uk>
Signed-off-by: Michał Winiarski <michal.winiarski at intel.com>
---
 tests/gem_pipe_control_store_loop.c | 213 ++++++++++++++++--------------------
 1 file changed, 96 insertions(+), 117 deletions(-)

diff --git a/tests/gem_pipe_control_store_loop.c b/tests/gem_pipe_control_store_loop.c
index a155ad1..a80ab75 100644
--- a/tests/gem_pipe_control_store_loop.c
+++ b/tests/gem_pipe_control_store_loop.c
@@ -26,10 +26,10 @@
  */
 
 /*
- * Testcase: (TLB-)Coherency of pipe_control QW writes
+ * Testcase: (TLB-)Coherency of pipe_control writes
  *
- * Writes a counter-value into an always newly allocated target bo (by disabling
- * buffer reuse). Decently trashes on tlb inconsistencies, too.
+ * Writes a counter-value into an always newly allocated target bo.
+ * Decently trashes on tlb inconsistencies, too.
  */
 #include "igt.h"
 #include <stdlib.h>
@@ -43,11 +43,11 @@
 #include "drm.h"
 #include "intel_bufmgr.h"
 
-IGT_TEST_DESCRIPTION("Test (TLB-)Coherency of pipe_control QW writes.");
+IGT_TEST_DESCRIPTION("Test (TLB-)Coherency of pipe_control writes.");
 
-static drm_intel_bufmgr *bufmgr;
-struct intel_batchbuffer *batch;
 uint32_t devid;
+int gen;
+int fd;
 
 #define GFX_OP_PIPE_CONTROL	((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
 #define   PIPE_CONTROL_WRITE_IMMEDIATE	(1<<14)
@@ -60,134 +60,113 @@ uint32_t devid;
 #define   PIPE_CONTROL_CS_STALL	(1<<20)
 #define   PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
 
-/* Like the store dword test, but we create new command buffers each time */
+#define TEST_STORE_LOOP_QWORD_WRITE (1 << 0)
+
 static void
-store_pipe_control_loop(bool preuse_buffer)
+store_pipe_control_loop(uint32_t flags)
 {
-	int i, val = 0;
-	uint32_t *buf;
-	drm_intel_bo *target_bo;
-
-	for (i = 0; i < SLOW_QUICK(0x10000, 4); i++) {
-		/* we want to check tlb consistency of the pipe_control target,
-		 * so get a new buffer every time around */
-		target_bo = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
-		igt_assert(target_bo);
-
-		if (preuse_buffer) {
-			COLOR_BLIT_COPY_BATCH_START(0);
-			OUT_BATCH((3 << 24) | (0xf0 << 16) | 64);
-			OUT_BATCH(0);
-			OUT_BATCH(1 << 16 | 1);
-
-			/*
-			 * IMPORTANT: We need to preuse the buffer in a
-			 * different domain than what the pipe control write
-			 * (and kernel wa) uses!
-			 */
-			OUT_RELOC_FENCED(target_bo,
-			     I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-			     0);
-			OUT_BATCH(0xdeadbeef);
-			ADVANCE_BATCH();
-
-			intel_batchbuffer_flush(batch);
-		}
+	const bool qword_write = flags & TEST_STORE_LOOP_QWORD_WRITE;
 
-		/* gem_storedw_batches_loop.c is a bit overenthusiastic with
-		 * creating new batchbuffers - with buffer reuse disabled, the
-		 * support code will do that for us. */
-		if (batch->gen >= 8) {
-			BEGIN_BATCH(4, 1);
-			OUT_BATCH(GFX_OP_PIPE_CONTROL + 1);
-			OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
-			OUT_RELOC_FENCED(target_bo,
-			     I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
-			     PIPE_CONTROL_GLOBAL_GTT);
-			OUT_BATCH(val); /* write data */
-			ADVANCE_BATCH();
-
-		} else if (batch->gen >= 6) {
-			/* work-around hw issue, see intel_emit_post_sync_nonzero_flush
-			 * in mesa sources. */
-			BEGIN_BATCH(4, 1);
-			OUT_BATCH(GFX_OP_PIPE_CONTROL);
-			OUT_BATCH(PIPE_CONTROL_CS_STALL |
-			     PIPE_CONTROL_STALL_AT_SCOREBOARD);
-			OUT_BATCH(0); /* address */
-			OUT_BATCH(0); /* write data */
-			ADVANCE_BATCH();
-
-			BEGIN_BATCH(4, 1);
-			OUT_BATCH(GFX_OP_PIPE_CONTROL);
-			OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
-			OUT_RELOC(target_bo,
-			     I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, 
-			     PIPE_CONTROL_GLOBAL_GTT);
-			OUT_BATCH(val); /* write data */
-			ADVANCE_BATCH();
-		} else if (batch->gen >= 4) {
-			BEGIN_BATCH(4, 1);
-			OUT_BATCH(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_WC_FLUSH |
-					PIPE_CONTROL_TC_FLUSH |
-					PIPE_CONTROL_WRITE_IMMEDIATE | 2);
-			OUT_RELOC(target_bo,
-				I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
-				PIPE_CONTROL_GLOBAL_GTT);
-			OUT_BATCH(val);
-			OUT_BATCH(0xdeadbeef);
-			ADVANCE_BATCH();
+	int val, i;
+	uint32_t reloc_offset;
+	uint32_t batch_handle;
+	uint32_t batch[7];
+	uint32_t buf_handle;
+	uint32_t *buf;
+	struct drm_i915_gem_relocation_entry reloc;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 object[2];
+
+	batch_handle = gem_create(fd, 4096);
+
+	for (val = 0; val < SLOW_QUICK(0x10000, 4); val++) {
+		i = 0;
+		buf_handle = gem_create(fd, 4096);
+
+		buf = gem_mmap__cpu(fd, buf_handle, 0, 4096, PROT_READ | PROT_WRITE);
+		gem_set_domain(fd, buf_handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+		buf[0] = 0xdeadbeef;
+		buf[1] = 0xdeadbeef;
+
+		if (gen >= 6) {
+			batch[i++] = GFX_OP_PIPE_CONTROL + (gen >= 8) + qword_write;
+			batch[i++] = PIPE_CONTROL_WRITE_IMMEDIATE;
+			batch[i++] = 0; /* reloc */
+			reloc_offset = i - 1;
+			if (gen >= 8)
+				batch[i++] = 0; /* reloc_high */
+		} else {
+			/* qword write */
+			batch[i++] = (GFX_OP_PIPE_CONTROL |
+					PIPE_CONTROL_WRITE_IMMEDIATE);
+			batch[i++] = 0; /* reloc */
+			reloc_offset = i - 1;
 		}
 
-		intel_batchbuffer_flush_on_ring(batch, 0);
-
-		drm_intel_bo_map(target_bo, 1);
-
-		buf = target_bo->virtual;
-		igt_assert(buf[0] == val);
-
-		drm_intel_bo_unmap(target_bo);
-		/* Make doublesure that this buffer won't get reused. */
-		drm_intel_bo_disable_reuse(target_bo);
-		drm_intel_bo_unreference(target_bo);
-
-		val++;
+		batch[i++] = val; /* write data */
+		if (qword_write)
+			batch[i++] = ~val; /* dword_high */
+		else
+			batch[i++] = MI_NOOP | 0xabcd;
+		batch[i++] = MI_BATCH_BUFFER_END;
+
+		gem_write(fd, batch_handle, 0, batch, sizeof(batch));
+
+		memset(object, 0, sizeof(object));
+		memset(&reloc, 0, sizeof(reloc));
+		memset(&execbuf, 0, sizeof(execbuf));
+
+		reloc.target_handle = buf_handle;
+		reloc.delta = 0;
+		reloc.offset = reloc_offset * sizeof(batch[0]);
+		reloc.presumed_offset = 0;
+		reloc.read_domains = I915_GEM_DOMAIN_RENDER;
+		reloc.write_domain = I915_GEM_DOMAIN_RENDER;
+
+		if (gen == 6)
+			object[0].flags |= EXEC_OBJECT_NEEDS_GTT;
+		object[0].handle = buf_handle;
+		object[1].handle = batch_handle;
+		object[1].relocation_count = 1;
+		object[1].relocs_ptr = (uintptr_t)&reloc;
+
+		execbuf.buffers_ptr = (uintptr_t)object;
+		execbuf.buffer_count = 2;
+		gem_execbuf(fd, &execbuf);
+
+		gem_wait(fd, buf_handle, NULL);
+
+		igt_assert_eq_u32(buf[0], val);
+		if (qword_write)
+			igt_assert_eq_u32(buf[1], ~val);
+		else
+			igt_assert_eq_u32(buf[1], 0xdeadbeef);
+
+		munmap(buf, 4096);
+		gem_close(fd, buf_handle);
 	}
+	gem_close(fd, batch_handle);
 }
 
-int fd;
-
 igt_main
 {
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
 		devid = intel_get_drm_devid(fd);
+		gen = intel_gen(devid);
 
-		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
-		igt_assert(bufmgr);
-
-		igt_skip_on(IS_GEN2(devid) || IS_GEN3(devid));
+		igt_skip_on(gen < 4);
 		igt_skip_on(devid == PCI_CHIP_I965_G); /* has totally broken pipe control */
-
-		/* IMPORTANT: No call to
-		 * drm_intel_bufmgr_gem_enable_reuse(bufmgr);
-		 * here because we wan't to have fresh buffers (to trash the tlb)
-		 * every time! */
-
-		batch = intel_batchbuffer_alloc(bufmgr, devid);
-		igt_assert(batch);
 	}
 
-	igt_subtest("fresh-buffer")
-		store_pipe_control_loop(false);
-
-	igt_subtest("reused-buffer")
-		store_pipe_control_loop(true);
-
-	igt_fixture {
-		intel_batchbuffer_free(batch);
-		drm_intel_bufmgr_destroy(bufmgr);
+	igt_subtest("buffer-dword-write") {
+			/* no dword writes on gen4/gen5 and gen9+ */
+			igt_skip_on(gen < 6 || gen > 8);
+			store_pipe_control_loop(0);
+	}
+	igt_subtest("buffer-qword-write")
+			store_pipe_control_loop(TEST_STORE_LOOP_QWORD_WRITE);
 
+	igt_fixture
 		close(fd);
-	}
 }
-- 
2.7.1



More information about the Intel-gfx mailing list