Commit e5143bb2 authored by Kenneth Graunke's avatar Kenneth Graunke
Browse files

iris: Improve direct CPU map heuristics

We were promoting reads with a valid primary to direct CPU maps even
if the mmap mode was IRIS_MMAP_WC, which would mean uncached reads from
VRAM.  In that case, GPU blits are in fact useful!

We were also only checking for !DISCARD_RANGE rather than MAP_READ,
which isn't a great idea for image maps, given the discussion in the
previous commit about image map semantics.

The original code was also just confusingly structured.  Make a helper
function with clearly defined cases where we want to bail on CPU maps.
parent a5cd4572
Pipeline #735106 waiting for manual action with stages
......@@ -2383,6 +2383,41 @@ can_promote_to_async(const struct iris_resource *res,
box->x + box->width);
}
static bool
prefer_cpu_access(const struct iris_resource *res,
const struct pipe_box *box,
enum pipe_map_flags usage,
unsigned level,
bool map_would_stall)
{
const enum iris_mmap_mode mmap_mode = iris_bo_mmap_mode(res->bo);
/* We must be able to map it. */
if (mmap_mode == IRIS_MMAP_NONE)
return false;
const bool write = usage & PIPE_MAP_WRITE;
const bool read = usage & PIPE_MAP_READ;
/* We want to avoid uncached reads because they are slow. */
if (read && mmap_mode != IRIS_MMAP_WB)
return false;
/* 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.
*/
if (map_would_stall && !read)
return false;
/* Use the GPU for writes if it would compress the data. */
if (write && isl_aux_usage_has_compression(res->aux.usage))
return false;
/* Writes & Cached CPU reads are fine as long as the primary is valid. */
return !iris_has_invalid_primary(res, level, 1, box->z, box->depth);
}
static void *
iris_transfer_map(struct pipe_context *ctx,
struct pipe_resource *resource,
......@@ -2486,30 +2521,8 @@ iris_transfer_map(struct pipe_context *ctx,
if (usage & PIPE_MAP_WRITE)
util_range_add(&res->base.b, &res->valid_buffer_range, box->x, box->x + box->width);
if (iris_bo_mmap_mode(res->bo) != IRIS_MMAP_NONE) {
/* GPU copies are not useful for buffer reads. Instead of stalling to
* read from the original buffer, we'd simply copy it to a temporary...
* then stall (a bit longer) to read from that buffer.
*
* Images are less clear-cut. Resolves can be destructive, removing
* some of the underlying compression, so we'd rather blit the data to
* a linear temporary and map that, to avoid the resolve.
*/
if (!(usage & PIPE_MAP_DISCARD_RANGE) &&
!iris_has_invalid_primary(res, level, 1, box->z, box->depth)) {
usage |= PIPE_MAP_DIRECTLY;
}
/* We can map directly if it wouldn't stall, there's no compression,
* and we aren't doing an uncached read.
*/
if (!map_would_stall &&
!isl_aux_usage_has_compression(res->aux.usage) &&
!((usage & PIPE_MAP_READ) &&
iris_bo_mmap_mode(res->bo) != IRIS_MMAP_WB)) {
usage |= PIPE_MAP_DIRECTLY;
}
}
if (prefer_cpu_access(res, box, usage, level, map_would_stall))
usage |= PIPE_MAP_DIRECTLY;
/* TODO: Teach iris_map_tiled_memcpy about Tile4... */
if (res->surf.tiling == ISL_TILING_4)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment