From 2d799250346331a93b21678dc5605cff74dfa3a1 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 26 Apr 2019 10:44:18 -0700 Subject: [PATCH] iris: Avoid unnecessary resolves on transfer maps We were always resolving the buffer as if we were accessing it via CPU maps, which don't understand any auxiliary surfaces. But we often copy to a temporary using BLORP, which understands compression just fine. So we can avoid the resolve, and accelerate the copy as well. Fixes: 9d1334d2a0f ("iris: Use copy_region and staging resources to avoid transfer stalls") Reviewed-by: Rafael Antognolli --- src/gallium/drivers/iris/iris_resource.c | 44 +++++++++++++++--------- src/gallium/drivers/iris/iris_resource.h | 3 ++ 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index cc19e601a75..a8d0291862e 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -1707,21 +1707,29 @@ iris_transfer_map(struct pipe_context *ctx, usage |= PIPE_TRANSFER_DISCARD_RANGE; } - bool map_would_stall = false; - - if (resource->target != PIPE_BUFFER) { - iris_resource_access_raw(ice, &ice->batches[IRIS_BATCH_RENDER], res, - level, box->z, box->depth, - usage & PIPE_TRANSFER_WRITE); - } - if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED) && can_promote_to_async(res, box, usage)) { usage |= PIPE_TRANSFER_UNSYNCHRONIZED; } + bool need_resolve = false; + bool need_color_resolve = false; + + if (resource->target != PIPE_BUFFER) { + bool need_hiz_resolve = iris_resource_level_has_hiz(res, level); + + need_color_resolve = + (res->aux.usage == ISL_AUX_USAGE_CCS_D || + res->aux.usage == ISL_AUX_USAGE_CCS_E) && + iris_has_color_unresolved(res, level, 1, box->z, box->depth); + + need_resolve = need_color_resolve || need_hiz_resolve; + } + + bool map_would_stall = false; + if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { - map_would_stall = resource_is_busy(ice, res); + map_would_stall = need_resolve || resource_is_busy(ice, res); if (map_would_stall && (usage & PIPE_TRANSFER_DONTBLOCK) && (usage & PIPE_TRANSFER_MAP_DIRECTLY)) @@ -1769,25 +1777,29 @@ iris_transfer_map(struct pipe_context *ctx, * temporary and map that, to avoid the resolve. (It might be better to * a tiled temporary and use the tiled_memcpy paths...) */ - if (!(usage & PIPE_TRANSFER_DISCARD_RANGE) && - res->aux.usage != ISL_AUX_USAGE_CCS_E && - res->aux.usage != ISL_AUX_USAGE_CCS_D) { + if (!(usage & PIPE_TRANSFER_DISCARD_RANGE) && !need_color_resolve) no_gpu = true; - } const struct isl_format_layout *fmtl = isl_format_get_layout(surf->format); if (fmtl->txc == ISL_TXC_ASTC) no_gpu = true; if ((map_would_stall || res->aux.usage == ISL_AUX_USAGE_CCS_E) && !no_gpu) { - /* If we need a synchronous mapping and the resource is busy, - * we copy to/from a linear temporary buffer using the GPU. + /* If we need a synchronous mapping and the resource is busy, or needs + * resolving, we copy to/from a linear temporary buffer using the GPU. */ map->batch = &ice->batches[IRIS_BATCH_RENDER]; map->blorp = &ice->blorp; iris_map_copy_region(map); } else { - /* Otherwise we're free to map on the CPU. Flush if needed. */ + /* Otherwise we're free to map on the CPU. */ + + if (need_resolve) { + iris_resource_access_raw(ice, &ice->batches[IRIS_BATCH_RENDER], res, + level, box->z, box->depth, + usage & PIPE_TRANSFER_WRITE); + } + if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { for (int i = 0; i < IRIS_BATCH_COUNT; i++) { if (iris_batch_references(&ice->batches[i], res->bo)) diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h index 1fdabb40733..304339eb470 100644 --- a/src/gallium/drivers/iris/iris_resource.h +++ b/src/gallium/drivers/iris/iris_resource.h @@ -436,6 +436,9 @@ void iris_resource_check_level_layer(const struct iris_resource *res, bool iris_resource_level_has_hiz(const struct iris_resource *res, uint32_t level); +bool iris_has_color_unresolved(const struct iris_resource *res, + unsigned start_level, unsigned num_levels, + unsigned start_layer, unsigned num_layers); enum isl_aux_usage iris_resource_render_aux_usage(struct iris_context *ice, struct iris_resource *res, -- 2.30.2