broadcom/vc5: Implement GFXH-1742 workaround (emit 2 dummy stores on 4.x).
authorEric Anholt <eric@anholt.net>
Wed, 25 Apr 2018 21:18:52 +0000 (14:18 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 26 Apr 2018 18:30:22 +0000 (11:30 -0700)
This should fix help with intermittent GPU hangs in tests switching
formats while rendering small frames.  Unfortunately, it didn't help with
the tests I'm having troubles with.

src/gallium/drivers/vc5/vc5_rcl.c

index 7f804aa27a52316977d72e14f7c9e472e7601e24..7d32d9ad0eaede3e77862e59f815c78e8c404297 100644 (file)
@@ -715,20 +715,39 @@ v3dX(emit_rcl)(struct vc5_job *job)
                 coords.tile_row_number = 0;
         }
 
+        /* Emit an initial clear of the tile buffers.  This is necessary for
+         * any buffers that should be cleared (since clearing normally happens
+         * at the *end* of the generic tile list), but it's also nice to clear
+         * everything so the first tile doesn't inherit any contents from some
+         * previous frame.
+         *
+         * Also, implement the GFXH-1742 workaround.  There's a race in the HW
+         * between the RCL updating the TLB's internal type/size and the
+         * spawning of the QPU instances using the TLB's current internal
+         * type/size.  To make sure the QPUs get the right state,, we need 1
+         * dummy store in between internal type/size changes on V3D 3.x, and 2
+         * dummy stores on 4.x.
+         */
 #if V3D_VERSION < 40
         cl_emit(&job->rcl, STORE_TILE_BUFFER_GENERAL, store) {
                 store.buffer_to_store = NONE;
         }
 #else
-        cl_emit(&job->rcl, END_OF_LOADS, end);
-        cl_emit(&job->rcl, STORE_TILE_BUFFER_GENERAL, store) {
-                store.buffer_to_store = NONE;
-        }
-        cl_emit(&job->rcl, CLEAR_TILE_BUFFERS, clear) {
-                clear.clear_z_stencil_buffer = true;
-                clear.clear_all_render_targets = true;
+        for (int i = 0; i < 2; i++) {
+                if (i > 0)
+                        cl_emit(&job->rcl, TILE_COORDINATES, coords);
+                cl_emit(&job->rcl, END_OF_LOADS, end);
+                cl_emit(&job->rcl, STORE_TILE_BUFFER_GENERAL, store) {
+                        store.buffer_to_store = NONE;
+                }
+                if (i == 0) {
+                        cl_emit(&job->rcl, CLEAR_TILE_BUFFERS, clear) {
+                                clear.clear_z_stencil_buffer = true;
+                                clear.clear_all_render_targets = true;
+                        }
+                }
+                cl_emit(&job->rcl, END_OF_TILE_MARKER, end);
         }
-        cl_emit(&job->rcl, END_OF_TILE_MARKER, end);
 #endif
 
         cl_emit(&job->rcl, FLUSH_VCD_CACHE, flush);