diff --git a/renderdoc/driver/d3d12/d3d12_command_list.h b/renderdoc/driver/d3d12/d3d12_command_list.h index 33b4d350c..3f208e915 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list.h +++ b/renderdoc/driver/d3d12/d3d12_command_list.h @@ -409,6 +409,9 @@ public: IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, EndEvent()); + void PatchedExecuteIndirect(ID3D12GraphicsCommandList *list, ResourceId sig, UINT maxCount, + ResourceId arg, UINT64 argOffs, ResourceId countbuf, UINT64 countOffs); + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, ExecuteIndirect(ID3D12CommandSignature *pCommandSignature, UINT MaxCommandCount, ID3D12Resource *pArgumentBuffer, diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index f3a63b04d..456c24ba5 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -2638,6 +2638,137 @@ void WrappedID3D12GraphicsCommandList::ExecuteBundle(ID3D12GraphicsCommandList * m_pReal->ExecuteBundle(Unwrap(pCommandList)); } +void WrappedID3D12GraphicsCommandList::PatchedExecuteIndirect(ID3D12GraphicsCommandList *list, + ResourceId sig, UINT maxCount, + ResourceId arg, UINT64 argOffs, + ResourceId countbuf, UINT64 countOffs) +{ + WrappedID3D12CommandSignature *comSig = + GetResourceManager()->GetLiveAs(sig); + ID3D12Resource *argBuf = GetResourceManager()->GetLiveAs(arg); + ID3D12Resource *countBuf = GetResourceManager()->GetLiveAs(countbuf); + + uint32_t count = maxCount; + + vector data; + if(countBuf) + { + m_pDevice->GetDebugManager()->GetBufferData(countBuf, countOffs, 4, data); + count = RDCMIN(count, *(uint32_t *)&data[0]); + } + + m_pDevice->GetDebugManager()->GetBufferData(argBuf, argOffs, count * comSig->sig.ByteStride, data); + + ID3D12Resource *indirectBuf = m_pDevice->GetDebugManager()->GetIndirectBuffer(data.size()); + + D3D12_RANGE range = {}; + byte *mapPtr = NULL; + indirectBuf->Map(0, &range, (void **)&mapPtr); + + byte *dataPtr = &data[0]; + + for(uint32_t i = 0; i < count; i++) + { + byte *dst = mapPtr; + byte *src = dataPtr; + mapPtr += comSig->sig.ByteStride; + dataPtr += comSig->sig.ByteStride; + + for(size_t a = 0; a < comSig->sig.arguments.size(); a++) + { + const D3D12_INDIRECT_ARGUMENT_DESC &arg = comSig->sig.arguments[a]; + + switch(arg.Type) + { + case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW: + memcpy(dst, src, sizeof(D3D12_DRAW_ARGUMENTS)); + dst += sizeof(D3D12_DRAW_ARGUMENTS); + src += sizeof(D3D12_DRAW_ARGUMENTS); + break; + case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED: + memcpy(dst, src, sizeof(D3D12_DRAW_INDEXED_ARGUMENTS)); + dst += sizeof(D3D12_DRAW_INDEXED_ARGUMENTS); + src += sizeof(D3D12_DRAW_INDEXED_ARGUMENTS); + break; + case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH: + memcpy(dst, src, sizeof(D3D12_DISPATCH_ARGUMENTS)); + dst += sizeof(D3D12_DISPATCH_ARGUMENTS); + src += sizeof(D3D12_DISPATCH_ARGUMENTS); + break; + case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT: + memcpy(dst, src, sizeof(uint32_t)); + dst += sizeof(uint32_t); + src += sizeof(uint32_t); + break; + case D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW: + { + D3D12_VERTEX_BUFFER_VIEW *srcVB = (D3D12_VERTEX_BUFFER_VIEW *)src; + D3D12_VERTEX_BUFFER_VIEW *dstVB = (D3D12_VERTEX_BUFFER_VIEW *)dst; + + ResourceId id; + uint64_t offs; + m_pDevice->GetResIDFromAddr(srcVB->BufferLocation, id, offs); + + ID3D12Resource *res = GetResourceManager()->GetLiveAs(id); + if(res) + dstVB->BufferLocation = res->GetGPUVirtualAddress() + offs; + + dstVB->SizeInBytes = srcVB->SizeInBytes; + dstVB->StrideInBytes = srcVB->StrideInBytes; + + dst += sizeof(D3D12_VERTEX_BUFFER_VIEW); + src += sizeof(D3D12_VERTEX_BUFFER_VIEW); + break; + } + case D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW: + { + D3D12_INDEX_BUFFER_VIEW *srcIB = (D3D12_INDEX_BUFFER_VIEW *)src; + D3D12_INDEX_BUFFER_VIEW *dstIB = (D3D12_INDEX_BUFFER_VIEW *)dst; + + ResourceId id; + uint64_t offs; + m_pDevice->GetResIDFromAddr(srcIB->BufferLocation, id, offs); + + ID3D12Resource *res = GetResourceManager()->GetLiveAs(id); + if(res) + dstIB->BufferLocation = res->GetGPUVirtualAddress() + offs; + + dstIB->SizeInBytes = srcIB->SizeInBytes; + dstIB->Format = srcIB->Format; + + dst += sizeof(D3D12_INDEX_BUFFER_VIEW); + src += sizeof(D3D12_INDEX_BUFFER_VIEW); + break; + } + case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW: + case D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW: + case D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW: + { + D3D12_GPU_VIRTUAL_ADDRESS *srcAddr = (D3D12_GPU_VIRTUAL_ADDRESS *)src; + D3D12_GPU_VIRTUAL_ADDRESS *dstAddr = (D3D12_GPU_VIRTUAL_ADDRESS *)dst; + + ResourceId id; + uint64_t offs; + m_pDevice->GetResIDFromAddr(*srcAddr, id, offs); + + ID3D12Resource *res = GetResourceManager()->GetLiveAs(id); + if(res) + *dstAddr = res->GetGPUVirtualAddress() + offs; + + dst += sizeof(D3D12_GPU_VIRTUAL_ADDRESS); + src += sizeof(D3D12_GPU_VIRTUAL_ADDRESS); + break; + } + } + } + } + + range.End = data.size(); + indirectBuf->Unmap(0, &range); + + list->ExecuteIndirect(comSig->GetReal(), count, Unwrap(indirectBuf), 0, NULL, 0); +} + bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( ID3D12CommandSignature *pCommandSignature, UINT MaxCommandCount, ID3D12Resource *pArgumentBuffer, UINT64 ArgumentBufferOffset, ID3D12Resource *pCountBuffer, UINT64 CountBufferOffset) @@ -2647,7 +2778,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( SERIALISE_ELEMENT(UINT, maxCount, MaxCommandCount); SERIALISE_ELEMENT(ResourceId, arg, GetResID(pArgumentBuffer)); SERIALISE_ELEMENT(UINT64, argOffs, ArgumentBufferOffset); - SERIALISE_ELEMENT(ResourceId, count, GetResID(pCountBuffer)); + SERIALISE_ELEMENT(ResourceId, countbuf, GetResID(pCountBuffer)); SERIALISE_ELEMENT(UINT64, countOffs, CountBufferOffset); if(m_State < WRITING) @@ -2655,32 +2786,23 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( if(m_State == EXECUTING) { - pCommandSignature = GetResourceManager()->GetLiveAs(sig); - pArgumentBuffer = GetResourceManager()->GetLiveAs(arg); - pCountBuffer = GetResourceManager()->GetLiveAs(count); - if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList)) { ID3D12GraphicsCommandList *list = m_Cmd->RerecordCmdList(CommandList); - Unwrap(list)->ExecuteIndirect(Unwrap(pCommandSignature), maxCount, Unwrap(pArgumentBuffer), - argOffs, Unwrap(pCountBuffer), countOffs); + PatchedExecuteIndirect(Unwrap(list), sig, maxCount, arg, argOffs, countbuf, countOffs); } } else if(m_State == READING) { - pCommandSignature = GetResourceManager()->GetLiveAs(sig); - pArgumentBuffer = GetResourceManager()->GetLiveAs(arg); - pCountBuffer = GetResourceManager()->GetLiveAs(count); - - GetList(CommandList) - ->ExecuteIndirect(Unwrap(pCommandSignature), maxCount, Unwrap(pArgumentBuffer), argOffs, - Unwrap(pCountBuffer), countOffs); + WrappedID3D12CommandSignature *comSig = + GetResourceManager()->GetLiveAs(sig); const string desc = m_pSerialiser->GetDebugStr(); m_Cmd->AddEvent(EXEC_INDIRECT, desc); - string name = "ExecuteIndirect(...)"; + string name = StringFormat::Fmt("ExecuteIndirect(%u arguments, maxCommands = %u)", + comSig->sig.arguments.size(), maxCount); FetchDrawcall draw; draw.name = name; @@ -2692,9 +2814,12 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( D3D12DrawcallTreeNode &drawNode = m_Cmd->GetDrawcallStack().back()->children.back(); drawNode.resourceUsage.push_back(std::make_pair( - GetResID(pArgumentBuffer), EventUsage(drawNode.draw.eventID, eUsage_Indirect))); + GetResourceManager()->GetLiveID(arg), EventUsage(drawNode.draw.eventID, eUsage_Indirect))); drawNode.resourceUsage.push_back( - std::make_pair(GetResID(pCountBuffer), EventUsage(drawNode.draw.eventID, eUsage_Indirect))); + std::make_pair(GetResourceManager()->GetLiveID(countbuf), + EventUsage(drawNode.draw.eventID, eUsage_Indirect))); + + PatchedExecuteIndirect(GetList(CommandList), sig, maxCount, arg, argOffs, countbuf, countOffs); } return true; diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index fb253b7ad..148a78438 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -169,6 +169,12 @@ struct D3D12RootSignature vector samplers; }; +struct D3D12CommandSignature +{ + UINT ByteStride; + vector arguments; +}; + #define IMPLEMENT_IUNKNOWN_WITH_REFCOUNTER_CUSTOMQUERY \ ULONG STDMETHODCALLTYPE AddRef() { return RefCounter12::AddRef(); } \ ULONG STDMETHODCALLTYPE Release() { return RefCounter12::Release(); } diff --git a/renderdoc/driver/d3d12/d3d12_debug.cpp b/renderdoc/driver/d3d12/d3d12_debug.cpp index 62f2a2488..e4ad1d11d 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.cpp +++ b/renderdoc/driver/d3d12/d3d12_debug.cpp @@ -228,8 +228,30 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper) RDCERR("Failed to create readback buffer, HRESULT: 0x%08x", hr); return; } + + hr = m_WrappedDevice->CreateCommandAllocator( + D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void **)&m_ReadbackAlloc); + + if(FAILED(hr)) + { + RDCERR("Failed to create readback command allocator, HRESULT: 0x%08x", hr); + return; + } + + hr = m_WrappedDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_ReadbackAlloc, + NULL, __uuidof(ID3D12GraphicsCommandList), + (void **)&m_ReadbackList); + + if(FAILED(hr)) + { + RDCERR("Failed to create readback command list, HRESULT: 0x%08x", hr); + return; + } } + m_IndirectBuffer = NULL; + m_IndirectSize = 0; + RenderDoc::Inst().SetProgress(DebugManagerInit, 0.2f); // create fixed samplers, point and linear @@ -723,6 +745,10 @@ D3D12DebugManager::~D3D12DebugManager() SAFE_RELEASE(m_TexResource); SAFE_RELEASE(m_ReadbackBuffer); + SAFE_RELEASE(m_ReadbackAlloc); + SAFE_RELEASE(m_ReadbackList); + + SAFE_RELEASE(m_IndirectBuffer); m_WrappedDevice->InternalRelease(); @@ -1832,7 +1858,7 @@ void D3D12DebugManager::GetBufferData(ID3D12Resource *buffer, uint64_t offset, u return; } - ID3D12GraphicsCommandList *list = m_WrappedDevice->GetNewList(); + m_ReadbackList->Reset(m_ReadbackAlloc, NULL); D3D12_RESOURCE_BARRIER barrier = {}; @@ -1840,18 +1866,20 @@ void D3D12DebugManager::GetBufferData(ID3D12Resource *buffer, uint64_t offset, u barrier.Transition.StateBefore = m_WrappedDevice->GetSubresourceStates(GetResID(buffer))[0]; barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; - list->ResourceBarrier(1, &barrier); + m_ReadbackList->ResourceBarrier(1, &barrier); while(length > 0) { uint64_t chunkSize = RDCMIN(length, m_ReadbackSize); - list->CopyBufferRegion(m_ReadbackBuffer, 0, buffer, offset, chunkSize); + m_ReadbackList->CopyBufferRegion(m_ReadbackBuffer, 0, buffer, offset, chunkSize); - list->Close(); + m_ReadbackList->Close(); - m_WrappedDevice->ExecuteLists(); - m_WrappedDevice->FlushLists(); + ID3D12CommandList *l = m_ReadbackList; + m_WrappedDevice->GetQueue()->ExecuteCommandLists(1, &l); + m_WrappedDevice->GPUSync(); + m_ReadbackAlloc->Reset(); D3D12_RANGE range = {0, (size_t)chunkSize}; @@ -1874,12 +1902,50 @@ void D3D12DebugManager::GetBufferData(ID3D12Resource *buffer, uint64_t offset, u outOffs += chunkSize; length -= chunkSize; - - if(length > 0) - list = m_WrappedDevice->GetNewList(); } } +ID3D12Resource *D3D12DebugManager::GetIndirectBuffer(size_t size) +{ + if(m_IndirectSize && size <= m_IndirectSize) + { + return m_IndirectBuffer; + } + + m_IndirectSize = RDCMAX(size, (size_t)128 * 1024); + + SAFE_RELEASE(m_IndirectBuffer); + + D3D12_RESOURCE_DESC indirectDesc; + indirectDesc.Alignment = 0; + indirectDesc.DepthOrArraySize = 1; + indirectDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + indirectDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + indirectDesc.Format = DXGI_FORMAT_UNKNOWN; + indirectDesc.Height = 1; + indirectDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + indirectDesc.MipLevels = 1; + indirectDesc.SampleDesc.Count = 1; + indirectDesc.SampleDesc.Quality = 0; + indirectDesc.Width = m_IndirectSize; + + D3D12_HEAP_PROPERTIES heapProps; + heapProps.Type = D3D12_HEAP_TYPE_CUSTOM; + heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE; + heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_L0; + heapProps.CreationNodeMask = 1; + heapProps.VisibleNodeMask = 1; + + HRESULT hr = m_WrappedDevice->CreateCommittedResource( + &heapProps, D3D12_HEAP_FLAG_NONE, &indirectDesc, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT, NULL, + __uuidof(ID3D12Resource), (void **)&m_IndirectBuffer); + + if(FAILED(hr)) + RDCERR("Failed to create indirect buffer, HRESULT: 0x%08x", hr); + + return m_IndirectBuffer; +} + void D3D12DebugManager::RenderHighlightBox(float w, float h, float scale) { OutputWindow &outw = m_OutputWindows[m_CurrentOutputWindow]; diff --git a/renderdoc/driver/d3d12/d3d12_debug.h b/renderdoc/driver/d3d12/d3d12_debug.h index ae98a7b41..cbbb25847 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.h +++ b/renderdoc/driver/d3d12/d3d12_debug.h @@ -83,6 +83,8 @@ public: void GetBufferData(ResourceId buff, uint64_t offset, uint64_t length, vector &retData); void GetBufferData(ID3D12Resource *buff, uint64_t offset, uint64_t length, vector &retData); + ID3D12Resource *GetIndirectBuffer(size_t size); + D3D12_CPU_DESCRIPTOR_HANDLE AllocRTV(); void FreeRTV(D3D12_CPU_DESCRIPTOR_HANDLE handle); @@ -187,8 +189,13 @@ private: ID3D12Resource *m_PickPixelTex; D3D12_CPU_DESCRIPTOR_HANDLE m_PickPixelRTV; + ID3D12GraphicsCommandList *m_ReadbackList; + ID3D12CommandAllocator *m_ReadbackAlloc; ID3D12Resource *m_ReadbackBuffer; + ID3D12Resource *m_IndirectBuffer; + size_t m_IndirectSize; + ID3D12Resource *m_TexResource; static const uint64_t m_ReadbackSize = 16 * 1024 * 1024; diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index c1bae1a78..fe07eca11 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -1838,6 +1838,23 @@ ID3D12GraphicsCommandList *WrappedID3D12Device::GetNewList() return ret; } +void WrappedID3D12Device::ExecuteList(ID3D12GraphicsCommandList *list) +{ + ID3D12CommandList *l = list; + GetQueue()->ExecuteCommandLists(1, &l); + + for(auto it = m_InternalCmds.pendingcmds.begin(); it != m_InternalCmds.pendingcmds.end(); ++it) + { + if(list == *it) + { + m_InternalCmds.pendingcmds.erase(it); + break; + } + } + + m_InternalCmds.submittedcmds.push_back(list); +} + void WrappedID3D12Device::ExecuteLists() { // nothing to do @@ -1869,7 +1886,8 @@ void WrappedID3D12Device::FlushLists(bool forceSync) m_InternalCmds.submittedcmds.end()); m_InternalCmds.submittedcmds.clear(); - m_Alloc->Reset(); + if(m_InternalCmds.pendingcmds.empty()) + m_Alloc->Reset(); } } diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index c33215f4d..3079d6989 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -296,6 +296,8 @@ private: std::vector m_DynamicDescriptorCopies; std::vector m_DynamicDescriptorWrites; + std::vector m_GPUAddresses; + void FlushPendingDescriptorWrites(); // used both on capture and replay side to track resource states. Only locked @@ -368,6 +370,11 @@ public: ID3D12CommandAllocator *GetAlloc() { return m_Alloc; } void ApplyBarriers(vector &barriers); + void GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs) + { + GPUAddressRange::GetResIDFromAddr(m_GPUAddresses, addr, id, offs); + } + bool IsCubemap(ResourceId id) { return m_Cubemaps.find(id) != m_Cubemaps.end(); } // returns thread-local temporary memory byte *GetTempMemory(size_t s); @@ -395,6 +402,7 @@ public: } m_InternalCmds; ID3D12GraphicsCommandList *GetNewList(); + void ExecuteList(ID3D12GraphicsCommandList *list); void ExecuteLists(); void FlushLists(bool forceSync = false); diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp index 79934c32d..e6d4fb3c2 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp @@ -871,10 +871,23 @@ bool WrappedID3D12Device::Serialise_CreateCommittedResource( SERIALISE_ELEMENT(IID, guid, riidResource); SERIALISE_ELEMENT(ResourceId, Res, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()); + SERIALISE_ELEMENT(uint64_t, gpuAddress, + ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddress()); + if(m_State == READING) { pOptimizedClearValue = HasClearValue ? &clearVal : NULL; + if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + GPUAddressRange range; + range.start = gpuAddress; + range.end = gpuAddress + desc.Width; + range.id = Res; + + GPUAddressRange::AddTo(m_GPUAddresses, range); + } + ID3D12Resource *ret = NULL; HRESULT hr = m_pDevice->CreateCommittedResource(&props, flags, &desc, state, pOptimizedClearValue, guid, (void **)&ret); @@ -1046,11 +1059,24 @@ bool WrappedID3D12Device::Serialise_CreatePlacedResource( SERIALISE_ELEMENT(IID, guid, riid); SERIALISE_ELEMENT(ResourceId, Res, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()); + SERIALISE_ELEMENT(uint64_t, gpuAddress, + ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddress()); + if(m_State == READING) { pHeap = GetResourceManager()->GetLiveAs(Heap); pOptimizedClearValue = HasClearValue ? &clearVal : NULL; + if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + GPUAddressRange range; + range.start = gpuAddress; + range.end = gpuAddress + desc.Width; + range.id = Res; + + GPUAddressRange::AddTo(m_GPUAddresses, range); + } + ID3D12Resource *ret = NULL; HRESULT hr = m_pDevice->CreatePlacedResource(Unwrap(pHeap), Offset, &desc, state, pOptimizedClearValue, guid, (void **)&ret); @@ -1304,7 +1330,8 @@ bool WrappedID3D12Device::Serialise_CreateCommandSignature(Serialiser *localSeri pRootSignature = GetResourceManager()->GetLiveAs(RootSig); ID3D12CommandSignature *ret = NULL; - HRESULT hr = m_pDevice->CreateCommandSignature(&desc, pRootSignature, guid, (void **)&ret); + HRESULT hr = + m_pDevice->CreateCommandSignature(&desc, Unwrap(pRootSignature), guid, (void **)&ret); if(FAILED(hr)) { @@ -1312,7 +1339,13 @@ bool WrappedID3D12Device::Serialise_CreateCommandSignature(Serialiser *localSeri } else { - ret = new WrappedID3D12CommandSignature(ret, this); + WrappedID3D12CommandSignature *wrapped = new WrappedID3D12CommandSignature(ret, this); + + wrapped->sig.ByteStride = desc.ByteStride; + wrapped->sig.arguments.insert(wrapped->sig.arguments.begin(), desc.pArgumentDescs, + desc.pArgumentDescs + desc.NumArgumentDescs); + + ret = wrapped; GetResourceManager()->AddLiveResource(CommandSig, ret); } diff --git a/renderdoc/driver/d3d12/d3d12_manager.cpp b/renderdoc/driver/d3d12/d3d12_manager.cpp index ec6b53418..d35e69851 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.cpp +++ b/renderdoc/driver/d3d12/d3d12_manager.cpp @@ -220,6 +220,9 @@ void D3D12Descriptor::Create(D3D12_DESCRIPTOR_HEAP_TYPE heapType, WrappedID3D12D if(nonsamp.resource == NULL) counter = NULL; + if(counter == NULL && desc && desc->ViewDimension == D3D12_UAV_DIMENSION_BUFFER) + desc->Buffer.CounterOffsetInBytes = 0; + dev->CreateUnorderedAccessView(nonsamp.resource, counter, desc, handle); break; } diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index ad4620f6a..b64bc2a35 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -24,6 +24,7 @@ #pragma once +#include #include "api/replay/renderdoc_replay.h" #include "common/wrapped_pool.h" #include "core/core.h" @@ -281,6 +282,60 @@ struct CmdListRecordingInfo class WrappedID3D12Resource; +struct GPUAddressRange +{ + D3D12_GPU_VIRTUAL_ADDRESS start, end; + ResourceId id; + + bool operator<(const D3D12_GPU_VIRTUAL_ADDRESS &o) const + { + if(o < start) + return true; + + return false; + } + + static void AddTo(std::vector &addresses, GPUAddressRange range) + { + auto it = std::lower_bound(addresses.begin(), addresses.end(), range.start); + RDCASSERT(it == addresses.begin() || it == addresses.end() || range.start < it->start || + range.start >= it->end); + + addresses.insert(it, range); + } + + static void RemoveFrom(std::vector &addresses, D3D12_GPU_VIRTUAL_ADDRESS baseAddr) + { + auto it = std::lower_bound(addresses.begin(), addresses.end(), baseAddr); + RDCASSERT(it != addresses.end() && baseAddr >= it->start && baseAddr < it->end); + + addresses.erase(it); + } + + static void GetResIDFromAddr(std::vector &addresses, + D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs) + { + id = ResourceId(); + offs = 0; + + if(addr == 0) + return; + + if(addresses.empty()) + return; + + auto it = std::lower_bound(addresses.begin(), addresses.end(), addr); + if(it == addresses.end()) + return; + + if(addr < it->start || addr >= it->end) + return; + + id = it->id; + offs = addr - it->start; + } +}; + struct MapState { WrappedID3D12Resource *res; diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index 4f6738db3..ae937ebdc 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.cpp +++ b/renderdoc/driver/d3d12/d3d12_resources.cpp @@ -27,7 +27,7 @@ #include "d3d12_command_list.h" #include "d3d12_command_queue.h" -std::vector WrappedID3D12Resource::m_Addresses; +std::vector WrappedID3D12Resource::m_Addresses; std::map WrappedID3D12Resource::m_List; std::map diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index 68dc3c283..8217a60de 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -24,7 +24,6 @@ #pragma once -#include #include "driver/shaders/dxbc/dxbc_inspect.h" #include "d3d12_device.h" #include "d3d12_manager.h" @@ -299,6 +298,8 @@ class WrappedID3D12CommandSignature : public WrappedDeviceChild12 { - struct AddressRange - { - D3D12_GPU_VIRTUAL_ADDRESS start, end; - ResourceId id; - - bool operator<(const D3D12_GPU_VIRTUAL_ADDRESS &o) const - { - if(o < start) - return true; - - return false; - } - }; - - static std::vector m_Addresses; + static std::vector m_Addresses; bool resident; @@ -660,24 +647,7 @@ public: static void GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs) { - id = ResourceId(); - offs = 0; - - if(addr == 0) - return; - - if(m_Addresses.empty()) - return; - - auto it = std::lower_bound(m_Addresses.begin(), m_Addresses.end(), addr); - if(it == m_Addresses.end()) - return; - - if(addr < it->start || addr >= it->end) - return; - - id = it->id; - offs = addr - it->start; + GPUAddressRange::GetResIDFromAddr(m_Addresses, addr, id, offs); } // overload to just return the id in case the offset isn't needed @@ -707,16 +677,12 @@ public: { D3D12_GPU_VIRTUAL_ADDRESS addr = m_pReal->GetGPUVirtualAddress(); - auto it = std::lower_bound(m_Addresses.begin(), m_Addresses.end(), addr); - RDCASSERT(it == m_Addresses.begin() || it == m_Addresses.end() || addr < it->start || - addr >= it->end); - - AddressRange range; + GPUAddressRange range; range.start = addr; range.end = addr + m_pReal->GetDesc().Width; range.id = GetResourceID(); - m_Addresses.insert(it, range); + GPUAddressRange::AddTo(m_Addresses, range); } } virtual ~WrappedID3D12Resource() @@ -725,14 +691,7 @@ public: // assuming only valid for buffers if(m_pReal->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - D3D12_GPU_VIRTUAL_ADDRESS addr = m_pReal->GetGPUVirtualAddress(); - - auto it = std::lower_bound(m_Addresses.begin(), m_Addresses.end(), addr); - RDCASSERT(it != m_Addresses.end() && addr >= it->start && addr < it->end); - - m_Addresses.erase(it); - } + GPUAddressRange::RemoveFrom(m_Addresses, m_pReal->GetGPUVirtualAddress()); Shutdown(); }