[i-g-t v2 22/27] lib/intel_batchbuffer: Add helpers to support bb execbuf3

Bhanuprakash Modem bhanuprakash.modem at intel.com
Tue Jan 24 07:35:06 UTC 2023


Create new helpers to support bb execbuf3.

Credits-to: Niranjana Vishwanathapura <niranjana.vishwanathapura at intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem at intel.com>
---
 lib/igt_syncobj.h       |   1 +
 lib/intel_batchbuffer.c | 110 +++++++++++++++++++++++++++++++++++++---
 lib/intel_batchbuffer.h |   3 ++
 3 files changed, 108 insertions(+), 6 deletions(-)

diff --git a/lib/igt_syncobj.h b/lib/igt_syncobj.h
index 8a1480a9..f7c79c74 100644
--- a/lib/igt_syncobj.h
+++ b/lib/igt_syncobj.h
@@ -27,6 +27,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <drm.h>
+#include <time.h>
 
 uint32_t syncobj_create(int fd, uint32_t flags);
 void syncobj_destroy(int fd, uint32_t handle);
diff --git a/lib/intel_batchbuffer.c b/lib/intel_batchbuffer.c
index 8311b69e..25ed7316 100644
--- a/lib/intel_batchbuffer.c
+++ b/lib/intel_batchbuffer.c
@@ -38,6 +38,7 @@
 #include "i915/gem_create.h"
 #include "i915/gem_vm.h"
 #include "i915/i915_vm_bind.h"
+#include "igt_syncobj.h"
 #include "intel_batchbuffer.h"
 #include "intel_bufops.h"
 #include "intel_chipset.h"
@@ -201,11 +202,14 @@ fill_object(struct drm_i915_gem_exec_object2 *obj,
 	obj->relocs_ptr = to_user_pointer(relocs);
 }
 
-static uint32_t find_engine(const intel_ctx_cfg_t *cfg, unsigned int class)
+uint32_t intel_bb_find_engine(const intel_ctx_cfg_t *cfg, unsigned int class)
 {
 	unsigned int i;
 	uint32_t engine_id = -1;
 
+	if (!cfg)
+		return 0;
+
 	for (i = 0; i < cfg->num_engines; i++) {
 		if (cfg->engines[i].engine_class == class)
 			engine_id = i;
@@ -226,7 +230,7 @@ static void exec_blit(int fd,
 	uint32_t blt_id = HAS_BLT_RING(devid) ? I915_EXEC_BLT : I915_EXEC_DEFAULT;
 
 	if (cfg)
-		blt_id = find_engine(cfg, I915_ENGINE_CLASS_COPY);
+		blt_id = intel_bb_find_engine(cfg, I915_ENGINE_CLASS_COPY);
 
 	exec = (struct drm_i915_gem_execbuffer2) {
 		.buffers_ptr = to_user_pointer(objs),
@@ -2198,6 +2202,94 @@ void intel_bb_exec(struct intel_bb *ibb, uint32_t end_offset,
 	igt_assert_eq(__intel_bb_exec(ibb, end_offset, flags, sync), 0);
 }
 
+/*
+ * __intel_bb_exec3:
+ * @ibb: pointer to intel_bb
+ * @engine_idx: engine index
+ * @sync: if true wait for execbuf completion, otherwise caller is responsible
+ * to wait for completion
+ *
+ * Returns: 0 on success, otherwise errno.
+ *
+ */
+int __intel_bb_exec3(struct intel_bb *ibb, uint32_t engine_idx, bool sync)
+{
+	struct drm_i915_gem_timeline_fence exec_fence = { };
+	struct drm_i915_gem_execbuffer3 execbuf;
+	struct drm_i915_gem_exec_object2 *objects;
+	uint32_t i;
+	int ret;
+
+	igt_assert(ibb->vm_id);
+	ibb->objects[0]->relocs_ptr = to_user_pointer(ibb->relocs);
+	ibb->objects[0]->relocation_count = ibb->num_relocs;
+	ibb->objects[0]->handle = ibb->handle;
+	ibb->objects[0]->offset = ibb->batch_offset;
+	ibb->objects[0]->rsvd2 = ibb->size;
+
+	gem_write(ibb->i915, ibb->handle, 0, ibb->batch, ibb->size);
+
+	objects = create_objects_array(ibb);
+	for (i = 0; i < ibb->num_objects; i++)
+		i915_vm_bind(ibb->i915, ibb->vm_id, objects[i].offset,
+			     objects[i].handle, 0, objects[i].rsvd2, 0, 0, 0);
+
+	exec_fence.handle = syncobj_create(ibb->i915, 0);
+	exec_fence.flags = I915_TIMELINE_FENCE_SIGNAL;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.ctx_id = ibb->ctx;
+	execbuf.batch_address = ibb->batch_offset;
+	execbuf.engine_idx = engine_idx;
+	execbuf.fence_count = 1;
+	execbuf.timeline_fences = to_user_pointer(&exec_fence);
+
+	if (ibb->dump_base64)
+		intel_bb_dump_base64(ibb, LINELEN);
+
+	ret = __gem_execbuf3(ibb->i915, &execbuf);
+	if (ret) {
+		free(objects);
+		return ret;
+	}
+
+	/* Update addresses in the cache */
+	update_offsets(ibb, objects);
+
+	igt_assert(syncobj_timeline_wait(ibb->i915, &exec_fence.handle, NULL, 1,
+					 gettime_ns() + (2 * NSEC_PER_SEC),
+					 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
+	syncobj_destroy(ibb->i915, exec_fence.handle);
+
+	for (i = 0; i < ibb->num_objects; i++)
+		i915_vm_unbind(ibb->i915, ibb->vm_id, objects[i].offset, objects[i].rsvd2);
+
+	if (ibb->debug) {
+		if (intel_bb_debug_tree) {
+			igt_info("\nTree:\n");
+			twalk(ibb->root, print_node);
+		}
+	}
+
+	free(objects);
+
+	return 0;
+}
+
+/**
+ * intel_bb_exec3:
+ * @ibb: pointer to intel_bb
+ * @engine_idx: engine index
+ * @sync: if true wait for execbuf completion, otherwise caller is responsible
+ * to wait for completion
+ *
+ * Do execbuf3 on context selected during bb creation. Asserts on failure.
+ */
+void intel_bb_exec3(struct intel_bb *ibb, uint32_t engine_idx, bool sync)
+{
+	igt_assert_eq(__intel_bb_exec3(ibb, engine_idx, sync), 0);
+}
+
 /**
  * intel_bb_get_object_address:
  * @ibb: pointer to intel_bb
@@ -2269,8 +2361,14 @@ uint32_t intel_bb_emit_flush_common(struct intel_bb *ibb)
 
 static void intel_bb_exec_with_ring(struct intel_bb *ibb,uint32_t ring)
 {
-	intel_bb_exec(ibb, intel_bb_offset(ibb),
-		      ring | I915_EXEC_NO_RELOC, false);
+	if (ibb->vm_id) {
+		uint32_t engine_idx = intel_bb_find_engine(ibb->cfg, I915_ENGINE_CLASS_RENDER);
+
+		intel_bb_exec3(ibb, engine_idx, false);
+	} else {
+		intel_bb_exec(ibb, intel_bb_offset(ibb),
+			      ring | I915_EXEC_NO_RELOC, false);
+	}
 	intel_bb_reset(ibb, false);
 }
 
@@ -2306,7 +2404,7 @@ void intel_bb_flush_render(struct intel_bb *ibb)
 		return;
 
 	if (has_ctx_cfg(ibb))
-		ring = find_engine(ibb->cfg, I915_ENGINE_CLASS_RENDER);
+		ring = intel_bb_find_engine(ibb->cfg, I915_ENGINE_CLASS_RENDER);
 	else
 		ring = I915_EXEC_RENDER;
 
@@ -2329,7 +2427,7 @@ void intel_bb_flush_blit(struct intel_bb *ibb)
 		return;
 
 	if (has_ctx_cfg(ibb))
-		ring = find_engine(ibb->cfg, I915_ENGINE_CLASS_COPY);
+		ring = intel_bb_find_engine(ibb->cfg, I915_ENGINE_CLASS_COPY);
 	else
 		ring = HAS_BLT_RING(ibb->devid) ? I915_EXEC_BLT : I915_EXEC_DEFAULT;
 
diff --git a/lib/intel_batchbuffer.h b/lib/intel_batchbuffer.h
index 59eda50a..a4d7e21d 100644
--- a/lib/intel_batchbuffer.h
+++ b/lib/intel_batchbuffer.h
@@ -382,6 +382,7 @@ static inline uint32_t intel_bb_pxp_appid(struct intel_bb *ibb)
 	return ibb->pxp.appid;
 }
 
+uint32_t intel_bb_find_engine(const intel_ctx_cfg_t *cfg, unsigned int class);
 struct drm_i915_gem_exec_object2 *
 intel_bb_add_object(struct intel_bb *ibb, uint32_t handle, uint64_t size,
 		    uint64_t offset, uint64_t alignment, bool write);
@@ -442,11 +443,13 @@ uint64_t intel_bb_offset_reloc_to_object(struct intel_bb *ibb,
 
 int __intel_bb_exec(struct intel_bb *ibb, uint32_t end_offset,
 			uint64_t flags, bool sync);
+int __intel_bb_exec3(struct intel_bb *ibb, uint32_t engine_idx, bool sync);
 
 void intel_bb_dump_cache(struct intel_bb *ibb);
 
 void intel_bb_exec(struct intel_bb *ibb, uint32_t end_offset,
 		   uint64_t flags, bool sync);
+void intel_bb_exec3(struct intel_bb *ibb, uint32_t engine_idx, bool sync);
 
 uint64_t intel_bb_get_object_offset(struct intel_bb *ibb, uint32_t handle);
 bool intel_bb_object_offset_to_buf(struct intel_bb *ibb, struct intel_buf *buf);
-- 
2.39.0



More information about the Intel-gfx-trybot mailing list