d3d12: add screen pending-free list plumbing

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:38:22 -07:00 committed by Marge Bot
parent af746cc2a6
commit 381b56389c
4 changed files with 72 additions and 0 deletions

View file

@ -215,6 +215,57 @@ d3d12_bo_unreference(struct d3d12_bo *bo)
}
}
bool
d3d12_screen_reclaim_completed(struct d3d12_screen *screen)
{
uint64_t completed = screen->fence->GetCompletedValue();
struct list_head retired;
list_inithead(&retired);
mtx_lock(&screen->pending_free_lock);
list_for_each_entry_safe(struct d3d12_pending_free_entry, entry,
&screen->pending_free_list, link) {
if (entry->fence_value > completed)
break;
list_del(&entry->link);
list_addtail(&entry->link, &retired);
}
mtx_unlock(&screen->pending_free_lock);
bool dropped = !list_is_empty(&retired);
list_for_each_entry_safe(struct d3d12_pending_free_entry, entry, &retired, link) {
d3d12_bo_unreference(entry->bo);
FREE(entry);
}
return dropped;
}
bool
d3d12_screen_reclaim_one(struct d3d12_screen *screen)
{
uint64_t target = 0;
bool have_target = false;
mtx_lock(&screen->pending_free_lock);
if (!list_is_empty(&screen->pending_free_list)) {
struct d3d12_pending_free_entry *head =
list_first_entry(&screen->pending_free_list,
struct d3d12_pending_free_entry, link);
target = head->fence_value;
have_target = true;
}
mtx_unlock(&screen->pending_free_lock);
if (!have_target)
return false;
if (screen->fence->GetCompletedValue() < target)
screen->fence->SetEventOnCompletion(target, nullptr);
d3d12_screen_reclaim_completed(screen);
return true;
}
void *
d3d12_bo_map(struct d3d12_bo *bo, D3D12_RANGE *range)
{

View file

@ -158,6 +158,18 @@ d3d12_bo_map(struct d3d12_bo *bo, D3D12_RANGE *range);
void
d3d12_bo_unmap(struct d3d12_bo *bo, D3D12_RANGE *range);
struct d3d12_pending_free_entry {
struct list_head link;
struct d3d12_bo *bo;
uint64_t fence_value;
};
bool
d3d12_screen_reclaim_completed(struct d3d12_screen *screen);
bool
d3d12_screen_reclaim_one(struct d3d12_screen *screen);
struct pb_manager *
d3d12_bufmgr_create(struct d3d12_screen *screen);

View file

@ -598,6 +598,9 @@ d3d12_is_format_supported(struct pipe_screen *pscreen,
void
d3d12_deinit_screen(struct d3d12_screen *screen)
{
while (d3d12_screen_reclaim_one(screen))
;
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
if (screen->rtv_pool) {
@ -666,6 +669,7 @@ d3d12_destroy_screen(struct d3d12_screen *screen)
{
slab_destroy_parent(&screen->transfer_pool);
mtx_destroy(&screen->submit_mutex);
mtx_destroy(&screen->pending_free_lock);
mtx_destroy(&screen->descriptor_pool_mutex);
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
@ -1300,6 +1304,8 @@ d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LU
screen->adapter_luid = *adapter_luid;
mtx_init(&screen->descriptor_pool_mutex, mtx_plain);
mtx_init(&screen->submit_mutex, mtx_plain);
mtx_init(&screen->pending_free_lock, mtx_plain);
list_inithead(&screen->pending_free_list);
list_inithead(&screen->context_list);
screen->context_id_count = 16;

View file

@ -87,6 +87,9 @@ struct d3d12_screen {
ID3D12Fence *fence;
uint64_t fence_value;
mtx_t pending_free_lock;
struct list_head pending_free_list;
struct list_head residency_list;
ID3D12Fence *residency_fence;
uint64_t residency_fence_value;