mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-13 01:05:44 +00:00
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:
@@ -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>
|
||||
|
||||
@@ -267,7 +267,6 @@ enum class D3D11Chunk : uint32_t
|
||||
{
|
||||
DeviceInitialisation = (uint32_t)SystemChunk::FirstDriverChunk,
|
||||
SetResourceName,
|
||||
ReleaseResource,
|
||||
CreateSwapBuffer,
|
||||
CreateTexture1D,
|
||||
CreateTexture2D,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -2561,7 +2561,6 @@ void WrappedID3D12Device::ReplayLog(uint32_t startEventID, uint32_t endEventID,
|
||||
{
|
||||
D3D12MarkerRegion apply(GetQueue(), "!!!!RenderDoc Internal: ApplyInitialContents");
|
||||
ApplyInitialContents();
|
||||
GetResourceManager()->ReleaseInFrameResources();
|
||||
}
|
||||
|
||||
ExecuteLists();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -2242,8 +2242,6 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
|
||||
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
|
||||
GetResourceManager()->ReleaseInFrameResources();
|
||||
}
|
||||
|
||||
m_State = CaptureState::ActiveReplaying;
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user