Allow out of bounds GPU addresses when serialising

* Worst case this is just as invalid as an application, if it uses a totally
  bogus VA. However in D3D12 it is apparently valid to refer to VAs out of
  bounds of any resource as long as it's within bounds of an underlying heap. To
  handle this without serialising VAs as Heap+offset we instead just allow the
  address lookup to run out of bounds and pick the next lowest buffer. If the
  offset is greater than the buffer size then we're probably no worse than the
  application.
This commit is contained in:
baldurk
2023-09-22 14:47:37 +01:00
parent e8a7560b51
commit fe6b702ff4
4 changed files with 37 additions and 1 deletions
+29
View File
@@ -1037,3 +1037,32 @@ void GPUAddressRangeTracker::GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr, Re
id = range.id;
offs = addr - range.start;
}
void GPUAddressRangeTracker::GetResIDFromAddrAllowOutOfBounds(D3D12_GPU_VIRTUAL_ADDRESS addr,
ResourceId &id, UINT64 &offs)
{
id = ResourceId();
offs = 0;
if(addr == 0)
return;
GPUAddressRange range;
// this should really be a read-write lock
{
SCOPED_READLOCK(addressLock);
auto it = std::lower_bound(addresses.begin(), addresses.end(), addr);
if(it == addresses.end())
return;
range = *it;
}
if(addr < range.start)
return;
id = range.id;
offs = addr - range.start;
}
+1
View File
@@ -529,6 +529,7 @@ struct GPUAddressRangeTracker
void AddTo(const GPUAddressRange &range);
void RemoveFrom(const GPUAddressRange &range);
void GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs);
void GetResIDFromAddrAllowOutOfBounds(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs);
};
struct MapState
+6
View File
@@ -969,6 +969,12 @@ public:
m_Addresses.GetResIDFromAddr(addr, id, offs);
}
static void GetResIDFromAddrAllowOutOfBounds(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id,
UINT64 &offs)
{
m_Addresses.GetResIDFromAddrAllowOutOfBounds(addr, id, offs);
}
// overload to just return the id in case the offset isn't needed
static ResourceId GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr)
{
+1 -1
View File
@@ -334,7 +334,7 @@ void DoSerialise(SerialiserType &ser, D3D12BufferLocation &el)
UINT64 offs = 0;
if(ser.IsWriting() || ser.IsStructurising())
WrappedID3D12Resource::GetResIDFromAddr(el.Location, buffer, offs);
WrappedID3D12Resource::GetResIDFromAddrAllowOutOfBounds(el.Location, buffer, offs);
if(ser.IsStructurising() && rm)
buffer = rm->GetOriginalID(buffer);