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 <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35042>
This commit is contained in:
Jose Maria Casanova Crespo 2025-05-18 14:46:43 +02:00 committed by Marge Bot
parent 45367643f6
commit 6ff509593c
3 changed files with 22 additions and 3 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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)