vc4: Avoid flushing when mapping buffers that aren't in the batch.
authorEric Anholt <eric@anholt.net>
Fri, 1 Aug 2014 22:33:06 +0000 (15:33 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 11 Aug 2014 21:45:31 +0000 (14:45 -0700)
This should prevent a bunch of unnecessary flushes for things like
updating immediate vertex data.

src/gallium/drivers/vc4/vc4_context.c
src/gallium/drivers/vc4/vc4_context.h
src/gallium/drivers/vc4/vc4_resource.c

index 6799e7ebf616b53c9a731f97f70d79c042f4ddc3..11e42a3ad914d3bc0b1798f61a68cfa3f32f8cfa 100644 (file)
@@ -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)
 {
index 85cdf41e4279da73f7e9042775285ad84e28b62e..d63678713580c8578436ea8cb835e21aaa16aff4 100644 (file)
@@ -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);
index 9df2aae435bdf7267890792d7ef5dc5d39e8e60c..3b1abd11152e16ec204aee7f817e96bebe91e86c 100644 (file)
@@ -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)