summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2019-09-07 22:51:15 -0700
committerKenneth Graunke <kenneth@whitecape.org>2019-09-09 15:08:22 -0700
commit410894c643274975aab781e9c412f7a339a7547b (patch)
treec063e14bf5dbaf1d9cd4e999adfaecf6721a7467
parent7d28e9ddd62eeccf6c528beee6b1a58fdfb7f5a0 (diff)
iris: Avoid flushing for cache history on transfer range flushes
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).
-rw-r--r--src/gallium/drivers/iris/iris_resource.c13
-rw-r--r--src/gallium/drivers/iris/iris_resource.h2
2 files changed, 13 insertions, 2 deletions
diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c
index 989c112a3e3..5b1fde7aac6 100644
--- a/src/gallium/drivers/iris/iris_resource.c
+++ b/src/gallium/drivers/iris/iris_resource.c
@@ -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) {
diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h
index 304339eb470..5e3356e5055 100644
--- a/src/gallium/drivers/iris/iris_resource.h
+++ b/src/gallium/drivers/iris/iris_resource.h
@@ -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 *);
};