vc4: Don't flush on read-only access of buffers read by the CL.
authorEric Anholt <eric@anholt.net>
Fri, 15 Apr 2016 21:27:34 +0000 (14:27 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 18 Apr 2016 17:10:44 +0000 (10:10 -0700)
Fixes piglit mixed-immediate-and-vbo, and may significantly improve
performance of applications that store a 4-byte IB in the same VBO as
vertex data.

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

index a0888f232656231f92e809850b19e1d65bf5cfd1..eeadea0b1db3db03396e4805fbfd2e0b115dff99 100644 (file)
@@ -133,7 +133,8 @@ vc4_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
  * This helps avoid flushing the command buffers when unnecessary.
  */
 bool
-vc4_cl_references_bo(struct pipe_context *pctx, struct vc4_bo *bo)
+vc4_cl_references_bo(struct pipe_context *pctx, struct vc4_bo *bo,
+                     bool include_reads)
 {
         struct vc4_context *vc4 = vc4_context(pctx);
 
@@ -143,10 +144,12 @@ vc4_cl_references_bo(struct pipe_context *pctx, struct vc4_bo *bo)
         /* 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 < cl_offset(&vc4->bo_handles) / 4; i++) {
-                if (referenced_bos[i] == bo) {
-                        return true;
+        if (include_reads) {
+                struct vc4_bo **referenced_bos = vc4->bo_pointers.base;
+                for (int i = 0; i < cl_offset(&vc4->bo_handles) / 4; i++) {
+                        if (referenced_bos[i] == bo) {
+                                return true;
+                        }
                 }
         }
 
index aa973bddcdaabe91d2b74e7c35b911684bc52c5c..2457e67941db0e56b87ec8254c0995a4599384c2 100644 (file)
@@ -397,7 +397,8 @@ void vc4_flush(struct pipe_context *pctx);
 void vc4_job_init(struct vc4_context *vc4);
 void vc4_job_submit(struct vc4_context *vc4);
 void vc4_job_reset(struct vc4_context *vc4);
-bool vc4_cl_references_bo(struct pipe_context *pctx, struct vc4_bo *bo);
+bool vc4_cl_references_bo(struct pipe_context *pctx, struct vc4_bo *bo,
+                          bool include_reads);
 void vc4_emit_state(struct pipe_context *pctx);
 void vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c);
 struct qpu_reg *vc4_register_allocate(struct vc4_context *vc4, struct vc4_compile *c);
index 2f89da5f9f137cc47f3c8dc22014d5ba3627f356..050941c3e6f1a1b184ebb99b34d3fc400793b91c 100644 (file)
@@ -171,7 +171,12 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
                         vc4_flush(pctx);
                 }
         } else if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
-                if (vc4_cl_references_bo(pctx, rsc->bo)) {
+                /* 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 (vc4_cl_references_bo(pctx, rsc->bo,
+                                         usage & PIPE_TRANSFER_WRITE)) {
                         if ((usage & PIPE_TRANSFER_DISCARD_RANGE) &&
                             prsc->last_level == 0 &&
                             prsc->width0 == box->width &&