v3d: skip tlb loads when emitting clears with a draw call

We skip loading the tile buffer from memory if the job has flagged
a clear (job->clears) for the buffer, however, this only tracks
clears emitted via the TLB. In some cases we may need to fallback
to clearing with a draw call, in which case we also want to skip
the load.

Reviewed-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30205>
This commit is contained in:
Iago Toral Quiroga
2024-07-16 10:04:41 +02:00
committed by Marge Bot
parent c9f26a9995
commit 4e19c139de
2 changed files with 18 additions and 5 deletions

View File

@@ -432,6 +432,11 @@ struct v3d_job {
* first rendering.
*/
uint32_t clear;
/* Bitmask of PIPE_CLEAR_* of buffers that were cleared using a draw
* call (not necessarily before the first rendering) instead of a TLB
* clear.
*/
uint32_t clear_draw;
/* Bitmask of PIPE_CLEAR_* of buffers that have been read by a draw
* call without having been cleared first.
*/

View File

@@ -1357,11 +1357,11 @@ 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 | job->clear_draw;
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 & ~job->clear;
job->load |= PIPE_CLEAR_DEPTH & ~clear_mask;
if (v3d->zsa->base.depth_writemask)
job->store |= PIPE_CLEAR_DEPTH;
rsc->initialized_buffers = PIPE_CLEAR_DEPTH;
@@ -1374,7 +1374,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 & ~job->clear;
job->load |= PIPE_CLEAR_STENCIL & ~clear_mask;
if (v3d->zsa->base.stencil[0].writemask ||
v3d->zsa->base.stencil[1].writemask) {
job->store |= PIPE_CLEAR_STENCIL;
@@ -1390,7 +1390,7 @@ 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 & ~job->clear;
job->load |= bit & ~clear_mask;
if (v3d->blend->base.rt[blend_rt].colormask)
job->store |= bit;
v3d_job_add_bo(job, rsc->bo);
@@ -1619,10 +1619,18 @@ v3d_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
*/
static void
v3d_draw_clear(struct v3d_context *v3d,
struct v3d_job *job,
unsigned buffers,
const union pipe_color_union *color,
double depth, unsigned stencil)
{
/* Flag we are clearing these buffers with a draw call so we can
* skip loads for them. Notice that if we had emitted any draw calls
* before this clear the loads will still happen, since those previous
* draw calls would have flagged them.
*/
job->clear_draw |= buffers;
v3d_blitter_save(v3d, false, true);
util_blitter_clear(v3d->blitter,
v3d->framebuffer.width,
@@ -1770,7 +1778,7 @@ v3d_clear(struct pipe_context *pctx, unsigned buffers, const struct pipe_scissor
if (!buffers || !v3d_render_condition_check(v3d))
return;
v3d_draw_clear(v3d, buffers, color, depth, stencil);
v3d_draw_clear(v3d, job, buffers, color, depth, stencil);
}
static void