iris: Don't bother with PIPE_CONTROLs for CPU writes and no history
authorKenneth Graunke <kenneth@whitecape.org>
Thu, 20 Jun 2019 04:30:52 +0000 (23:30 -0500)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 20 Jun 2019 18:32:16 +0000 (13:32 -0500)
If a buffer has no usage history, we don't have any read only cache
invalidates to do.  If we've written it with the CPU, we don't need
to flush the render cache.  The only bit remaining is the CS stall
from iris_flush_bits_for_history.  We can just skip the PIPE_CONTROL
in this case.

This is pretty common - an app creates a buffer, fills it with data,
and then binds it for some purpose.

Cuts 36% of the flushes in Manhattan 3.0 on Kabylake GT2.

src/gallium/drivers/iris/iris_resource.c

index a413cbae9b3c175b4705f69270f731c8d0cea2c2..8ca1e6e940a67f6cf4bb4b97ee5b3bf469c640de 100644 (file)
@@ -1479,12 +1479,15 @@ iris_transfer_flush_region(struct pipe_context *ctx,
                        (map->staging ? PIPE_CONTROL_RENDER_TARGET_FLUSH : 0);
    }
 
-   for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
-      struct iris_batch *batch = &ice->batches[i];
-      if (batch->contains_draw || batch->cache.render->entries) {
-         iris_batch_maybe_flush(batch, 24);
-         iris_emit_pipe_control_flush(batch, "cache history: transfer flush",
-                                      history_flush);
+   if (history_flush & ~PIPE_CONTROL_CS_STALL) {
+      for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
+         struct iris_batch *batch = &ice->batches[i];
+         if (batch->contains_draw || batch->cache.render->entries) {
+            iris_batch_maybe_flush(batch, 24);
+            iris_emit_pipe_control_flush(batch,
+                                         "cache history: transfer flush",
+                                         history_flush);
+         }
       }
    }