From 534f39c72323848629434d2541da547a4c197062 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 2 Jul 2019 11:29:53 +0100 Subject: [PATCH] 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. --- renderdoc/driver/d3d11/d3d11_context_wrap.cpp | 10 ++++------ .../demos/d3d11/d3d11_resource_lifetimes.cpp | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index a9fe7c7b0..a73f6974f 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -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; diff --git a/util/test/demos/d3d11/d3d11_resource_lifetimes.cpp b/util/test/demos/d3d11/d3d11_resource_lifetimes.cpp index 36282d90c..c48964679 100644 --- a/util/test/demos/d3d11/d3d11_resource_lifetimes.cpp +++ b/util/test/demos/d3d11/d3d11_resource_lifetimes.cpp @@ -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();