From b956568215f46a25872d59f18d9cd12d74a3a2fb Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 8 Jul 2016 18:01:48 +0300 Subject: [PATCH] Can't wrap virtual addresses - they can be byte offsetted. * We need to pass them through unwrapped and use a lookup table to get the resource's ID from them when necessary --- .../driver/d3d12/d3d12_command_list_wrap.cpp | 51 +++---------- renderdoc/driver/d3d12/d3d12_common.cpp | 6 +- renderdoc/driver/d3d12/d3d12_device_wrap.cpp | 10 +-- renderdoc/driver/d3d12/d3d12_resources.cpp | 18 +---- renderdoc/driver/d3d12/d3d12_resources.h | 71 +++++++++++++++++-- 5 files changed, 82 insertions(+), 74 deletions(-) diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index fdac397bf..40a409318 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -552,7 +552,7 @@ void WrappedID3D12GraphicsCommandList::SetGraphicsRoot32BitConstants(UINT RootPa void WrappedID3D12GraphicsCommandList::SetComputeRootConstantBufferView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) { - m_pReal->SetComputeRootConstantBufferView(RootParameterIndex, Unwrap(BufferLocation)); + m_pReal->SetComputeRootConstantBufferView(RootParameterIndex, BufferLocation); } bool WrappedID3D12GraphicsCommandList::Serialise_SetGraphicsRootConstantBufferView( @@ -566,7 +566,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetGraphicsRootConstantBufferVi { WrappedID3D12Resource *pRes = GetResourceManager()->GetLiveAs(buffer); - GetList(CommandList)->SetGraphicsRootConstantBufferView(idx, pRes->GetGPU()); + GetList(CommandList)->SetGraphicsRootConstantBufferView(idx, pRes->GetGPUVirtualAddress()); } return true; @@ -575,7 +575,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetGraphicsRootConstantBufferVi void WrappedID3D12GraphicsCommandList::SetGraphicsRootConstantBufferView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) { - m_pReal->SetGraphicsRootConstantBufferView(RootParameterIndex, Unwrap(BufferLocation)); + m_pReal->SetGraphicsRootConstantBufferView(RootParameterIndex, BufferLocation); if(m_State >= WRITING) { @@ -590,25 +590,25 @@ void WrappedID3D12GraphicsCommandList::SetGraphicsRootConstantBufferView( void WrappedID3D12GraphicsCommandList::SetComputeRootShaderResourceView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) { - m_pReal->SetComputeRootShaderResourceView(RootParameterIndex, Unwrap(BufferLocation)); + m_pReal->SetComputeRootShaderResourceView(RootParameterIndex, BufferLocation); } void WrappedID3D12GraphicsCommandList::SetGraphicsRootShaderResourceView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) { - m_pReal->SetGraphicsRootShaderResourceView(RootParameterIndex, Unwrap(BufferLocation)); + m_pReal->SetGraphicsRootShaderResourceView(RootParameterIndex, BufferLocation); } void WrappedID3D12GraphicsCommandList::SetComputeRootUnorderedAccessView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) { - m_pReal->SetComputeRootUnorderedAccessView(RootParameterIndex, Unwrap(BufferLocation)); + m_pReal->SetComputeRootUnorderedAccessView(RootParameterIndex, BufferLocation); } void WrappedID3D12GraphicsCommandList::SetGraphicsRootUnorderedAccessView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) { - m_pReal->SetGraphicsRootUnorderedAccessView(RootParameterIndex, Unwrap(BufferLocation)); + m_pReal->SetGraphicsRootUnorderedAccessView(RootParameterIndex, BufferLocation); } bool WrappedID3D12GraphicsCommandList::Serialise_IASetIndexBuffer(const D3D12_INDEX_BUFFER_VIEW *pView) @@ -630,17 +630,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_IASetIndexBuffer(const D3D12_IN void WrappedID3D12GraphicsCommandList::IASetIndexBuffer(const D3D12_INDEX_BUFFER_VIEW *pView) { - if(pView) - { - D3D12_INDEX_BUFFER_VIEW view = *pView; - view.BufferLocation = Unwrap(view.BufferLocation); - - m_pReal->IASetIndexBuffer(&view); - } - else - { - m_pReal->IASetIndexBuffer(pView); - } + m_pReal->IASetIndexBuffer(pView); if(m_State >= WRITING) { @@ -674,17 +664,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_IASetVertexBuffers( void WrappedID3D12GraphicsCommandList::IASetVertexBuffers(UINT StartSlot, UINT NumViews, const D3D12_VERTEX_BUFFER_VIEW *pViews) { - D3D12_VERTEX_BUFFER_VIEW *unwrapped = new D3D12_VERTEX_BUFFER_VIEW[NumViews]; - - for(UINT i = 0; i < NumViews; i++) - { - unwrapped[i] = pViews[i]; - unwrapped[i].BufferLocation = Unwrap(unwrapped[i].BufferLocation); - } - - m_pReal->IASetVertexBuffers(StartSlot, NumViews, unwrapped); - - SAFE_DELETE_ARRAY(unwrapped); + m_pReal->IASetVertexBuffers(StartSlot, NumViews, pViews); if(m_State >= WRITING) { @@ -700,18 +680,7 @@ void WrappedID3D12GraphicsCommandList::IASetVertexBuffers(UINT StartSlot, UINT N void WrappedID3D12GraphicsCommandList::SOSetTargets(UINT StartSlot, UINT NumViews, const D3D12_STREAM_OUTPUT_BUFFER_VIEW *pViews) { - D3D12_STREAM_OUTPUT_BUFFER_VIEW *unwrapped = new D3D12_STREAM_OUTPUT_BUFFER_VIEW[NumViews]; - - for(UINT i = 0; i < NumViews; i++) - { - unwrapped[i] = pViews[i]; - unwrapped[i].BufferLocation = Unwrap(unwrapped[i].BufferLocation); - unwrapped[i].BufferFilledSizeLocation = Unwrap(unwrapped[i].BufferFilledSizeLocation); - } - - m_pReal->SOSetTargets(StartSlot, NumViews, unwrapped); - - SAFE_DELETE_ARRAY(unwrapped); + m_pReal->SOSetTargets(StartSlot, NumViews, pViews); } bool WrappedID3D12GraphicsCommandList::Serialise_OMSetRenderTargets( diff --git a/renderdoc/driver/d3d12/d3d12_common.cpp b/renderdoc/driver/d3d12/d3d12_common.cpp index 591c97723..03d11130d 100644 --- a/renderdoc/driver/d3d12/d3d12_common.cpp +++ b/renderdoc/driver/d3d12/d3d12_common.cpp @@ -481,7 +481,7 @@ void Serialiser::Serialise(const char *name, D3D12_VERTEX_BUFFER_VIEW &el) { ID3D12Resource *res = rm->GetLiveAs(buffer); if(res) - el.BufferLocation = Unwrap(res->GetGPUVirtualAddress()); + el.BufferLocation = res->GetGPUVirtualAddress(); else el.BufferLocation = 0; } @@ -508,7 +508,7 @@ void Serialiser::Serialise(const char *name, D3D12_INDEX_BUFFER_VIEW &el) { ID3D12Resource *res = rm->GetLiveAs(buffer); if(res) - el.BufferLocation = Unwrap(res->GetGPUVirtualAddress()); + el.BufferLocation = res->GetGPUVirtualAddress(); else el.BufferLocation = 0; } @@ -535,7 +535,7 @@ void Serialiser::Serialise(const char *name, D3D12_CONSTANT_BUFFER_VIEW_DESC &el { ID3D12Resource *res = rm->GetLiveAs(buffer); if(res) - el.BufferLocation = Unwrap(res->GetGPUVirtualAddress()); + el.BufferLocation = res->GetGPUVirtualAddress(); else el.BufferLocation = 0; } diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp index 15c75294a..1ab23a2ef 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp @@ -534,15 +534,7 @@ void WrappedID3D12Device::CreateConstantBufferView(const D3D12_CONSTANT_BUFFER_V D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) { GetWrapped(DestDescriptor)->Init(pDesc); - - D3D12_CONSTANT_BUFFER_VIEW_DESC desc; - if(pDesc) - { - desc = *pDesc; - desc.BufferLocation = Unwrap(desc.BufferLocation); - } - - return m_pDevice->CreateConstantBufferView(pDesc ? &desc : NULL, Unwrap(DestDescriptor)); + return m_pDevice->CreateConstantBufferView(pDesc, Unwrap(DestDescriptor)); } void WrappedID3D12Device::CreateShaderResourceView(ID3D12Resource *pResource, diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index 4efa48d77..d585db52f 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.cpp +++ b/renderdoc/driver/d3d12/d3d12_resources.cpp @@ -26,6 +26,8 @@ #include "d3d12_command_list.h" #include "d3d12_command_queue.h" +std::vector WrappedID3D12Resource::m_Addresses; + #undef D3D12_TYPE_MACRO #define D3D12_TYPE_MACRO(iface) WRAPPED_POOL_INST(CONCAT(Wrapped, iface)); @@ -125,24 +127,10 @@ D3D12ResourceRecord *GetRecord(ID3D12DeviceChild *ptr) return res->GetResourceRecord(); } -template <> -D3D12_GPU_VIRTUAL_ADDRESS Unwrap(D3D12_GPU_VIRTUAL_ADDRESS addr) -{ - if(addr == 0) - return addr; - - WrappedID3D12Resource *res = (WrappedID3D12Resource *)addr; - return res->GetGPU(); -} - template <> ResourceId GetResID(D3D12_GPU_VIRTUAL_ADDRESS addr) { - if(addr == 0) - return ResourceId(); - - WrappedID3D12Resource *res = (WrappedID3D12Resource *)addr; - return res->GetResourceID(); + return WrappedID3D12Resource::GetResIDFromAddr(addr); } WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *real, diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index e66f63dac..8d591f9bd 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -24,6 +24,7 @@ #pragma once +#include #include "driver/shaders/dxbc/dxbc_inspect.h" #include "d3d12_device.h" #include "d3d12_manager.h" @@ -447,9 +448,40 @@ public: class WrappedID3D12Resource : 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; + public: ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12Resource); + static ResourceId GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr) + { + if(m_Addresses.empty()) + return ResourceId(); + + auto it = std::lower_bound(m_Addresses.begin(), m_Addresses.end(), addr); + if(it == m_Addresses.end()) + return ResourceId(); + + if(addr < it->start || addr >= it->end) + return ResourceId(); + + return it->id; + } + enum { TypeEnum = Resource_Resource, @@ -458,8 +490,38 @@ public: WrappedID3D12Resource(ID3D12Resource *real, WrappedID3D12Device *device) : WrappedDeviceChild12(real, device) { + // 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.begin() || it == m_Addresses.end() || addr < it->start || + addr >= it->end); + + AddressRange range; + range.start = addr; + range.end = addr + m_pReal->GetDesc().Width; + range.id = GetResourceID(); + + m_Addresses.insert(it, range); + } + } + virtual ~WrappedID3D12Resource() + { + // 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); + } + + Shutdown(); } - virtual ~WrappedID3D12Resource() { Shutdown(); } ////////////////////////////// // implement ID3D12Resource @@ -476,10 +538,9 @@ public: virtual D3D12_RESOURCE_DESC STDMETHODCALLTYPE GetDesc() { return m_pReal->GetDesc(); } virtual D3D12_GPU_VIRTUAL_ADDRESS STDMETHODCALLTYPE GetGPUVirtualAddress() { - return (D3D12_GPU_VIRTUAL_ADDRESS) this; + return m_pReal->GetGPUVirtualAddress(); } - D3D12_GPU_VIRTUAL_ADDRESS GetGPU() { return m_pReal->GetGPUVirtualAddress(); } virtual HRESULT STDMETHODCALLTYPE WriteToSubresource(UINT DstSubresource, const D3D12_BOX *pDstBox, const void *pSrcData, UINT SrcRowPitch, UINT SrcDepthPitch) @@ -620,8 +681,6 @@ ID3D12DeviceChild *Unwrap(ID3D12DeviceChild *ptr); template <> D3D12ResourceRecord *GetRecord(ID3D12DeviceChild *ptr); -// specialisations for aliasing ID3D12Resource pointer as a D3D12_GPU_VIRTUAL_ADDRESS -template <> -D3D12_GPU_VIRTUAL_ADDRESS Unwrap(D3D12_GPU_VIRTUAL_ADDRESS addr); +// specialisations for looking up ID3D12Resource pointer from its D3D12_GPU_VIRTUAL_ADDRESS template <> ResourceId GetResID(D3D12_GPU_VIRTUAL_ADDRESS addr); \ No newline at end of file