Restore initial state for resources created mid-frame on D3D12

This commit is contained in:
baldurk
2021-01-06 16:58:43 +00:00
parent 0e60918e4d
commit cc36581592
4 changed files with 59 additions and 7 deletions
+9 -1
View File
@@ -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();
+5
View File
@@ -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
+43 -5
View File
@@ -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)
{
+2 -1
View File
@@ -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,