mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-13 05:20:45 +00:00
Add verification of TLAS build inputs
This commit is contained in:
@@ -847,7 +847,7 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress(
|
||||
resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
resBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
resBarrier.Transition.pResource = patchRaytracing->m_patchedInstanceBuffer->Resource();
|
||||
resBarrier.Transition.pResource = patchRaytracing->patchedInstanceBuffer->Resource();
|
||||
resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
||||
resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
resBarriers.push_back(resBarrier);
|
||||
@@ -866,7 +866,7 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress(
|
||||
// unroll the instances list into a flat array (which will then get patched below in-place)
|
||||
D3D12GpuBuffer *tempBuffer = rtManager->UnrollBLASInstancesList(
|
||||
unwrappedList, accStructInput.Inputs, addressPairResAddress, addressCount,
|
||||
patchRaytracing->m_patchedInstanceBuffer);
|
||||
patchRaytracing->patchedInstanceBuffer);
|
||||
|
||||
accStructInput.Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
|
||||
|
||||
@@ -880,9 +880,20 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress(
|
||||
}
|
||||
else
|
||||
{
|
||||
unwrappedList->CopyBufferRegion(patchRaytracing->m_patchedInstanceBuffer->Resource(),
|
||||
patchRaytracing->m_patchedInstanceBuffer->Offset(),
|
||||
unwrappedList->CopyBufferRegion(patchRaytracing->patchedInstanceBuffer->Resource(),
|
||||
patchRaytracing->patchedInstanceBuffer->Offset(),
|
||||
instanceResource, instanceResOffset, totalInstancesSize);
|
||||
|
||||
if(D3D12_Debug_RTAuditing())
|
||||
{
|
||||
GetResourceManager()->GetGPUBufferAllocator().Alloc(
|
||||
D3D12GpuBufferHeapType::ReadBackHeap, D3D12GpuBufferHeapMemoryFlag::Default,
|
||||
totalInstancesSize, 256, &patchRaytracing->unpatchedInstanceBufferReadback);
|
||||
|
||||
unwrappedList->CopyBufferRegion(patchRaytracing->unpatchedInstanceBufferReadback->Resource(),
|
||||
patchRaytracing->unpatchedInstanceBufferReadback->Offset(),
|
||||
instanceResource, instanceResOffset, totalInstancesSize);
|
||||
}
|
||||
}
|
||||
|
||||
D3D12AccStructPatchInfo patchInfo = rtManager->GetAccStructPatchInfo();
|
||||
@@ -894,7 +905,7 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress(
|
||||
resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
resBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
resBarrier.Transition.pResource = patchRaytracing->m_patchedInstanceBuffer->Resource();
|
||||
resBarrier.Transition.pResource = patchRaytracing->patchedInstanceBuffer->Resource();
|
||||
resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
||||
resBarriers.push_back(resBarrier);
|
||||
@@ -928,7 +939,7 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress(
|
||||
D3D12_RESOURCE_BARRIER resBarrier;
|
||||
resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
|
||||
resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
resBarrier.UAV.pResource = patchRaytracing->m_patchedInstanceBuffer->Resource();
|
||||
resBarrier.UAV.pResource = patchRaytracing->patchedInstanceBuffer->Resource();
|
||||
unwrappedList->ResourceBarrier(1, &resBarrier);
|
||||
}
|
||||
|
||||
@@ -940,14 +951,15 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress(
|
||||
(UINT)D3D12PatchTLASBuildParam::RootAddressPairSrv, addressPairResAddress);
|
||||
unwrappedList->SetComputeRootUnorderedAccessView(
|
||||
(UINT)D3D12PatchTLASBuildParam::RootPatchedAddressUav,
|
||||
patchRaytracing->m_patchedInstanceBuffer->Address());
|
||||
patchRaytracing->patchedInstanceBuffer->Address());
|
||||
|
||||
unwrappedList->Dispatch(accStructInput.Inputs.NumDescs, 1, 1);
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER resBarrier;
|
||||
resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
|
||||
resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
resBarrier.UAV.pResource = patchRaytracing->m_patchedInstanceBuffer->Resource();
|
||||
resBarrier.UAV.pResource = patchRaytracing->patchedInstanceBuffer->Resource();
|
||||
unwrappedList->ResourceBarrier(1, &resBarrier);
|
||||
}
|
||||
|
||||
@@ -956,7 +968,7 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress(
|
||||
resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
resBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
resBarrier.Transition.pResource = patchRaytracing->m_patchedInstanceBuffer->Resource();
|
||||
resBarrier.Transition.pResource = patchRaytracing->patchedInstanceBuffer->Resource();
|
||||
resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
||||
resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
|
||||
unwrappedList->ResourceBarrier(1, &resBarrier);
|
||||
@@ -993,6 +1005,22 @@ bool WrappedID3D12GraphicsCommandList::Serialise_BuildRaytracingAccelerationStru
|
||||
BakedCmdListInfo::PatchRaytracing &patchInfo =
|
||||
bakedCmdInfo.m_patchRaytracingInfo[bakedCmdInfo.curEventID];
|
||||
|
||||
D3D12AccelerationStructure *accStructAtDstOffset = NULL;
|
||||
|
||||
if(D3D12_Debug_RTAuditing())
|
||||
{
|
||||
ResourceId destASBId;
|
||||
D3D12BufferOffset destASBOffset;
|
||||
|
||||
WrappedID3D12Resource::GetResIDFromAddr(AccStructDesc.DestAccelerationStructureData,
|
||||
destASBId, destASBOffset);
|
||||
|
||||
WrappedID3D12Resource *destASB =
|
||||
GetResourceManager()->GetCurrentAs<WrappedID3D12Resource>(destASBId);
|
||||
|
||||
RDCASSERT(destASB->GetAccStructIfExist(destASBOffset, &accStructAtDstOffset));
|
||||
}
|
||||
|
||||
if(IsActiveReplaying(m_State))
|
||||
{
|
||||
if(m_Cmd->InRerecordRange(m_Cmd->m_LastCmdListID))
|
||||
@@ -1004,9 +1032,15 @@ bool WrappedID3D12GraphicsCommandList::Serialise_BuildRaytracingAccelerationStru
|
||||
{
|
||||
patchInfo.m_patched = false;
|
||||
PatchAccStructBlasAddress(AccStructDesc, Unwrap4(list), &patchInfo);
|
||||
|
||||
// the destination AS *will* be present by definition, but we only fetch it and store it
|
||||
// here for auditing so the pointer may be NULL.
|
||||
patchInfo.destinationAS =
|
||||
accStructAtDstOffset ? accStructAtDstOffset->GetResourceID() : ResourceId();
|
||||
|
||||
if(patchInfo.m_patched)
|
||||
{
|
||||
AccStructDesc.Inputs.InstanceDescs = patchInfo.m_patchedInstanceBuffer->Address();
|
||||
AccStructDesc.Inputs.InstanceDescs = patchInfo.patchedInstanceBuffer->Address();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1017,6 +1051,13 @@ bool WrappedID3D12GraphicsCommandList::Serialise_BuildRaytracingAccelerationStru
|
||||
// Switch back to previous state
|
||||
bakedCmdInfo.state.ApplyState(m_pDevice, list);
|
||||
}
|
||||
else if(AccStructDesc.Inputs.Type == D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL)
|
||||
{
|
||||
// the destination AS *will* be present by definition, but we only fetch it and store it
|
||||
// here for auditing so the pointer may be NULL.
|
||||
patchInfo.destinationAS =
|
||||
accStructAtDstOffset ? accStructAtDstOffset->GetResourceID() : ResourceId();
|
||||
}
|
||||
|
||||
if(!D3D12_Debug_RTAuditing())
|
||||
{
|
||||
@@ -1039,13 +1080,18 @@ bool WrappedID3D12GraphicsCommandList::Serialise_BuildRaytracingAccelerationStru
|
||||
if(GetResourceManager()->GetGPUBufferAllocator().Alloc(
|
||||
D3D12GpuBufferHeapType::DefaultHeapWithUav, D3D12GpuBufferHeapMemoryFlag::Default,
|
||||
totalInstancesSize, D3D12_RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT,
|
||||
&patchInfo.m_patchedInstanceBuffer))
|
||||
&patchInfo.patchedInstanceBuffer))
|
||||
{
|
||||
PatchAccStructBlasAddress(AccStructDesc, Unwrap4(pCommandList), &patchInfo);
|
||||
|
||||
// the destination AS *will* be present by definition, but we only fetch it and store it
|
||||
// here for auditing so the pointer may be NULL.
|
||||
patchInfo.destinationAS =
|
||||
accStructAtDstOffset ? accStructAtDstOffset->GetResourceID() : ResourceId();
|
||||
|
||||
if(patchInfo.m_patched)
|
||||
{
|
||||
AccStructDesc.Inputs.InstanceDescs = patchInfo.m_patchedInstanceBuffer->Address();
|
||||
AccStructDesc.Inputs.InstanceDescs = patchInfo.patchedInstanceBuffer->Address();
|
||||
}
|
||||
|
||||
// Switch back to previous state
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "d3d12_resources.h"
|
||||
|
||||
RDOC_EXTERN_CONFIG(bool, D3D12_Debug_SingleSubmitFlushing);
|
||||
RDOC_EXTERN_CONFIG(bool, D3D12_Debug_RTAuditing);
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedID3D12CommandQueue::Serialise_UpdateTileMappings(
|
||||
@@ -491,11 +492,93 @@ bool WrappedID3D12CommandQueue::Serialise_ExecuteCommandLists(SerialiserType &se
|
||||
|
||||
ID3D12CommandList *list = Unwrap(ppCommandLists[i]);
|
||||
real->ExecuteCommandLists(1, &list);
|
||||
if(D3D12_Debug_SingleSubmitFlushing())
|
||||
if(D3D12_Debug_SingleSubmitFlushing() || D3D12_Debug_RTAuditing())
|
||||
m_pDevice->GPUSync();
|
||||
|
||||
BakedCmdListInfo &info = m_Cmd.m_BakedCmdListInfo[cmd];
|
||||
|
||||
if(D3D12_Debug_RTAuditing())
|
||||
{
|
||||
for(auto it = info.m_patchRaytracingInfo.begin(); it != info.m_patchRaytracingInfo.end();
|
||||
++it)
|
||||
{
|
||||
if(!it->second.unpatchedInstanceBufferReadback)
|
||||
{
|
||||
if(it->second.destinationAS != ResourceId())
|
||||
{
|
||||
D3D12AccelerationStructure *as =
|
||||
(D3D12AccelerationStructure *)GetResourceManager()->GetLiveResource(
|
||||
it->second.destinationAS);
|
||||
as->seenReplayBuild = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const D3D12_RAYTRACING_INSTANCE_DESC *instances =
|
||||
(const D3D12_RAYTRACING_INSTANCE_DESC *)
|
||||
it->second.unpatchedInstanceBufferReadback->Map();
|
||||
|
||||
ResourceId id = it->second.destinationAS;
|
||||
|
||||
RDCLOG("Verifying TLAS build of %s at relative %u in %s", ToStr(id).c_str(), it->first,
|
||||
ToStr(cmd).c_str());
|
||||
|
||||
for(UINT desc = 0; desc < it->second.numDescs; desc++)
|
||||
{
|
||||
// silently ignore NULL BLASs
|
||||
if(instances[desc].AccelerationStructure == 0)
|
||||
continue;
|
||||
|
||||
ResourceId blasId;
|
||||
UINT64 blasOffs;
|
||||
m_pDevice->GetResIDFromOrigAddr(instances[desc].AccelerationStructure, blasId,
|
||||
blasOffs);
|
||||
|
||||
WrappedID3D12Resource *blas =
|
||||
GetResourceManager()->GetLiveAs<WrappedID3D12Resource>(blasId);
|
||||
|
||||
D3D12AccelerationStructure *blasCheck = NULL;
|
||||
rdcstr invalid;
|
||||
|
||||
if(blasId == ResourceId() || blas == NULL)
|
||||
invalid = StringFormat::Fmt("Address references non-existant buffer");
|
||||
else if(!blas->GetAccStructIfExist(blasOffs, &blasCheck))
|
||||
invalid = StringFormat::Fmt("No valid AS known at buffer location");
|
||||
else if(blasCheck->Type() == D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL)
|
||||
invalid = StringFormat::Fmt("TLAS referenced by TLAS");
|
||||
|
||||
if(!invalid.empty())
|
||||
{
|
||||
RDCERR("%s[%u]: %s", ToStr(id).c_str(), desc, invalid.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
if(id < GetResourceManager()->GetOriginalID(blasCheck->GetResourceID()))
|
||||
{
|
||||
RDCERR("%s[%u]: BLAS referenced by TLAS is newer than TLAS", ToStr(id).c_str(), desc);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!blasCheck->seenReplayBuild)
|
||||
{
|
||||
RDCERR("%s[%u]: BLAS referenced by TLAS has not been built yet on replay",
|
||||
ToStr(id).c_str(), desc);
|
||||
continue;
|
||||
}
|
||||
|
||||
RDCLOG("%s[%u]: valid BLAS referenced at %llx (%llx on replay)", ToStr(id).c_str(),
|
||||
desc, instances[desc].AccelerationStructure,
|
||||
blas->GetGPUVirtualAddress() + blasOffs);
|
||||
|
||||
RDCASSERTEQUAL(blasCheck->GetVirtualAddress(), blas->GetGPUVirtualAddress() + blasOffs);
|
||||
}
|
||||
|
||||
it->second.unpatchedInstanceBufferReadback->Unmap();
|
||||
SAFE_RELEASE(it->second.unpatchedInstanceBufferReadback);
|
||||
}
|
||||
}
|
||||
|
||||
if(!info.executeEvents.empty())
|
||||
{
|
||||
// ensure all GPU work has finished for readback of arguments
|
||||
|
||||
@@ -205,7 +205,10 @@ struct BakedCmdListInfo
|
||||
struct PatchRaytracing
|
||||
{
|
||||
bool m_patched = false;
|
||||
D3D12GpuBuffer *m_patchedInstanceBuffer;
|
||||
uint32_t numDescs = 0;
|
||||
D3D12GpuBuffer *patchedInstanceBuffer = NULL;
|
||||
D3D12GpuBuffer *unpatchedInstanceBufferReadback = NULL;
|
||||
ResourceId destinationAS;
|
||||
};
|
||||
|
||||
rdcflatmap<uint32_t, PatchRaytracing> m_patchRaytracingInfo;
|
||||
|
||||
@@ -1684,6 +1684,8 @@ public:
|
||||
|
||||
ASBuildData *buildData = NULL;
|
||||
|
||||
// only valid on replay - for auditing
|
||||
bool seenReplayBuild = false;
|
||||
private:
|
||||
WrappedID3D12Resource *m_asbWrappedResource;
|
||||
D3D12BufferOffset m_asbWrappedResourceBufferOffset;
|
||||
|
||||
Reference in New Issue
Block a user