mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 22:10: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 "util/u_dump.h"
|
||||||
|
|
||||||
#include "freedreno_blitter.h"
|
#include "freedreno_blitter.h"
|
||||||
|
#include "freedreno_fence.h"
|
||||||
#include "freedreno_resource.h"
|
#include "freedreno_resource.h"
|
||||||
|
|
||||||
#include "fd6_blitter.h"
|
#include "fd6_blitter.h"
|
||||||
|
|
@ -486,6 +487,8 @@ fd6_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd_fence_ref(pctx->screen, &ctx->last_fence, NULL);
|
||||||
|
|
||||||
batch = fd_bc_alloc_batch(&ctx->screen->batch_cache, ctx, true);
|
batch = fd_bc_alloc_batch(&ctx->screen->batch_cache, ctx, true);
|
||||||
|
|
||||||
fd6_emit_restore(batch, batch->draw);
|
fd6_emit_restore(batch, batch->draw);
|
||||||
|
|
|
||||||
|
|
@ -49,13 +49,23 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep,
|
||||||
|
|
||||||
DBG("%p: flush: flags=%x\n", ctx->batch, flags);
|
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)
|
if (!batch)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Take a ref to the batch's fence (batch can be unref'd when flushed: */
|
/* Take a ref to the batch's fence (batch can be unref'd when flushed: */
|
||||||
fd_fence_ref(pctx->screen, &fence, batch->fence);
|
fd_fence_ref(pctx->screen, &fence, batch->fence);
|
||||||
|
|
||||||
if (flags & PIPE_FLUSH_FENCE_FD)
|
/* 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;
|
batch->needs_out_fence_fd = true;
|
||||||
|
|
||||||
if (!ctx->screen->reorder) {
|
if (!ctx->screen->reorder) {
|
||||||
|
|
@ -66,9 +76,12 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep,
|
||||||
fd_bc_flush(&ctx->screen->batch_cache, ctx);
|
fd_bc_flush(&ctx->screen->batch_cache, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
if (fencep)
|
if (fencep)
|
||||||
fd_fence_ref(pctx->screen, fencep, fence);
|
fd_fence_ref(pctx->screen, fencep, fence);
|
||||||
|
|
||||||
|
fd_fence_ref(pctx->screen, &ctx->last_fence, fence);
|
||||||
|
|
||||||
fd_fence_ref(pctx->screen, &fence, NULL);
|
fd_fence_ref(pctx->screen, &fence, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,6 +150,8 @@ fd_context_destroy(struct pipe_context *pctx)
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
|
fd_fence_ref(pctx->screen, &ctx->last_fence, NULL);
|
||||||
|
|
||||||
if (ctx->screen->reorder && util_queue_is_initialized(&ctx->flush_queue))
|
if (ctx->screen->reorder && util_queue_is_initialized(&ctx->flush_queue))
|
||||||
util_queue_destroy(&ctx->flush_queue);
|
util_queue_destroy(&ctx->flush_queue);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,12 @@ struct fd_context {
|
||||||
*/
|
*/
|
||||||
struct fd_batch *batch;
|
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
|
/* Are we in process of shadowing a resource? Used to detect recursion
|
||||||
* in transfer_map, and skip unneeded synchronization.
|
* in transfer_map, and skip unneeded synchronization.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include "freedreno_draw.h"
|
#include "freedreno_draw.h"
|
||||||
#include "freedreno_context.h"
|
#include "freedreno_context.h"
|
||||||
|
#include "freedreno_fence.h"
|
||||||
#include "freedreno_state.h"
|
#include "freedreno_state.h"
|
||||||
#include "freedreno_resource.h"
|
#include "freedreno_resource.h"
|
||||||
#include "freedreno_query_acc.h"
|
#include "freedreno_query_acc.h"
|
||||||
|
|
@ -98,6 +99,8 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd_fence_ref(pctx->screen, &ctx->last_fence, NULL);
|
||||||
|
|
||||||
/* Upload a user index buffer. */
|
/* Upload a user index buffer. */
|
||||||
struct pipe_resource *indexbuf = NULL;
|
struct pipe_resource *indexbuf = NULL;
|
||||||
unsigned index_offset = 0;
|
unsigned index_offset = 0;
|
||||||
|
|
@ -382,6 +385,8 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
|
||||||
if (!fd_render_condition_check(pctx))
|
if (!fd_render_condition_check(pctx))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
fd_fence_ref(pctx->screen, &ctx->last_fence, NULL);
|
||||||
|
|
||||||
if (ctx->in_blit) {
|
if (ctx->in_blit) {
|
||||||
fd_batch_reset(batch);
|
fd_batch_reset(batch);
|
||||||
fd_context_all_dirty(ctx);
|
fd_context_all_dirty(ctx);
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include "freedreno_resource.h"
|
#include "freedreno_resource.h"
|
||||||
#include "freedreno_batch_cache.h"
|
#include "freedreno_batch_cache.h"
|
||||||
|
#include "freedreno_fence.h"
|
||||||
#include "freedreno_screen.h"
|
#include "freedreno_screen.h"
|
||||||
#include "freedreno_surface.h"
|
#include "freedreno_surface.h"
|
||||||
#include "freedreno_context.h"
|
#include "freedreno_context.h"
|
||||||
|
|
@ -1070,6 +1071,8 @@ void
|
||||||
fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond, bool discard,
|
fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond, bool discard,
|
||||||
enum fd_render_stage stage)
|
enum fd_render_stage stage)
|
||||||
{
|
{
|
||||||
|
fd_fence_ref(ctx->base.screen, &ctx->last_fence, NULL);
|
||||||
|
|
||||||
util_blitter_save_fragment_constant_buffer_slot(ctx->blitter,
|
util_blitter_save_fragment_constant_buffer_slot(ctx->blitter,
|
||||||
ctx->constbuf[PIPE_SHADER_FRAGMENT].cb);
|
ctx->constbuf[PIPE_SHADER_FRAGMENT].cb);
|
||||||
util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vtx.vertexbuf.vb);
|
util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vtx.vertexbuf.vb);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue