From 6ff509593ced88feec810aa653cf727da8629758 Mon Sep 17 00:00:00 2001 From: Jose Maria Casanova Crespo Date: Sun, 18 May 2025 14:46:43 +0200 Subject: [PATCH] v3d: Only apply TLB load invalidation on first job after FB state update Mark when at least one job for the current active FBO has already been submitted since the last framebuffer state update. With this we can apply TLB load invalidation only to the first job that is submitted to the same FBO. Not applying TLB loads invalidation on follow-up jobs targeting the same framebuffer state. With this we avoid doing incorrect invalidations when we force a job submission for a reason not related with a new framebuffer bind. Cc: mesa-stable Reviewed-by: Iago Toral Quiroga Part-of: --- src/gallium/drivers/v3d/v3d_context.h | 7 +++++++ src/gallium/drivers/v3d/v3d_job.c | 16 +++++++++++++--- src/gallium/drivers/v3d/v3dx_state.c | 2 ++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h index 04bd66435d5..a557364dfde 100644 --- a/src/gallium/drivers/v3d/v3d_context.h +++ b/src/gallium/drivers/v3d/v3d_context.h @@ -636,6 +636,13 @@ struct v3d_context { unsigned sample_mask; struct pipe_framebuffer_state framebuffer; + /* Flags if we have submitted any jobs for the current framebuffer so + * we can make skip framebuffer invalidation for cases where we had to + * split the command list into multiple jobs for the same frame (i.e. + * queries, reaching CL size limits of any kind, etc.). + */ + bool submitted_any_jobs_for_current_fbo; + /* Per render target, whether we should swap the R and B fields in the * shader's color output and in blending. If render targets disagree * on the R/B swap and use the constant color, then we would need to diff --git a/src/gallium/drivers/v3d/v3d_job.c b/src/gallium/drivers/v3d/v3d_job.c index d68b0b8fcbb..3adb3f73f46 100644 --- a/src/gallium/drivers/v3d/v3d_job.c +++ b/src/gallium/drivers/v3d/v3d_job.c @@ -443,7 +443,11 @@ v3d_get_job_for_fbo(struct v3d_context *v3d) struct v3d_resource *rsc = v3d_resource(cbufs[i].texture); if (!rsc->writes) job->clear_tlb |= PIPE_CLEAR_COLOR0 << i; - if (rsc->invalidated) { + /* Loads invalidations only applies to the first job + * submitted after a framebuffer state update + */ + if (rsc->invalidated && + !v3d->submitted_any_jobs_for_current_fbo) { job->invalidated_load |= PIPE_CLEAR_COLOR0 << i; rsc->invalidated = false; } @@ -460,11 +464,15 @@ v3d_get_job_for_fbo(struct v3d_context *v3d) if (!rsc->writes) job->clear_tlb |= PIPE_CLEAR_STENCIL; - if (rsc->invalidated) { + /* Loads invalidations only applies to the first job submitted + * after a framebuffer state update + */ + if (rsc->invalidated && + !v3d->submitted_any_jobs_for_current_fbo) { /* Currently gallium only applies invalidates if it * affects both depth and stencil together. */ - job->invalidated_load |= + job->invalidated_load |= PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL; rsc->invalidated = false; if (rsc->separate_stencil) @@ -757,6 +765,8 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job) } done: + if (v3d->job == job) + v3d->submitted_any_jobs_for_current_fbo = true; v3d_job_free(v3d, job); } diff --git a/src/gallium/drivers/v3d/v3dx_state.c b/src/gallium/drivers/v3d/v3dx_state.c index 87aa99c43c1..f0b17231f8a 100644 --- a/src/gallium/drivers/v3d/v3dx_state.c +++ b/src/gallium/drivers/v3d/v3dx_state.c @@ -523,6 +523,8 @@ v3d_set_framebuffer_state(struct pipe_context *pctx, v3d->swap_color_rb = 0; v3d->blend_dst_alpha_one = 0; + v3d->submitted_any_jobs_for_current_fbo = false; + for (int i = 0; i < v3d->framebuffer.nr_cbufs; i++) { const struct pipe_surface *cbuf = &v3d->framebuffer.cbufs[i]; if (!cbuf->texture)