mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-05 22:31:08 +00:00
Restore initial state for resources created mid-frame on D3D12
This commit is contained in:
@@ -2100,9 +2100,17 @@ bool WrappedID3D12Device::Serialise_BeginCaptureFrame(SerialiserType &ser)
|
||||
{
|
||||
rdcarray<D3D12_RESOURCE_BARRIER> barriers;
|
||||
|
||||
if(IsReplayingAndReading() && IsLoading(m_State))
|
||||
{
|
||||
m_InitialResourceStates = m_ResourceStates;
|
||||
}
|
||||
|
||||
std::map<ResourceId, SubresourceStateVector> initialStates;
|
||||
|
||||
{
|
||||
SCOPED_LOCK(m_ResourceStatesLock); // not needed on replay, but harmless also
|
||||
GetResourceManager()->SerialiseResourceStates(ser, barriers, m_ResourceStates);
|
||||
GetResourceManager()->SerialiseResourceStates(ser, barriers, m_ResourceStates,
|
||||
m_InitialResourceStates);
|
||||
}
|
||||
|
||||
SERIALISE_CHECK_READ_ERRORS();
|
||||
|
||||
@@ -683,6 +683,11 @@ private:
|
||||
std::map<ResourceId, SubresourceStateVector> m_ResourceStates;
|
||||
Threading::CriticalSection m_ResourceStatesLock;
|
||||
|
||||
// used on replay only. Contains the initial resource states before any barriers - this allows us
|
||||
// to reset any resources to their proper initial state if they were created mid-frame, since for
|
||||
// those we won't have recorded their state at the start of the frame capture.
|
||||
std::map<ResourceId, SubresourceStateVector> m_InitialResourceStates;
|
||||
|
||||
std::set<ResourceId> m_Cubemaps;
|
||||
|
||||
// only valid on replay
|
||||
|
||||
@@ -682,14 +682,17 @@ void D3D12ResourceManager::ApplyBarriers(rdcarray<D3D12_RESOURCE_BARRIER> &barri
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void D3D12ResourceManager::SerialiseResourceStates(SerialiserType &ser,
|
||||
rdcarray<D3D12_RESOURCE_BARRIER> &barriers,
|
||||
std::map<ResourceId, SubresourceStateVector> &states)
|
||||
void D3D12ResourceManager::SerialiseResourceStates(
|
||||
SerialiserType &ser, rdcarray<D3D12_RESOURCE_BARRIER> &barriers,
|
||||
std::map<ResourceId, SubresourceStateVector> &states,
|
||||
const std::map<ResourceId, SubresourceStateVector> &initialStates)
|
||||
{
|
||||
SERIALISE_ELEMENT_LOCAL(NumMems, (uint32_t)states.size());
|
||||
|
||||
auto srcit = states.begin();
|
||||
|
||||
std::unordered_set<ResourceId> processed;
|
||||
|
||||
for(uint32_t i = 0; i < NumMems; i++)
|
||||
{
|
||||
SERIALISE_ELEMENT_LOCAL(Resource, srcit->first).TypedAs("ID3D12Resource *"_lit);
|
||||
@@ -701,6 +704,8 @@ void D3D12ResourceManager::SerialiseResourceStates(SerialiserType &ser,
|
||||
|
||||
if(IsReplayingAndReading() && liveid != ResourceId())
|
||||
{
|
||||
processed.insert(liveid);
|
||||
|
||||
for(size_t m = 0; m < States.size(); m++)
|
||||
{
|
||||
if(states[liveid][m] != States[m])
|
||||
@@ -722,15 +727,48 @@ void D3D12ResourceManager::SerialiseResourceStates(SerialiserType &ser,
|
||||
srcit++;
|
||||
}
|
||||
|
||||
// for any resources that didn't have a recorded state, use the initialStates we're given and
|
||||
// restore them if needed
|
||||
if(IsReplayingAndReading())
|
||||
{
|
||||
for(auto it = initialStates.begin(); it != initialStates.end(); ++it)
|
||||
{
|
||||
// ignore internal resources, we only care about restoring states for captured resources
|
||||
if(GetOriginalID(it->first) == it->first)
|
||||
continue;
|
||||
|
||||
if(processed.find(it->first) == processed.end())
|
||||
{
|
||||
for(size_t m = 0; m < it->second.size(); m++)
|
||||
{
|
||||
if(states[it->first][m] != it->second[m])
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER b;
|
||||
b.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
b.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
b.Transition.pResource = (ID3D12Resource *)GetCurrentResource(it->first);
|
||||
b.Transition.Subresource = (UINT)m;
|
||||
b.Transition.StateBefore = states[it->first][m];
|
||||
b.Transition.StateAfter = it->second[m];
|
||||
|
||||
barriers.push_back(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ApplyBarriers(barriers, states);
|
||||
}
|
||||
|
||||
template void D3D12ResourceManager::SerialiseResourceStates(
|
||||
ReadSerialiser &ser, rdcarray<D3D12_RESOURCE_BARRIER> &barriers,
|
||||
std::map<ResourceId, SubresourceStateVector> &states);
|
||||
std::map<ResourceId, SubresourceStateVector> &states,
|
||||
const std::map<ResourceId, SubresourceStateVector> &initialStates);
|
||||
template void D3D12ResourceManager::SerialiseResourceStates(
|
||||
WriteSerialiser &ser, rdcarray<D3D12_RESOURCE_BARRIER> &barriers,
|
||||
std::map<ResourceId, SubresourceStateVector> &states);
|
||||
std::map<ResourceId, SubresourceStateVector> &states,
|
||||
const std::map<ResourceId, SubresourceStateVector> &initialStates);
|
||||
|
||||
void D3D12ResourceManager::SetInternalResource(ID3D12DeviceChild *res)
|
||||
{
|
||||
|
||||
@@ -652,7 +652,8 @@ public:
|
||||
|
||||
template <typename SerialiserType>
|
||||
void SerialiseResourceStates(SerialiserType &ser, rdcarray<D3D12_RESOURCE_BARRIER> &barriers,
|
||||
std::map<ResourceId, SubresourceStateVector> &states);
|
||||
std::map<ResourceId, SubresourceStateVector> &states,
|
||||
const std::map<ResourceId, SubresourceStateVector> &initialStates);
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool Serialise_InitialState(SerialiserType &ser, ResourceId id, D3D12ResourceRecord *record,
|
||||
|
||||
Reference in New Issue
Block a user