[Mesa-dev] [PATCH 09/13] i965: Always create the batch with the batch object in the first execobject slot
Chris Wilson
chris at chris-wilson.co.uk
Thu Jul 20 15:37:45 UTC 2017
Quoting Kenneth Graunke (2017-07-19 23:43:04)
> On Wednesday, July 19, 2017 3:09:17 AM PDT Chris Wilson wrote:
> > Even if we are using older kernels that do not accept the batch in the
> > first slot, we can simplify our code by creating the batch with itself
> > in the first slot and moving it to the end on execbuf submission.
> > ---
> > src/mesa/drivers/dri/i965/intel_batchbuffer.c | 70 ++++++++++++---------------
> > 1 file changed, 31 insertions(+), 39 deletions(-)
>
> Alternatively, instead of swapping them out, we could simply add_exec_bo the
> batch at the end, and in execbuffer() do:
>
> if (!use_batch_first) {
> execbuf.buffers_ptr++;
> execbuf.buffers_count--;
> }
>
> to skip over the batchbuffer entry at the beginning. That seems easier...
To do that neatly I thought I would need to break apart execbuffer().
Something like,
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index f88e000b71..729f411be2 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -645,8 +645,14 @@ do_flush_locked(struct brw_context *brw, int in_fence_fd, int *out_fence_fd)
}
}
- if (!brw->screen->no_hw) {
- unsigned int flags;
+ if (ret == 0 && !brw->screen->no_hw) {
+ struct drm_i915_gem_execbuffer2 execbuf = {
+ .buffers_ptr = (uintptr_t) batch->exec_objects,
+ .buffer_count = batch->exec_count,
+ .batch_len = used,
+ /* rsvd1 is actually the context ID */
+ .rsvd1 = batch->ring == RENDER_RING ? brw->hw_ctx : 0;
+ };
/* The requirement for using I915_EXEC_NO_RELOC are:
*
@@ -660,37 +666,63 @@ do_flush_locked(struct brw_context *brw, int in_fence_fd, int *out_fence_fd)
* To avoid stalling, execobject.offset should match the current
* address of that object within the active context.
*/
- flags = I915_EXEC_NO_RELOC;
+ execbuf.flags = I915_EXEC_NO_RELOC;
if (brw->gen >= 6 && batch->ring == BLT_RING) {
- flags |= I915_EXEC_BLT;
+ execbuf.flags |= I915_EXEC_BLT;
} else {
- flags |= I915_EXEC_RENDER;
+ execbuf.flags |= I915_EXEC_RENDER;
}
if (batch->needs_sol_reset)
- flags |= I915_EXEC_GEN7_SOL_RESET;
+ execbuf.flags |= I915_EXEC_GEN7_SOL_RESET;
- struct drm_i915_gem_exec_object2 *exec_object = &batch->exec_objects[0];
+ unsigned int index;
+ if (batch->use_exec_lut) {
+ execbuf.flags |= I915_EXEC_BATCH_FIRST | I915_EXEC_HANDLE_LUT;
+ index = 0;
+ } else {
+ index = add_exec_bo(batch, target);
+ execbuf.buffers_ptr = (uintptr_t) (batch->exec_objects + 1);
+ }
+ struct drm_i915_gem_exec_object2 *exec_object =
+ &batch->exec_objects[index];
assert(exec_object->handle == batch->bo->gem_handle);
exec_object->relocation_count = batch->reloc_count;
exec_object->relocs_ptr = (uintptr_t) batch->relocs;
- if (batch->use_exec_lut) {
- flags |= I915_EXEC_BATCH_FIRST | I915_EXEC_HANDLE_LUT;
- } else {
- struct drm_i915_gem_exec_object2 tmp = *exec_object;
- unsigned int index = batch->exec_count - 1;
- *exec_object = batch->exec_objects[index];
- batch->exec_objects[index] = tmp;
+
+ unsigned long cmd = DRM_IOCTL_I915_GEM_EXECBUFFER2;
+
+ if (in_fence_fd != -1) {
+ execbuf.rsvd2 = in_fence;
+ execbuf.flags |= I915_EXEC_FENCE_IN;
}
- if (ret == 0) {
- uint32_t hw_ctx = batch->ring == RENDER_RING ? brw->hw_ctx : 0;
+ if (out_fence_fd != NULL) {
+ cmd = DRM_IOCTL_I915_GEM_EXECBUFFER2_WR;
+ *out_fence_fd = -1;
+ execbuf.flags |= I915_EXEC_FENCE_OUT;
+ }
+
+ if (drmIoctl(fd, cmd, &execbuf))
+ ret = -errno;
+
+ for (int i = 0; i < batch->exec_count; i++) {
+ struct brw_bo *bo = batch->exec_bos[i];
- ret = execbuffer(dri_screen->fd, batch, hw_ctx,
- 4 * USED_BATCH(*batch),
- in_fence_fd, out_fence_fd, flags);
+ bo->idle = false;
+ bo->index = -1;
+
+ /* Update brw_bo::offset64 */
+ if (batch->exec_objects[i].offset != bo->offset64) {
+ DBG("BO %d migrated: 0x%" PRIx64 " -> 0x%llx\n",
+ bo->gem_handle, bo->offset64, batch->exec_objects[i].offset);
+ bo->offset64 = batch->exec_objects[i].offset;
+ }
}
+ if (ret == 0 && out_fence != NULL)
+ *out_fence = execbuf.rsvd2 >> 32;
+
throttle(brw);
}
More information about the mesa-dev
mailing list