v3d: Only flush jobs that write texture from different job submission.

Avoids flushing jobs that write a texture that is read by a job in the
same job submission.

Now we need to handle the case where a texture is written by the
graphics pipeline and it is read by a compute pipeline.

Before this patch, glTextureBarrier() could be implemented as a NOP in
v3d. So the driver was doing more flushing than needed when
glTextureBarrier was not used.

v2: Use V3D_FLUSH_ALWAYS for resources written by graphics pipeline
    and read by compute insead of V3D_FLUSH_DEFAULT. (Iago Toral)

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27550>
This commit is contained in:
Jose Maria Casanova Crespo 2024-01-17 12:38:15 +01:00 committed by Marge Bot
parent 7cbb47a86f
commit 6f138819f4
6 changed files with 19 additions and 5 deletions

View file

@ -121,7 +121,7 @@ traces:
supertuxkart/supertuxkart-mansion-egl-gles-v2.trace:
broadcom-rpi4:
checksum: b24708141d2642bbdd05274a2104b0d4
checksum: 93fe17a18ab10d862b5a42b4ea05a658
valve/counterstrike-source-v2.trace:
broadcom-rpi4:

View file

@ -195,14 +195,17 @@ v3d_flush_jobs_writing_resource(struct v3d_context *v3d,
struct v3d_resource *rsc = v3d_resource(prsc);
/* We need to sync if graphics pipeline reads a resource written
* by the compute pipeline. The same would be needed for the case of
* graphics-compute dependency but nowadays all compute jobs
* are serialized with the previous submitted job.
* by the compute pipeline. The same is needed for the case of
* graphics-compute dependency but flushing the job.
*/
if (!is_compute_pipeline && rsc->bo != NULL && rsc->compute_written) {
v3d->sync_on_last_compute_job = true;
rsc->compute_written = false;
}
if (is_compute_pipeline && rsc->bo != NULL && rsc->graphics_written) {
flush_cond = V3D_FLUSH_ALWAYS;
rsc->graphics_written = false;
}
if (!entry)
return;

View file

@ -236,6 +236,7 @@ v3d_map_usage_prep(struct pipe_context *pctx,
if (usage & PIPE_MAP_WRITE) {
rsc->writes++;
rsc->graphics_written = true;
rsc->initialized_buffers = ~0;
}
}

View file

@ -100,6 +100,11 @@ struct v3d_resource {
*/
bool compute_written;
/**
* Indicates if the Graphics pipeline has written the resource
*/
bool graphics_written;
/**
* Number of times the resource has been written to.
*

View file

@ -174,7 +174,7 @@ v3d_predraw_check_stage_inputs(struct pipe_context *pctx,
v3d_update_shadow_texture(pctx, &view->base);
v3d_flush_jobs_writing_resource(v3d, view->texture,
V3D_FLUSH_DEFAULT,
V3D_FLUSH_NOT_CURRENT_JOB,
s == PIPE_SHADER_COMPUTE);
}
@ -1026,12 +1026,16 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
u_foreach_bit(i, v3d->ssbo[s].enabled_mask) {
v3d_job_add_write_resource(job,
v3d->ssbo[s].sb[i].buffer);
struct v3d_resource *rsc= v3d_resource(v3d->ssbo[s].sb[i].buffer);
rsc->graphics_written = true;
job->tmu_dirty_rcl = true;
}
u_foreach_bit(i, v3d->shaderimg[s].enabled_mask) {
v3d_job_add_write_resource(job,
v3d->shaderimg[s].si[i].base.resource);
struct v3d_resource *rsc= v3d_resource(v3d->shaderimg[s].si[i].base.resource);
rsc->graphics_written = true;
job->tmu_dirty_rcl = true;
}
}

View file

@ -102,6 +102,7 @@ store_general(struct v3d_job *job,
struct v3d_resource *rsc = v3d_resource(psurf->texture);
rsc->writes++;
rsc->graphics_written = true;
uint32_t layer_offset =
v3d_layer_offset(&rsc->base, psurf->u.tex.level,