From 2016dec6a4b590ac0ee6ad094fd38b04f11ec7bb Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Mon, 18 Jul 2022 14:28:30 -0700 Subject: [PATCH] d3d12: Move desired resource state to new files Reviewed-by: Bill Kristiansen Part-of: --- .../drivers/d3d12/D3D12ResourceState.cpp | 77 +++---------------- .../drivers/d3d12/D3D12ResourceState.h | 55 +------------ src/gallium/drivers/d3d12/d3d12_bufmgr.cpp | 2 +- .../drivers/d3d12/d3d12_resource_state.cpp | 64 +++++++++++++++ .../drivers/d3d12/d3d12_resource_state.h | 50 ++++++++++++ 5 files changed, 128 insertions(+), 120 deletions(-) diff --git a/src/gallium/drivers/d3d12/D3D12ResourceState.cpp b/src/gallium/drivers/d3d12/D3D12ResourceState.cpp index 5ad24c00965..f7f0830aa26 100644 --- a/src/gallium/drivers/d3d12/D3D12ResourceState.cpp +++ b/src/gallium/drivers/d3d12/D3D12ResourceState.cpp @@ -22,61 +22,7 @@ */ #include "D3D12ResourceState.h" - -//---------------------------------------------------------------------------------------------------------------------------------- - D3D12_RESOURCE_STATES CDesiredResourceState::GetSubresourceState(UINT SubresourceIndex) const -{ - if (AreAllSubresourcesSame()) - { - SubresourceIndex = 0; - } - return m_spSubresourceStates[SubresourceIndex]; -} - -//---------------------------------------------------------------------------------------------------------------------------------- -void CDesiredResourceState::UpdateSubresourceState(unsigned SubresourceIndex, D3D12_RESOURCE_STATES state) -{ - assert(SubresourceIndex < m_spSubresourceStates.size()); - if (m_spSubresourceStates[SubresourceIndex] == UNKNOWN_RESOURCE_STATE || - state == UNKNOWN_RESOURCE_STATE || - IsD3D12WriteState(state)) - { - m_spSubresourceStates[SubresourceIndex] = state; - } - else - { - // Accumulate read state state bits - m_spSubresourceStates[SubresourceIndex] |= state; - } -} - -//---------------------------------------------------------------------------------------------------------------------------------- -void CDesiredResourceState::SetResourceState(D3D12_RESOURCE_STATES state) -{ - m_bAllSubresourcesSame = true; - UpdateSubresourceState(0, state); -} - -//---------------------------------------------------------------------------------------------------------------------------------- -void CDesiredResourceState::SetSubresourceState(UINT SubresourceIndex, D3D12_RESOURCE_STATES state) -{ - if (m_bAllSubresourcesSame && m_spSubresourceStates.size() > 1) - { - std::fill(m_spSubresourceStates.begin() + 1, m_spSubresourceStates.end(), m_spSubresourceStates[0]); - m_bAllSubresourcesSame = false; - } - if (m_spSubresourceStates.size() == 1) - { - SubresourceIndex = 0; - } - UpdateSubresourceState(SubresourceIndex, state); -} - -//---------------------------------------------------------------------------------------------------------------------------------- -void CDesiredResourceState::Reset() -{ - SetResourceState(UNKNOWN_RESOURCE_STATE); -} +#define UNKNOWN_RESOURCE_STATE (D3D12_RESOURCE_STATES) 0x8000u //---------------------------------------------------------------------------------------------------------------------------------- void CCurrentResourceState::ConvertToSubresourceTracking() @@ -171,7 +117,7 @@ ResourceStateManager::ResourceStateManager() void ResourceStateManager::TransitionResource(TransitionableResourceState& Resource, D3D12_RESOURCE_STATES state) { - Resource.m_DesiredState.SetResourceState(state); + d3d12_set_desired_resource_state(&Resource.m_DesiredState, state); if (!Resource.IsTransitionPending()) { list_add(&Resource.m_TransitionListEntry, &m_TransitionListHead); @@ -183,7 +129,7 @@ void ResourceStateManager::TransitionSubresource(TransitionableResourceState& Re UINT SubresourceIndex, D3D12_RESOURCE_STATES state) { - Resource.m_DesiredState.SetSubresourceState(SubresourceIndex, state); + d3d12_set_desired_subresource_state(&Resource.m_DesiredState, SubresourceIndex, state); if (!Resource.IsTransitionPending()) { list_add(&Resource.m_TransitionListEntry, &m_TransitionListHead); @@ -222,7 +168,7 @@ void ResourceStateManager::ApplyResourceTransitionsPreamble(bool IsImplicitDispa // If the transition involves a write state, then the destination should just be the requested destination. // Otherwise, accumulate read states to minimize future transitions (by triggering the above condition). - if (!IsD3D12WriteState(DestinationState) && !IsD3D12WriteState(CurrentState)) + if (!d3d12_is_write_state(DestinationState) && !d3d12_is_write_state(CurrentState)) { DestinationState |= CurrentState; } @@ -254,7 +200,7 @@ void ResourceStateManager::ProcessTransitioningResource(ID3D12Resource* pTransit { // Figure out the set of subresources that are transitioning auto& DestinationState = TransitionableResourceState.m_DesiredState; - bool bAllSubresourcesAtOnce = CurrentState.AreAllSubresourcesSame() && DestinationState.AreAllSubresourcesSame(); + bool bAllSubresourcesAtOnce = CurrentState.AreAllSubresourcesSame() && DestinationState.homogenous; D3D12_RESOURCE_BARRIER TransitionDesc; memset(&TransitionDesc, 0, sizeof(TransitionDesc)); @@ -264,11 +210,10 @@ void ResourceStateManager::ProcessTransitioningResource(ID3D12Resource* pTransit UINT numSubresources = bAllSubresourcesAtOnce ? 1 : NumTotalSubresources; for (UINT i = 0; i < numSubresources; ++i) { - D3D12_RESOURCE_STATES SubresourceDestinationState = DestinationState.GetSubresourceState(i); + D3D12_RESOURCE_STATES after = d3d12_get_desired_subresource_state(&DestinationState, i); TransitionDesc.Transition.Subresource = bAllSubresourcesAtOnce ? D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES : i; // Is this subresource currently being used, or is it just being iterated over? - D3D12_RESOURCE_STATES after = DestinationState.GetSubresourceState(i); if (after == UNKNOWN_RESOURCE_STATE) { // This subresource doesn't have any transition requested - move on to the next. @@ -278,7 +223,7 @@ void ResourceStateManager::ProcessTransitioningResource(ID3D12Resource* pTransit // This is a transition into a state that is both write and non-write. // This is invalid according to D3D12. We're venturing into undefined behavior // land, but let's just pick the write state. - if (IsD3D12WriteState(after) && + if (d3d12_is_write_state(after) && (after & ~RESOURCE_STATE_ALL_WRITE_BITS) != 0) { after &= RESOURCE_STATE_ALL_WRITE_BITS; @@ -290,7 +235,6 @@ void ResourceStateManager::ProcessTransitioningResource(ID3D12Resource* pTransit ProcessTransitioningSubresourceExplicit( CurrentState, i, - SubresourceDestinationState, after, TransitionableResourceState, TransitionDesc, @@ -299,7 +243,7 @@ void ResourceStateManager::ProcessTransitioningResource(ID3D12Resource* pTransit // Update destination states. // Coalesce destination state to ensure that it's set for the entire resource. - DestinationState.SetResourceState(UNKNOWN_RESOURCE_STATE); + d3d12_reset_desired_resource_state(&DestinationState); } @@ -307,7 +251,6 @@ void ResourceStateManager::ProcessTransitioningResource(ID3D12Resource* pTransit void ResourceStateManager::ProcessTransitioningSubresourceExplicit( CCurrentResourceState& CurrentState, UINT SubresourceIndex, - D3D12_RESOURCE_STATES state, D3D12_RESOURCE_STATES after, TransitionableResourceState& TransitionableResourceState, D3D12_RESOURCE_BARRIER& TransitionDesc, @@ -352,7 +295,7 @@ void ResourceStateManager::ProcessTransitioningSubresourceExplicit( assert(TransitionDesc.Transition.StateBefore != TransitionDesc.Transition.StateAfter); m_vResourceBarriers.push_back(TransitionDesc); // throw( bad_alloc ) - MayDecay = CurrentState.SupportsSimultaneousAccess() && !IsD3D12WriteState(after); + MayDecay = CurrentState.SupportsSimultaneousAccess() && !d3d12_is_write_state(after); IsPromotion = false; } } @@ -362,7 +305,7 @@ void ResourceStateManager::ProcessTransitioningSubresourceExplicit( if(after != StateIfPromoted) { after = StateIfPromoted; - MayDecay = !IsD3D12WriteState(after); + MayDecay = !d3d12_is_write_state(after); IsPromotion = true; } } diff --git a/src/gallium/drivers/d3d12/D3D12ResourceState.h b/src/gallium/drivers/d3d12/D3D12ResourceState.h index f1bbc88eb20..055c641fffd 100644 --- a/src/gallium/drivers/d3d12/D3D12ResourceState.h +++ b/src/gallium/drivers/d3d12/D3D12ResourceState.h @@ -36,59 +36,10 @@ #pragma GCC diagnostic ignored "-Winvalid-offsetof" #endif -#define UNKNOWN_RESOURCE_STATE (D3D12_RESOURCE_STATES)0x8000u #define RESOURCE_STATE_VALID_BITS 0x2f3fff #define RESOURCE_STATE_VALID_INTERNAL_BITS 0x2fffff -const D3D12_RESOURCE_STATES RESOURCE_STATE_ALL_WRITE_BITS = -D3D12_RESOURCE_STATE_RENDER_TARGET | -D3D12_RESOURCE_STATE_UNORDERED_ACCESS | -D3D12_RESOURCE_STATE_DEPTH_WRITE | -D3D12_RESOURCE_STATE_STREAM_OUT | -D3D12_RESOURCE_STATE_COPY_DEST | -D3D12_RESOURCE_STATE_RESOLVE_DEST | -D3D12_RESOURCE_STATE_VIDEO_DECODE_WRITE | -D3D12_RESOURCE_STATE_VIDEO_PROCESS_WRITE; //--------------------------------------------------------------------------------------------------------------------------------- -inline bool IsD3D12WriteState(UINT State) -{ - return (State & RESOURCE_STATE_ALL_WRITE_BITS) != 0; -} - -inline bool SupportsSimultaneousAccess(const D3D12_RESOURCE_DESC &desc) -{ - return D3D12_RESOURCE_DIMENSION_BUFFER == desc.Dimension || - !!(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS); -} - -//================================================================================================================================== -// CDesiredResourceState -// Stores the current desired state of either an entire resource, or each subresource. -//================================================================================================================================== -class CDesiredResourceState -{ -private: - bool m_bAllSubresourcesSame = true; - - std::vector m_spSubresourceStates; - -public: - CDesiredResourceState(UINT SubresourceCount) : - m_spSubresourceStates(SubresourceCount) - { - } - - bool AreAllSubresourcesSame() const { return m_bAllSubresourcesSame; } - - D3D12_RESOURCE_STATES GetSubresourceState(UINT SubresourceIndex) const; - void SetResourceState(D3D12_RESOURCE_STATES state); - void SetSubresourceState(UINT SubresourceIndex, D3D12_RESOURCE_STATES state); - - void Reset(); - -private: - void UpdateSubresourceState(unsigned SubresourceIndex, D3D12_RESOURCE_STATES state); -}; //================================================================================================================================== // CCurrentResourceState @@ -139,19 +90,20 @@ public: struct TransitionableResourceState { struct list_head m_TransitionListEntry; - CDesiredResourceState m_DesiredState; + struct d3d12_desired_resource_state m_DesiredState; TransitionableResourceState(ID3D12Resource *pResource, UINT TotalSubresources, bool SupportsSimultaneousAccess) : - m_DesiredState(TotalSubresources), m_TotalSubresources(TotalSubresources), m_currentState(TotalSubresources, SupportsSimultaneousAccess), m_pResource(pResource) { list_inithead(&m_TransitionListEntry); + d3d12_desired_resource_state_init(&m_DesiredState, TotalSubresources); } ~TransitionableResourceState() { + d3d12_desired_resource_state_cleanup(&m_DesiredState); if (IsTransitionPending()) { list_del(&m_TransitionListEntry); @@ -285,7 +237,6 @@ private: const CCurrentResourceState::LogicalState &NewLogicalState); void ProcessTransitioningSubresourceExplicit(CCurrentResourceState& CurrentState, UINT i, - D3D12_RESOURCE_STATES state, D3D12_RESOURCE_STATES after, TransitionableResourceState& TransitionableResourceState, D3D12_RESOURCE_BARRIER& TransitionDesc, diff --git a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp index 5d9a935d3fe..a5dbf7d20ed 100644 --- a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp +++ b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp @@ -67,7 +67,7 @@ create_trans_state(ID3D12Resource *res, enum pipe_format format) return new TransitionableResourceState(res, total_subresources, - SupportsSimultaneousAccess(desc)); + d3d12_resource_supports_simultaneous_access(&desc)); } static void diff --git a/src/gallium/drivers/d3d12/d3d12_resource_state.cpp b/src/gallium/drivers/d3d12/d3d12_resource_state.cpp index 535e74ba436..b64a5e03d2a 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource_state.cpp +++ b/src/gallium/drivers/d3d12/d3d12_resource_state.cpp @@ -23,3 +23,67 @@ #include "d3d12_resource_state.h" +#define UNKNOWN_RESOURCE_STATE (D3D12_RESOURCE_STATES) 0x8000u + +bool +d3d12_desired_resource_state_init(d3d12_desired_resource_state *state, uint32_t subresource_count) +{ + state->homogenous = true; + state->num_subresources = subresource_count; + state->subresource_states = (D3D12_RESOURCE_STATES *)calloc(subresource_count, sizeof(D3D12_RESOURCE_STATES)); + return state->subresource_states != nullptr; +} + +void +d3d12_desired_resource_state_cleanup(d3d12_desired_resource_state *state) +{ + free(state->subresource_states); +} + +D3D12_RESOURCE_STATES +d3d12_get_desired_subresource_state(const d3d12_desired_resource_state *state, uint32_t subresource_index) +{ + if (state->homogenous) + subresource_index = 0; + return state->subresource_states[subresource_index]; +} + +static void +update_subresource_state(D3D12_RESOURCE_STATES *existing_state, D3D12_RESOURCE_STATES new_state) +{ + if (*existing_state == UNKNOWN_RESOURCE_STATE || new_state == UNKNOWN_RESOURCE_STATE || + d3d12_is_write_state(new_state)) { + *existing_state = new_state; + } else { + /* Accumulate read state state bits */ + *existing_state |= new_state; + } +} + +void +d3d12_set_desired_resource_state(d3d12_desired_resource_state *state_obj, D3D12_RESOURCE_STATES state) +{ + state_obj->homogenous = true; + update_subresource_state(&state_obj->subresource_states[0], state); +} + +void +d3d12_set_desired_subresource_state(d3d12_desired_resource_state *state_obj, + uint32_t subresource, + D3D12_RESOURCE_STATES 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; + } + + update_subresource_state(&state_obj->subresource_states[subresource], state); +} + +void +d3d12_reset_desired_resource_state(d3d12_desired_resource_state *state_obj) +{ + d3d12_set_desired_resource_state(state_obj, UNKNOWN_RESOURCE_STATE); +} diff --git a/src/gallium/drivers/d3d12/d3d12_resource_state.h b/src/gallium/drivers/d3d12/d3d12_resource_state.h index b35abb4b799..f09741452a9 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource_state.h +++ b/src/gallium/drivers/d3d12/d3d12_resource_state.h @@ -24,6 +24,56 @@ #ifndef D3D12_RESOURCE_STATE_H #define D3D12_RESOURCE_STATE_H +#include +#include +#include "d3d12_common.h" + +const D3D12_RESOURCE_STATES RESOURCE_STATE_ALL_WRITE_BITS = + D3D12_RESOURCE_STATE_RENDER_TARGET | D3D12_RESOURCE_STATE_UNORDERED_ACCESS | D3D12_RESOURCE_STATE_DEPTH_WRITE | + D3D12_RESOURCE_STATE_STREAM_OUT | D3D12_RESOURCE_STATE_COPY_DEST | D3D12_RESOURCE_STATE_RESOLVE_DEST | + D3D12_RESOURCE_STATE_VIDEO_DECODE_WRITE | D3D12_RESOURCE_STATE_VIDEO_PROCESS_WRITE; + +inline bool +d3d12_is_write_state(D3D12_RESOURCE_STATES state) +{ + return (state & RESOURCE_STATE_ALL_WRITE_BITS) != D3D12_RESOURCE_STATE_COMMON; +} + +inline bool +d3d12_resource_supports_simultaneous_access(const D3D12_RESOURCE_DESC *desc) +{ + return desc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER || + (desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS) != D3D12_RESOURCE_FLAG_NONE; +} + +/* Stores the current desired state of either an entire resource, or each subresource. */ +struct d3d12_desired_resource_state +{ + bool homogenous; + uint32_t num_subresources; + D3D12_RESOURCE_STATES *subresource_states; +}; + +bool +d3d12_desired_resource_state_init(d3d12_desired_resource_state *state, + uint32_t subresource_count); + +void +d3d12_desired_resource_state_cleanup(d3d12_desired_resource_state *state); + +D3D12_RESOURCE_STATES +d3d12_get_desired_subresource_state(const d3d12_desired_resource_state *state, uint32_t subresource_index); + +void +d3d12_set_desired_resource_state(d3d12_desired_resource_state *state_obj, D3D12_RESOURCE_STATES state); + +void +d3d12_set_desired_subresource_state(d3d12_desired_resource_state *state_obj, + uint32_t subresource, + D3D12_RESOURCE_STATES state); + +void +d3d12_reset_desired_resource_state(d3d12_desired_resource_state *state_obj); #endif // D3D12_RESOURCE_STATE_H