d3d12: clear stale per-context BO state at context destroy

Assisted-by: Claude Opus 4.7
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41322>
This commit is contained in:
Jesse Natalie 2026-05-01 14:42:33 -07:00 committed by Marge Bot
parent 381b56389c
commit 3e47a65811
4 changed files with 28 additions and 8 deletions

View file

@ -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 <dxguids/dxguids.h>
@ -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);

View file

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

View file

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

View file

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