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 <robdclark@gmail.com>
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user