mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 20:00:10 +01:00
freedreno: avoid no-op flushes by re-using last-fence
Noticed that with webgl (in chromium, at least) we end up generating a lot of no-op submits just to get a fence. Tracking the last fence and returning that if there is no rendering since last flush avoids this. Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
01194cd582
commit
ddb7fadaf8
5 changed files with 34 additions and 2 deletions
|
|
@ -28,6 +28,7 @@
|
|||
#include "util/u_dump.h"
|
||||
|
||||
#include "freedreno_blitter.h"
|
||||
#include "freedreno_fence.h"
|
||||
#include "freedreno_resource.h"
|
||||
|
||||
#include "fd6_blitter.h"
|
||||
|
|
@ -486,6 +487,8 @@ fd6_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
|
|||
return;
|
||||
}
|
||||
|
||||
fd_fence_ref(pctx->screen, &ctx->last_fence, NULL);
|
||||
|
||||
batch = fd_bc_alloc_batch(&ctx->screen->batch_cache, ctx, true);
|
||||
|
||||
fd6_emit_restore(batch, batch->draw);
|
||||
|
|
|
|||
|
|
@ -49,14 +49,24 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep,
|
|||
|
||||
DBG("%p: flush: flags=%x\n", ctx->batch, flags);
|
||||
|
||||
/* if no rendering since last flush, ie. app just decided it needed
|
||||
* a fence, re-use the last one:
|
||||
*/
|
||||
if (ctx->last_fence) {
|
||||
fd_fence_ref(pctx->screen, &fence, ctx->last_fence);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!batch)
|
||||
return;
|
||||
|
||||
/* Take a ref to the batch's fence (batch can be unref'd when flushed: */
|
||||
fd_fence_ref(pctx->screen, &fence, batch->fence);
|
||||
|
||||
if (flags & PIPE_FLUSH_FENCE_FD)
|
||||
batch->needs_out_fence_fd = true;
|
||||
/* TODO is it worth trying to figure out if app is using fence-fd's, to
|
||||
* avoid requesting one every batch?
|
||||
*/
|
||||
batch->needs_out_fence_fd = true;
|
||||
|
||||
if (!ctx->screen->reorder) {
|
||||
fd_batch_flush(batch, true, false);
|
||||
|
|
@ -66,9 +76,12 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep,
|
|||
fd_bc_flush(&ctx->screen->batch_cache, ctx);
|
||||
}
|
||||
|
||||
out:
|
||||
if (fencep)
|
||||
fd_fence_ref(pctx->screen, fencep, fence);
|
||||
|
||||
fd_fence_ref(pctx->screen, &ctx->last_fence, fence);
|
||||
|
||||
fd_fence_ref(pctx->screen, &fence, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -137,6 +150,8 @@ fd_context_destroy(struct pipe_context *pctx)
|
|||
|
||||
DBG("");
|
||||
|
||||
fd_fence_ref(pctx->screen, &ctx->last_fence, NULL);
|
||||
|
||||
if (ctx->screen->reorder && util_queue_is_initialized(&ctx->flush_queue))
|
||||
util_queue_destroy(&ctx->flush_queue);
|
||||
|
||||
|
|
|
|||
|
|
@ -230,6 +230,12 @@ struct fd_context {
|
|||
*/
|
||||
struct fd_batch *batch;
|
||||
|
||||
/* NULL if there has been rendering since last flush. Otherwise
|
||||
* keeps a reference to the last fence so we can re-use it rather
|
||||
* than having to flush no-op batch.
|
||||
*/
|
||||
struct pipe_fence_handle *last_fence;
|
||||
|
||||
/* Are we in process of shadowing a resource? Used to detect recursion
|
||||
* in transfer_map, and skip unneeded synchronization.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "freedreno_draw.h"
|
||||
#include "freedreno_context.h"
|
||||
#include "freedreno_fence.h"
|
||||
#include "freedreno_state.h"
|
||||
#include "freedreno_resource.h"
|
||||
#include "freedreno_query_acc.h"
|
||||
|
|
@ -98,6 +99,8 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
|||
return;
|
||||
}
|
||||
|
||||
fd_fence_ref(pctx->screen, &ctx->last_fence, NULL);
|
||||
|
||||
/* Upload a user index buffer. */
|
||||
struct pipe_resource *indexbuf = NULL;
|
||||
unsigned index_offset = 0;
|
||||
|
|
@ -382,6 +385,8 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
|
|||
if (!fd_render_condition_check(pctx))
|
||||
return;
|
||||
|
||||
fd_fence_ref(pctx->screen, &ctx->last_fence, NULL);
|
||||
|
||||
if (ctx->in_blit) {
|
||||
fd_batch_reset(batch);
|
||||
fd_context_all_dirty(ctx);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "freedreno_resource.h"
|
||||
#include "freedreno_batch_cache.h"
|
||||
#include "freedreno_fence.h"
|
||||
#include "freedreno_screen.h"
|
||||
#include "freedreno_surface.h"
|
||||
#include "freedreno_context.h"
|
||||
|
|
@ -1070,6 +1071,8 @@ void
|
|||
fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond, bool discard,
|
||||
enum fd_render_stage stage)
|
||||
{
|
||||
fd_fence_ref(ctx->base.screen, &ctx->last_fence, NULL);
|
||||
|
||||
util_blitter_save_fragment_constant_buffer_slot(ctx->blitter,
|
||||
ctx->constbuf[PIPE_SHADER_FRAGMENT].cb);
|
||||
util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vtx.vertexbuf.vb);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue