diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/v3d/v3d_blit.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_context.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_job.c | 51 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_resource.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3dx_draw.c | 21 |
5 files changed, 61 insertions, 20 deletions
diff --git a/src/gallium/drivers/v3d/v3d_blit.c b/src/gallium/drivers/v3d/v3d_blit.c index d42e8fd0e69..e177369dd10 100644 --- a/src/gallium/drivers/v3d/v3d_blit.c +++ b/src/gallium/drivers/v3d/v3d_blit.c @@ -380,7 +380,7 @@ 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_jobs_writing_resource(v3d, psrc, false); v3d_flush_jobs_reading_resource(v3d, pdst); struct drm_v3d_submit_tfu tfu = { @@ -537,5 +537,5 @@ v3d_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info) * run into unexpected OOMs when blits are used for a large series of * texture uploads before using the textures. */ - v3d_flush_jobs_writing_resource(v3d, info.dst.resource); + v3d_flush_jobs_writing_resource(v3d, info.dst.resource, false); } diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h index 7c8952ebb74..9143f53cee8 100644 --- a/src/gallium/drivers/v3d/v3d_context.h +++ b/src/gallium/drivers/v3d/v3d_context.h @@ -594,7 +594,8 @@ void v3d_job_add_tf_write_resource(struct v3d_job *job, struct pipe_resource *pr 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); + struct pipe_resource *prsc, + bool always_flush); void v3d_flush_jobs_reading_resource(struct v3d_context *v3d, struct pipe_resource *prsc); void v3d_update_compiled_shaders(struct v3d_context *v3d, uint8_t prim_mode); diff --git a/src/gallium/drivers/v3d/v3d_job.c b/src/gallium/drivers/v3d/v3d_job.c index 6f3fa709616..9b24f12e7e9 100644 --- a/src/gallium/drivers/v3d/v3d_job.c +++ b/src/gallium/drivers/v3d/v3d_job.c @@ -168,16 +168,51 @@ v3d_job_add_tf_write_resource(struct v3d_job *job, struct pipe_resource *prsc) _mesa_set_add(job->tf_write_prscs, prsc); } +static bool +v3d_job_writes_resource_from_tf(struct v3d_job *job, + struct pipe_resource *prsc) +{ + if (!job->tf_enabled) + return false; + + if (!job->tf_write_prscs) + return false; + + return _mesa_set_search(job->tf_write_prscs, prsc) != NULL; +} + void v3d_flush_jobs_writing_resource(struct v3d_context *v3d, - struct pipe_resource *prsc) + struct pipe_resource *prsc, + bool always_flush) { struct hash_entry *entry = _mesa_hash_table_search(v3d->write_jobs, prsc); - if (entry) { - struct v3d_job *job = entry->data; - v3d_job_submit(v3d, job); + if (!entry) + return; + + struct v3d_job *job = entry->data; + + /* For writes from TF in the same job we use the "Wait for TF" + * feature provided by the hardware so we don't want to flush. + * The exception to this is when the caller is about to map the + * resource since in that case we don't have a 'Wait for TF' command + * the in command stream. In this scenario the caller is expected + * to set 'always_flush' to True. + */ + bool needs_flush; + if (always_flush) { + needs_flush = true; + } else if (!v3d->job || v3d->job != job) { + /* Write from a different job: always flush */ + needs_flush = true; + } else { + /* Write from currrent job: flush if not TF */ + needs_flush = !v3d_job_writes_resource_from_tf(job, prsc); } + + if (needs_flush) + v3d_job_submit(v3d, job); } void @@ -186,7 +221,13 @@ v3d_flush_jobs_reading_resource(struct v3d_context *v3d, { struct v3d_resource *rsc = v3d_resource(prsc); - v3d_flush_jobs_writing_resource(v3d, prsc); + /* We only need to force the flush on TF writes, which is the only + * case where we might skip the flush to use the 'Wait for TF' + * command. Here we are flushing for a read, which means that the + * 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, false); hash_table_foreach(v3d->jobs, entry) { struct v3d_job *job = entry->data; diff --git a/src/gallium/drivers/v3d/v3d_resource.c b/src/gallium/drivers/v3d/v3d_resource.c index 10abee4e8f6..e2f112328fc 100644 --- a/src/gallium/drivers/v3d/v3d_resource.c +++ b/src/gallium/drivers/v3d/v3d_resource.c @@ -179,7 +179,7 @@ v3d_map_usage_prep(struct pipe_context *pctx, if (usage & PIPE_TRANSFER_WRITE) v3d_flush_jobs_reading_resource(v3d, prsc); else - v3d_flush_jobs_writing_resource(v3d, prsc); + v3d_flush_jobs_writing_resource(v3d, prsc, true); } if (usage & PIPE_TRANSFER_WRITE) { diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c index 201813c69d6..0d23ac6bb2d 100644 --- a/src/gallium/drivers/v3d/v3dx_draw.c +++ b/src/gallium/drivers/v3d/v3dx_draw.c @@ -145,11 +145,6 @@ v3d_predraw_check_stage_inputs(struct pipe_context *pctx, { struct v3d_context *v3d = v3d_context(pctx); - /* XXX perf: If we're reading from the output of TF in this job, we - * should instead be using the wait for transform feedback - * functionality. - */ - /* Flush writes to textures we're sampling. */ for (int i = 0; i < v3d->tex[s].num_textures; i++) { struct pipe_sampler_view *pview = v3d->tex[s].textures[i]; @@ -161,21 +156,22 @@ v3d_predraw_check_stage_inputs(struct pipe_context *pctx, view->base.format != PIPE_FORMAT_X32_S8X24_UINT) v3d_update_shadow_texture(pctx, &view->base); - v3d_flush_jobs_writing_resource(v3d, view->texture); + v3d_flush_jobs_writing_resource(v3d, view->texture, false); } /* Flush writes to UBOs. */ foreach_bit(i, v3d->constbuf[s].enabled_mask) { struct pipe_constant_buffer *cb = &v3d->constbuf[s].cb[i]; if (cb->buffer) - v3d_flush_jobs_writing_resource(v3d, cb->buffer); + v3d_flush_jobs_writing_resource(v3d, cb->buffer, false); } /* Flush writes to our image views */ foreach_bit(i, v3d->shaderimg[s].enabled_mask) { struct v3d_image_view *view = &v3d->shaderimg[s].si[i]; - v3d_flush_jobs_writing_resource(v3d, view->base.resource); + v3d_flush_jobs_writing_resource(v3d, view->base.resource, + false); } /* Flush writes to our vertex buffers (i.e. from transform feedback) */ @@ -183,7 +179,8 @@ v3d_predraw_check_stage_inputs(struct pipe_context *pctx, foreach_bit(i, v3d->vertexbuf.enabled_mask) { struct pipe_vertex_buffer *vb = &v3d->vertexbuf.vb[i]; - v3d_flush_jobs_writing_resource(v3d, vb->buffer.resource); + v3d_flush_jobs_writing_resource(v3d, vb->buffer.resource, + false); } } } @@ -654,8 +651,10 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) for (int s = 0; s < PIPE_SHADER_COMPUTE; s++) v3d_predraw_check_stage_inputs(pctx, s); - if (info->indirect) - v3d_flush_jobs_writing_resource(v3d, info->indirect->buffer); + if (info->indirect) { + v3d_flush_jobs_writing_resource(v3d, info->indirect->buffer, + false); + } v3d_predraw_check_outputs(pctx); |