Module: Mesa
Branch: master
Commit: 534917495dca07bb63dbec49450c706fce36f176
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=534917495dca07bb63dbec49450c706fce36f176

Author: Rob Clark <robdcl...@gmail.com>
Date:   Wed Oct 12 10:42:57 2016 -0400

freedreno: no-op render when we need a fence

If app tries to create a fence but there is no rendering to submit, we
need a dummy/no-op submit.  Use a string-marker for the purpose.. mostly
since it avoids needing to realize that the packet format changes in
later gen's (so one less place to fixup for a5xx).

Signed-off-by: Rob Clark <robdcl...@gmail.com>

---

 src/gallium/drivers/freedreno/freedreno_context.c | 11 ++++++-
 src/gallium/drivers/freedreno/freedreno_gmem.c    | 35 +++++++++++++++++++----
 src/gallium/drivers/freedreno/freedreno_gmem.h    |  1 +
 3 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/freedreno/freedreno_context.c 
b/src/gallium/drivers/freedreno/freedreno_context.c
index 0364507..1128d91 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.c
+++ b/src/gallium/drivers/freedreno/freedreno_context.c
@@ -53,8 +53,17 @@ fd_context_flush(struct pipe_context *pctx, struct 
pipe_fence_handle **fence,
                fd_bc_flush(&ctx->screen->batch_cache, ctx);
        }
 
-       if (fence)
+       if (fence) {
+               /* if there hasn't been any rendering submitted yet, we might 
not
+                * have actually created a fence
+                */
+               if (!ctx->last_fence || ctx->batch->needs_out_fence_fd) {
+                       ctx->batch->needs_flush = true;
+                       fd_gmem_render_noop(ctx->batch);
+                       fd_batch_reset(ctx->batch);
+               }
                fd_fence_ref(pctx->screen, fence, ctx->last_fence);
+       }
 }
 
 /**
diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c 
b/src/gallium/drivers/freedreno/freedreno_gmem.c
index 69fb16d..aeccebd 100644
--- a/src/gallium/drivers/freedreno/freedreno_gmem.c
+++ b/src/gallium/drivers/freedreno/freedreno_gmem.c
@@ -359,6 +359,20 @@ render_sysmem(struct fd_batch *batch)
        fd_reset_wfi(batch);
 }
 
+static void
+flush_ring(struct fd_batch *batch)
+{
+       struct fd_context *ctx = batch->ctx;
+       int out_fence_fd = -1;
+
+       fd_ringbuffer_flush2(batch->gmem, batch->in_fence_fd,
+                       batch->needs_out_fence_fd ? &out_fence_fd : NULL);
+
+       fd_fence_ref(&ctx->screen->base, &ctx->last_fence, NULL);
+       ctx->last_fence = fd_fence_create(ctx,
+                       fd_ringbuffer_timestamp(batch->gmem), out_fence_fd);
+}
+
 void
 fd_gmem_render_tiles(struct fd_batch *batch)
 {
@@ -399,13 +413,22 @@ fd_gmem_render_tiles(struct fd_batch *batch)
                ctx->stats.batch_gmem++;
        }
 
-       int out_fence_fd = -1;
-       fd_ringbuffer_flush2(batch->gmem, batch->in_fence_fd,
-                       batch->needs_out_fence_fd ? &out_fence_fd : NULL);
+       flush_ring(batch);
+}
 
-       fd_fence_ref(&ctx->screen->base, &ctx->last_fence, NULL);
-       ctx->last_fence = fd_fence_create(ctx,
-                       fd_ringbuffer_timestamp(batch->gmem), out_fence_fd);
+/* special case for when we need to create a fence but have no rendering
+ * to flush.. just emit a no-op string-marker packet.
+ */
+void
+fd_gmem_render_noop(struct fd_batch *batch)
+{
+       struct fd_context *ctx = batch->ctx;
+       struct pipe_context *pctx = &ctx->base;
+
+       pctx->emit_string_marker(pctx, "noop", 4);
+       /* emit IB to drawcmds (which contain the string marker): */
+       ctx->emit_ib(batch->gmem, batch->draw);
+       flush_ring(batch);
 }
 
 /* tile needs restore if it isn't completely contained within the
diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.h 
b/src/gallium/drivers/freedreno/freedreno_gmem.h
index 116423a..6598ea9 100644
--- a/src/gallium/drivers/freedreno/freedreno_gmem.h
+++ b/src/gallium/drivers/freedreno/freedreno_gmem.h
@@ -62,6 +62,7 @@ struct fd_gmem_stateobj {
 struct fd_batch;
 
 void fd_gmem_render_tiles(struct fd_batch *batch);
+void fd_gmem_render_noop(struct fd_batch *batch);
 
 bool fd_gmem_needs_restore(struct fd_batch *batch, struct fd_tile *tile,
                uint32_t buffers);

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to