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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user