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)