[Intel-gfx] [PATCH 16/21] i965: Add explicit fence tracking to batch flush

Chris Wilson chris at chris-wilson.co.uk
Thu Aug 25 09:08:34 UTC 2016


Wire up the infrastructure to pass in and receive back a file descriptor
describing a fence (a sync_file object in the kernel) associated with
the batch. Fences can be passed in that the GPU must wait for before
executing the batch. Ideally those waits with neither block the client
nor the GPU from performing other tasks until the fences are signaled.
All batches submitted after this are only executed after the first batch,
the GL command stream is always ordered. Furthermore, the client can
request a fence associated with this point in the GL command stream that
can be passed to others (and used to serialise other GL command
streams). See EGL_ANDROID_native_fence_sync.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 src/mesa/drivers/dri/i965/brw_context.h       |  2 ++
 src/mesa/drivers/dri/i965/intel_batchbuffer.c | 29 ++++++++++++++++++---------
 src/mesa/drivers/dri/i965/intel_batchbuffer.h |  7 +++++--
 3 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 33a919b..f2dd164 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -625,6 +625,8 @@ struct intel_batchbuffer {
    uint32_t *cpu_map;
 #define BATCH_SZ (8192*sizeof(uint32_t))
 
+   int fence; /* fd to array of fences to wait on before GPU executes batch */
+
    uint32_t state_batch_offset;
    enum brw_gpu_ring ring;
    bool needs_sol_reset;
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index caa33f8..d60f95b 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -41,6 +41,8 @@ intel_batchbuffer_reset(struct brw_context *brw);
 void
 intel_batchbuffer_init(struct brw_context *brw)
 {
+   brw->batch.fence = -1;
+
    intel_batchbuffer_reset(brw);
 
    if (!brw->has_llc) {
@@ -59,6 +61,11 @@ intel_batchbuffer_reset(struct brw_context *brw)
    }
    brw->batch.last_bo = brw->batch.bo;
 
+   if (brw->batch.fence != -1) {
+      close(brw->batch.fence);
+      brw->batch.fence = -1;
+   }
+
    brw_render_cache_set_clear(brw);
 
    brw->batch.bo = drm_intel_bo_alloc(brw->bufmgr, "batchbuffer",
@@ -101,6 +108,9 @@ intel_batchbuffer_reset_to_saved(struct brw_context *brw)
 void
 intel_batchbuffer_free(struct brw_context *brw)
 {
+   if (brw->batch.fence != -1)
+      close(brw->batch.fence);
+
    free(brw->batch.cpu_map);
    drm_intel_bo_unreference(brw->batch.last_bo);
    drm_intel_bo_unreference(brw->batch.bo);
@@ -319,7 +329,7 @@ throttle(struct brw_context *brw)
 /* TODO: Push this whole function into bufmgr.
  */
 static int
-do_flush_locked(struct brw_context *brw)
+do_flush_locked(struct brw_context *brw, int *out_fence)
 {
    struct intel_batchbuffer *batch = &brw->batch;
    int ret = 0;
@@ -337,11 +347,14 @@ do_flush_locked(struct brw_context *brw)
    }
 
    if (!brw->intelScreen->no_hw) {
+      drm_intel_context *ctx;
       int flags;
 
       if (brw->gen >= 6 && batch->ring == BLT_RING) {
+         ctx = NULL;
          flags = I915_EXEC_BLT;
       } else {
+         ctx = brw->hw_ctx;
          flags = I915_EXEC_RENDER |
             (brw->use_resource_streamer ? I915_EXEC_RESOURCE_STREAMER : 0);
       }
@@ -352,13 +365,10 @@ do_flush_locked(struct brw_context *brw)
          if (unlikely(INTEL_DEBUG & DEBUG_AUB))
             brw_annotate_aub(brw);
 
-	 if (brw->hw_ctx == NULL || batch->ring != RENDER_RING) {
-            ret = drm_intel_bo_mrb_exec(batch->bo, 4 * USED_BATCH(*batch),
-                                        NULL, 0, 0, flags);
-	 } else {
-	    ret = drm_intel_gem_bo_context_exec(batch->bo, brw->hw_ctx,
-                                                4 * USED_BATCH(*batch), flags);
-	 }
+         ret = drm_intel_gem_bo_fence_exec(batch->bo, ctx,
+                                           4 * USED_BATCH(*batch),
+                                           batch->fence, out_fence,
+                                           flags);
       }
 
       throttle(brw);
@@ -380,6 +390,7 @@ do_flush_locked(struct brw_context *brw)
 
 int
 _intel_batchbuffer_flush(struct brw_context *brw,
+			 int *out_fence,
 			 const char *file, int line)
 {
    int ret;
@@ -419,7 +430,7 @@ _intel_batchbuffer_flush(struct brw_context *brw,
    /* Check that we didn't just wrap our batchbuffer at a bad time. */
    assert(!brw->no_batch_wrap);
 
-   ret = do_flush_locked(brw);
+   ret = do_flush_locked(brw, out_fence);
 
    if (unlikely(INTEL_DEBUG & DEBUG_SYNC)) {
       fprintf(stderr, "waiting for idle\n");
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.h b/src/mesa/drivers/dri/i965/intel_batchbuffer.h
index fbb5158..e966d7a 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.h
@@ -46,11 +46,14 @@ void intel_batchbuffer_reset_to_saved(struct brw_context *brw);
 void intel_batchbuffer_require_space(struct brw_context *brw, GLuint sz,
                                      enum brw_gpu_ring ring);
 
-int _intel_batchbuffer_flush(struct brw_context *brw,
+int _intel_batchbuffer_flush(struct brw_context *brw, int *out_fence,
 			     const char *file, int line);
 
 #define intel_batchbuffer_flush(intel) \
-	_intel_batchbuffer_flush(intel, __FILE__, __LINE__)
+	_intel_batchbuffer_flush(intel, NULL, __FILE__, __LINE__)
+
+#define intel_batchbuffer_flush_fence(intel, fence) \
+	_intel_batchbuffer_flush(intel, fence, __FILE__, __LINE__)
 
 
 
-- 
2.9.3



More information about the Intel-gfx mailing list