summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2019-04-26 10:44:18 -0700
committerKenneth Graunke <kenneth@whitecape.org>2019-08-22 18:31:17 -0700
commit2d799250346331a93b21678dc5605cff74dfa3a1 (patch)
tree752a8cbc542b3c9ddd7c2cd825ed1738f956874c
parent136629a1e3aace12297ff61c2ee32caa21aba99b (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.c44
-rw-r--r--src/gallium/drivers/iris/iris_resource.h3
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,