From bc9616129e5c29ebc4808539079df55d9f8471c4 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Mon, 18 Jul 2022 16:11:59 -0700 Subject: [PATCH] d3d12: Move current resource state to new files Reviewed-by: Bill Kristiansen Part-of: --- .../drivers/d3d12/D3D12ResourceState.cpp | 122 +++--------------- .../drivers/d3d12/D3D12ResourceState.h | 57 +------- src/gallium/drivers/d3d12/d3d12_context.cpp | 4 +- src/gallium/drivers/d3d12/d3d12_resource.h | 2 +- .../drivers/d3d12/d3d12_resource_state.cpp | 93 +++++++++++++ .../drivers/d3d12/d3d12_resource_state.h | 43 ++++++ 6 files changed, 166 insertions(+), 155 deletions(-) diff --git a/src/gallium/drivers/d3d12/D3D12ResourceState.cpp b/src/gallium/drivers/d3d12/D3D12ResourceState.cpp index f7f0830aa26..ad777507294 100644 --- a/src/gallium/drivers/d3d12/D3D12ResourceState.cpp +++ b/src/gallium/drivers/d3d12/D3D12ResourceState.cpp @@ -24,87 +24,6 @@ #include "D3D12ResourceState.h" #define UNKNOWN_RESOURCE_STATE (D3D12_RESOURCE_STATES) 0x8000u -//---------------------------------------------------------------------------------------------------------------------------------- -void CCurrentResourceState::ConvertToSubresourceTracking() -{ - if (m_bAllSubresourcesSame && m_spLogicalState.size() > 1) - { - std::fill(m_spLogicalState.begin() + 1, m_spLogicalState.end(), m_spLogicalState[0]); - m_bAllSubresourcesSame = false; - } -} - -//---------------------------------------------------------------------------------------------------------------------------------- -CCurrentResourceState::CCurrentResourceState(UINT SubresourceCount, bool bSimultaneousAccess) - : m_bSimultaneousAccess(bSimultaneousAccess) - , m_spLogicalState(SubresourceCount) -{ - m_spLogicalState[0] = LogicalState{}; -} - -//---------------------------------------------------------------------------------------------------------------------------------- -D3D12_RESOURCE_STATES CCurrentResourceState::StateIfPromoted(D3D12_RESOURCE_STATES State, UINT SubresourceIndex) -{ - D3D12_RESOURCE_STATES Result = D3D12_RESOURCE_STATE_COMMON; - - if (m_bSimultaneousAccess || !!(State & ( - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | - D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | - D3D12_RESOURCE_STATE_COPY_SOURCE | - D3D12_RESOURCE_STATE_COPY_DEST))) - { - auto CurState = GetLogicalSubresourceState(SubresourceIndex); - - // If the current state is COMMON... - if(CurState.State == D3D12_RESOURCE_STATE_COMMON) - { - // ...then promotion is allowed - Result = State; - } - // If the current state is a read state resulting from previous promotion... - else if(CurState.IsPromotedState && !!(CurState.State & D3D12_RESOURCE_STATE_GENERIC_READ)) - { - // ...then (accumulated) promotion is allowed - Result = State |= CurState.State; - } - } - - return Result; -} - - - -//---------------------------------------------------------------------------------------------------------------------------------- -void CCurrentResourceState::SetLogicalResourceState(LogicalState const& State) -{ - m_bAllSubresourcesSame = true; - m_spLogicalState[0] = State; -} - -//---------------------------------------------------------------------------------------------------------------------------------- -void CCurrentResourceState::SetLogicalSubresourceState(UINT SubresourceIndex, LogicalState const& State) -{ - ConvertToSubresourceTracking(); - m_spLogicalState[SubresourceIndex] = State; -} - -//---------------------------------------------------------------------------------------------------------------------------------- -auto CCurrentResourceState::GetLogicalSubresourceState(UINT SubresourceIndex) const -> LogicalState const& -{ - if (AreAllSubresourcesSame()) - { - SubresourceIndex = 0; - } - return m_spLogicalState[SubresourceIndex]; -} - -//---------------------------------------------------------------------------------------------------------------------------------- -void CCurrentResourceState::Reset() -{ - m_bAllSubresourcesSame = true; - m_spLogicalState[0] = LogicalState{}; -} - //---------------------------------------------------------------------------------------------------------------------------------- ResourceStateManager::ResourceStateManager() { @@ -177,30 +96,30 @@ void ResourceStateManager::ApplyResourceTransitionsPreamble(bool IsImplicitDispa //---------------------------------------------------------------------------------------------------------------------------------- void ResourceStateManager::AddCurrentStateUpdate(TransitionableResourceState& Resource, - CCurrentResourceState& CurrentState, + d3d12_resource_state *CurrentState, UINT SubresourceIndex, - const CCurrentResourceState::LogicalState &NewLogicalState) + const d3d12_subresource_state *NewLogicalState) { if (SubresourceIndex == D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES) { - CurrentState.SetLogicalResourceState(NewLogicalState); + d3d12_set_resource_state(CurrentState, NewLogicalState); } else { - CurrentState.SetLogicalSubresourceState(SubresourceIndex, NewLogicalState); + d3d12_set_subresource_state(CurrentState, SubresourceIndex, NewLogicalState); } } //---------------------------------------------------------------------------------------------------------------------------------- void ResourceStateManager::ProcessTransitioningResource(ID3D12Resource* pTransitioningResource, TransitionableResourceState& TransitionableResourceState, - CCurrentResourceState& CurrentState, + d3d12_resource_state *CurrentState, UINT NumTotalSubresources, UINT64 ExecutionId) { // Figure out the set of subresources that are transitioning auto& DestinationState = TransitionableResourceState.m_DesiredState; - bool bAllSubresourcesAtOnce = CurrentState.AreAllSubresourcesSame() && DestinationState.homogenous; + bool bAllSubresourcesAtOnce = CurrentState->homogenous && DestinationState.homogenous; D3D12_RESOURCE_BARRIER TransitionDesc; memset(&TransitionDesc, 0, sizeof(TransitionDesc)); @@ -249,7 +168,7 @@ void ResourceStateManager::ProcessTransitioningResource(ID3D12Resource* pTransit //---------------------------------------------------------------------------------------------------------------------------------- void ResourceStateManager::ProcessTransitioningSubresourceExplicit( - CCurrentResourceState& CurrentState, + d3d12_resource_state *CurrentState, UINT SubresourceIndex, D3D12_RESOURCE_STATES after, TransitionableResourceState& TransitionableResourceState, @@ -261,25 +180,26 @@ void ResourceStateManager::ProcessTransitioningSubresourceExplicit( // Any non-simultaneous-access resources currently in the // COMMON state can still be implicitly promoted to SRV, // NON_PS_SRV, COPY_SRC, or COPY_DEST. - CCurrentResourceState::LogicalState CurrentLogicalState = CurrentState.GetLogicalSubresourceState(SubresourceIndex); + d3d12_subresource_state CurrentLogicalState = *d3d12_get_subresource_state(CurrentState, SubresourceIndex); // If the last time this logical state was set was in a different // execution period and is decayable then decay the current state // to COMMON - if(ExecutionId != CurrentLogicalState.ExecutionId && CurrentLogicalState.MayDecay) + if(ExecutionId != CurrentLogicalState.execution_id && CurrentLogicalState.may_decay) { - CurrentLogicalState.State = D3D12_RESOURCE_STATE_COMMON; - CurrentLogicalState.IsPromotedState = false; + CurrentLogicalState.state = D3D12_RESOURCE_STATE_COMMON; + CurrentLogicalState.is_promoted = false; } bool MayDecay = false; bool IsPromotion = false; // If not promotable then StateIfPromoted will be D3D12_RESOURCE_STATE_COMMON - auto StateIfPromoted = CurrentState.StateIfPromoted(after, SubresourceIndex); + auto StateIfPromoted = + d3d12_resource_state_if_promoted(after, CurrentState->supports_simultaneous_access, &CurrentLogicalState); - if ( D3D12_RESOURCE_STATE_COMMON == StateIfPromoted ) + if (D3D12_RESOURCE_STATE_COMMON == StateIfPromoted) { - if (CurrentLogicalState.State == D3D12_RESOURCE_STATE_UNORDERED_ACCESS && + if (CurrentLogicalState.state == D3D12_RESOURCE_STATE_UNORDERED_ACCESS && after == D3D12_RESOURCE_STATE_UNORDERED_ACCESS && m_IsImplicitDispatch) { @@ -287,15 +207,15 @@ void ResourceStateManager::ProcessTransitioningSubresourceExplicit( UAVBarrier.UAV.pResource = TransitionDesc.Transition.pResource; m_vResourceBarriers.push_back(UAVBarrier); } - else if (TransitionRequired(CurrentLogicalState.State, /*inout*/ after)) + else if (TransitionRequired(CurrentLogicalState.state, /*inout*/ after)) { // Insert a single concrete barrier (for non-simultaneous access resources). - TransitionDesc.Transition.StateBefore = D3D12_RESOURCE_STATES(CurrentLogicalState.State); + TransitionDesc.Transition.StateBefore = D3D12_RESOURCE_STATES(CurrentLogicalState.state); TransitionDesc.Transition.StateAfter = D3D12_RESOURCE_STATES(after); assert(TransitionDesc.Transition.StateBefore != TransitionDesc.Transition.StateAfter); m_vResourceBarriers.push_back(TransitionDesc); // throw( bad_alloc ) - MayDecay = CurrentState.SupportsSimultaneousAccess() && !d3d12_is_write_state(after); + MayDecay = CurrentState->supports_simultaneous_access && !d3d12_is_write_state(after); IsPromotion = false; } } @@ -310,11 +230,11 @@ void ResourceStateManager::ProcessTransitioningSubresourceExplicit( } } - CCurrentResourceState::LogicalState NewLogicalState{after, ExecutionId, IsPromotion, MayDecay}; + d3d12_subresource_state NewLogicalState{after, ExecutionId, IsPromotion, MayDecay}; AddCurrentStateUpdate(TransitionableResourceState, CurrentState, TransitionDesc.Transition.Subresource, - NewLogicalState); + &NewLogicalState); } //---------------------------------------------------------------------------------------------------------------------------------- @@ -353,7 +273,7 @@ void ResourceStateManager::ApplyAllResourceTransitions(ID3D12GraphicsCommandList ProcessTransitioningResource( pResource, CurResource, - CurResource.GetCurrentState(), + &CurResource.m_currentState, CurResource.NumSubresources(), ExecutionId); }); diff --git a/src/gallium/drivers/d3d12/D3D12ResourceState.h b/src/gallium/drivers/d3d12/D3D12ResourceState.h index 055c641fffd..83ad793013d 100644 --- a/src/gallium/drivers/d3d12/D3D12ResourceState.h +++ b/src/gallium/drivers/d3d12/D3D12ResourceState.h @@ -40,48 +40,6 @@ #define RESOURCE_STATE_VALID_INTERNAL_BITS 0x2fffff //--------------------------------------------------------------------------------------------------------------------------------- - -//================================================================================================================================== -// CCurrentResourceState -// Stores the current state of either an entire resource, or each subresource. -// Current state can either be shared read across multiple queues, or exclusive on a single queue. -//================================================================================================================================== -class CCurrentResourceState -{ -public: - struct LogicalState - { - D3D12_RESOURCE_STATES State = D3D12_RESOURCE_STATE_COMMON; - UINT64 ExecutionId = 0; - bool IsPromotedState = false; - bool MayDecay = false; - }; - -private: - const bool m_bSimultaneousAccess; - bool m_bAllSubresourcesSame = true; - - std::vector m_spLogicalState; - - void ConvertToSubresourceTracking(); - -public: - CCurrentResourceState(UINT SubresourceCount, bool bSimultaneousAccess); - - bool SupportsSimultaneousAccess() const { return m_bSimultaneousAccess; } - - // Returns the destination state if the current state is promotable. - // Returns D3D12_RESOURCE_STATE_COMMON if not. - D3D12_RESOURCE_STATES StateIfPromoted(D3D12_RESOURCE_STATES state, UINT SubresourceIndex); - - bool AreAllSubresourcesSame() const { return m_bAllSubresourcesSame; } - - void SetLogicalResourceState(LogicalState const& State); - void SetLogicalSubresourceState(UINT SubresourceIndex, LogicalState const& State); - LogicalState const& GetLogicalSubresourceState(UINT SubresourceIndex) const; - - void Reset(); -}; //================================================================================================================================== // TransitionableResourceState @@ -91,14 +49,15 @@ struct TransitionableResourceState { struct list_head m_TransitionListEntry; struct d3d12_desired_resource_state m_DesiredState; + struct d3d12_resource_state m_currentState; TransitionableResourceState(ID3D12Resource *pResource, UINT TotalSubresources, bool SupportsSimultaneousAccess) : m_TotalSubresources(TotalSubresources), - m_currentState(TotalSubresources, SupportsSimultaneousAccess), m_pResource(pResource) { list_inithead(&m_TransitionListEntry); d3d12_desired_resource_state_init(&m_DesiredState, TotalSubresources); + d3d12_resource_state_init(&m_currentState, TotalSubresources, SupportsSimultaneousAccess); } ~TransitionableResourceState() @@ -114,15 +73,11 @@ struct TransitionableResourceState UINT NumSubresources() { return m_TotalSubresources; } - CCurrentResourceState& GetCurrentState() { return m_currentState; } - inline ID3D12Resource* GetD3D12Resource() const { return m_pResource; } private: unsigned m_TotalSubresources; - CCurrentResourceState m_currentState; - ID3D12Resource* m_pResource; }; @@ -224,7 +179,7 @@ private: // May update the destination state of the resource. void ProcessTransitioningResource(ID3D12Resource* pTransitioningResource, TransitionableResourceState& TransitionableResourceState, - CCurrentResourceState& CurrentState, + d3d12_resource_state *CurrentState, UINT NumTotalSubresources, UINT64 ExecutionId); @@ -232,10 +187,10 @@ private: // Helpers static bool TransitionRequired(D3D12_RESOURCE_STATES CurrentState, D3D12_RESOURCE_STATES& DestinationState); void AddCurrentStateUpdate(TransitionableResourceState& Resource, - CCurrentResourceState& CurrentState, + d3d12_resource_state *CurrentState, UINT SubresourceIndex, - const CCurrentResourceState::LogicalState &NewLogicalState); - void ProcessTransitioningSubresourceExplicit(CCurrentResourceState& CurrentState, + const d3d12_subresource_state *NewLogicalState); + void ProcessTransitioningSubresourceExplicit(d3d12_resource_state *CurrentState, UINT i, D3D12_RESOURCE_STATES after, TransitionableResourceState& TransitionableResourceState, diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp index fa4ab2dffca..d60c44d5475 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context.cpp @@ -1967,7 +1967,7 @@ d3d12_transition_resource_state(struct d3d12_context *ctx, D3D12_RESOURCE_STATES state, d3d12_bind_invalidate_option bind_invalidate) { - TransitionableResourceState *xres = d3d12_resource_state(res); + TransitionableResourceState *xres = d3d12_transitionable_resource_state(res); if (bind_invalidate == D3D12_BIND_INVALIDATE_FULL) d3d12_invalidate_context_bindings(ctx, res); @@ -1984,7 +1984,7 @@ d3d12_transition_subresources_state(struct d3d12_context *ctx, D3D12_RESOURCE_STATES state, d3d12_bind_invalidate_option bind_invalidate) { - TransitionableResourceState *xres = d3d12_resource_state(res); + TransitionableResourceState *xres = d3d12_transitionable_resource_state(res); if(bind_invalidate == D3D12_BIND_INVALIDATE_FULL) d3d12_invalidate_context_bindings(ctx, res); diff --git a/src/gallium/drivers/d3d12/d3d12_resource.h b/src/gallium/drivers/d3d12/d3d12_resource.h index 1b735d2c626..b9abe42ea7e 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource.h +++ b/src/gallium/drivers/d3d12/d3d12_resource.h @@ -102,7 +102,7 @@ d3d12_resource_resource(struct d3d12_resource *res) } static inline struct TransitionableResourceState * -d3d12_resource_state(struct d3d12_resource *res) +d3d12_transitionable_resource_state(struct d3d12_resource *res) { uint64_t offset; if (!res->bo) diff --git a/src/gallium/drivers/d3d12/d3d12_resource_state.cpp b/src/gallium/drivers/d3d12/d3d12_resource_state.cpp index b64a5e03d2a..0d213408880 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource_state.cpp +++ b/src/gallium/drivers/d3d12/d3d12_resource_state.cpp @@ -23,6 +23,8 @@ #include "d3d12_resource_state.h" +#include + #define UNKNOWN_RESOURCE_STATE (D3D12_RESOURCE_STATES) 0x8000u bool @@ -87,3 +89,94 @@ d3d12_reset_desired_resource_state(d3d12_desired_resource_state *state_obj) { d3d12_set_desired_resource_state(state_obj, UNKNOWN_RESOURCE_STATE); } + +bool +d3d12_resource_state_init(d3d12_resource_state *state, uint32_t subresource_count, bool simultaneous_access) +{ + state->homogenous = true; + state->supports_simultaneous_access = simultaneous_access; + state->num_subresources = subresource_count; + state->subresource_states = (d3d12_subresource_state *)calloc(subresource_count, sizeof(d3d12_subresource_state)); + return state->subresource_states != nullptr; +} + +void +d3d12_resource_state_cleanup(d3d12_resource_state *state) +{ + free(state->subresource_states); +} + +const d3d12_subresource_state * +d3d12_get_subresource_state(const d3d12_resource_state *state, uint32_t subresource) +{ + if (state->homogenous) + subresource = 0; + return &state->subresource_states[subresource]; +} + +void +d3d12_set_resource_state(d3d12_resource_state *state_obj, const d3d12_subresource_state *state) +{ + state_obj->homogenous = true; + state_obj->subresource_states[0] = *state; +} + +void +d3d12_set_subresource_state(d3d12_resource_state *state_obj, uint32_t subresource, const d3d12_subresource_state *state) +{ + if (state_obj->homogenous && state_obj->num_subresources > 1) { + for (unsigned i = 1; i < state_obj->num_subresources; ++i) { + state_obj->subresource_states[i] = state_obj->subresource_states[0]; + } + state_obj->homogenous = false; + } + + state_obj->subresource_states[subresource] = *state; +} + +void +d3d12_reset_resource_state(d3d12_resource_state *state) +{ + d3d12_subresource_state subres_state = {}; + d3d12_set_resource_state(state, &subres_state); +} + +D3D12_RESOURCE_STATES +d3d12_resource_state_if_promoted(D3D12_RESOURCE_STATES desired_state, + bool simultaneous_access, + const d3d12_subresource_state *current_state) +{ + D3D12_RESOURCE_STATES result = D3D12_RESOURCE_STATE_COMMON; + const D3D12_RESOURCE_STATES promotable_states = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_COPY_SOURCE | D3D12_RESOURCE_STATE_COPY_DEST; + + if (simultaneous_access || + (desired_state & promotable_states) != D3D12_RESOURCE_STATE_COMMON) { + // If the current state is COMMON... + if (current_state->state == D3D12_RESOURCE_STATE_COMMON) + // ...then promotion is allowed + return desired_state; + + // If the current state is a read state resulting from previous promotion... + if (current_state->is_promoted && + (current_state->state & D3D12_RESOURCE_STATE_GENERIC_READ) != D3D12_RESOURCE_STATE_COMMON) + // ...then (accumulated) promotion is allowed + return desired_state | current_state->state; + } + + return D3D12_RESOURCE_STATE_COMMON; +} + +void +d3d12_resource_state_copy(d3d12_resource_state *dest, d3d12_resource_state *src) +{ + assert(dest->num_subresources == src->num_subresources); + if (src->homogenous) + d3d12_set_resource_state(dest, &src->subresource_states[0]); + else { + dest->homogenous = false; + for (unsigned i = 0; i < src->num_subresources; ++i) + dest->subresource_states[i] = src->subresource_states[i]; + } +} diff --git a/src/gallium/drivers/d3d12/d3d12_resource_state.h b/src/gallium/drivers/d3d12/d3d12_resource_state.h index f09741452a9..22916da6fbb 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource_state.h +++ b/src/gallium/drivers/d3d12/d3d12_resource_state.h @@ -76,4 +76,47 @@ d3d12_set_desired_subresource_state(d3d12_desired_resource_state *state_obj, void d3d12_reset_desired_resource_state(d3d12_desired_resource_state *state_obj); +struct d3d12_subresource_state +{ + D3D12_RESOURCE_STATES state; + uint64_t execution_id; + bool is_promoted; + bool may_decay; +}; + +/* Stores the current state of either an entire resource, or each subresource */ +struct d3d12_resource_state +{ + bool homogenous; + bool supports_simultaneous_access; + uint32_t num_subresources; + d3d12_subresource_state *subresource_states; +}; + +bool +d3d12_resource_state_init(d3d12_resource_state *state, uint32_t subresource_count, bool simultaneous_access); + +void +d3d12_resource_state_cleanup(d3d12_resource_state *state); + +const d3d12_subresource_state * +d3d12_get_subresource_state(const d3d12_resource_state *state, uint32_t subresource); + +void +d3d12_set_resource_state(d3d12_resource_state *state_obj, const d3d12_subresource_state *state); + +void +d3d12_set_subresource_state(d3d12_resource_state *state_obj, uint32_t subresource, const d3d12_subresource_state *state); + +void +d3d12_reset_resource_state(d3d12_resource_state *state); + +D3D12_RESOURCE_STATES +d3d12_resource_state_if_promoted(D3D12_RESOURCE_STATES desired_state, + bool simultaneous_access, + const d3d12_subresource_state *current_state); + +void +d3d12_resource_state_copy(d3d12_resource_state *dest, d3d12_resource_state *src); + #endif // D3D12_RESOURCE_STATE_H