Remove unused 'in-frame resources' concept and serialising releases

* Historically a long time ago, resources created in the middle of a
  frame capture were then replayed with their creation/destruction each
  time the frame was replayed. Likewise resources destroyed before the
  frame (but kept alive for a dependency) were also released on replay.
* This was faithful but unnecessary. Now we just create all resources
  needed anywhere in the frame up front, and release them only on
  shutdown.
This commit is contained in:
baldurk
2017-12-11 13:46:21 +00:00
parent 24803cd58c
commit 847cba546a
10 changed files with 11 additions and 173 deletions
+4 -58
View File
@@ -333,9 +333,6 @@ public:
WrappedResourceType GetCurrentResource(ResourceId id);
void ReleaseCurrentResource(ResourceId id);
void MarkInFrame(bool inFrame) { m_InFrame = inFrame; }
void ReleaseInFrameResources();
// insert the chunks for the resources referenced in the frame
void InsertReferencedChunks(WriteSerialiser &ser);
@@ -443,8 +440,6 @@ protected:
virtual void Create_InitialState(ResourceId id, WrappedResourceType live, bool hasData) = 0;
virtual void Apply_InitialState(WrappedResourceType live, InitialContentData initial) = 0;
bool m_InFrame;
// very coarse lock, protects EVERYTHING. This could certainly be improved and it may be a
// bottleneck
// for performance. Given that the main use cases are write-rarely read-often the lock should be
@@ -483,8 +478,7 @@ protected:
map<ResourceId, ResourceId> m_OriginalIDs, m_LiveIDs;
// used during replay - holds resources allocated and the original id that they represent
// for a) in-frame creations and b) pre-frame creations respectively.
map<ResourceId, WrappedResourceType> m_InframeResourceMap, m_LiveResourceMap;
map<ResourceId, WrappedResourceType> m_LiveResourceMap;
// used during capture - holds resource records by id.
map<ResourceId, RecordType *> m_ResourceRecords;
@@ -502,8 +496,6 @@ ResourceManagerType::ResourceManager()
{
if(RenderDoc::Inst().GetCrashHandler())
RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(ResourceManager));
m_InFrame = false;
}
template <typename WrappedResourceType, typename RealResourceType, typename RecordType>
@@ -520,17 +512,6 @@ void ResourceManagerType::Shutdown()
m_LiveResourceMap.erase(removeit);
}
while(!m_InframeResourceMap.empty())
{
auto it = m_InframeResourceMap.begin();
ResourceId id = it->first;
ResourceTypeRelease(it->second);
auto removeit = m_InframeResourceMap.find(id);
if(removeit != m_InframeResourceMap.end())
m_InframeResourceMap.erase(removeit);
}
FreeInitialContents();
RDCASSERT(m_ResourceRecords.empty());
@@ -540,7 +521,6 @@ template <typename WrappedResourceType, typename RealResourceType, typename Reco
ResourceManagerType::~ResourceManager()
{
RDCASSERT(m_LiveResourceMap.empty());
RDCASSERT(m_InframeResourceMap.empty());
RDCASSERT(m_InitialContents.empty());
RDCASSERT(m_ResourceRecords.empty());
@@ -1119,21 +1099,6 @@ void ResourceManagerType::ApplyInitialContentsNonChunks(WriteSerialiser &ser)
}
}
template <typename WrappedResourceType, typename RealResourceType, typename RecordType>
void ResourceManagerType::ReleaseInFrameResources()
{
SCOPED_LOCK(m_Lock);
// clean up last frame's temporaries - we needed to keep them around so they were valid for
// pipeline inspection etc after replaying the last log.
for(auto it = m_InframeResourceMap.begin(); it != m_InframeResourceMap.end(); ++it)
{
ResourceTypeRelease(it->second);
}
m_InframeResourceMap.clear();
}
template <typename WrappedResourceType, typename RealResourceType, typename RecordType>
void ResourceManagerType::ClearReferencedResources()
{
@@ -1314,22 +1279,14 @@ void ResourceManagerType::AddLiveResource(ResourceId origid, WrappedResourceType
m_OriginalIDs[GetID(livePtr)] = origid;
m_LiveIDs[origid] = GetID(livePtr);
if(m_InFrame && m_InframeResourceMap.find(origid) != m_InframeResourceMap.end())
{
ResourceTypeRelease(m_InframeResourceMap[origid]);
m_InframeResourceMap.erase(origid);
}
else if(!m_InFrame && m_LiveResourceMap.find(origid) != m_LiveResourceMap.end())
if(m_LiveResourceMap.find(origid) != m_LiveResourceMap.end())
{
RDCERR("Releasing live resource for duplicate creation: %llu", origid);
ResourceTypeRelease(m_LiveResourceMap[origid]);
m_LiveResourceMap.erase(origid);
}
if(m_InFrame)
m_InframeResourceMap[origid] = livePtr;
else
m_LiveResourceMap[origid] = livePtr;
m_LiveResourceMap[origid] = livePtr;
}
template <typename WrappedResourceType, typename RealResourceType, typename RecordType>
@@ -1341,7 +1298,6 @@ bool ResourceManagerType::HasLiveResource(ResourceId origid)
return false;
return (m_Replacements.find(origid) != m_Replacements.end() ||
m_InframeResourceMap.find(origid) != m_InframeResourceMap.end() ||
m_LiveResourceMap.find(origid) != m_LiveResourceMap.end());
}
@@ -1358,9 +1314,6 @@ WrappedResourceType ResourceManagerType::GetLiveResource(ResourceId origid)
if(m_Replacements.find(origid) != m_Replacements.end())
return GetLiveResource(m_Replacements[origid]);
if(m_InframeResourceMap.find(origid) != m_InframeResourceMap.end())
return m_InframeResourceMap[origid];
if(m_LiveResourceMap.find(origid) != m_LiveResourceMap.end())
return m_LiveResourceMap[origid];
@@ -1374,14 +1327,7 @@ void ResourceManagerType::EraseLiveResource(ResourceId origid)
RDCASSERT(HasLiveResource(origid), origid);
if(m_InframeResourceMap.find(origid) != m_InframeResourceMap.end())
{
m_InframeResourceMap.erase(origid);
}
else
{
m_LiveResourceMap.erase(origid);
}
m_LiveResourceMap.erase(origid);
}
template <typename WrappedResourceType, typename RealResourceType, typename RecordType>
-1
View File
@@ -267,7 +267,6 @@ enum class D3D11Chunk : uint32_t
{
DeviceInitialisation = (uint32_t)SystemChunk::FirstDriverChunk,
SetResourceName,
ReleaseResource,
CreateSwapBuffer,
CreateTexture1D,
CreateTexture2D,
-4
View File
@@ -1148,8 +1148,6 @@ ReplayStatus WrappedID3D11DeviceContext::ReplayLog(CaptureState readType, uint32
m_CurEventID = 1;
}
m_pDevice->GetResourceManager()->MarkInFrame(true);
uint64_t startOffset = ser.GetReader()->GetOffset();
for(;;)
@@ -1280,8 +1278,6 @@ ReplayStatus WrappedID3D11DeviceContext::ReplayLog(CaptureState readType, uint32
m_StructuredFile = NULL;
m_pDevice->GetResourceManager()->MarkInFrame(false);
m_DoStateVerify = false;
return ReplayStatus::Succeeded;
+4 -97
View File
@@ -775,7 +775,6 @@ bool WrappedID3D11Device::ProcessChunk(ReadSerialiser &ser, D3D11Chunk context)
return true;
}
case D3D11Chunk::SetResourceName: return Serialise_SetResourceName(ser, 0x0, "");
case D3D11Chunk::ReleaseResource: return Serialise_ReleaseResource(ser, 0x0);
case D3D11Chunk::CreateSwapBuffer: return Serialise_WrapSwapchainBuffer(ser, 0x0, 0x0, 0, 0x0);
case D3D11Chunk::CreateTexture1D: return Serialise_CreateTexture1D(ser, 0x0, 0x0, 0x0);
@@ -1092,7 +1091,6 @@ void WrappedID3D11Device::ReplayLog(uint32_t startEventID, uint32_t endEventID,
{
D3D11MarkerRegion apply("!!!!RenderDoc Internal: ApplyInitialContents");
GetResourceManager()->ApplyInitialContents();
GetResourceManager()->ReleaseInFrameResources();
}
m_State = CaptureState::ActiveReplaying;
@@ -2262,23 +2260,6 @@ void WrappedID3D11Device::SetResourceName(ID3D11DeviceChild *pResource, const ch
}
}
template <typename SerialiserType>
bool WrappedID3D11Device::Serialise_ReleaseResource(SerialiserType &ser, ID3D11DeviceChild *pResource)
{
SERIALISE_ELEMENT(pResource);
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading() && pResource)
{
GetResourceManager()->EraseLiveResource(
GetResourceManager()->GetOriginalID(GetIDForResource(pResource)));
SAFE_RELEASE(pResource);
}
return true;
}
void WrappedID3D11Device::ReleaseResource(ID3D11DeviceChild *res)
{
ResourceId idx = GetIDForResource(res);
@@ -2294,88 +2275,14 @@ void WrappedID3D11Device::ReleaseResource(ID3D11DeviceChild *res)
SCOPED_LOCK(m_D3DLock);
D3D11ResourceType type = IdentifyTypeByPtr(res);
D3D11ResourceRecord *record = m_DeviceRecord;
if(IsBackgroundCapturing(m_State))
{
if(type == Resource_ShaderResourceView || type == Resource_DepthStencilView ||
type == Resource_UnorderedAccessView || type == Resource_RenderTargetView ||
type == Resource_Buffer || type == Resource_Texture1D || type == Resource_Texture2D ||
type == Resource_Texture3D || type == Resource_CommandList)
{
record = GetResourceManager()->GetResourceRecord(idx);
RDCASSERT(record);
if(record->SpecialResource)
{
record = m_DeviceRecord;
}
else if(record->GetRefCount() == 1)
{
// we're about to decrement this chunk out of existance!
// don't hold onto the record to add the chunk.
record = NULL;
}
}
}
GetResourceManager()->MarkCleanResource(idx);
if(type == Resource_DeviceContext)
{
if(WrappedID3D11DeviceContext::IsAlloc(res))
RemoveDeferredContext((WrappedID3D11DeviceContext *)res);
}
bool serialiseRelease = true;
WrappedID3D11CommandList *cmdList = (WrappedID3D11CommandList *)res;
// don't serialise releases of counters or queries since we ignore them.
// Also don't serialise releases of command lists that weren't captured,
// since their creation won't be in the log either.
if(type == Resource_Counter || type == Resource_Query ||
(type == Resource_CommandList && !cmdList->IsCaptured()))
serialiseRelease = false;
if(type == Resource_DeviceState)
serialiseRelease = false;
if(type == Resource_CommandList && !cmdList->IsCaptured())
{
record = GetResourceManager()->GetResourceRecord(idx);
if(record)
record->Delete(GetResourceManager());
}
if(serialiseRelease)
{
WriteSerialiser &ser = m_ScratchSerialiser;
if(IsBackgroundCapturing(m_State))
{
SCOPED_SERIALISE_CHUNK(D3D11Chunk::ReleaseResource);
Serialise_ReleaseResource(ser, res);
if(record)
{
record->AddChunk(scope.Get());
}
}
if(record == NULL)
{
// if record is NULL then we just deleted a reference-less resource.
// That means it is not used and can be safely discarded, so just
// throw away the serialiser contents
ser.GetWriter()->Rewind();
}
record = GetResourceManager()->GetResourceRecord(idx);
if(record)
record->Delete(m_ResourceManager);
}
D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(idx);
if(record)
record->Delete(GetResourceManager());
}
WrappedID3D11DeviceContext *WrappedID3D11Device::GetDeferredContext(size_t idx)
+2 -1
View File
@@ -440,6 +440,8 @@ public:
void RemoveDeferredContext(WrappedID3D11DeviceContext *defctx);
WrappedID3D11DeviceContext *GetDeferredContext(size_t idx);
void ReleaseResource(ID3D11DeviceChild *pResource);
ResourceId GetResourceID() { return m_ResourceID; }
FrameRecord &GetFrameRecord() { return m_FrameRecord; }
FrameStatistics &GetFrameStats() { return m_FrameRecord.frameInfo.stats; }
@@ -530,7 +532,6 @@ public:
const char *Name);
IMPLEMENT_FUNCTION_SERIALISED(HRESULT, SetShaderDebugPath, ID3D11DeviceChild *pResource,
const char *Path);
IMPLEMENT_FUNCTION_SERIALISED(void, ReleaseResource, ID3D11DeviceChild *pResource);
// Swap Chain
IMPLEMENT_FUNCTION_SERIALISED(IUnknown *, WrapSwapchainBuffer, WrappedIDXGISwapChain4 *swap,
+1 -2
View File
@@ -59,13 +59,12 @@ std::string DoStringise(const D3D11ResourceType &el)
template <>
std::string DoStringise(const D3D11Chunk &el)
{
RDCCOMPILE_ASSERT((uint32_t)D3D11Chunk::Max == 1128, "Chunks changed without updating names");
RDCCOMPILE_ASSERT((uint32_t)D3D11Chunk::Max == 1127, "Chunks changed without updating names");
BEGIN_ENUM_STRINGISE(D3D11Chunk)
{
STRINGISE_ENUM_CLASS_NAMED(DeviceInitialisation, "Device Initialisation");
STRINGISE_ENUM_CLASS_NAMED(SetResourceName, "ID3D11Resource::SetDebugName");
STRINGISE_ENUM_CLASS_NAMED(ReleaseResource, "IUnknown::Release");
STRINGISE_ENUM_CLASS_NAMED(CreateSwapBuffer, "IDXGISwapChain::GetBuffer");
STRINGISE_ENUM_CLASS_NAMED(CreateTexture1D, "ID3D11Device::CreateTexture1D");
STRINGISE_ENUM_CLASS_NAMED(CreateTexture2D, "ID3D11Device::CreateTexture2D");
-1
View File
@@ -2561,7 +2561,6 @@ void WrappedID3D12Device::ReplayLog(uint32_t startEventID, uint32_t endEventID,
{
D3D12MarkerRegion apply(GetQueue(), "!!!!RenderDoc Internal: ApplyInitialContents");
ApplyInitialContents();
GetResourceManager()->ReleaseInFrameResources();
}
ExecuteLists();
-5
View File
@@ -4733,8 +4733,6 @@ ReplayStatus WrappedOpenGL::ContextReplayLog(CaptureState readType, uint32_t sta
m_LastEventID = ~0U;
}
GetResourceManager()->MarkInFrame(true);
uint64_t startOffset = ser.GetReader()->GetOffset();
for(;;)
@@ -4800,8 +4798,6 @@ ReplayStatus WrappedOpenGL::ContextReplayLog(CaptureState readType, uint32_t sta
}
}
GetResourceManager()->MarkInFrame(false);
return ReplayStatus::Succeeded;
}
@@ -5228,7 +5224,6 @@ void WrappedOpenGL::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
{
GLMarkerRegion apply("!!!!RenderDoc Internal: ApplyInitialContents");
GetResourceManager()->ApplyInitialContents();
GetResourceManager()->ReleaseInFrameResources();
}
m_State = CaptureState::ActiveReplaying;
-2
View File
@@ -2242,8 +2242,6 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
SubmitCmds();
FlushQ();
GetResourceManager()->ReleaseInFrameResources();
}
m_State = CaptureState::ActiveReplaying;
-2
View File
@@ -48,14 +48,12 @@ public:
// be calling Shutdown() after the device that owns them is destroyed. Instead
// we just have to leak ourselves.
RDCASSERT(m_LiveResourceMap.empty());
RDCASSERT(m_InframeResourceMap.empty());
RDCASSERT(m_InitialContents.empty());
RDCASSERT(m_ResourceRecords.empty());
RDCASSERT(m_CurrentResourceMap.empty());
RDCASSERT(m_WrapperMap.empty());
m_LiveResourceMap.clear();
m_InframeResourceMap.clear();
m_InitialContents.clear();
m_ResourceRecords.clear();
m_CurrentResourceMap.clear();