summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-08-01 15:33:06 -0700
committerEric Anholt <[email protected]>2014-08-11 14:45:31 -0700
commit2259cc5aebcb16636b1399dd438beed9d9867e67 (patch)
tree23c5a96fefbf0fc88555931a57806e06c97820fe /src
parent6b2583412f0789d2aec71e55e1e187d1ad17f721 (diff)
vc4: Avoid flushing when mapping buffers that aren't in the batch.
This should prevent a bunch of unnecessary flushes for things like updating immediate vertex data.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/vc4/vc4_context.c48
-rw-r--r--src/gallium/drivers/vc4/vc4_context.h1
-rw-r--r--src/gallium/drivers/vc4/vc4_resource.c2
3 files changed, 50 insertions, 1 deletions
diff --git a/src/gallium/drivers/vc4/vc4_context.c b/src/gallium/drivers/vc4/vc4_context.c
index 6799e7ebf61..11e42a3ad91 100644
--- a/src/gallium/drivers/vc4/vc4_context.c
+++ b/src/gallium/drivers/vc4/vc4_context.c
@@ -248,6 +248,54 @@ vc4_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
vc4_flush(pctx);
}
+/**
+ * Flushes the current command lists if they reference the given BO.
+ *
+ * This helps avoid flushing the command buffers when unnecessary.
+ */
+void
+vc4_flush_for_bo(struct pipe_context *pctx, struct vc4_bo *bo)
+{
+ struct vc4_context *vc4 = vc4_context(pctx);
+
+ if (!vc4->needs_flush)
+ return;
+
+ /* Walk all the referenced BOs in the drawing command list to see if
+ * they match.
+ */
+ struct vc4_bo **referenced_bos = vc4->bo_pointers.base;
+ for (int i = 0; i < (vc4->bo_handles.next -
+ vc4->bo_handles.base) / 4; i++) {
+ if (referenced_bos[i] == bo) {
+ vc4_flush(pctx);
+ return;
+ }
+ }
+
+ /* Also check for the Z/color buffers, since the references to those
+ * are only added immediately before submit.
+ */
+ struct vc4_surface *csurf = vc4_surface(vc4->framebuffer.cbufs[0]);
+ if (csurf) {
+ struct vc4_resource *ctex = vc4_resource(csurf->base.texture);
+ if (ctex->bo == bo) {
+ vc4_flush(pctx);
+ return;
+ }
+ }
+
+ struct vc4_surface *zsurf = vc4_surface(vc4->framebuffer.zsbuf);
+ if (zsurf) {
+ struct vc4_resource *ztex =
+ vc4_resource(zsurf->base.texture);
+ if (ztex->bo == bo) {
+ vc4_flush(pctx);
+ return;
+ }
+ }
+}
+
static void
vc4_context_destroy(struct pipe_context *pctx)
{
diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h
index 85cdf41e427..d6367871358 100644
--- a/src/gallium/drivers/vc4/vc4_context.h
+++ b/src/gallium/drivers/vc4/vc4_context.h
@@ -217,6 +217,7 @@ void vc4_write_uniforms(struct vc4_context *vc4,
int shader_index);
void vc4_flush(struct pipe_context *pctx);
+void vc4_flush_for_bo(struct pipe_context *pctx, struct vc4_bo *bo);
void vc4_emit_state(struct pipe_context *pctx);
void vc4_generate_code(struct qcompile *c);
void vc4_update_compiled_shaders(struct vc4_context *vc4);
diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c
index 9df2aae435b..3b1abd11152 100644
--- a/src/gallium/drivers/vc4/vc4_resource.c
+++ b/src/gallium/drivers/vc4/vc4_resource.c
@@ -57,7 +57,7 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
enum pipe_format format = prsc->format;
char *buf;
- vc4_flush(pctx);
+ vc4_flush_for_bo(pctx, rsc->bo);
ptrans = util_slab_alloc(&vc4->transfer_pool);
if (!ptrans)