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>
This commit is contained in:
Nanley Chery
2020-10-29 15:32:32 -07:00
committed by Marge Bot
parent c488fb6dfe
commit 5194cbc766
5 changed files with 69 additions and 4 deletions
-4
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;
+50
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);
@@ -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;
+8
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"
@@ -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);
+2
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]);
+9
View File
@@ -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