mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-06 14:51:04 +00:00
When serialising a clear, save view desc so we can recreate it if needed
* This is a bit convoluted so follow with me here... * As an optimisation, when not capturing a frame we serialise clears as clears for resources and mark those resources as clean. This way if a resource is cleared, then used in the frame, we don't have to worry about fetching or storing its initial data - we just replay the clear once while initialising and we're done. * The alternative here is to mark a resource dirty when it's cleared, and then we might have to read back and serialise a completely flat image - rather wasteful. * The problem is that if the resource is referenced but its view isn't then the view will be trimmed from the capture and we don't have it around to actually perform the clear. This only started being a problem when views were tracked in their own separate records. * We can't create a circular dependency from view -> resource -> view as that would create cycles and keep lots of things alive pointlessly. Instead we add serialisation of the resource & view descriptor so that we can recreate the view on demand if need be. This adds 32 bytes to each clear and since clears aren't hugely frequent it's not a big deal
This commit is contained in:
@@ -6255,6 +6255,31 @@ bool WrappedID3D11DeviceContext::Serialise_ClearRenderTargetView(
|
||||
{
|
||||
SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pRenderTargetView));
|
||||
|
||||
// at time of writing we don't support the 11.3 DESC1, but for the sake
|
||||
// of not having to bump serialisation version later we'll serialise that
|
||||
// version of the descriptor. We can just alias the memory because the only
|
||||
// difference is some union members got larger.
|
||||
union
|
||||
{
|
||||
D3D11_RENDER_TARGET_VIEW_DESC1 Desc1;
|
||||
D3D11_RENDER_TARGET_VIEW_DESC Desc;
|
||||
} ViewDesc;
|
||||
ResourceId resID;
|
||||
|
||||
RDCEraseEl(ViewDesc.Desc1);
|
||||
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
pRenderTargetView->GetDesc(&ViewDesc.Desc);
|
||||
resID = ((WrappedID3D11RenderTargetView *)pRenderTargetView)->GetResourceResID();
|
||||
}
|
||||
|
||||
if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000009)
|
||||
{
|
||||
m_pSerialiser->Serialise("ViewDesc", ViewDesc.Desc1);
|
||||
m_pSerialiser->Serialise("resID", resID);
|
||||
}
|
||||
|
||||
float Color[4] = {0};
|
||||
|
||||
if(m_State >= WRITING)
|
||||
@@ -6262,11 +6287,34 @@ bool WrappedID3D11DeviceContext::Serialise_ClearRenderTargetView(
|
||||
|
||||
m_pSerialiser->SerialisePODArray<4>("ColorRGBA", Color);
|
||||
|
||||
if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View))
|
||||
if(m_State <= EXECUTING)
|
||||
{
|
||||
m_pRealContext->ClearRenderTargetView(
|
||||
UNWRAP(WrappedID3D11RenderTargetView, m_pDevice->GetResourceManager()->GetLiveResource(View)),
|
||||
Color);
|
||||
if(m_pDevice->GetResourceManager()->HasLiveResource(View))
|
||||
{
|
||||
m_pRealContext->ClearRenderTargetView(
|
||||
UNWRAP(WrappedID3D11RenderTargetView,
|
||||
m_pDevice->GetResourceManager()->GetLiveResource(View)),
|
||||
Color);
|
||||
}
|
||||
else if(m_pDevice->GetLogVersion() >= 0x000009)
|
||||
{
|
||||
// no live view, we have to create one ourselves to clear with.
|
||||
if(m_pDevice->GetResourceManager()->HasLiveResource(resID))
|
||||
{
|
||||
ID3D11RenderTargetView *view = NULL;
|
||||
m_pDevice->CreateRenderTargetView(
|
||||
(ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(resID),
|
||||
&ViewDesc.Desc, &view);
|
||||
m_pRealContext->ClearRenderTargetView(UNWRAP(WrappedID3D11RenderTargetView, view), Color);
|
||||
SAFE_RELEASE(view);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN(
|
||||
"No view was found to perform clear - data might be wrong. "
|
||||
"Re-capture with latest RenderDoc to solve this issue.");
|
||||
}
|
||||
}
|
||||
|
||||
const string desc = m_pSerialiser->GetDebugStr();
|
||||
@@ -6381,6 +6429,31 @@ bool WrappedID3D11DeviceContext::Serialise_ClearUnorderedAccessViewUint(
|
||||
{
|
||||
SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pUnorderedAccessView));
|
||||
|
||||
// at time of writing we don't support the 11.3 DESC1, but for the sake
|
||||
// of not having to bump serialisation version later we'll serialise that
|
||||
// version of the descriptor. We can just alias the memory because the only
|
||||
// difference is some union members got larger.
|
||||
union
|
||||
{
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC1 Desc1;
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC Desc;
|
||||
} ViewDesc;
|
||||
ResourceId resID;
|
||||
|
||||
RDCEraseEl(ViewDesc.Desc1);
|
||||
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
pUnorderedAccessView->GetDesc(&ViewDesc.Desc);
|
||||
resID = ((WrappedID3D11UnorderedAccessView *)pUnorderedAccessView)->GetResourceResID();
|
||||
}
|
||||
|
||||
if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000009)
|
||||
{
|
||||
m_pSerialiser->Serialise("ViewDesc", ViewDesc.Desc1);
|
||||
m_pSerialiser->Serialise("resID", resID);
|
||||
}
|
||||
|
||||
UINT Values[4] = {0};
|
||||
|
||||
if(m_State >= WRITING)
|
||||
@@ -6388,12 +6461,35 @@ bool WrappedID3D11DeviceContext::Serialise_ClearUnorderedAccessViewUint(
|
||||
|
||||
m_pSerialiser->SerialisePODArray<4>("Values", Values);
|
||||
|
||||
if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View))
|
||||
if(m_State <= EXECUTING)
|
||||
{
|
||||
m_pRealContext->ClearUnorderedAccessViewUint(
|
||||
UNWRAP(WrappedID3D11UnorderedAccessView,
|
||||
m_pDevice->GetResourceManager()->GetLiveResource(View)),
|
||||
Values);
|
||||
if(m_pDevice->GetResourceManager()->HasLiveResource(View))
|
||||
{
|
||||
m_pRealContext->ClearUnorderedAccessViewUint(
|
||||
UNWRAP(WrappedID3D11UnorderedAccessView,
|
||||
m_pDevice->GetResourceManager()->GetLiveResource(View)),
|
||||
Values);
|
||||
}
|
||||
else if(m_pDevice->GetLogVersion() >= 0x000009)
|
||||
{
|
||||
// no live view, we have to create one ourselves to clear with.
|
||||
if(m_pDevice->GetResourceManager()->HasLiveResource(resID))
|
||||
{
|
||||
ID3D11UnorderedAccessView *view = NULL;
|
||||
m_pDevice->CreateUnorderedAccessView(
|
||||
(ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(resID),
|
||||
&ViewDesc.Desc, &view);
|
||||
m_pRealContext->ClearUnorderedAccessViewUint(UNWRAP(WrappedID3D11UnorderedAccessView, view),
|
||||
Values);
|
||||
SAFE_RELEASE(view);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN(
|
||||
"No view was found to perform clear - data might be wrong. "
|
||||
"Re-capture with latest RenderDoc to solve this issue.");
|
||||
}
|
||||
}
|
||||
|
||||
const string desc = m_pSerialiser->GetDebugStr();
|
||||
@@ -6500,6 +6596,31 @@ bool WrappedID3D11DeviceContext::Serialise_ClearUnorderedAccessViewFloat(
|
||||
{
|
||||
SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pUnorderedAccessView));
|
||||
|
||||
// at time of writing we don't support the 11.3 DESC1, but for the sake
|
||||
// of not having to bump serialisation version later we'll serialise that
|
||||
// version of the descriptor. We can just alias the memory because the only
|
||||
// difference is some union members got larger.
|
||||
union
|
||||
{
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC1 Desc1;
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC Desc;
|
||||
} ViewDesc;
|
||||
ResourceId resID;
|
||||
|
||||
RDCEraseEl(ViewDesc.Desc1);
|
||||
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
pUnorderedAccessView->GetDesc(&ViewDesc.Desc);
|
||||
resID = ((WrappedID3D11UnorderedAccessView *)pUnorderedAccessView)->GetResourceResID();
|
||||
}
|
||||
|
||||
if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000009)
|
||||
{
|
||||
m_pSerialiser->Serialise("ViewDesc", ViewDesc.Desc1);
|
||||
m_pSerialiser->Serialise("resID", resID);
|
||||
}
|
||||
|
||||
FLOAT Values[4] = {0};
|
||||
|
||||
if(m_State >= WRITING)
|
||||
@@ -6507,12 +6628,35 @@ bool WrappedID3D11DeviceContext::Serialise_ClearUnorderedAccessViewFloat(
|
||||
|
||||
m_pSerialiser->SerialisePODArray<4>("Values", Values);
|
||||
|
||||
if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View))
|
||||
if(m_State <= EXECUTING)
|
||||
{
|
||||
m_pRealContext->ClearUnorderedAccessViewFloat(
|
||||
UNWRAP(WrappedID3D11UnorderedAccessView,
|
||||
m_pDevice->GetResourceManager()->GetLiveResource(View)),
|
||||
Values);
|
||||
if(m_pDevice->GetResourceManager()->HasLiveResource(View))
|
||||
{
|
||||
m_pRealContext->ClearUnorderedAccessViewFloat(
|
||||
UNWRAP(WrappedID3D11UnorderedAccessView,
|
||||
m_pDevice->GetResourceManager()->GetLiveResource(View)),
|
||||
Values);
|
||||
}
|
||||
else if(m_pDevice->GetLogVersion() >= 0x000009)
|
||||
{
|
||||
// no live view, we have to create one ourselves to clear with.
|
||||
if(m_pDevice->GetResourceManager()->HasLiveResource(resID))
|
||||
{
|
||||
ID3D11UnorderedAccessView *view = NULL;
|
||||
m_pDevice->CreateUnorderedAccessView(
|
||||
(ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(resID),
|
||||
&ViewDesc.Desc, &view);
|
||||
m_pRealContext->ClearUnorderedAccessViewFloat(
|
||||
UNWRAP(WrappedID3D11UnorderedAccessView, view), Values);
|
||||
SAFE_RELEASE(view);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN(
|
||||
"No view was found to perform clear - data might be wrong. "
|
||||
"Re-capture with latest RenderDoc to solve this issue.");
|
||||
}
|
||||
}
|
||||
|
||||
const string desc = m_pSerialiser->GetDebugStr();
|
||||
@@ -6621,11 +6765,50 @@ bool WrappedID3D11DeviceContext::Serialise_ClearDepthStencilView(
|
||||
SERIALISE_ELEMENT(float, Depth, Depth_);
|
||||
SERIALISE_ELEMENT(uint8_t, Stencil, Stencil_);
|
||||
|
||||
if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View))
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC ViewDesc = {};
|
||||
ResourceId resID;
|
||||
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
m_pRealContext->ClearDepthStencilView(
|
||||
UNWRAP(WrappedID3D11DepthStencilView, m_pDevice->GetResourceManager()->GetLiveResource(View)),
|
||||
ClearFlags, Depth, Stencil);
|
||||
pDepthStencilView->GetDesc(&ViewDesc);
|
||||
resID = ((WrappedID3D11DepthStencilView *)pDepthStencilView)->GetResourceResID();
|
||||
}
|
||||
|
||||
if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000009)
|
||||
{
|
||||
m_pSerialiser->Serialise("ViewDesc", ViewDesc);
|
||||
m_pSerialiser->Serialise("resID", resID);
|
||||
}
|
||||
|
||||
if(m_State <= EXECUTING)
|
||||
{
|
||||
if(m_pDevice->GetResourceManager()->HasLiveResource(View))
|
||||
{
|
||||
m_pRealContext->ClearDepthStencilView(
|
||||
UNWRAP(WrappedID3D11DepthStencilView,
|
||||
m_pDevice->GetResourceManager()->GetLiveResource(View)),
|
||||
ClearFlags, Depth, Stencil);
|
||||
}
|
||||
else if(m_pDevice->GetLogVersion() >= 0x000009)
|
||||
{
|
||||
// no live view, we have to create one ourselves to clear with.
|
||||
if(m_pDevice->GetResourceManager()->HasLiveResource(resID))
|
||||
{
|
||||
ID3D11DepthStencilView *view = NULL;
|
||||
m_pDevice->CreateDepthStencilView(
|
||||
(ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(resID), &ViewDesc,
|
||||
&view);
|
||||
m_pRealContext->ClearDepthStencilView(UNWRAP(WrappedID3D11DepthStencilView, view),
|
||||
ClearFlags, Depth, Stencil);
|
||||
SAFE_RELEASE(view);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN(
|
||||
"No view was found to perform clear - data might be wrong. "
|
||||
"Re-capture with latest RenderDoc to solve this issue.");
|
||||
}
|
||||
}
|
||||
|
||||
const string desc = m_pSerialiser->GetDebugStr();
|
||||
|
||||
@@ -202,14 +202,21 @@ D3D11InitParams::D3D11InitParams()
|
||||
// and set some defaults if necessary).
|
||||
// Here we list which non-current versions we support, and what changed
|
||||
const uint32_t D3D11InitParams::D3D11_OLD_VERSIONS[D3D11InitParams::D3D11_NUM_SUPPORTED_OLD_VERSIONS] = {
|
||||
0x000004, // from 0x4 to 0x5, we added the stream-out hidden counters in the context's
|
||||
// Serialise_BeginCaptureFrame
|
||||
0x000005, // from 0x5 to 0x6, several new calls were made 'drawcalls', like Copy &
|
||||
// GenerateMips, with serialised debug messages
|
||||
0x000006, // from 0x6 to 0x7, we added some more padding in some buffer & texture chunks to
|
||||
// get larger alignment than 16-byte
|
||||
0x000007, // from 0x7 to 0x8, we changed the UAV arrays in the render state to be D3D11.1
|
||||
// sized and separate CS array.
|
||||
// from 0x4 to 0x5, we added the stream-out hidden counters in the context's
|
||||
// Serialise_BeginCaptureFrame
|
||||
0x000004,
|
||||
// from 0x5 to 0x6, several new calls were made 'drawcalls', like Copy &
|
||||
// GenerateMips, with serialised debug messages
|
||||
0x000005,
|
||||
// from 0x6 to 0x7, we added some more padding in some buffer & texture chunks to
|
||||
// get larger alignment than 16-byte
|
||||
0x000006,
|
||||
// from 0x7 to 0x8, we changed the UAV arrays in the render state to be D3D11.1
|
||||
// sized and separate CS array.
|
||||
0x000007,
|
||||
// from 0x8 to 0x9, we added the view creation details to clear calls in the device
|
||||
// record so that we can still perform the clear even if the view wasn't referenced.
|
||||
0x000008,
|
||||
};
|
||||
|
||||
ReplayCreateStatus D3D11InitParams::Serialise()
|
||||
|
||||
@@ -61,10 +61,10 @@ struct D3D11InitParams : public RDCInitParams
|
||||
UINT NumFeatureLevels;
|
||||
D3D_FEATURE_LEVEL FeatureLevels[16];
|
||||
|
||||
static const uint32_t D3D11_SERIALISE_VERSION = 0x0000008;
|
||||
static const uint32_t D3D11_SERIALISE_VERSION = 0x0000009;
|
||||
|
||||
// backwards compatibility for old logs described at the declaration of this array
|
||||
static const uint32_t D3D11_NUM_SUPPORTED_OLD_VERSIONS = 4;
|
||||
static const uint32_t D3D11_NUM_SUPPORTED_OLD_VERSIONS = 5;
|
||||
static const uint32_t D3D11_OLD_VERSIONS[D3D11_NUM_SUPPORTED_OLD_VERSIONS];
|
||||
|
||||
// version number internal to d3d11 stream
|
||||
|
||||
Reference in New Issue
Block a user