iris: Mark constants dirty on transfer unmap even if no flushes occur
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 23 Apr 2019 02:11:44 +0000 (19:11 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 23 Apr 2019 07:24:08 +0000 (00:24 -0700)
I have various conditions in place to try and avoid unnecessary
PIPE_CONTROL flushes, especially to batches which may have never
used the buffer being mapped.  But if we do a CPU map to a bound
constant buffer, we still need to mark push constants dirty, even
if there's nothing happening in batches that would warrant a flush.

Fixes obvious misrendering in the "XCOM 2: War of the Chosen" menus
(lots of rainbow colored triangles).  Fixes lots of blinking elements
in "Shadow of Mordor".  Fixes missing crowd rendering in "DiRT Rally".

src/gallium/drivers/iris/iris_resource.c

index 5a12ee0..0011439 100644 (file)
@@ -1397,6 +1397,11 @@ iris_transfer_flush_region(struct pipe_context *ctx,
          iris_flush_and_dirty_for_history(ice, &ice->batches[i], res);
       }
    }
+
+   /* Make sure we flag constants dirty even if there's no need to emit
+    * any PIPE_CONTROLs to a batch.
+    */
+   iris_flush_and_dirty_for_history(ice, NULL, res);
 }
 
 static void
@@ -1435,7 +1440,7 @@ iris_flush_and_dirty_for_history(struct iris_context *ice,
    /* We've likely used the rendering engine (i.e. BLORP) to write to this
     * surface.  Flush the render cache so the data actually lands.
     */
-   if (batch->name != IRIS_BATCH_COMPUTE)
+   if (batch && batch->name != IRIS_BATCH_COMPUTE)
       flush |= PIPE_CONTROL_RENDER_TARGET_FLUSH;
 
    uint64_t dirty = 0ull;
@@ -1461,7 +1466,8 @@ iris_flush_and_dirty_for_history(struct iris_context *ice,
    if (res->bind_history & (PIPE_BIND_SHADER_BUFFER | PIPE_BIND_SHADER_IMAGE))
       flush |= PIPE_CONTROL_DATA_CACHE_FLUSH;
 
-   iris_emit_pipe_control_flush(batch, flush);
+   if (batch)
+      iris_emit_pipe_control_flush(batch, flush);
 
    ice->state.dirty |= dirty;
 }