Ensure resources created mid-frame are properly forced referenced

This commit is contained in:
baldurk
2024-11-14 10:21:10 +00:00
parent 1b39f2676b
commit 83ac6d3697
6 changed files with 42 additions and 16 deletions
@@ -783,6 +783,9 @@ bool WrappedID3D12GraphicsCommandList::ProcessASBuildAfterSubmission(ResourceId
m_pDevice->CreateAS(dstASB, destASBOffset, byteSize, accStructAtDestOffset);
m_pDevice->AddForcedReference(record);
// in case we're currently capturing, immediately consider the AS as referenced
GetResourceManager()->MarkResourceFrameReferenced(accStructAtDestOffset->GetResourceID(),
eFrameRef_Read);
}
else
{
+15
View File
@@ -3331,6 +3331,21 @@ void WrappedID3D12Device::UploadBLASBufferAddresses()
m_addressBufferUploaded = true;
}
void WrappedID3D12Device::AddForcedReference(D3D12ResourceRecord *record)
{
{
SCOPED_LOCK(m_ForcedReferencesLock);
m_ForcedReferences.push_back(record);
}
// in case we're currently capturing, immediately consider the resource as referenced. If we're
// not capturing this will naturally be cleared before the frame capture starts and we don't have
// to consider races as this is internally locked. If we're racing with a frame capture starting
// we will either add this redundantly (after clear but before forced references are added) or as
// required (after references are cleared and after forced references are added)
GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read);
}
void WrappedID3D12Device::ReleaseResource(ID3D12DeviceChild *res)
{
ResourceId id = GetResID(res);
+1 -5
View File
@@ -888,11 +888,7 @@ public:
const D3D12_FEATURE_DATA_D3D12_OPTIONS16 &GetOpts16() { return m_D3D12Opts16; }
void RemoveQueue(WrappedID3D12CommandQueue *queue);
void AddForcedReference(D3D12ResourceRecord *record)
{
SCOPED_LOCK(m_ForcedReferencesLock);
m_ForcedReferences.push_back(record);
}
void AddForcedReference(D3D12ResourceRecord *record);
// only valid on replay
const std::map<ResourceId, WrappedID3D12Resource *> &GetResourceList() { return *m_ResourceList; }
+15
View File
@@ -5349,6 +5349,21 @@ ResourceId WrappedVulkan::GetPartialCommandBuffer()
return m_Partial.partialStack.back().cmdId;
}
void WrappedVulkan::AddForcedReference(VkResourceRecord *record)
{
{
SCOPED_LOCK(m_ForcedReferencesLock);
m_ForcedReferences.push_back(record);
}
// in case we're currently capturing, immediately consider the resource as referenced. If we're
// not capturing this will naturally be cleared before the frame capture starts and we don't have
// to consider races as this is internally locked. If we're racing with a frame capture starting
// we will either add this redundantly (after clear but before forced references are added) or as
// required (after references are cleared and after forced references are added)
GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read);
}
void WrappedVulkan::AddAction(const ActionDescription &a)
{
m_AddedAction = true;
+1 -5
View File
@@ -952,11 +952,7 @@ private:
return ret;
}
void AddForcedReference(VkResourceRecord *record)
{
SCOPED_LOCK(m_ForcedReferencesLock);
m_ForcedReferences.push_back(record);
}
void AddForcedReference(VkResourceRecord *record);
// used on replay side to track the queue family of command buffers and pools
std::map<ResourceId, uint32_t> m_commandQueueFamilies;
@@ -1510,9 +1510,8 @@ VkResult WrappedVulkan::vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkD
// if the buffer was force-referenced, do the same with the memory
if(IsForcedReference(record))
{
// in case we're currently capturing, immediately consider the buffer and backing memory as
// read-before-write referenced
GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read);
// AddForcedReference will also call MarkResourceFrameReferenced() on the buffer in case
// we're currently capturing, do the same with the memory with the correct semantics.
GetResourceManager()->MarkMemoryFrameReferenced(id, memoryOffset, record->memSize,
eFrameRef_ReadBeforeWrite);
@@ -3020,9 +3019,8 @@ VkResult WrappedVulkan::vkBindBufferMemory2(VkDevice device, uint32_t bindInfoCo
// if the buffer was force-referenced, do the same with the memory
if(IsForcedReference(bufrecord))
{
// in case we're currently capturing, immediately consider the buffer and backing memory as
// read-before-write referenced
GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read);
// AddForcedReference will also call MarkResourceFrameReferenced() on the buffer in case
// we're currently capturing, do the same with the memory with the correct semantics.
GetResourceManager()->MarkMemoryFrameReferenced(
GetResID(pBindInfos[i].memory), pBindInfos[i].memoryOffset, bufrecord->memSize,
eFrameRef_ReadBeforeWrite);
@@ -3409,6 +3407,9 @@ VkResult WrappedVulkan::vkCreateAccelerationStructureKHR(
// reference them. We force ref generics too as they could bottom or top level so we
// conservatively assume they are bottom
AddForcedReference(record);
// in case we're currently capturing, immediately consider the AS as referenced
GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read);
}
}
else