summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/v3d/v3d_blit.c4
-rw-r--r--src/gallium/drivers/v3d/v3d_context.h3
-rw-r--r--src/gallium/drivers/v3d/v3d_job.c51
-rw-r--r--src/gallium/drivers/v3d/v3d_resource.c2
-rw-r--r--src/gallium/drivers/v3d/v3dx_draw.c21
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);