Handle nested Map/Unmap calls by refcounting

This commit is contained in:
baldurk
2016-10-26 18:31:54 +02:00
parent e8e7ad711a
commit 451203187d
2 changed files with 21 additions and 7 deletions
+2
View File
@@ -394,6 +394,8 @@ struct D3D12ResourceRecord : public ResourceRecord
struct MapData
{
MapData() : refcount(0), realPtr(NULL), shadowPtr(NULL) {}
volatile int32_t refcount;
byte *realPtr;
byte *shadowPtr;
};
+19 -7
View File
@@ -311,8 +311,7 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12Resource::Map(UINT Subresource,
// pass a NULL range as we might want to read from the whole range
HRESULT hr = m_pReal->Map(Subresource, NULL, &mapPtr);
if(ppData)
*ppData = mapPtr;
*ppData = mapPtr;
if(SUCCEEDED(hr) && GetResourceRecord())
{
@@ -320,10 +319,17 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12Resource::Map(UINT Subresource,
if(Subresource >= map.size())
map.resize(Subresource + 1);
// the map pointer should be NULL or identical (if we are in a nested Map)
RDCASSERT(map[Subresource].realPtr == mapPtr || map[Subresource].realPtr == NULL);
map[Subresource].realPtr = (byte *)mapPtr;
// need to register this so we can flush any updates in case it's left persistant
m_pDevice->Map(this, Subresource);
int32_t refcount = Atomic::Inc32(&map[Subresource].refcount);
// on the first map, register this so we can flush any updates in case it's left persistant
if(refcount == 1)
m_pDevice->Map(this, Subresource);
}
return hr;
@@ -338,10 +344,16 @@ void STDMETHODCALLTYPE WrappedID3D12Resource::Unmap(UINT Subresource, const D3D1
// may not have a map if e.g. no pointer was requested
if(Subresource < map.size())
{
m_pDevice->Unmap(this, Subresource, map[Subresource].realPtr, pWrittenRange);
int32_t refcount = Atomic::Dec32(&map[Subresource].refcount);
map[Subresource].realPtr = NULL;
Serialiser::FreeAlignedBuffer(map[Subresource].shadowPtr);
if(refcount == 0)
{
m_pDevice->Unmap(this, Subresource, map[Subresource].realPtr, pWrittenRange);
Serialiser::FreeAlignedBuffer(map[Subresource].shadowPtr);
map[Subresource].realPtr = NULL;
map[Subresource].shadowPtr = NULL;
}
}
}