diff mbox

[2/2] tests/gem_exec_parse: test for chained batch buffers

Message ID 1413409962-23097-2-git-send-email-bradley.d.volkin@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

bradley.d.volkin@intel.com Oct. 15, 2014, 9:52 p.m. UTC
From: Brad Volkin <bradley.d.volkin@intel.com>

libva makes extensive use of chained batch buffers. The batch
buffer copy portion of the command parser has the potential to
break chained batches, so add a simple test to make sure that
doesn't happen.

Signed-off-by: Brad Volkin <bradley.d.volkin@intel.com>
---
 lib/intel_reg.h        |   1 +
 tests/gem_exec_parse.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 106 insertions(+)
diff mbox

Patch

diff --git a/lib/intel_reg.h b/lib/intel_reg.h
index f0fc5fd..fcc9d7c 100644
--- a/lib/intel_reg.h
+++ b/lib/intel_reg.h
@@ -2571,6 +2571,7 @@  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define MI_BATCH_BUFFER_END	(0xA << 23)
 #define MI_BATCH_NON_SECURE		(1)
 #define MI_BATCH_NON_SECURE_I965	(1 << 8)
+#define MI_BATCH_NON_SECURE_HSW		(1<<13) /* Additional bit for RCS */
 
 #define MAX_DISPLAY_PIPES	2
 
diff --git a/tests/gem_exec_parse.c b/tests/gem_exec_parse.c
index 568bd4a..3ff6a66 100644
--- a/tests/gem_exec_parse.c
+++ b/tests/gem_exec_parse.c
@@ -183,6 +183,96 @@  static void exec_split_batch(int fd, uint32_t *cmds,
 	gem_close(fd, cmd_bo);
 }
 
+static void exec_batch_chained(int fd, uint32_t cmd_bo, uint32_t *cmds,
+			       int size, int patch_offset,
+			       uint64_t expected_value)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 objs[3];
+	struct drm_i915_gem_relocation_entry reloc;
+	struct drm_i915_gem_relocation_entry first_level_reloc;
+
+	uint32_t target_bo = gem_create(fd, 4096);
+	uint32_t first_level_bo = gem_create(fd, 4096);
+	uint64_t actual_value = 0;
+
+	static uint32_t first_level_cmds[] = {
+		MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965,
+		0,
+		MI_BATCH_BUFFER_END,
+		0,
+	};
+
+	if (IS_HASWELL(intel_get_drm_devid(fd)))
+		first_level_cmds[0] |= MI_BATCH_NON_SECURE_HSW;
+
+	gem_write(fd, first_level_bo, 0,
+		  first_level_cmds, sizeof(first_level_cmds));
+	gem_write(fd, cmd_bo, 0, cmds, size);
+
+	reloc.offset = patch_offset;
+	reloc.delta = 0;
+	reloc.target_handle = target_bo;
+	reloc.read_domains = I915_GEM_DOMAIN_RENDER;
+	reloc.write_domain = I915_GEM_DOMAIN_RENDER;
+	reloc.presumed_offset = 0;
+
+	first_level_reloc.offset = 4;
+	first_level_reloc.delta = 0;
+	first_level_reloc.target_handle = cmd_bo;
+	first_level_reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+	first_level_reloc.write_domain = 0;
+	first_level_reloc.presumed_offset = 0;
+
+	objs[0].handle = target_bo;
+	objs[0].relocation_count = 0;
+	objs[0].relocs_ptr = 0;
+	objs[0].alignment = 0;
+	objs[0].offset = 0;
+	objs[0].flags = 0;
+	objs[0].rsvd1 = 0;
+	objs[0].rsvd2 = 0;
+
+	objs[1].handle = cmd_bo;
+	objs[1].relocation_count = 1;
+	objs[1].relocs_ptr = (uintptr_t)&reloc;
+	objs[1].alignment = 0;
+	objs[1].offset = 0;
+	objs[1].flags = 0;
+	objs[1].rsvd1 = 0;
+	objs[1].rsvd2 = 0;
+
+	objs[2].handle = first_level_bo;
+	objs[2].relocation_count = 1;
+	objs[2].relocs_ptr = (uintptr_t)&first_level_reloc;
+	objs[2].alignment = 0;
+	objs[2].offset = 0;
+	objs[2].flags = 0;
+	objs[2].rsvd1 = 0;
+	objs[2].rsvd2 = 0;
+
+	execbuf.buffers_ptr = (uintptr_t)objs;
+	execbuf.buffer_count = 3;
+	execbuf.batch_start_offset = 0;
+	execbuf.batch_len = sizeof(first_level_cmds);
+	execbuf.cliprects_ptr = 0;
+	execbuf.num_cliprects = 0;
+	execbuf.DR1 = 0;
+	execbuf.DR4 = 0;
+	execbuf.flags = I915_EXEC_RENDER;
+	i915_execbuffer2_set_context_id(execbuf, 0);
+	execbuf.rsvd2 = 0;
+
+	gem_execbuf(fd, &execbuf);
+	gem_sync(fd, cmd_bo);
+
+	gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value));
+	igt_assert_eq(expected_value, actual_value);
+
+	gem_close(fd, first_level_bo);
+	gem_close(fd, target_bo);
+}
+
 uint32_t handle;
 int fd;
 
@@ -366,6 +456,21 @@  igt_main
 			   -EINVAL);
 	}
 
+	igt_subtest("chained-batch") {
+		uint32_t pc[] = {
+			GFX_OP_PIPE_CONTROL,
+			PIPE_CONTROL_QW_WRITE,
+			0, // To be patched
+			0x12000000,
+			0,
+			MI_BATCH_BUFFER_END,
+		};
+		exec_batch_chained(fd, handle,
+				   pc, sizeof(pc),
+				   8, // patch offset,
+				   0x12000000);
+	}
+
 	igt_fixture {
 		gem_close(fd, handle);