iris: Avoid flushing for cache history on transfer range flushes
authorKenneth Graunke <kenneth@whitecape.org>
Sun, 8 Sep 2019 05:51:15 +0000 (22:51 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 9 Sep 2019 22:08:22 +0000 (15:08 -0700)
The VBO module maps a buffer with GL_MAP_FLUSH_EXPLICIT, and keeps
appending data, and calling glFlushMappedBufferRange().  We were
invalidating the VF cache each time it flushed a new range, which
results in a ton of VF flushes.

If the contents of the destination in the target range are undefined
(never even possibly written), this patch makes us assume that it's
likely not in the cache and so cache invalidations are required.  If
the destination range is defined, we continue cache flushing as we may
need to expunge stale data.

This eliminates 88% of the VF cache invalidates on Manhattan 3.0.
Improves performance in Manhattan 3.0 on my Icelake 8x8 with the GPU
frequency locked to 700Mhz by 0.376724% +/- 0.0989183% (n=10).

src/gallium/drivers/iris/iris_resource.c
src/gallium/drivers/iris/iris_resource.h

index 989c112a3e3e29431c3b3cb23c134df3fee8b24e..5b1fde7aac65a115b16d0cf005e8adf286c5829e 100644 (file)
@@ -1746,6 +1746,10 @@ iris_transfer_map(struct pipe_context *ctx,
    xfer->box = *box;
    *ptransfer = xfer;
 
+   map->dest_had_defined_contents =
+      util_ranges_intersect(&res->valid_buffer_range, box->x,
+                            box->x + box->width);
+
    if (usage & PIPE_TRANSFER_WRITE)
       util_range_add(&res->valid_buffer_range, box->x, box->x + box->width);
 
@@ -1826,8 +1830,13 @@ iris_transfer_flush_region(struct pipe_context *ctx,
    uint32_t history_flush = 0;
 
    if (res->base.target == PIPE_BUFFER) {
-      history_flush |= iris_flush_bits_for_history(res) |
-                       (map->staging ? PIPE_CONTROL_RENDER_TARGET_FLUSH : 0);
+      if (map->staging)
+         history_flush |= PIPE_CONTROL_RENDER_TARGET_FLUSH;
+
+      if (map->dest_had_defined_contents)
+         history_flush |= iris_flush_bits_for_history(res);
+
+      util_range_add(&res->valid_buffer_range, box->x, box->x + box->width);
    }
 
    if (history_flush & ~PIPE_CONTROL_CS_STALL) {
index 304339eb470f673c0eaeb9d012b8b013ab8f43d1..5e3356e5055c64434d7309a158815f1659de2adb 100644 (file)
@@ -232,6 +232,8 @@ struct iris_transfer {
    struct blorp_context *blorp;
    struct iris_batch *batch;
 
+   bool dest_had_defined_contents;
+
    void (*unmap)(struct iris_transfer *);
 };