Lock around access to GPUAddressRange vector

This commit is contained in:
baldurk
2016-10-26 23:12:57 +02:00
parent a396713f3c
commit e1c0400e40
5 changed files with 45 additions and 26 deletions
+2 -2
View File
@@ -301,7 +301,7 @@ private:
std::vector<DynamicDescriptorCopy> m_DynamicDescriptorCopies;
std::vector<DynamicDescriptorWrite> m_DynamicDescriptorWrites;
std::vector<GPUAddressRange> 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(); }
+2 -2
View File
@@ -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;
+32 -14
View File
@@ -294,9 +294,21 @@ struct GPUAddressRange
return false;
}
};
static void AddTo(std::vector<GPUAddressRange> &addresses, GPUAddressRange range)
struct GPUAddressRangeTracker
{
GPUAddressRangeTracker() {}
// no copying
GPUAddressRangeTracker(const GPUAddressRangeTracker &);
GPUAddressRangeTracker &operator=(const GPUAddressRangeTracker &);
std::vector<GPUAddressRange> 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<GPUAddressRange> &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<GPUAddressRange> &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;
}
};
+4 -3
View File
@@ -27,7 +27,7 @@
#include "d3d12_command_list.h"
#include "d3d12_command_queue.h"
std::vector<GPUAddressRange> WrappedID3D12Resource::m_Addresses;
GPUAddressRangeTracker WrappedID3D12Resource::m_Addresses;
std::map<ResourceId, WrappedID3D12Resource *> WrappedID3D12Resource::m_List;
std::map<WrappedID3D12PipelineState::DXBCKey, WrappedID3D12PipelineState::ShaderEntry *>
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,
+5 -5
View File
@@ -653,7 +653,7 @@ public:
class WrappedID3D12Resource : public WrappedDeviceChild12<ID3D12Resource>
{
static std::vector<GPUAddressRange> 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();
}