diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index c4e326f41..2f304f1b6 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -301,7 +301,7 @@ private: std::vector m_DynamicDescriptorCopies; std::vector m_DynamicDescriptorWrites; - std::vector m_GPUAddresses; + GPUAddressRangeTracker m_GPUAddresses; void FlushPendingDescriptorWrites(); @@ -377,7 +377,7 @@ public: void GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs) { - GPUAddressRange::GetResIDFromAddr(m_GPUAddresses, addr, id, offs); + m_GPUAddresses.GetResIDFromAddr(addr, id, offs); } bool IsCubemap(ResourceId id) { return m_Cubemaps.find(id) != m_Cubemaps.end(); } diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp index 549675d3f..bd1f6347d 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp @@ -919,7 +919,7 @@ bool WrappedID3D12Device::Serialise_CreateCommittedResource( range.end = gpuAddress + desc.Width; range.id = Res; - GPUAddressRange::AddTo(m_GPUAddresses, range); + m_GPUAddresses.AddTo(range); } ID3D12Resource *ret = NULL; @@ -1108,7 +1108,7 @@ bool WrappedID3D12Device::Serialise_CreatePlacedResource( range.end = gpuAddress + desc.Width; range.id = Res; - GPUAddressRange::AddTo(m_GPUAddresses, range); + m_GPUAddresses.AddTo(range); } ID3D12Resource *ret = NULL; diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index c3179b329..b48664945 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -294,9 +294,21 @@ struct GPUAddressRange return false; } +}; - static void AddTo(std::vector &addresses, GPUAddressRange range) +struct GPUAddressRangeTracker +{ + GPUAddressRangeTracker() {} + // no copying + GPUAddressRangeTracker(const GPUAddressRangeTracker &); + GPUAddressRangeTracker &operator=(const GPUAddressRangeTracker &); + + std::vector addresses; + Threading::CriticalSection addressLock; + + void AddTo(GPUAddressRange range) { + SCOPED_LOCK(addressLock); 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); @@ -304,16 +316,16 @@ struct GPUAddressRange addresses.insert(it, range); } - static void RemoveFrom(std::vector &addresses, D3D12_GPU_VIRTUAL_ADDRESS baseAddr) + void RemoveFrom(D3D12_GPU_VIRTUAL_ADDRESS baseAddr) { + SCOPED_LOCK(addressLock); 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) + void GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs) { id = ResourceId(); offs = 0; @@ -321,18 +333,24 @@ struct GPUAddressRange if(addr == 0) return; - if(addresses.empty()) + GPUAddressRange range; + + // this should really be a read-write lock + { + SCOPED_LOCK(addressLock); + + auto it = std::lower_bound(addresses.begin(), addresses.end(), addr); + if(it == addresses.end()) + return; + + range = *it; + } + + if(addr < range.start || addr >= range.end) 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; + id = range.id; + offs = addr - range.start; } }; diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index fba163a38..7bfe1e672 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; +GPUAddressRangeTracker WrappedID3D12Resource::m_Addresses; std::map WrappedID3D12Resource::m_List; std::map WrappedID3D12PipelineState::m_Shaders; @@ -387,8 +387,9 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12Resource::WriteToSubresource(UINT DstSubr void WrappedID3D12Resource::RefBuffers(D3D12ResourceManager *rm) { // only buffers go into m_Addresses - for(size_t i = 0; i < m_Addresses.size(); i++) - rm->MarkResourceFrameReferenced(m_Addresses[i].id, eFrameRef_Read); + SCOPED_LOCK(m_Addresses.addressLock); + for(size_t i = 0; i < m_Addresses.addresses.size(); i++) + rm->MarkResourceFrameReferenced(m_Addresses.addresses[i].id, eFrameRef_Read); } WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *real, diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index 7db85e3d4..6b535b551 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -653,7 +653,7 @@ public: class WrappedID3D12Resource : public WrappedDeviceChild12 { - static std::vector m_Addresses; + static GPUAddressRangeTracker m_Addresses; bool resident; @@ -666,7 +666,7 @@ public: static void GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs) { - GPUAddressRange::GetResIDFromAddr(m_Addresses, addr, id, offs); + m_Addresses.GetResIDFromAddr(addr, id, offs); } // overload to just return the id in case the offset isn't needed @@ -675,7 +675,7 @@ public: ResourceId id; UINT64 offs; - GetResIDFromAddr(addr, id, offs); + m_Addresses.GetResIDFromAddr(addr, id, offs); return id; } @@ -701,7 +701,7 @@ public: range.end = addr + m_pReal->GetDesc().Width; range.id = GetResourceID(); - GPUAddressRange::AddTo(m_Addresses, range); + m_Addresses.AddTo(range); } } virtual ~WrappedID3D12Resource() @@ -710,7 +710,7 @@ public: // assuming only valid for buffers if(m_pReal->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - GPUAddressRange::RemoveFrom(m_Addresses, m_pReal->GetGPUVirtualAddress()); + m_Addresses.RemoveFrom(m_pReal->GetGPUVirtualAddress()); Shutdown(); }