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 <contact@emersion.fr>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7384>
(cherry picked from commit 5194cbc766)
This commit is contained in:
Nanley Chery 2020-10-29 15:32:32 -07:00 committed by Dylan Baker
parent 151bff94c3
commit 06c593be5b
6 changed files with 70 additions and 5 deletions

View file

@ -4009,7 +4009,7 @@
"description": "iris: Flush dmabufs during context flushes",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"master_sha": null,
"because_sha": null
},

View file

@ -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;

View file

@ -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);
@ -261,6 +306,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;

View file

@ -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"
@ -536,6 +537,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;
@ -772,6 +776,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);

View file

@ -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]);

View file

@ -808,6 +808,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