d3d12: transfer batch local_bos refs to screen at submit

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:46:06 -07:00 committed by Marge Bot
parent 3e47a65811
commit a518b7f103
2 changed files with 44 additions and 1 deletions

View file

@ -60,6 +60,7 @@ d3d12_init_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
_mesa_key_pointer_equal);
batch->local_bos = UTIL_DYNARRAY_INIT;
batch->local_bo_pending = UTIL_DYNARRAY_INIT;
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
batch->surfaces = _mesa_set_create(NULL, _mesa_hash_pointer,
@ -183,13 +184,17 @@ d3d12_reset_batch(struct d3d12_context *ctx, struct d3d12_batch *batch, uint64_t
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
_mesa_set_clear(batch->objects, delete_object);
util_dynarray_foreach(&batch->local_bos, d3d12_bo*, bo) {
(*bo)->local_reference_mask[batch->ctx_id] &= ~(1 << batch->ctx_index);
delete_bo(*bo);
}
util_dynarray_clear(&batch->local_bos);
util_dynarray_foreach(&batch->local_bo_pending, struct d3d12_pending_free_entry*, entry)
FREE(*entry);
util_dynarray_clear(&batch->local_bo_pending);
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if (d3d12_screen(ctx->base.screen)->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
_mesa_hash_table_clear(batch->sampler_tables, delete_sampler_view_table);
@ -234,6 +239,7 @@ d3d12_destroy_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
_mesa_set_destroy(batch->objects, NULL);
util_dynarray_fini(&batch->local_bos);
util_dynarray_fini(&batch->local_bo_pending);
}
void
@ -320,6 +326,38 @@ d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
batch->fence = d3d12_create_fence(screen, true);
if (batch->fence) {
unsigned n_local = util_dynarray_num_elements(&batch->local_bo_pending,
struct d3d12_pending_free_entry*);
bool all_ok = n_local > 0;
struct d3d12_pending_free_entry **entries =
(struct d3d12_pending_free_entry **)util_dynarray_begin(&batch->local_bo_pending);
for (unsigned i = 0; i < n_local; ++i) {
if (!entries[i]) {
all_ok = false;
break;
}
}
if (all_ok) {
struct d3d12_bo **bos =
(struct d3d12_bo **)util_dynarray_begin(&batch->local_bos);
uint64_t fv = batch->fence->value;
mtx_lock(&screen->pending_free_lock);
for (unsigned i = 0; i < n_local; ++i) {
entries[i]->fence_value = fv;
list_addtail(&entries[i]->link, &screen->pending_free_list);
}
mtx_unlock(&screen->pending_free_lock);
for (unsigned i = 0; i < n_local; ++i)
bos[i]->local_reference_mask[batch->ctx_id] &= ~(1 << batch->ctx_index);
util_dynarray_clear(&batch->local_bos);
util_dynarray_clear(&batch->local_bo_pending);
}
}
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
/* batch->queries is NULL when no grfx supported */
if (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
@ -365,6 +403,10 @@ d3d12_batch_acquire_reference(struct d3d12_batch *batch,
if ((bo->local_reference_mask[batch->ctx_id] & (1 << batch->ctx_index)) == 0) {
d3d12_bo_reference(bo);
util_dynarray_append(&batch->local_bos, bo);
struct d3d12_pending_free_entry *entry = MALLOC_STRUCT(d3d12_pending_free_entry);
if (entry)
entry->bo = bo;
util_dynarray_append(&batch->local_bo_pending, entry);
bo->local_reference_mask[batch->ctx_id] |= (1 << batch->ctx_index);
bo->local_reference_state[batch->ctx_id][batch->ctx_index] = batch_bo_reference_none;
}

View file

@ -47,6 +47,7 @@ struct d3d12_batch {
struct hash_table *bos;
struct util_dynarray local_bos;
struct util_dynarray local_bo_pending;
struct hash_table *sampler_tables;
struct set *sampler_views;
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS