diff options
author | Kenneth Graunke <kenneth@whitecape.org> | 2019-04-26 10:44:18 -0700 |
---|---|---|
committer | Kenneth Graunke <kenneth@whitecape.org> | 2019-08-22 18:31:17 -0700 |
commit | 2d799250346331a93b21678dc5605cff74dfa3a1 (patch) | |
tree | 752a8cbc542b3c9ddd7c2cd825ed1738f956874c | |
parent | 136629a1e3aace12297ff61c2ee32caa21aba99b (diff) |
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 <rafael.antognolli@intel.com>
-rw-r--r-- | src/gallium/drivers/iris/iris_resource.c | 44 | ||||
-rw-r--r-- | 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 cc19e601a75a..a8d0291862eb 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 1fdabb407335..304339eb470f 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, |