Module: Mesa Branch: main Commit: 8a3ac9852436f1a0296eff4912024af2e576ee65 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=8a3ac9852436f1a0296eff4912024af2e576ee65
Author: Giancarlo Devich <[email protected]> Date: Tue Mar 14 11:26:36 2023 -0700 d3d12: Track up to 16 contexts worth of pending barriers locally in bos Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21909> --- src/gallium/drivers/d3d12/d3d12_bufmgr.h | 1 + src/gallium/drivers/d3d12/d3d12_context.h | 1 + src/gallium/drivers/d3d12/d3d12_resource_state.cpp | 78 +++++++++++++++------- 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_bufmgr.h b/src/gallium/drivers/d3d12/d3d12_bufmgr.h index 74639a415e5..170580601f6 100644 --- a/src/gallium/drivers/d3d12/d3d12_bufmgr.h +++ b/src/gallium/drivers/d3d12/d3d12_bufmgr.h @@ -59,6 +59,7 @@ struct d3d12_bo { int64_t last_used_timestamp; uint64_t last_used_fence; enum d3d12_residency_status residency_status; + uint16_t local_needs_resolve_state; unsigned local_context_state_mask; d3d12_context_state_table_entry local_context_states[16]; diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h index 460abfa7940..2b8c1b72b42 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.h +++ b/src/gallium/drivers/d3d12/d3d12_context.h @@ -187,6 +187,7 @@ struct d3d12_context { struct util_dynarray recently_destroyed_bos; struct util_dynarray barrier_scratch; struct set *pending_barriers_bos; + struct util_dynarray local_pending_barriers_bos; struct pipe_constant_buffer cbufs[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; struct pipe_framebuffer_state fb; diff --git a/src/gallium/drivers/d3d12/d3d12_resource_state.cpp b/src/gallium/drivers/d3d12/d3d12_resource_state.cpp index c978b4670d0..71906af92db 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource_state.cpp +++ b/src/gallium/drivers/d3d12/d3d12_resource_state.cpp @@ -200,6 +200,7 @@ d3d12_context_state_table_init(struct d3d12_context *ctx) { ctx->bo_state_table = _mesa_hash_table_u64_create(nullptr); ctx->pending_barriers_bos = _mesa_pointer_set_create(nullptr); + util_dynarray_init(&ctx->local_pending_barriers_bos, nullptr); } void @@ -213,7 +214,9 @@ d3d12_context_state_table_destroy(struct d3d12_context *ctx) util_dynarray_fini(&ctx->barrier_scratch); if (ctx->state_fixup_cmdlist) ctx->state_fixup_cmdlist->Release(); + _mesa_set_destroy(ctx->pending_barriers_bos, nullptr); + util_dynarray_fini(&ctx->local_pending_barriers_bos); } static unsigned @@ -462,7 +465,16 @@ d3d12_transition_resource_state(struct d3d12_context *ctx, d3d12_context_state_table_entry *state_entry = find_or_create_state_entry(ctx, res->bo); if (flags & D3D12_TRANSITION_FLAG_ACCUMULATE_STATE) { set_desired_resource_state(&state_entry->desired, state); - _mesa_set_add(ctx->pending_barriers_bos, res->bo); + + if (ctx->id != D3D12_CONTEXT_NO_ID) { + if ((res->bo->local_needs_resolve_state & (1 << ctx->id)) == 0) { + util_dynarray_append(&ctx->local_pending_barriers_bos, struct d3d12_bo*, res->bo); + res->bo->local_needs_resolve_state |= (1 << ctx->id); + } + } + else + _mesa_set_add(ctx->pending_barriers_bos, res->bo); + } else if (state_entry->batch_end.homogenous) { append_barrier(ctx, res->bo, state_entry, state, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, false); } else { @@ -511,40 +523,56 @@ d3d12_transition_subresources_state(struct d3d12_context *ctx, } } - if (is_accumulate) - _mesa_set_add(ctx->pending_barriers_bos, res->bo); + if (is_accumulate) { + if (ctx->id != D3D12_CONTEXT_NO_ID) { + if ((res->bo->local_needs_resolve_state & (1 << ctx->id)) == 0) { + util_dynarray_append(&ctx->local_pending_barriers_bos, struct d3d12_bo*, res->bo); + res->bo->local_needs_resolve_state |= (1 << ctx->id); + } + } + else + _mesa_set_add(ctx->pending_barriers_bos, res->bo); + } } -void -d3d12_apply_resource_states(struct d3d12_context *ctx, bool is_implicit_dispatch) +static void apply_resource_state(struct d3d12_context *ctx, bool is_implicit_dispatch, d3d12_bo *bo) { - set_foreach_remove(ctx->pending_barriers_bos, entry) { - d3d12_bo *bo = (d3d12_bo *)entry->key; + d3d12_context_state_table_entry* state_entry = find_or_create_state_entry(ctx, bo); + d3d12_desired_resource_state* destination_state = &state_entry->desired; + d3d12_resource_state* current_state = &state_entry->batch_end; - d3d12_context_state_table_entry *state_entry = find_or_create_state_entry(ctx, bo); - d3d12_desired_resource_state *destination_state = &state_entry->desired; - d3d12_resource_state *current_state = &state_entry->batch_end; + // Figure out the set of subresources that are transitioning + bool all_resources_at_once = current_state->homogenous && destination_state->homogenous; - // Figure out the set of subresources that are transitioning - bool all_resources_at_once = current_state->homogenous && destination_state->homogenous; + UINT num_subresources = all_resources_at_once ? 1 : current_state->num_subresources; + for (UINT i = 0; i < num_subresources; ++i) { + D3D12_RESOURCE_STATES after = get_desired_subresource_state(destination_state, i); + UINT subresource = num_subresources == 1 ? D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES : i; - UINT num_subresources = all_resources_at_once ? 1 : current_state->num_subresources; - for (UINT i = 0; i < num_subresources; ++i) { - D3D12_RESOURCE_STATES after = get_desired_subresource_state(destination_state, i); - UINT subresource = num_subresources == 1 ? D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES : i; + // Is this subresource currently being used, or is it just being iterated over? + if (after == UNKNOWN_RESOURCE_STATE) { + // This subresource doesn't have any transition requested - move on to the next. + continue; + } - // Is this subresource currently being used, or is it just being iterated over? - if (after == UNKNOWN_RESOURCE_STATE) { - // This subresource doesn't have any transition requested - move on to the next. - continue; - } + append_barrier(ctx, bo, state_entry, after, subresource, is_implicit_dispatch); + } - append_barrier(ctx, bo, state_entry, after, subresource, is_implicit_dispatch); - } + // Update destination states. + reset_desired_resource_state(destination_state); +} - // Update destination states. - reset_desired_resource_state(destination_state); +void +d3d12_apply_resource_states(struct d3d12_context *ctx, bool is_implicit_dispatch) +{ + set_foreach_remove(ctx->pending_barriers_bos, entry) + apply_resource_state(ctx, is_implicit_dispatch, (d3d12_bo *)entry->key); + + util_dynarray_foreach(&ctx->local_pending_barriers_bos, struct d3d12_bo*, bo) { + apply_resource_state(ctx, is_implicit_dispatch, *bo); + (*bo)->local_needs_resolve_state &= ~(1 << ctx->id); } + util_dynarray_clear(&ctx->local_pending_barriers_bos); if (ctx->barrier_scratch.size) { ctx->cmdlist->ResourceBarrier(util_dynarray_num_elements(&ctx->barrier_scratch, D3D12_RESOURCE_BARRIER),
