diff --git a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp index 1d161d97eaf..7dfe8a23d90 100644 --- a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp +++ b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp @@ -30,6 +30,7 @@ #include "pipebuffer/pb_bufmgr.h" #include "util/format/u_format.h" +#include "util/set.h" #include "util/u_memory.h" #include @@ -195,9 +196,13 @@ d3d12_bo_unreference(struct d3d12_bo *bo) /* MSVC's offsetof fails when the name is ambiguous between struct and function */ typedef struct d3d12_context d3d12_context_type; - list_for_each_entry(d3d12_context_type, ctx, &bo->screen->context_list, context_list_entry) - if (ctx->id == D3D12_CONTEXT_NO_ID) + list_for_each_entry(d3d12_context_type, ctx, &bo->screen->context_list, context_list_entry) { + if (ctx->id == D3D12_CONTEXT_NO_ID) { util_dynarray_append_typed(&ctx->recently_destroyed_bos, uint64_t, bo->unique_id); + } else if (bo->local_context_state_mask & (1u << ctx->id)) { + _mesa_set_remove_key(ctx->local_state_bos, bo); + } + } mtx_unlock(&bo->screen->submit_mutex); diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h index 75c2cc5d9f3..3d4df5f9f6f 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.h +++ b/src/gallium/drivers/d3d12/d3d12_context.h @@ -184,6 +184,7 @@ struct d3d12_context { ID3D12GraphicsCommandList8 *cmdlist8; ID3D12GraphicsCommandList *state_fixup_cmdlist; struct hash_table_u64 *bo_state_table; + struct set *local_state_bos; struct blitter_context *blitter; uint flags; bool queries_disabled; diff --git a/src/gallium/drivers/d3d12/d3d12_context_common.cpp b/src/gallium/drivers/d3d12/d3d12_context_common.cpp index beca58ffc23..77489d37eee 100644 --- a/src/gallium/drivers/d3d12/d3d12_context_common.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context_common.cpp @@ -49,6 +49,7 @@ #include "indices/u_primconvert.h" #include "util/u_atomic.h" #include "util/u_blitter.h" +#include "util/set.h" #include "util/u_dual_blend.h" #include "util/u_framebuffer.h" #include "util/u_helpers.h" @@ -85,12 +86,6 @@ d3d12_context_destroy(struct pipe_context *pctx) } struct d3d12_screen *screen = d3d12_screen(pctx->screen); - mtx_lock(&screen->submit_mutex); - list_del(&ctx->context_list_entry); - if (ctx->id != D3D12_CONTEXT_NO_ID) - screen->context_id_list[screen->context_id_count++] = ctx->id; - mtx_unlock(&screen->submit_mutex); - #ifdef HAVE_GALLIUM_D3D12_GRAPHICS if ((screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) && !(ctx->flags & PIPE_CONTEXT_MEDIA_ONLY)) { @@ -108,6 +103,22 @@ d3d12_context_destroy(struct pipe_context *pctx) if (ctx->cmdlist8) ctx->cmdlist8->Release(); + mtx_lock(&screen->submit_mutex); + list_del(&ctx->context_list_entry); + if (ctx->id != D3D12_CONTEXT_NO_ID) { + unsigned context_bit = 1u << ctx->id; + set_foreach(ctx->local_state_bos, entry) { + struct d3d12_bo *bo = (struct d3d12_bo *)entry->key; + if (bo->local_context_state_mask & context_bit) { + d3d12_destroy_context_state_table_entry(&bo->local_context_states[ctx->id]); + bo->local_context_state_mask &= ~context_bit; + } + } + _mesa_set_clear(ctx->local_state_bos, nullptr); + screen->context_id_list[screen->context_id_count++] = ctx->id; + } + mtx_unlock(&screen->submit_mutex); + #ifdef HAVE_GALLIUM_D3D12_GRAPHICS if ((screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) && !(ctx->flags & PIPE_CONTEXT_MEDIA_ONLY)) { #ifdef _WIN32 diff --git a/src/gallium/drivers/d3d12/d3d12_resource_state.cpp b/src/gallium/drivers/d3d12/d3d12_resource_state.cpp index 412ac2bda8b..ead8c5bd89e 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource_state.cpp +++ b/src/gallium/drivers/d3d12/d3d12_resource_state.cpp @@ -209,6 +209,7 @@ void d3d12_context_state_table_init(struct d3d12_context *ctx) { ctx->bo_state_table = _mesa_hash_table_u64_create(nullptr); + ctx->local_state_bos = _mesa_pointer_set_create(nullptr); ctx->pending_barriers_bos = _mesa_pointer_set_create(nullptr); util_dynarray_init(&ctx->local_pending_barriers_bos, nullptr); } @@ -221,6 +222,7 @@ d3d12_context_state_table_destroy(struct d3d12_context *ctx) free(entry->data); } _mesa_hash_table_u64_destroy(ctx->bo_state_table); + _mesa_set_destroy(ctx->local_state_bos, nullptr); util_dynarray_fini(&ctx->barrier_scratch); if (ctx->state_fixup_cmdlist) ctx->state_fixup_cmdlist->Release(); @@ -266,6 +268,7 @@ find_or_create_state_entry(struct d3d12_context *ctx, d3d12_bo *bo) if ((bo->local_context_state_mask & context_bit) == 0) { init_state_table_entry(&bo->local_context_states[ctx->id], bo); bo->local_context_state_mask |= context_bit; + _mesa_set_add(ctx->local_state_bos, bo); } return &bo->local_context_states[ctx->id]; }