From 00566622e30aa2000be5a1139013a9cfb22f1315 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 6 Jan 2017 10:33:36 +0100 Subject: [PATCH] Detect and drop calls setting a GPU virtual address of 0 --- renderdoc/driver/d3d12/d3d12_command_list.h | 2 ++ .../driver/d3d12/d3d12_command_list_wrap.cpp | 30 +++++++++++++++++++ renderdoc/driver/d3d12/d3d12_commands.cpp | 26 ++++++++++++++++ renderdoc/driver/d3d12/d3d12_device.cpp | 29 ++++++++++++++++++ renderdoc/driver/d3d12/d3d12_device.h | 2 ++ 5 files changed, 89 insertions(+) diff --git a/renderdoc/driver/d3d12/d3d12_command_list.h b/renderdoc/driver/d3d12/d3d12_command_list.h index 808a4a1ef..3d1e41356 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list.h +++ b/renderdoc/driver/d3d12/d3d12_command_list.h @@ -133,6 +133,8 @@ public: m_Init.type = type; } + bool ValidateRootGPUVA(ResourceId buffer); + ////////////////////////////// // implement IUnknown diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index 4e407f929..e1c211314 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -1517,8 +1517,13 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetComputeRootConstantBufferVie SERIALISE_ELEMENT(UINT64, byteOffset, offs); if(m_State < WRITING) + { m_Cmd->m_LastCmdListID = CommandList; + if(ValidateRootGPUVA(buffer)) + return true; + } + if(m_State == EXECUTING) { if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList)) @@ -1589,8 +1594,13 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetComputeRootShaderResourceVie SERIALISE_ELEMENT(UINT64, byteOffset, offs); if(m_State < WRITING) + { m_Cmd->m_LastCmdListID = CommandList; + if(ValidateRootGPUVA(buffer)) + return true; + } + if(m_State == EXECUTING) { if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList)) @@ -1661,8 +1671,13 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetComputeRootUnorderedAccessVi SERIALISE_ELEMENT(UINT64, byteOffset, offs); if(m_State < WRITING) + { m_Cmd->m_LastCmdListID = CommandList; + if(ValidateRootGPUVA(buffer)) + return true; + } + if(m_State == EXECUTING) { if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList)) @@ -2017,8 +2032,13 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetGraphicsRootConstantBufferVi SERIALISE_ELEMENT(UINT64, byteOffset, offs); if(m_State < WRITING) + { m_Cmd->m_LastCmdListID = CommandList; + if(ValidateRootGPUVA(buffer)) + return true; + } + if(m_State == EXECUTING) { if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList)) @@ -2090,8 +2110,13 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetGraphicsRootShaderResourceVi SERIALISE_ELEMENT(UINT64, byteOffset, offs); if(m_State < WRITING) + { m_Cmd->m_LastCmdListID = CommandList; + if(ValidateRootGPUVA(buffer)) + return true; + } + if(m_State == EXECUTING) { if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList)) @@ -2163,8 +2188,13 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetGraphicsRootUnorderedAccessV SERIALISE_ELEMENT(UINT64, byteOffset, offs); if(m_State < WRITING) + { m_Cmd->m_LastCmdListID = CommandList; + if(ValidateRootGPUVA(buffer)) + return true; + } + if(m_State == EXECUTING) { if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList)) diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index 642269732..8bccb1429 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -666,6 +666,32 @@ WrappedID3D12GraphicsCommandList::~WrappedID3D12GraphicsCommandList() SAFE_RELEASE(m_pReal); } +bool WrappedID3D12GraphicsCommandList::ValidateRootGPUVA(ResourceId buffer) +{ + if(!GetResourceManager()->HasLiveResource(buffer)) + { + // abort, we don't have this buffer. Print errors while reading + if(m_State == READING) + { + if(buffer != ResourceId()) + { + RDCERR("Don't have live buffer for %llu", buffer); + } + else + { + m_pDevice->AddDebugMessage(eDbgCategory_Resource_Manipulation, eDbgSeverity_Medium, + eDbgSource_IncorrectAPIUse, + "Binding 0 as a GPU Virtual Address in a root constant is " + "invalid. This call will be dropped during replay."); + } + } + + return true; + } + + return false; +} + HRESULT STDMETHODCALLTYPE WrappedID3D12GraphicsCommandList::QueryInterface(REFIID riid, void **ppvObject) { diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 2f9dd2331..16a0769ac 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -1593,6 +1593,35 @@ void WrappedID3D12Device::ReleaseResource(ID3D12DeviceChild *res) } } +void WrappedID3D12Device::AddDebugMessage(DebugMessageCategory c, DebugMessageSeverity sv, + DebugMessageSource src, std::string d) +{ + D3D12CommandData &cmd = *m_Queue->GetCommandData(); + + DebugMessage msg; + msg.eventID = 0; + msg.messageID = 0; + msg.source = src; + msg.category = c; + msg.severity = sv; + msg.description = d; + + if(m_State == EXECUTING) + { + // look up the EID this drawcall came from + D3D12CommandData::DrawcallUse use(cmd.m_CurChunkOffset, 0); + auto it = std::lower_bound(cmd.m_DrawcallUses.begin(), cmd.m_DrawcallUses.end(), use); + RDCASSERT(it != cmd.m_DrawcallUses.end()); + + msg.eventID = it->eventID; + AddDebugMessage(msg); + } + else + { + cmd.m_EventMessages.push_back(msg); + } +} + vector WrappedID3D12Device::GetDebugMessages() { vector ret; diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index 81755b4c1..4c698b6d5 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -362,6 +362,8 @@ public: FetchFrameRecord &GetFrameRecord() { return m_FrameRecord; } const FetchDrawcall *GetDrawcall(uint32_t eventID); + void AddDebugMessage(DebugMessageCategory c, DebugMessageSeverity sv, DebugMessageSource src, + std::string d); void AddDebugMessage(const DebugMessage &msg) { m_DebugMessages.push_back(msg); } vector GetDebugMessages();