From 5194cbc76633e4458f1c5f1db388950cae0200a9 Mon Sep 17 00:00:00 2001 From: Nanley Chery Date: Thu, 29 Oct 2020 15:32:32 -0700 Subject: [PATCH] iris: Flush dmabufs during context flushes Currently, every modifier that uses CCS also lacks support for fast-clears. On gen9+, dmabufs may gain fast-cleared blocks through clear calls. On gen12, fast-clearing can occur during any rendering operation. Mark when dmabufs gain fast-cleared blocks and flush them during a context flush operation. Cc: mesa-stable Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3425 Tested-by: Simon Ser Reviewed-by: Kenneth Graunke Part-of: --- src/gallium/drivers/iris/iris_clear.c | 4 -- src/gallium/drivers/iris/iris_context.c | 50 +++++++++++++++++++++++++ src/gallium/drivers/iris/iris_context.h | 8 ++++ src/gallium/drivers/iris/iris_fence.c | 2 + src/gallium/drivers/iris/iris_resolve.c | 9 +++++ 5 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/iris/iris_clear.c b/src/gallium/drivers/iris/iris_clear.c index c2009ba7aee..9be44e460a0 100644 --- a/src/gallium/drivers/iris/iris_clear.c +++ b/src/gallium/drivers/iris/iris_clear.c @@ -107,10 +107,6 @@ can_fast_clear_color(struct iris_context *ice, return false; } - /* XXX: if (irb->mt->supports_fast_clear) - * see intel_miptree_create_for_dri_image() - */ - if (!iris_is_color_fast_clear_compatible(ice, res->surf.format, color)) return false; diff --git a/src/gallium/drivers/iris/iris_context.c b/src/gallium/drivers/iris/iris_context.c index 6005a2a6f3b..4064f55f681 100644 --- a/src/gallium/drivers/iris/iris_context.c +++ b/src/gallium/drivers/iris/iris_context.c @@ -185,6 +185,49 @@ iris_get_sample_position(struct pipe_context *ctx, out_value[1] = u.a.y[sample_index]; } +static bool +create_dirty_dmabuf_set(struct iris_context *ice) +{ + assert(ice->dirty_dmabufs == NULL); + + ice->dirty_dmabufs = _mesa_pointer_set_create(ice); + return ice->dirty_dmabufs != NULL; +} + +void +iris_mark_dirty_dmabuf(struct iris_context *ice, + struct pipe_resource *res) +{ + if (!_mesa_set_search(ice->dirty_dmabufs, res)) { + _mesa_set_add(ice->dirty_dmabufs, res); + pipe_reference(NULL, &res->reference); + } +} + +static void +clear_dirty_dmabuf_set(struct iris_context *ice) +{ + set_foreach(ice->dirty_dmabufs, entry) { + struct pipe_resource *res = (struct pipe_resource *)entry->key; + if (pipe_reference(&res->reference, NULL)) + res->screen->resource_destroy(res->screen, res); + } + + _mesa_set_clear(ice->dirty_dmabufs, NULL); +} + +void +iris_flush_dirty_dmabufs(struct iris_context *ice) +{ + set_foreach(ice->dirty_dmabufs, entry) { + struct pipe_resource *res = (struct pipe_resource *)entry->key; + ice->ctx.flush_resource(&ice->ctx, res); + } + + clear_dirty_dmabuf_set(ice); +} + + /** * Destroy a context, freeing any associated memory. */ @@ -197,6 +240,8 @@ iris_destroy_context(struct pipe_context *ctx) if (ctx->stream_uploader) u_upload_destroy(ctx->stream_uploader); + clear_dirty_dmabuf_set(ice); + screen->vtbl.destroy_state(ice); iris_destroy_program_cache(ice); iris_destroy_border_color_pool(ice); @@ -258,6 +303,11 @@ iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags) } ctx->const_uploader = ctx->stream_uploader; + if (!create_dirty_dmabuf_set(ice)) { + ralloc_free(ice); + return NULL; + } + ctx->destroy = iris_destroy_context; ctx->set_debug_callback = iris_set_debug_callback; ctx->set_device_reset_callback = iris_set_device_reset_callback; diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index d2a38acba1e..83d01380238 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -25,6 +25,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" +#include "util/set.h" #include "util/slab.h" #include "util/u_debug.h" #include "intel/blorp/blorp.h" @@ -545,6 +546,9 @@ struct iris_context { /** A device reset status callback for notifying that the GPU is hosed. */ struct pipe_device_reset_callback reset; + /** A set of dmabuf resources dirtied beyond their default aux-states. */ + struct set *dirty_dmabufs; + /** Slab allocator for iris_transfer_map objects. */ struct slab_child_pool transfer_pool; @@ -784,6 +788,10 @@ iris_create_context(struct pipe_screen *screen, void *priv, unsigned flags); void iris_lost_context_state(struct iris_batch *batch); +void iris_mark_dirty_dmabuf(struct iris_context *ice, + struct pipe_resource *res); +void iris_flush_dirty_dmabufs(struct iris_context *ice); + void iris_init_blit_functions(struct pipe_context *ctx); void iris_init_clear_functions(struct pipe_context *ctx); void iris_init_program_functions(struct pipe_context *ctx); diff --git a/src/gallium/drivers/iris/iris_fence.c b/src/gallium/drivers/iris/iris_fence.c index 958ae789191..75ef06117f7 100644 --- a/src/gallium/drivers/iris/iris_fence.c +++ b/src/gallium/drivers/iris/iris_fence.c @@ -241,6 +241,8 @@ iris_fence_flush(struct pipe_context *ctx, } } + iris_flush_dirty_dmabufs(ice); + if (!deferred) { for (unsigned i = 0; i < IRIS_BATCH_COUNT; i++) iris_batch_flush(&ice->batches[i]); diff --git a/src/gallium/drivers/iris/iris_resolve.c b/src/gallium/drivers/iris/iris_resolve.c index a5cd7f16b57..5e924ad6249 100644 --- a/src/gallium/drivers/iris/iris_resolve.c +++ b/src/gallium/drivers/iris/iris_resolve.c @@ -797,6 +797,15 @@ iris_resource_set_aux_state(struct iris_context *ice, ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_BINDINGS; } } + + if (res->mod_info && !res->mod_info->supports_clear_color) { + assert(res->mod_info->aux_usage != ISL_AUX_USAGE_NONE); + if (aux_state == ISL_AUX_STATE_CLEAR || + aux_state == ISL_AUX_STATE_COMPRESSED_CLEAR || + aux_state == ISL_AUX_STATE_PARTIAL_CLEAR) { + iris_mark_dirty_dmabuf(ice, &res->base); + } + } } enum isl_aux_usage