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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user