diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index 19298a0a5..7f53037e0 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -840,6 +840,54 @@ void WrappedID3D12GraphicsCommandList::ExecuteBundle(ID3D12GraphicsCommandList * m_pReal->ExecuteBundle(Unwrap(pCommandList)); } +bool WrappedID3D12GraphicsCommandList::Serialise_SetDescriptorHeaps( + UINT NumDescriptorHeaps, ID3D12DescriptorHeap *const *ppDescriptorHeaps) +{ + SERIALISE_ELEMENT(ResourceId, CommandList, GetResourceID()); + + std::vector DescriptorHeaps; + + if(m_State >= WRITING) + { + DescriptorHeaps.resize(NumDescriptorHeaps); + for(UINT i = 0; i < NumDescriptorHeaps; i++) + DescriptorHeaps[i] = GetResID(ppDescriptorHeaps[i]); + } + + m_pSerialiser->Serialise("DescriptorHeaps", DescriptorHeaps); + + if(m_State < WRITING) + m_Cmd->m_LastCmdListID = CommandList; + + if(m_State == EXECUTING) + { + if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList)) + { + std::vector heaps; + heaps.resize(DescriptorHeaps.size()); + for(size_t i = 0; i < heaps.size(); i++) + heaps[i] = Unwrap(GetResourceManager()->GetLiveAs(DescriptorHeaps[i])); + + Unwrap(m_Cmd->RerecordCmdList(CommandList))->SetDescriptorHeaps((UINT)heaps.size(), &heaps[0]); + + m_Cmd->m_RenderState.heaps.resize(heaps.size()); + for(size_t i = 0; i < heaps.size(); i++) + m_Cmd->m_RenderState.heaps[i] = GetResourceManager()->GetLiveID(DescriptorHeaps[i]); + } + } + else if(m_State == READING) + { + std::vector heaps; + heaps.resize(DescriptorHeaps.size()); + for(size_t i = 0; i < heaps.size(); i++) + heaps[i] = Unwrap(GetResourceManager()->GetLiveAs(DescriptorHeaps[i])); + + GetList(CommandList)->SetDescriptorHeaps((UINT)heaps.size(), &heaps[0]); + } + + return true; +} + void WrappedID3D12GraphicsCommandList::SetDescriptorHeaps(UINT NumDescriptorHeaps, ID3D12DescriptorHeap *const *ppDescriptorHeaps) { @@ -849,6 +897,16 @@ void WrappedID3D12GraphicsCommandList::SetDescriptorHeaps(UINT NumDescriptorHeap m_pReal->SetDescriptorHeaps(NumDescriptorHeaps, heaps); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(SET_DESC_HEAPS); + Serialise_SetDescriptorHeaps(NumDescriptorHeaps, ppDescriptorHeaps); + + m_ListRecord->AddChunk(scope.Get()); + for(UINT i = 0; i < NumDescriptorHeaps; i++) + m_ListRecord->MarkResourceFrameReferenced(GetResID(ppDescriptorHeaps[i]), eFrameRef_Read); + } + SAFE_DELETE_ARRAY(heaps); } @@ -906,10 +964,58 @@ void WrappedID3D12GraphicsCommandList::SetComputeRootDescriptorTable( m_pReal->SetComputeRootDescriptorTable(RootParameterIndex, Unwrap(BaseDescriptor)); } +bool WrappedID3D12GraphicsCommandList::Serialise_SetGraphicsRootDescriptorTable( + UINT RootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor) +{ + SERIALISE_ELEMENT(ResourceId, CommandList, GetResourceID()); + SERIALISE_ELEMENT(UINT, idx, RootParameterIndex); + SERIALISE_ELEMENT(PortableHandle, Descriptor, ToPortableHandle(BaseDescriptor)); + + if(m_State < WRITING) + m_Cmd->m_LastCmdListID = CommandList; + + if(m_State == EXECUTING) + { + if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList)) + { + Unwrap(m_Cmd->RerecordCmdList(CommandList)) + ->SetGraphicsRootDescriptorTable( + idx, GPUHandleFromPortableHandle(GetResourceManager(), Descriptor)); + + WrappedID3D12DescriptorHeap *heap = + GetResourceManager()->GetLiveAs(Descriptor.heap); + + if(m_Cmd->m_RenderState.graphics.sigelems.size() < idx + 1) + m_Cmd->m_RenderState.graphics.sigelems.resize(idx + 1); + + m_Cmd->m_RenderState.graphics.sigelems[idx] = + D3D12RenderState::SignatureElement(eRootTable, GetResID(heap), (UINT64)Descriptor.index); + } + } + else if(m_State == READING) + { + GetList(CommandList) + ->SetGraphicsRootDescriptorTable( + idx, GPUHandleFromPortableHandle(GetResourceManager(), Descriptor)); + } + + return true; +} + void WrappedID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable( UINT RootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor) { m_pReal->SetGraphicsRootDescriptorTable(RootParameterIndex, Unwrap(BaseDescriptor)); + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(SET_GFX_ROOT_TABLE); + Serialise_SetGraphicsRootDescriptorTable(RootParameterIndex, BaseDescriptor); + + m_ListRecord->AddChunk(scope.Get()); + m_ListRecord->MarkResourceFrameReferenced(GetResID(GetWrapped(BaseDescriptor)->nonsamp.heap), + eFrameRef_Read); + } } void WrappedID3D12GraphicsCommandList::SetComputeRoot32BitConstant(UINT RootParameterIndex, @@ -1217,12 +1323,12 @@ bool WrappedID3D12GraphicsCommandList::Serialise_OMSetRenderTargets( { if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList)) { - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = FromPortableHandle(GetResourceManager(), dsv); + D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = CPUHandleFromPortableHandle(GetResourceManager(), dsv); D3D12_CPU_DESCRIPTOR_HANDLE *rtHandles = new D3D12_CPU_DESCRIPTOR_HANDLE[numHandles]; for(UINT i = 0; i < numHandles; i++) - rtHandles[i] = FromPortableHandle(GetResourceManager(), rts[i]); + rtHandles[i] = CPUHandleFromPortableHandle(GetResourceManager(), rts[i]); Unwrap(m_Cmd->RerecordCmdList(CommandList)) ->OMSetRenderTargets(num, rtHandles, singlehandle ? TRUE : FALSE, @@ -1242,12 +1348,12 @@ bool WrappedID3D12GraphicsCommandList::Serialise_OMSetRenderTargets( } else if(m_State == READING) { - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = FromPortableHandle(GetResourceManager(), dsv); + D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = CPUHandleFromPortableHandle(GetResourceManager(), dsv); D3D12_CPU_DESCRIPTOR_HANDLE *rtHandles = new D3D12_CPU_DESCRIPTOR_HANDLE[numHandles]; for(UINT i = 0; i < numHandles; i++) - rtHandles[i] = FromPortableHandle(GetResourceManager(), rts[i]); + rtHandles[i] = CPUHandleFromPortableHandle(GetResourceManager(), rts[i]); GetList(CommandList) ->OMSetRenderTargets(num, rtHandles, singlehandle ? TRUE : FALSE, @@ -1371,7 +1477,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ClearRenderTargetView( if(m_State == EXECUTING) { - RenderTargetView = FromPortableHandle(GetResourceManager(), rtv); + RenderTargetView = CPUHandleFromPortableHandle(GetResourceManager(), rtv); if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList)) { @@ -1381,7 +1487,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ClearRenderTargetView( } else if(m_State == READING) { - RenderTargetView = FromPortableHandle(GetResourceManager(), rtv); + RenderTargetView = CPUHandleFromPortableHandle(GetResourceManager(), rtv); GetList(CommandList)->ClearRenderTargetView(RenderTargetView, Color, num, rects); diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index 4d6bba142..38a76f72a 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -281,7 +281,11 @@ void WrappedID3D12CommandQueue::ProcessChunk(uint64_t offset, D3D12ChunkType chu case SET_SCISSORS: m_ReplayList->Serialise_RSSetScissorRects(0, NULL); break; case SET_PIPE: m_ReplayList->Serialise_SetPipelineState(NULL); break; case SET_RTVS: m_ReplayList->Serialise_OMSetRenderTargets(0, NULL, FALSE, NULL); break; + case SET_DESC_HEAPS: m_ReplayList->Serialise_SetDescriptorHeaps(0, NULL); break; case SET_GFX_ROOT_SIG: m_ReplayList->Serialise_SetGraphicsRootSignature(NULL); break; + case SET_GFX_ROOT_TABLE: + m_ReplayList->Serialise_SetGraphicsRootDescriptorTable(0, D3D12_GPU_DESCRIPTOR_HANDLE()); + break; case SET_GFX_ROOT_CBV: m_ReplayList->Serialise_SetGraphicsRootConstantBufferView(0, D3D12_GPU_VIRTUAL_ADDRESS()); break; diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index 1b27b7afd..880de1fc4 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -216,7 +216,10 @@ void Serialiser::Serialise(const char *name, D3D12Descriptor &el); D3D12_CHUNK_MACRO(SET_VIEWPORTS, "ID3D12GraphicsCommandList::RSSetViewports") \ D3D12_CHUNK_MACRO(SET_SCISSORS, "ID3D12GraphicsCommandList::RSSetScissors") \ D3D12_CHUNK_MACRO(SET_PIPE, "ID3D12GraphicsCommandList::SetPipelineState") \ + D3D12_CHUNK_MACRO(SET_DESC_HEAPS, "ID3D12GraphicsCommandList::SetDescriptorHeaps") \ D3D12_CHUNK_MACRO(SET_RTVS, "ID3D12GraphicsCommandList::OMSetRenderTargets") \ + D3D12_CHUNK_MACRO(SET_GFX_ROOT_TABLE, \ + "ID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable") \ D3D12_CHUNK_MACRO(SET_GFX_ROOT_SIG, "ID3D12GraphicsCommandList::SetGraphicsRootSignature") \ D3D12_CHUNK_MACRO(SET_GFX_ROOT_CBV, \ "ID3D12GraphicsCommandList::SetGraphicsRootConstantBufferView") \ diff --git a/renderdoc/driver/d3d12/d3d12_manager.cpp b/renderdoc/driver/d3d12/d3d12_manager.cpp index e1f3d08d3..2ce156442 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.cpp +++ b/renderdoc/driver/d3d12/d3d12_manager.cpp @@ -185,7 +185,18 @@ PortableHandle ToPortableHandle(D3D12_CPU_DESCRIPTOR_HANDLE handle) return PortableHandle(GetResID(desc->samp.heap), desc->samp.idx); } -D3D12_CPU_DESCRIPTOR_HANDLE FromPortableHandle(D3D12ResourceManager *manager, PortableHandle handle) +PortableHandle ToPortableHandle(D3D12_GPU_DESCRIPTOR_HANDLE handle) +{ + if(handle.ptr == 0) + return PortableHandle(0); + + D3D12Descriptor *desc = GetWrapped(handle); + + return PortableHandle(GetResID(desc->samp.heap), desc->samp.idx); +} + +D3D12_CPU_DESCRIPTOR_HANDLE CPUHandleFromPortableHandle(D3D12ResourceManager *manager, + PortableHandle handle) { if(handle.heap == ResourceId()) return D3D12_CPU_DESCRIPTOR_HANDLE(); @@ -198,6 +209,20 @@ D3D12_CPU_DESCRIPTOR_HANDLE FromPortableHandle(D3D12ResourceManager *manager, Po return D3D12_CPU_DESCRIPTOR_HANDLE(); } +D3D12_GPU_DESCRIPTOR_HANDLE GPUHandleFromPortableHandle(D3D12ResourceManager *manager, + PortableHandle handle) +{ + if(handle.heap == ResourceId()) + return D3D12_GPU_DESCRIPTOR_HANDLE(); + + WrappedID3D12DescriptorHeap *heap = manager->GetLiveAs(handle.heap); + + if(heap) + return heap->GetGPU(handle.index); + + return D3D12_GPU_DESCRIPTOR_HANDLE(); +} + // debugging logging for barriers #if 1 #define BARRIER_DBG RDCLOG diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index d33654eb6..f25c258e2 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -216,7 +216,11 @@ struct PortableHandle class D3D12ResourceManager; PortableHandle ToPortableHandle(D3D12_CPU_DESCRIPTOR_HANDLE handle); -D3D12_CPU_DESCRIPTOR_HANDLE FromPortableHandle(D3D12ResourceManager *manager, PortableHandle handle); +PortableHandle ToPortableHandle(D3D12_GPU_DESCRIPTOR_HANDLE handle); +D3D12_CPU_DESCRIPTOR_HANDLE CPUHandleFromPortableHandle(D3D12ResourceManager *manager, + PortableHandle handle); +D3D12_GPU_DESCRIPTOR_HANDLE GPUHandleFromPortableHandle(D3D12ResourceManager *manager, + PortableHandle handle); struct D3D12ResourceRecord; diff --git a/renderdoc/driver/d3d12/d3d12_state.cpp b/renderdoc/driver/d3d12/d3d12_state.cpp index 5fa6c8870..8b7b98397 100644 --- a/renderdoc/driver/d3d12/d3d12_state.cpp +++ b/renderdoc/driver/d3d12/d3d12_state.cpp @@ -38,6 +38,8 @@ D3D12RenderState::D3D12RenderState() m_ResourceManager = NULL; + heaps.clear(); + pipe = graphics.rootsig = compute.rootsig = ResourceId(); graphics.sigelems.clear(); compute.sigelems.clear(); @@ -59,6 +61,8 @@ D3D12RenderState &D3D12RenderState::operator=(const D3D12RenderState &o) pipe = o.pipe; + heaps = o.heaps; + graphics.rootsig = o.graphics.rootsig; graphics.sigelems = o.graphics.sigelems; compute.rootsig = o.compute.rootsig; @@ -118,15 +122,24 @@ void D3D12RenderState::ApplyState(ID3D12GraphicsCommandList *cmd) cmd->IASetVertexBuffers((UINT)i, 1, &vb); } + std::vector descHeaps; + descHeaps.resize(heaps.size()); + + for(size_t i = 0; i < heaps.size(); i++) + descHeaps[i] = GetResourceManager()->GetCurrentAs(heaps[i]); + + if(!descHeaps.empty()) + cmd->SetDescriptorHeaps((UINT)descHeaps.size(), &descHeaps[0]); + if(!rts.empty() || dsv.heap != ResourceId()) { D3D12_CPU_DESCRIPTOR_HANDLE rtHandles[8]; - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = FromPortableHandle(GetResourceManager(), dsv); + D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = CPUHandleFromPortableHandle(GetResourceManager(), dsv); UINT numActualHandles = rtSingle ? 1 : (UINT)rts.size(); for(UINT i = 0; i < numActualHandles; i++) - rtHandles[i] = FromPortableHandle(GetResourceManager(), rts[i]); + rtHandles[i] = CPUHandleFromPortableHandle(GetResourceManager(), rts[i]); // need to unwrap here, as FromPortableHandle unwraps too. Unwrap(cmd)->OMSetRenderTargets((UINT)rts.size(), rtHandles, rtSingle ? TRUE : FALSE, diff --git a/renderdoc/driver/d3d12/d3d12_state.h b/renderdoc/driver/d3d12/d3d12_state.h index 7b7a01084..2e3117b38 100644 --- a/renderdoc/driver/d3d12/d3d12_state.h +++ b/renderdoc/driver/d3d12/d3d12_state.h @@ -119,6 +119,8 @@ struct D3D12RenderState vector constants; }; + vector heaps; + struct Pipeline { ResourceId rootsig;