[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