Don't try to populate maps from dirty resources with no initial contents

* If a buffer has been marked as dirty mid-frame but wasn't dirty at the start
  of the frame then it won't have initial contents. We have to treat it as if it
  wasn't dirty and fall back to using our existing data for it, assuming that is
  a valid way to pre-populate the map's shadow buffer.
This commit is contained in:
baldurk
2019-07-02 16:57:12 +01:00
parent 31fff66d4c
commit 534f39c723
2 changed files with 23 additions and 6 deletions
@@ -7398,15 +7398,13 @@ bool WrappedID3D11DeviceContext::Serialise_Map(SerialiserType &ser, ID3D11Resour
if(MapType != D3D11_MAP_WRITE_DISCARD)
{
if(m_pDevice->GetResourceManager()->IsResourceDirty(Resource))
{
ID3D11DeviceChild *initial =
m_pDevice->GetResourceManager()->GetInitialContents(Resource).resource;
ID3D11DeviceChild *initial =
m_pDevice->GetResourceManager()->GetInitialContents(Resource).resource;
if(initial)
{
if(WrappedID3D11Buffer::IsAlloc(pResource))
{
RDCASSERT(initial);
ID3D11Buffer *stage = (ID3D11Buffer *)initial;
D3D11_MAPPED_SUBRESOURCE mapped;
@@ -98,6 +98,21 @@ float4 main(v2f IN) : SV_Target0
return ret;
};
ID3D11BufferPtr dummy = MakeBuffer().Constant().Size(sizeof(Vec4f));
auto SetupVBuf = [this, dummy]() {
ID3D11BufferPtr ret = MakeBuffer().Vertex().Size(sizeof(Vec4f)).Mappable();
// force the buffer to become dirty
ctx->CopyResource(ret, dummy);
// map the dirty resource
D3D11_MAPPED_SUBRESOURCE map = Map(ret, 0, D3D11_MAP_WRITE_NO_OVERWRITE);
ctx->Unmap(ret, 0);
return ret;
};
auto TrashBuf = [this](ID3D11BufferPtr &buf) {
D3D11_MAPPED_SUBRESOURCE map = Map(buf, 0, D3D11_MAP_WRITE_DISCARD);
memset(map.pData, 0, sizeof(Vec4f));
@@ -177,6 +192,10 @@ float4 main(v2f IN) : SV_Target0
TrashBuf(cb);
TrashSRV(srv);
// create, dirty, and map the dirty buffer mid-frame
ID3D11BufferPtr vbtmp = SetupVBuf();
TrashBuf(vbtmp);
// set up resources for next frame
cb = SetupBuf();
srv = SetupSRV();