v3d: avoid load/store of tile buffer on invalidated framebuffer

With the information of the invalidated framebuffer we avoid the stores
of the results of tile buffer rendering that are not going to be used
again or the loads of the tile buffer when the buffer data can be ignored
as it would be never read.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30341>
This commit is contained in:
Jose Maria Casanova Crespo
2024-07-24 01:43:38 +02:00
committed by Marge Bot
parent 89c6fa1883
commit 6c46890325
4 changed files with 47 additions and 6 deletions

View File

@@ -118,6 +118,7 @@ v3d_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
struct v3d_resource *rsc = v3d_resource(prsc);
rsc->initialized_buffers = 0;
rsc->invalidated = true;
struct hash_entry *entry = _mesa_hash_table_search(v3d->write_jobs,
prsc);
@@ -125,8 +126,17 @@ v3d_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
return;
struct v3d_job *job = entry->data;
if (job->key.zsbuf && job->key.zsbuf->texture == prsc)
if (job->key.zsbuf && job->key.zsbuf->texture == prsc) {
job->store &= ~(PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL);
return;
}
for (int i = 0; i < job->nr_cbufs; i++) {
if (job->cbufs[i] && job->cbufs[i]->texture == prsc) {
job->store &= ~(PIPE_CLEAR_COLOR0 << i);
return;
}
}
}
/**

View File

@@ -448,6 +448,10 @@ struct v3d_job {
* clear.
*/
uint32_t clear_draw;
/* Bitmask of PIPE_CLEAR_* of attached buffers that were invalidated
* by glInvalidateFramebuffer so we can avoid loading them.
*/
uint32_t invalidated_load;
/* Bitmask of PIPE_CLEAR_* of buffers that have been read by a draw
* call without having been cleared first.
*/

View File

@@ -124,6 +124,12 @@ struct v3d_resource {
*/
uint32_t initialized_buffers;
/**
* The resource has been invalidated by glInvalidateFramebuffer so
* it doesn't need to be loaded until another job writes to it.
*/
bool invalidated;
/**
* A serial ID that is incremented every time a new BO is bound to a
* resource. We use this to track scenarios where we might need to

View File

@@ -1357,14 +1357,29 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
u_stream_outputs_for_vertices(info->mode, draws[0].count);
}
uint32_t clear_mask = job->clear_tlb | job->clear_draw;
if (v3d->zsa && job->zsbuf) {
struct v3d_resource *rsc = v3d_resource(job->zsbuf->texture);
if (rsc->invalidated) {
/* Currently gallium only applies invalidates if it
* affects both depth and stencil together.
*/
job->invalidated_load |=
PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL;
rsc->invalidated = false;
if (rsc->separate_stencil)
rsc->separate_stencil->invalidated = false;
}
}
uint32_t no_load_mask =
job->clear_tlb | job->clear_draw | job->invalidated_load;
if (v3d->zsa && job->zsbuf && v3d->zsa->base.depth_enabled) {
struct v3d_resource *rsc = v3d_resource(job->zsbuf->texture);
v3d_job_add_bo(job, rsc->bo);
job->load |= PIPE_CLEAR_DEPTH & ~clear_mask;
job->load |= PIPE_CLEAR_DEPTH & ~no_load_mask;
if (v3d->zsa->base.depth_writemask)
job->store |= PIPE_CLEAR_DEPTH;
rsc->initialized_buffers = PIPE_CLEAR_DEPTH;
rsc->initialized_buffers |= PIPE_CLEAR_DEPTH;
}
if (v3d->zsa && job->zsbuf && v3d->zsa->base.stencil[0].enabled) {
@@ -1374,7 +1389,7 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
v3d_job_add_bo(job, rsc->bo);
job->load |= PIPE_CLEAR_STENCIL & ~clear_mask;
job->load |= PIPE_CLEAR_STENCIL & ~no_load_mask;
if (v3d->zsa->base.stencil[0].writemask ||
v3d->zsa->base.stencil[1].writemask) {
job->store |= PIPE_CLEAR_STENCIL;
@@ -1382,6 +1397,7 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
rsc->initialized_buffers |= PIPE_CLEAR_STENCIL;
}
for (int i = 0; i < job->nr_cbufs; i++) {
uint32_t bit = PIPE_CLEAR_COLOR0 << i;
int blend_rt = v3d->blend->base.independent_blend_enable ? i : 0;
@@ -1390,7 +1406,12 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
continue;
struct v3d_resource *rsc = v3d_resource(job->cbufs[i]->texture);
job->load |= bit & ~clear_mask;
if (rsc->invalidated) {
job->invalidated_load |= bit;
rsc->invalidated = false;
} else {
job->load |= bit & ~no_load_mask;
}
if (v3d->blend->base.rt[blend_rt].colormask)
job->store |= bit;
v3d_job_add_bo(job, rsc->bo);