[Mesa-dev] [PATCH 10/13] i965: Push no_hw down to the execbuf call
Chris Wilson
chris at chris-wilson.co.uk
Wed Jul 19 10:09:18 UTC 2017
For the common path where we want to execute the batch, if we push the
no_hw detection down to the execbuf we can eliminate one loop over all
the execobjects. For the less common path where we don't want to execute
the batch, no_hw was leaving out_fence uninitialised.
Cc: Kenneth Graunke <kenneth at whitecape.org>
Cc: Matt Turner <mattst88 at gmail.com>
---
src/mesa/drivers/dri/i965/intel_batchbuffer.c | 116 +++++++++++++-------------
1 file changed, 56 insertions(+), 60 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index 7f5f240597..59b142cc75 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -438,13 +438,6 @@ static void do_batch_dump(struct brw_context *brw) { }
static void
brw_new_batch(struct brw_context *brw)
{
- /* Unreference any BOs held by the previous batch, and reset counts. */
- for (int i = 0; i < brw->batch.exec_count; i++) {
- if (brw->batch.exec_bos[i] != brw->batch.bo) {
- brw_bo_unreference(brw->batch.exec_bos[i]);
- }
- brw->batch.exec_bos[i] = NULL;
- }
brw->batch.reloc_count = 0;
brw->batch.exec_count = 0;
brw->batch.aperture_space = BATCH_SZ;
@@ -571,21 +564,21 @@ throttle(struct brw_context *brw)
}
static int
-execbuffer(int fd,
- struct intel_batchbuffer *batch,
- uint32_t ctx_id,
- int used,
+execbuffer(struct brw_context *brw,
int in_fence,
int *out_fence,
int flags)
{
+ struct intel_batchbuffer *batch = &brw->batch;
struct drm_i915_gem_execbuffer2 execbuf = {
.buffers_ptr = (uintptr_t) batch->exec_objects,
.buffer_count = batch->exec_count,
.batch_start_offset = 0,
- .batch_len = used,
+ .batch_len = 4 * USED_BATCH(*batch),
.flags = flags,
- .rsvd1 = ctx_id, /* rsvd1 is actually the context ID */
+
+ /* rsvd1 is actually the context ID */
+ .rsvd1 = batch->ring == RENDER_RING ? brw->hw_ctx : 0,
};
unsigned long cmd = DRM_IOCTL_I915_GEM_EXECBUFFER2;
@@ -601,9 +594,14 @@ execbuffer(int fd,
execbuf.flags |= I915_EXEC_FENCE_OUT;
}
- int ret = drmIoctl(fd, cmd, &execbuf);
- if (ret != 0)
- ret = -errno;
+ int ret = 0;
+ if (likely(!brw->screen->no_hw)) {
+ __DRIscreen *dri_screen = brw->screen->driScrnPriv;
+ if (unlikely(drmIoctl(dri_screen->fd, cmd, &execbuf)))
+ ret = -errno;
+ } else {
+ out_fence = NULL;
+ }
for (int i = 0; i < batch->exec_count; i++) {
struct brw_bo *bo = batch->exec_bos[i];
@@ -617,6 +615,11 @@ execbuffer(int fd,
bo->gem_handle, bo->offset64, batch->exec_objects[i].offset);
bo->offset64 = batch->exec_objects[i].offset;
}
+
+ if (batch->exec_bos[i] != batch->bo) {
+ brw_bo_unreference(batch->exec_bos[i]);
+ }
+ batch->exec_bos[i] = NULL;
}
if (ret == 0 && out_fence != NULL)
@@ -628,7 +631,6 @@ execbuffer(int fd,
static int
do_flush_locked(struct brw_context *brw, int in_fence_fd, int *out_fence_fd)
{
- __DRIscreen *dri_screen = brw->screen->driScrnPriv;
struct intel_batchbuffer *batch = &brw->batch;
int ret = 0;
@@ -644,55 +646,49 @@ do_flush_locked(struct brw_context *brw, int in_fence_fd, int *out_fence_fd)
}
}
- if (!brw->screen->no_hw) {
- unsigned int flags;
-
- /* The requirement for using I915_EXEC_NO_RELOC are:
- *
- * The addresses written in the objects must match the corresponding
- * reloc.presumed_offset which in turn must match the corresponding
- * execobject.offset.
- *
- * Any render targets written to in the batch must be flagged with
- * EXEC_OBJECT_WRITE.
- *
- * To avoid stalling, execobject.offset should match the current
- * address of that object within the active context.
- */
- flags = I915_EXEC_NO_RELOC;
- if (brw->gen >= 6 && batch->ring == BLT_RING) {
- flags |= I915_EXEC_BLT;
- } else {
- flags |= I915_EXEC_RENDER;
- }
+ unsigned int flags;
- if (batch->needs_sol_reset)
- flags |= I915_EXEC_GEN7_SOL_RESET;
-
- struct drm_i915_gem_exec_object2 *exec = &batch->exec_objects[0];
- assert(exec->handle == batch->bo->gem_handle);
- exec->relocation_count = batch->reloc_count;
- exec->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;
- unsigned int index = batch->exec_count - 1;
- *exec = batch->exec_objects[index];
- batch->exec_objects[index] = tmp;
- }
+ /* The requirement for using I915_EXEC_NO_RELOC are:
+ *
+ * The addresses written in the objects must match the corresponding
+ * reloc.presumed_offset which in turn must match the corresponding
+ * execobject.offset.
+ *
+ * Any render targets written to in the batch must be flagged with
+ * EXEC_OBJECT_WRITE.
+ *
+ * To avoid stalling, execobject.offset should match the current
+ * address of that object within the active context.
+ */
+ flags = I915_EXEC_NO_RELOC;
+ if (brw->gen >= 6 && batch->ring == BLT_RING) {
+ flags |= I915_EXEC_BLT;
+ } else {
+ flags |= I915_EXEC_RENDER;
+ }
- if (ret == 0) {
- uint32_t hw_ctx = batch->ring == RENDER_RING ? brw->hw_ctx : 0;
+ if (batch->needs_sol_reset)
+ flags |= I915_EXEC_GEN7_SOL_RESET;
- ret = execbuffer(dri_screen->fd, batch, hw_ctx,
- 4 * USED_BATCH(*batch),
- in_fence_fd, out_fence_fd, flags);
- }
+ struct drm_i915_gem_exec_object2 *exec = &batch->exec_objects[0];
+ assert(exec->handle == batch->bo->gem_handle);
+ exec->relocation_count = batch->reloc_count;
+ exec->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;
+ unsigned int index = batch->exec_count - 1;
+ *exec = batch->exec_objects[index];
+ batch->exec_objects[index] = tmp;
+ }
- throttle(brw);
+ if (ret == 0) {
+ ret = execbuffer(brw, in_fence_fd, out_fence_fd, flags);
}
+ throttle(brw);
+
if (unlikely(INTEL_DEBUG & DEBUG_BATCH))
do_batch_dump(brw);
--
2.13.3
More information about the mesa-dev
mailing list