diff --git a/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp index 39371df1c..559751034 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp @@ -1841,7 +1841,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_DispatchRays(SerialiserType &se Unwrap(GetResourceManager()->GetCurrentAs(state.stateobj))); state.ApplyComputeRootElementsUnwrapped(Unwrap4(list)); - m_Cmd->m_RayDispatches.push_back(patchedDispatch); + m_Cmd->m_RayDispatches.push_back(std::move(patchedDispatch)); uint32_t eventId = m_Cmd->HandlePreCallback(list, ActionFlags::DispatchRay); Unwrap4(list)->DispatchRays(&patchedDispatch.desc); @@ -1932,7 +1932,7 @@ void WrappedID3D12GraphicsCommandList::DispatchRays(_In_ const D3D12_DISPATCH_RA // during capture track the ray dispatches so the memory can be freed dynamically. On replay we // free all the memory at the end of each replay - m_RayDispatches.push_back(patchedDispatch.resources); + m_RayDispatches.push_back(std::move(patchedDispatch.resources)); // a ray dispatch certainly will pull in buffers we can't know about m_ListRecord->cmdInfo->forceMapsListEvent = true; diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index 043014bf7..c4d04ca1a 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -4095,12 +4095,6 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( WrappedID3D12CommandSignature *comSig = (WrappedID3D12CommandSignature *)pCommandSignature; - if(D3D12_Debug_RT_Auditing() && comSig->sig.raytraced) - { - // only one execute is allowed per command signature, if it's ray tracing and we're auditing then turn it off - MaxCommandCount = 0; - } - if(IsActiveReplaying(m_State)) { uint32_t actualCount = MaxCommandCount; @@ -4186,12 +4180,13 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( ID3D12Resource *argBuffer = Unwrap(patched.first); uint64_t argOffset = patched.second; + uint32_t maxCommands = MaxCommandCount; if(comSig->sig.raytraced) { PatchedRayDispatch patchedDispatch = {}; patchedDispatch = GetResourceManager()->GetRTManager()->PatchIndirectRayDispatch( - Unwrap(list), state.heaps, comSig, MaxCommandCount, patched.first, patched.second, + Unwrap(list), state.heaps, comSig, maxCommands, patched.first, patched.second, pCountBuffer, CountBufferOffset); argBuffer = patchedDispatch.resources.argumentBuffer->Resource(); @@ -4207,6 +4202,8 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( m_Cmd->m_RayDispatches.push_back(patchedDispatch); } + countToReplay = RDCMIN(countToReplay, maxCommands); + for(uint32_t i = 0; i < countToReplay; i++) { m_Cmd->m_IndirectData.commandSig = pCommandSignature; @@ -4259,12 +4256,13 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( ID3D12Resource *argBuffer = Unwrap(patched.first); UINT64 argOffset = patched.second; + uint32_t maxCommands = MaxCommandCount; if(comSig->sig.raytraced) { PatchedRayDispatch patchedDispatch = {}; patchedDispatch = GetResourceManager()->GetRTManager()->PatchIndirectRayDispatch( - Unwrap(list), state.heaps, comSig, MaxCommandCount, patched.first, patched.second, + Unwrap(list), state.heaps, comSig, maxCommands, patched.first, patched.second, pCountBuffer, CountBufferOffset); argBuffer = patchedDispatch.resources.argumentBuffer->Resource(); @@ -4280,7 +4278,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( m_Cmd->m_RayDispatches.push_back(patchedDispatch); } - uint32_t countToReplay = actualCount; + uint32_t countToReplay = RDCMIN(actualCount, maxCommands); if(m_Cmd->m_FirstEventID <= 1) { @@ -4358,13 +4356,14 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( ID3D12Resource *argBuffer = Unwrap(patched.first); UINT64 argOffset = patched.second; + uint32_t maxCommands = MaxCommandCount; if(comSig->sig.raytraced) { - PatchedRayDispatch patchedDispatch = {}; - patchedDispatch = GetResourceManager()->GetRTManager()->PatchIndirectRayDispatch( - Unwrap(list), state.heaps, comSig, MaxCommandCount, patched.first, patched.second, - pCountBuffer, CountBufferOffset); + PatchedRayDispatch patchedDispatch = + GetResourceManager()->GetRTManager()->PatchIndirectRayDispatch( + Unwrap(list), state.heaps, comSig, maxCommands, patched.first, patched.second, + pCountBuffer, CountBufferOffset); argBuffer = patchedDispatch.resources.argumentBuffer->Resource(); argOffset = patchedDispatch.resources.argumentBuffer->Offset(); @@ -4377,10 +4376,10 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( ->SetPipelineState1( Unwrap(GetResourceManager()->GetCurrentAs(state.stateobj))); state.ApplyComputeRootElementsUnwrapped(Unwrap(pCommandList)); - m_Cmd->m_RayDispatches.push_back(patchedDispatch); + m_Cmd->m_RayDispatches.push_back(std::move(patchedDispatch)); } - Unwrap(list)->ExecuteIndirect(comSig->GetReal(), MaxCommandCount, argBuffer, argOffset, + Unwrap(list)->ExecuteIndirect(comSig->GetReal(), maxCommands, argBuffer, argOffset, Unwrap(pCountBuffer), CountBufferOffset); const uint32_t sigSize = (uint32_t)comSig->sig.arguments.size(); diff --git a/renderdoc/driver/d3d12/d3d12_manager.cpp b/renderdoc/driver/d3d12/d3d12_manager.cpp index 9bee29ef9..b36ed5fca 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.cpp +++ b/renderdoc/driver/d3d12/d3d12_manager.cpp @@ -1668,7 +1668,7 @@ PatchedRayDispatch D3D12RTManager::PatchRayDispatch(ID3D12GraphicsCommandList4 * PatchedRayDispatch D3D12RTManager::PatchIndirectRayDispatch( ID3D12GraphicsCommandList *unwrappedCmd, rdcarray heaps, - ID3D12CommandSignature *pCommandSignature, UINT MaxCommandCount, ID3D12Resource *pArgumentBuffer, + ID3D12CommandSignature *pCommandSignature, UINT &MaxCommandCount, ID3D12Resource *pArgumentBuffer, UINT64 ArgumentBufferOffset, ID3D12Resource *pCountBuffer, UINT64 CountBufferOffset) { PatchedRayDispatch ret = {}; @@ -1682,7 +1682,9 @@ PatchedRayDispatch D3D12RTManager::PatchIndirectRayDispatch( // :( some games have fixed sizes, so any other estimate could fail. // games without fixed sizes would be reasonably served by 3 or 4 multiplied by the number of BLAS // in the largest TLAS, multiplied by the largest local root signature size. - uint32_t patchDataSize = 20 * 1024 * 1024 * MaxCommandCount; + // + // minimum of 64 bytes to account for MaxCommandCount so that we don't allocate 0-sized buffers + uint32_t patchDataSize = RDCMAX(64U, 20 * 1024 * 1024 * MaxCommandCount); if(D3D12_Debug_RT_IndirectEstimateOverride() > 0) patchDataSize = RDCMAX(patchDataSize, D3D12_Debug_RT_IndirectEstimateOverride()); @@ -1820,6 +1822,14 @@ PatchedRayDispatch D3D12RTManager::PatchIndirectRayDispatch( ret.resources.patchScratchBuffer = scratchBuffer; ret.resources.argumentBuffer = argsBuffer; + // TODO: Verify for indirect executes + + if(IsReplayMode(m_wrappedDevice->GetState()) && D3D12_Debug_RT_Auditing()) + { + // only one execute is allowed per command signature, if it's ray tracing and we're auditing then turn it off + MaxCommandCount = 0; + } + return ret; } @@ -3093,6 +3103,13 @@ bool D3D12GpuBufferAllocator::Alloc(D3D12GpuBufferHeapType heapType, D3D12GpuBufferHeapMemoryFlag heapMem, uint64_t size, uint64_t alignment, D3D12GpuBuffer **gpuBuffer) { + if(size == 0) + { + RDCERR("Can't allocate 0-byte buffer"); + *gpuBuffer = NULL; + return false; + } + SCOPED_LOCK(m_bufferAllocLock); bool success = false; if(heapType < D3D12GpuBufferHeapType::Count && heapType != D3D12GpuBufferHeapType::UnInitialized) diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index f8034cdcd..eba571485 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -1061,6 +1061,7 @@ struct PatchedRayDispatch SAFE_ADDREF(lookupBuffer); SAFE_ADDREF(patchScratchBuffer); SAFE_ADDREF(argumentBuffer); + SAFE_ADDREF(readbackBuffer); } void Release() @@ -1068,6 +1069,7 @@ struct PatchedRayDispatch SAFE_RELEASE(lookupBuffer); SAFE_RELEASE(patchScratchBuffer); SAFE_RELEASE(argumentBuffer); + SAFE_RELEASE(readbackBuffer); } }; @@ -1259,7 +1261,7 @@ public: PatchedRayDispatch PatchIndirectRayDispatch(ID3D12GraphicsCommandList *unwrappedCmd, rdcarray heaps, ID3D12CommandSignature *pCommandSignature, - UINT MaxCommandCount, ID3D12Resource *pArgumentBuffer, + UINT &MaxCommandCount, ID3D12Resource *pArgumentBuffer, UINT64 ArgumentBufferOffset, ID3D12Resource *pCountBuffer, UINT64 CountBufferOffset);