diff options
-rw-r--r-- | .pick_status.json | 2 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_blit.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_context.h | 12 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_job.c | 30 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_resource.c | 14 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_resource.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3dx_draw.c | 32 |
7 files changed, 77 insertions, 26 deletions
diff --git a/.pick_status.json b/.pick_status.json index b6cab30e5af..60091dfca91 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -4,7 +4,7 @@ "description": "v3d: Sync on last CS when non-compute stage uses resource written by CS", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": null }, diff --git a/src/gallium/drivers/v3d/v3d_blit.c b/src/gallium/drivers/v3d/v3d_blit.c index 6c69f00b704..2a743a1a954 100644 --- a/src/gallium/drivers/v3d/v3d_blit.c +++ b/src/gallium/drivers/v3d/v3d_blit.c @@ -128,7 +128,7 @@ v3d_tile_blit(struct pipe_context *pctx, const struct pipe_blit_info *info) struct pipe_surface *src_surf = v3d_get_blit_surface(pctx, info->src.resource, info->src.level); - v3d_flush_jobs_reading_resource(v3d, info->src.resource); + v3d_flush_jobs_reading_resource(v3d, info->src.resource, false); struct v3d_job *job = v3d_get_job(v3d, dst_surf, NULL); pipe_surface_reference(&job->color_read, src_surf); @@ -380,8 +380,8 @@ v3d_tfu(struct pipe_context *pctx, if (dst_base_slice->tiling == VC5_TILING_RASTER) return false; - v3d_flush_jobs_writing_resource(v3d, psrc, V3D_FLUSH_DEFAULT); - v3d_flush_jobs_reading_resource(v3d, pdst, V3D_FLUSH_DEFAULT); + v3d_flush_jobs_writing_resource(v3d, psrc, V3D_FLUSH_DEFAULT, false); + v3d_flush_jobs_reading_resource(v3d, pdst, V3D_FLUSH_DEFAULT, false); struct drm_v3d_submit_tfu tfu = { .ios = (height << 16) | width, @@ -538,5 +538,5 @@ v3d_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info) * texture uploads before using the textures. */ v3d_flush_jobs_writing_resource(v3d, info.dst.resource, - V3D_FLUSH_DEFAULT); + V3D_FLUSH_DEFAULT, false); } diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h index ecedbaf9efb..2bf9c41fd92 100644 --- a/src/gallium/drivers/v3d/v3d_context.h +++ b/src/gallium/drivers/v3d/v3d_context.h @@ -511,6 +511,12 @@ struct v3d_context { bool active_queries; + /** + * If a compute job writes a resource read by a non-compute stage we + * should sync on the last compute job. + */ + bool sync_on_last_compute_job; + uint32_t tf_prims_generated; uint32_t prims_generated; @@ -644,10 +650,12 @@ void v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job); void v3d_flush_jobs_using_bo(struct v3d_context *v3d, struct v3d_bo *bo); void v3d_flush_jobs_writing_resource(struct v3d_context *v3d, struct pipe_resource *prsc, - enum v3d_flush_cond flush_cond); + enum v3d_flush_cond flush_cond, + bool is_compute_pipeline); void v3d_flush_jobs_reading_resource(struct v3d_context *v3d, struct pipe_resource *prsc, - enum v3d_flush_cond flush_cond); + enum v3d_flush_cond flush_cond, + bool is_compute_pipeline); void v3d_update_compiled_shaders(struct v3d_context *v3d, uint8_t prim_mode); void v3d_update_compiled_cs(struct v3d_context *v3d); diff --git a/src/gallium/drivers/v3d/v3d_job.c b/src/gallium/drivers/v3d/v3d_job.c index 0acd8b033c2..31a6683151e 100644 --- a/src/gallium/drivers/v3d/v3d_job.c +++ b/src/gallium/drivers/v3d/v3d_job.c @@ -184,10 +184,23 @@ v3d_job_writes_resource_from_tf(struct v3d_job *job, void v3d_flush_jobs_writing_resource(struct v3d_context *v3d, struct pipe_resource *prsc, - enum v3d_flush_cond flush_cond) + enum v3d_flush_cond flush_cond, + bool is_compute_pipeline) { struct hash_entry *entry = _mesa_hash_table_search(v3d->write_jobs, prsc); + 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. + */ + if (!is_compute_pipeline && rsc->bo != NULL && rsc->compute_written) { + v3d->sync_on_last_compute_job = true; + rsc->compute_written = false; + } + if (!entry) return; @@ -220,7 +233,8 @@ v3d_flush_jobs_writing_resource(struct v3d_context *v3d, void v3d_flush_jobs_reading_resource(struct v3d_context *v3d, struct pipe_resource *prsc, - enum v3d_flush_cond flush_cond) + enum v3d_flush_cond flush_cond, + bool is_compute_pipeline) { struct v3d_resource *rsc = v3d_resource(prsc); @@ -230,7 +244,8 @@ v3d_flush_jobs_reading_resource(struct v3d_context *v3d, * caller intends to write to the resource, so we don't care if * there was a previous TF write to it. */ - v3d_flush_jobs_writing_resource(v3d, prsc, flush_cond); + v3d_flush_jobs_writing_resource(v3d, prsc, flush_cond, + is_compute_pipeline); hash_table_foreach(v3d->jobs, entry) { struct v3d_job *job = entry->data; @@ -329,7 +344,8 @@ v3d_get_job(struct v3d_context *v3d, for (int i = 0; i < V3D_MAX_DRAW_BUFFERS; i++) { if (cbufs[i]) { v3d_flush_jobs_reading_resource(v3d, cbufs[i]->texture, - V3D_FLUSH_DEFAULT); + V3D_FLUSH_DEFAULT, + false); pipe_surface_reference(&job->cbufs[i], cbufs[i]); if (cbufs[i]->texture->nr_samples > 1) @@ -338,7 +354,8 @@ v3d_get_job(struct v3d_context *v3d, } if (zsbuf) { v3d_flush_jobs_reading_resource(v3d, zsbuf->texture, - V3D_FLUSH_DEFAULT); + V3D_FLUSH_DEFAULT, + false); pipe_surface_reference(&job->zsbuf, zsbuf); if (zsbuf->texture->nr_samples > 1) job->msaa = true; @@ -356,7 +373,8 @@ v3d_get_job(struct v3d_context *v3d, if (rsc->separate_stencil) { v3d_flush_jobs_reading_resource(v3d, &rsc->separate_stencil->base, - V3D_FLUSH_DEFAULT); + V3D_FLUSH_DEFAULT, + false); _mesa_hash_table_insert(v3d->write_jobs, &rsc->separate_stencil->base, job); diff --git a/src/gallium/drivers/v3d/v3d_resource.c b/src/gallium/drivers/v3d/v3d_resource.c index c2590fac1e5..90608434eef 100644 --- a/src/gallium/drivers/v3d/v3d_resource.c +++ b/src/gallium/drivers/v3d/v3d_resource.c @@ -170,19 +170,23 @@ v3d_map_usage_prep(struct pipe_context *pctx, * don't violate any syncing requirements. */ v3d_flush_jobs_reading_resource(v3d, prsc, - V3D_FLUSH_DEFAULT); + V3D_FLUSH_DEFAULT, + false); } } else if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { /* If we're writing and the buffer is being used by the CL, we * have to flush the CL first. If we're only reading, we need * to flush if the CL has written our buffer. */ - if (usage & PIPE_TRANSFER_WRITE) + if (usage & PIPE_TRANSFER_WRITE) { v3d_flush_jobs_reading_resource(v3d, prsc, - V3D_FLUSH_ALWAYS); - else + V3D_FLUSH_ALWAYS, + false); + } else { v3d_flush_jobs_writing_resource(v3d, prsc, - V3D_FLUSH_ALWAYS); + V3D_FLUSH_ALWAYS, + false); + } } if (usage & PIPE_TRANSFER_WRITE) { diff --git a/src/gallium/drivers/v3d/v3d_resource.h b/src/gallium/drivers/v3d/v3d_resource.h index f0b7c26e048..812131dddf2 100644 --- a/src/gallium/drivers/v3d/v3d_resource.h +++ b/src/gallium/drivers/v3d/v3d_resource.h @@ -130,6 +130,11 @@ struct v3d_resource { bool tiled; /** + * Indicates if the CS has written the resource + */ + bool compute_written; + + /** * Number of times the resource has been written to. * * This is used to track whether we need to load the surface on first diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c index 3a5b1171020..91ae5ba4911 100644 --- a/src/gallium/drivers/v3d/v3dx_draw.c +++ b/src/gallium/drivers/v3d/v3dx_draw.c @@ -157,7 +157,8 @@ 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_DEFAULT, + s == PIPE_SHADER_COMPUTE); } /* Flush writes to UBOs. */ @@ -165,7 +166,8 @@ v3d_predraw_check_stage_inputs(struct pipe_context *pctx, struct pipe_constant_buffer *cb = &v3d->constbuf[s].cb[i]; if (cb->buffer) { v3d_flush_jobs_writing_resource(v3d, cb->buffer, - V3D_FLUSH_DEFAULT); + V3D_FLUSH_DEFAULT, + s == PIPE_SHADER_COMPUTE); } } @@ -174,7 +176,8 @@ v3d_predraw_check_stage_inputs(struct pipe_context *pctx, struct pipe_shader_buffer *sb = &v3d->ssbo[s].sb[i]; if (sb->buffer) { v3d_flush_jobs_reading_resource(v3d, sb->buffer, - V3D_FLUSH_NOT_CURRENT_JOB); + V3D_FLUSH_NOT_CURRENT_JOB, + s == PIPE_SHADER_COMPUTE); } } @@ -183,7 +186,8 @@ v3d_predraw_check_stage_inputs(struct pipe_context *pctx, struct v3d_image_view *view = &v3d->shaderimg[s].si[i]; v3d_flush_jobs_reading_resource(v3d, view->base.resource, - V3D_FLUSH_NOT_CURRENT_JOB); + V3D_FLUSH_NOT_CURRENT_JOB, + s == PIPE_SHADER_COMPUTE); } /* Flush writes to our vertex buffers (i.e. from transform feedback) */ @@ -192,7 +196,8 @@ v3d_predraw_check_stage_inputs(struct pipe_context *pctx, struct pipe_vertex_buffer *vb = &v3d->vertexbuf.vb[i]; v3d_flush_jobs_writing_resource(v3d, vb->buffer.resource, - V3D_FLUSH_DEFAULT); + V3D_FLUSH_DEFAULT, + false); } } } @@ -213,7 +218,8 @@ v3d_predraw_check_outputs(struct pipe_context *pctx) const struct pipe_stream_output_target *target = so->targets[i]; v3d_flush_jobs_reading_resource(v3d, target->buffer, - V3D_FLUSH_DEFAULT); + V3D_FLUSH_DEFAULT, + false); } } } @@ -667,7 +673,7 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) if (info->indirect) { v3d_flush_jobs_writing_resource(v3d, info->indirect->buffer, - V3D_FLUSH_DEFAULT); + V3D_FLUSH_DEFAULT, false); } v3d_predraw_check_outputs(pctx); @@ -699,6 +705,14 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) job->submit.in_sync_bcl = v3d->out_sync; } + /* We also need to ensure that compute is complete when render depends + * on resources written by it. + */ + if (v3d->sync_on_last_compute_job) { + job->submit.in_sync_bcl = v3d->out_sync; + v3d->sync_on_last_compute_job = false; + } + /* Mark SSBOs and images as being written. We don't actually know * which ones are read vs written, so just assume the worst. */ @@ -1114,13 +1128,15 @@ v3d_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info) foreach_bit(i, v3d->ssbo[PIPE_SHADER_COMPUTE].enabled_mask) { struct v3d_resource *rsc = v3d_resource( v3d->ssbo[PIPE_SHADER_COMPUTE].sb[i].buffer); - rsc->writes++; /* XXX */ + rsc->writes++; + rsc->compute_written = true; } foreach_bit(i, v3d->shaderimg[PIPE_SHADER_COMPUTE].enabled_mask) { struct v3d_resource *rsc = v3d_resource( v3d->shaderimg[PIPE_SHADER_COMPUTE].si[i].base.resource); rsc->writes++; + rsc->compute_written = true; } v3d_bo_unreference(&uniforms.bo); |