mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-08 08:40:55 +00:00
Handle UpdateSubresource workaround needed on software command lists
This commit is contained in:
@@ -111,6 +111,15 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real
|
||||
const bool debugSerialiser = true;
|
||||
#endif
|
||||
|
||||
m_NeedUpdateSubWorkaround = false;
|
||||
{
|
||||
D3D11_FEATURE_DATA_THREADING caps = {FALSE, FALSE};
|
||||
|
||||
hr = m_pDevice->CheckFeatureSupport(D3D11_FEATURE_THREADING, &caps, sizeof(caps));
|
||||
if(SUCCEEDED(hr) && !caps.DriverCommandLists)
|
||||
m_NeedUpdateSubWorkaround = true;
|
||||
}
|
||||
|
||||
if(RenderDoc::Inst().IsReplayApp())
|
||||
{
|
||||
m_State = READING;
|
||||
|
||||
@@ -188,6 +188,8 @@ private:
|
||||
|
||||
ID3D11DeviceContext2 *m_pRealContext2;
|
||||
|
||||
bool m_NeedUpdateSubWorkaround;
|
||||
|
||||
set<D3D11ResourceRecord *> m_DeferredRecords;
|
||||
map<ResourceId, int> m_MapResourceRecordAllocs;
|
||||
|
||||
|
||||
@@ -147,11 +147,63 @@ bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource1(ID3D11Resource *pD
|
||||
if(m_State == READING)
|
||||
RecordUpdateStats(DestResource, SourceDataLength, true);
|
||||
|
||||
if(flags == 0)
|
||||
if(flags == ~0U)
|
||||
{
|
||||
byte *adjustedData = SourceData;
|
||||
|
||||
if(pBox && m_NeedUpdateSubWorkaround && GetType() == D3D11_DEVICE_CONTEXT_DEFERRED)
|
||||
{
|
||||
RDCWARN("oops!");
|
||||
// apply the workaround for the data we're about to pass
|
||||
|
||||
D3D11_BOX alignedBox = *pBox;
|
||||
|
||||
DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
if(WrappedID3D11Texture1D::IsAlloc(DestResource))
|
||||
{
|
||||
D3D11_TEXTURE1D_DESC desc;
|
||||
((WrappedID3D11Texture1D *)DestResource)->GetDesc(&desc);
|
||||
fmt = desc.Format;
|
||||
}
|
||||
else if(WrappedID3D11Texture2D::IsAlloc(DestResource))
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
((WrappedID3D11Texture2D *)DestResource)->GetDesc(&desc);
|
||||
fmt = desc.Format;
|
||||
}
|
||||
else if(WrappedID3D11Texture3D::IsAlloc(DestResource))
|
||||
{
|
||||
D3D11_TEXTURE3D_DESC desc;
|
||||
((WrappedID3D11Texture3D *)DestResource)->GetDesc(&desc);
|
||||
fmt = desc.Format;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCASSERT(WrappedID3D11Buffer::IsAlloc(DestResource));
|
||||
}
|
||||
|
||||
// convert from pixels to blocks
|
||||
if(IsBlockFormat(fmt))
|
||||
{
|
||||
alignedBox.left /= 4;
|
||||
alignedBox.right /= 4;
|
||||
alignedBox.top /= 4;
|
||||
alignedBox.bottom /= 4;
|
||||
}
|
||||
|
||||
// if we couldn't get a format it's a buffer, so work in bytes
|
||||
if(fmt != DXGI_FORMAT_UNKNOWN)
|
||||
adjustedData = adjustedData - (alignedBox.front * SourceDepthPitch) -
|
||||
(alignedBox.top * SourceRowPitch) -
|
||||
(alignedBox.left * GetByteSize(1, 1, 1, fmt, 0));
|
||||
else
|
||||
adjustedData = adjustedData - alignedBox.left;
|
||||
}
|
||||
|
||||
m_pRealContext->UpdateSubresource(
|
||||
m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, pBox,
|
||||
SourceData, SourceRowPitch, SourceDepthPitch);
|
||||
adjustedData, SourceRowPitch, SourceDepthPitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -161,6 +213,16 @@ bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource1(ID3D11Resource *pD
|
||||
m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, pBox,
|
||||
SourceData, SourceRowPitch, SourceDepthPitch, flags);
|
||||
}
|
||||
else if(flags == 0)
|
||||
{
|
||||
// if flags is 0 UpdateSubresource1 behaves identically to UpdateSubresource
|
||||
// according to the docs. The only case is the deferred context bug workaround
|
||||
// isn't needed, but this wasn't properly handled before, and now this ambiguity
|
||||
// is resolved by passing ~0U as the flags to indicate a 'real' call to UpdateSubresource
|
||||
m_pRealContext->UpdateSubresource(
|
||||
m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, pBox,
|
||||
SourceData, SourceRowPitch, SourceDepthPitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Replaying a D3D11.1 context without D3D11.1 available");
|
||||
@@ -246,7 +308,7 @@ bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource1(ID3D11Resource *pD
|
||||
RecordUpdateStats(DestResource,
|
||||
SourceRowPitch * subHeight + SourceDepthPitch * subWidth * subHeight, true);
|
||||
|
||||
if(flags == 0)
|
||||
if(flags == ~0U)
|
||||
{
|
||||
m_pRealContext->UpdateSubresource(
|
||||
m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, NULL,
|
||||
@@ -260,9 +322,22 @@ bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource1(ID3D11Resource *pD
|
||||
m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, NULL,
|
||||
bufData, SourceRowPitch, SourceDepthPitch, flags);
|
||||
}
|
||||
else if(flags == 0)
|
||||
{
|
||||
// if flags is 0 UpdateSubresource1 behaves identically to UpdateSubresource
|
||||
// according to the docs. The only case is the deferred context bug workaround
|
||||
// isn't needed, but this wasn't properly handled before, and now this ambiguity
|
||||
// is resolved by passing ~0U as the flags to indicate a 'real' call to UpdateSubresource
|
||||
m_pRealContext->UpdateSubresource(
|
||||
m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, NULL,
|
||||
bufData, SourceRowPitch, SourceDepthPitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Replaying a D3D11.1 context without D3D11.1 available");
|
||||
m_pDevice->AddDebugMessage(
|
||||
eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration,
|
||||
"Replaying a call to UpdateSubresource1() without D3D11.1 available");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5628,8 +5628,10 @@ bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource(ID3D11Resource *pDs
|
||||
const void *pSrcData, UINT SrcRowPitch,
|
||||
UINT SrcDepthPitch)
|
||||
{
|
||||
// pass ~0U as the flags to indicate this came for UpdateSubresource, so we know to apply
|
||||
// deferred context workarounds or not
|
||||
return Serialise_UpdateSubresource1(pDstResource, DstSubresource, pDstBox, pSrcData, SrcRowPitch,
|
||||
SrcDepthPitch, 0);
|
||||
SrcDepthPitch, ~0U);
|
||||
}
|
||||
|
||||
void WrappedID3D11DeviceContext::UpdateSubresource(ID3D11Resource *pDstResource, UINT DstSubresource,
|
||||
@@ -5640,6 +5642,57 @@ void WrappedID3D11DeviceContext::UpdateSubresource(ID3D11Resource *pDstResource,
|
||||
|
||||
m_EmptyCommandList = false;
|
||||
|
||||
const void *pOrigSrcData = pSrcData;
|
||||
|
||||
if(pDstBox && m_NeedUpdateSubWorkaround && GetType() == D3D11_DEVICE_CONTEXT_DEFERRED)
|
||||
{
|
||||
// we need to apply the *inverse* of the workaround, which matches the broken D3D behaviour
|
||||
// so that we end up pointing at the expected data.
|
||||
|
||||
D3D11_BOX alignedBox = *pDstBox;
|
||||
|
||||
DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
if(WrappedID3D11Texture1D::IsAlloc(pDstResource))
|
||||
{
|
||||
D3D11_TEXTURE1D_DESC desc;
|
||||
((WrappedID3D11Texture1D *)pDstResource)->GetDesc(&desc);
|
||||
fmt = desc.Format;
|
||||
}
|
||||
else if(WrappedID3D11Texture2D::IsAlloc(pDstResource))
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
((WrappedID3D11Texture2D *)pDstResource)->GetDesc(&desc);
|
||||
fmt = desc.Format;
|
||||
}
|
||||
else if(WrappedID3D11Texture3D::IsAlloc(pDstResource))
|
||||
{
|
||||
D3D11_TEXTURE3D_DESC desc;
|
||||
((WrappedID3D11Texture3D *)pDstResource)->GetDesc(&desc);
|
||||
fmt = desc.Format;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCASSERT(WrappedID3D11Buffer::IsAlloc(pDstResource));
|
||||
}
|
||||
|
||||
// convert from pixels to blocks
|
||||
if(IsBlockFormat(fmt))
|
||||
{
|
||||
alignedBox.left /= 4;
|
||||
alignedBox.right /= 4;
|
||||
alignedBox.top /= 4;
|
||||
alignedBox.bottom /= 4;
|
||||
}
|
||||
|
||||
// if we couldn't get a format it's a buffer, so work in bytes
|
||||
if(fmt != DXGI_FORMAT_UNKNOWN)
|
||||
pSrcData = ((const BYTE *)pSrcData) + (alignedBox.front * SrcDepthPitch) +
|
||||
(alignedBox.top * SrcRowPitch) + (alignedBox.left * GetByteSize(1, 1, 1, fmt, 0));
|
||||
else
|
||||
pSrcData = ((const BYTE *)pSrcData) + (alignedBox.left);
|
||||
}
|
||||
|
||||
if(m_State == WRITING_CAPFRAME)
|
||||
{
|
||||
SCOPED_SERIALISE_CONTEXT(UPDATE_SUBRESOURCE);
|
||||
@@ -5842,8 +5895,11 @@ void WrappedID3D11DeviceContext::UpdateSubresource(ID3D11Resource *pDstResource,
|
||||
}
|
||||
}
|
||||
|
||||
// pass pOrigSrcData here because any workarounds etc need to be preserved as if we were never
|
||||
// in the way intercepting things.
|
||||
m_pRealContext->UpdateSubresource(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource),
|
||||
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch);
|
||||
DstSubresource, pDstBox, pOrigSrcData, SrcRowPitch,
|
||||
SrcDepthPitch);
|
||||
}
|
||||
|
||||
bool WrappedID3D11DeviceContext::Serialise_CopyStructureCount(ID3D11Buffer *pDstBuffer,
|
||||
|
||||
Reference in New Issue
Block a user