summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2018-04-25 14:18:52 -0700
committerEric Anholt <[email protected]>2018-04-26 11:30:22 -0700
commit57ceb95c842215880b7cb416fbdb9545276cfc05 (patch)
tree13f1f67c6e7900ffc48b138b36e93ff2dc4ebfc5
parentdc4cb04ee516c5e17181cf04d932dcc2da533388 (diff)
broadcom/vc5: Implement GFXH-1742 workaround (emit 2 dummy stores on 4.x).
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.
-rw-r--r--src/gallium/drivers/vc5/vc5_rcl.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/src/gallium/drivers/vc5/vc5_rcl.c b/src/gallium/drivers/vc5/vc5_rcl.c
index 7f804aa27a5..7d32d9ad0ea 100644
--- a/src/gallium/drivers/vc5/vc5_rcl.c
+++ b/src/gallium/drivers/vc5/vc5_rcl.c
@@ -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);