From 94f2619b7d1bba20cc0699dc5a000db5da3f9202 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 14 Dec 2022 16:06:45 -0800 Subject: [PATCH] iris: Don't reject CPU access for non-invalidating buffer write maps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Buffer maps that don't invalidate their destination range work better as direct CPU maps than staging blits. The application may write only part of the range, effectively combining the new data with existing data. So even if the map would stall, the staging blit path won't help us, as we have to read the existing data to populate the staging buffer before returning it. This incurs a stall anyway - plus a read and copy. In contrast, a direct map doesn't need to read any data - it can just write the destination and the existing data will still be there. Fixes excessive blits for stalling buffer writes that don't invalidate the buffer since my recent map heuristic rework. Fixes: bec68a85a2d ("iris: Improve direct CPU map heuristics") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7895 Reviewed-by: Tapani Pälli Part-of: --- src/gallium/drivers/iris/iris_resource.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index c416d8885ed..0649597198f 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -2399,6 +2399,8 @@ prefer_cpu_access(const struct iris_resource *res, const bool write = usage & PIPE_MAP_WRITE; const bool read = usage & PIPE_MAP_READ; + const bool preserve = + res->base.b.target == PIPE_BUFFER && !(usage & PIPE_MAP_DISCARD_RANGE); /* We want to avoid uncached reads because they are slow. */ if (read && mmap_mode != IRIS_MMAP_WB) @@ -2407,8 +2409,14 @@ prefer_cpu_access(const struct iris_resource *res, /* We want to avoid stalling. We can't avoid stalling for reads, though, * because the destination of a GPU staging copy would be busy and stall * in the exact same manner. So don't consider it for those. + * + * For buffer maps which aren't invalidating the destination, the GPU + * staging copy path would have to read the existing buffer contents in + * order to preserve them, effectively making it a read. But a direct + * mapping would be able to just write the necessary parts without the + * overhead of the copy. It may stall, but we would anyway. */ - if (map_would_stall && !read) + if (map_would_stall && !read && !preserve) return false; /* Use the GPU for writes if it would compress the data. */