d3d12: Move desired resource state to new files

Reviewed-by: Bill Kristiansen <billkris@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17688>
This commit is contained in:
Jesse Natalie
2022-07-18 14:28:30 -07:00
committed by Marge Bot
parent a277dbf1f4
commit 2016dec6a4
5 changed files with 128 additions and 120 deletions

View File

@@ -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;
}
}

View File

@@ -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<D3D12_RESOURCE_STATES> 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,

View File

@@ -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

View File

@@ -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);
}

View File

@@ -24,6 +24,56 @@
#ifndef D3D12_RESOURCE_STATE_H
#define D3D12_RESOURCE_STATE_H
#include <stdbool.h>
#include <stdint.h>
#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