Tweak render state invalid output merger handling, and log warnings

* We were allowing *any* difference between depth and render targets, but
  that's not quite right. Oversized depth is fine, but e.g. mismatched
  multisampled and not is invalid.
* We also take frame references on invalid attempted OM sets, so that the
  targets don't get trimmed from the log and potentially make the set valid
This commit is contained in:
baldurk
2015-01-11 01:53:32 +00:00
parent fe1040fb81
commit 249638820f
5 changed files with 94 additions and 8 deletions
+2
View File
@@ -165,6 +165,7 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device* real
}
else
{
m_CurrentPipelineState->SetDevice(m_pDevice);
m_pDevice->SoftRef();
if(m_State >= WRITING && RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists)
@@ -229,6 +230,7 @@ bool WrappedID3D11DeviceContext::Serialise_BeginCaptureFrame(bool applyInitialSt
m_DoStateVerify = false;
{
*m_CurrentPipelineState = state;
m_CurrentPipelineState->SetDevice(m_pDevice);
state.ApplyState(this);
}
m_DoStateVerify = true;
@@ -2910,6 +2910,29 @@ void WrappedID3D11DeviceContext::OMSetRenderTargets(UINT NumViews, ID3D11RenderT
m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView);
m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, NumViews);
}
else if(m_State >= WRITING)
{
// make sure to mark resources referenced if the OM state is invalid, so they aren't eliminated from the
// log (which might make this combination valid on replay without some of the targets!)
for(UINT i=0; i < NumViews; i++)
{
if(ppRenderTargetViews && ppRenderTargetViews[i])
{
ID3D11Resource *res = NULL;
ppRenderTargetViews[i]->GetResource(&res);
MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read);
SAFE_RELEASE(res);
}
}
if(pDepthStencilView)
{
ID3D11Resource *res = NULL;
pDepthStencilView->GetResource(&res);
MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read);
SAFE_RELEASE(res);
}
}
ID3D11UnorderedAccessView *UAVs[D3D11_PS_CS_UAV_REGISTER_COUNT] = {0};
m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, UAVs, 0, D3D11_PS_CS_UAV_REGISTER_COUNT);
@@ -3086,6 +3109,29 @@ void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews(UINT
m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, RTs, 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT);
m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView);
}
else if(m_State >= WRITING)
{
// make sure to mark resources referenced if the OM state is invalid, so they aren't eliminated from the
// log (which might make this combination valid on replay without some of the targets!)
for(UINT i=0; i < NumRTVs; i++)
{
if(ppRenderTargetViews && ppRenderTargetViews[i])
{
ID3D11Resource *res = NULL;
ppRenderTargetViews[i]->GetResource(&res);
MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read);
SAFE_RELEASE(res);
}
}
if(pDepthStencilView)
{
ID3D11Resource *res = NULL;
pDepthStencilView->GetResource(&res);
MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read);
SAFE_RELEASE(res);
}
}
}
if(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS)
+2
View File
@@ -2234,6 +2234,8 @@ void WrappedID3D11Device::ReplayLog(uint32_t frameID, uint32_t startEventID, uin
GetResourceManager()->ApplyInitialContents();
GetResourceManager()->ReleaseInFrameResources();
}
m_State = EXECUTING;
if(m_ReplayDefCtx == ResourceId())
{
+43 -8
View File
@@ -1272,6 +1272,8 @@ bool D3D11RenderState::ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11Dep
if(renderdim[i] != dim)
{
valid = false;
m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse,
"Invalid output merger - Render targets of different type");
break;
}
}
@@ -1280,6 +1282,8 @@ bool D3D11RenderState::ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11Dep
dim != D3D11_RESOURCE_DIMENSION_UNKNOWN &&
depthdim != dim)
{
m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse,
"Invalid output merger - Render target(s) and depth target of different type");
valid = false;
}
@@ -1368,6 +1372,8 @@ bool D3D11RenderState::ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11Dep
desc2.SampleDesc.Count != d2.SampleDesc.Count ||
desc2.SampleDesc.Quality != d2.SampleDesc.Quality)
{
m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse,
"Invalid output merger - Render targets are different dimensions");
valid = false;
break;
}
@@ -1392,19 +1398,37 @@ bool D3D11RenderState::ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11Dep
else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D)
{
((ID3D11Texture2D *)DepthResource)->GetDesc(&d2);
d3.Width = RDCMAX(1U, d2.Width >> DepthDesc.Texture2D.MipSlice);
d3.Height = RDCMAX(1U, d2.Height >> DepthDesc.Texture2D.MipSlice);
if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2D)
{
d3.Width = RDCMAX(1U, d2.Width >> DepthDesc.Texture2D.MipSlice);
d3.Height = RDCMAX(1U, d2.Height >> DepthDesc.Texture2D.MipSlice);
d3.Depth = 1;
}
else if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DARRAY)
{
d3.Width = RDCMAX(1U, d2.Width >> DepthDesc.Texture2DArray.MipSlice);
d3.Height = RDCMAX(1U, d2.Height >> DepthDesc.Texture2DArray.MipSlice);
d3.Depth = RDCMIN(d2.ArraySize, DepthDesc.Texture2DArray.ArraySize);
}
else if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMS)
{
d3.Width = d2.Width;
d3.Height = d2.Height;
d3.Depth = 1;
}
else if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY)
{
d3.Width = d2.Width;
d3.Height = d2.Height;
d3.Depth = RDCMIN(d2.ArraySize, DepthDesc.Texture2DMSArray.ArraySize);
}
}
else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D ||
dim == D3D11_RESOURCE_DIMENSION_BUFFER)
{
m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse,
"Invalid output merger - Depth target is Texture3D or Buffer (shouldn't be possible! How did you create this view?!)");
valid = false;
}
@@ -1417,15 +1441,26 @@ bool D3D11RenderState::ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11Dep
desc2.SampleDesc.Quality != d2.SampleDesc.Quality)
{
valid = false;
// explicitly allow over-sized depth targets
if(desc.Width < d3.Width &&
desc.Height < d3.Height &&
desc.Depth < d3.Depth &&
desc2.SampleDesc.Count == d2.SampleDesc.Count &&
desc2.SampleDesc.Quality == d2.SampleDesc.Quality)
{
valid = true;
m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse,
"Valid but unusual output merger - Depth target is larger than render target(s)");
}
else
{
m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse,
"Invalid output merger - Depth target is different size or MS count to render target(s)");
}
}
}
}
if(!valid)
{
//RDCDEBUG("Different effective dimensions between output views");
valid = true;
}
}
for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
@@ -421,6 +421,7 @@ struct D3D11RenderState
void Serialise(LogState state, WrappedID3D11Device *device);
void SetImmediatePipeline(WrappedID3D11Device *device) { m_ImmediatePipeline = true; m_pDevice = device; }
void SetDevice(WrappedID3D11Device *device) { m_pDevice = device; }
void MarkReferenced(WrappedID3D11DeviceContext *ctx, bool initial) const;
void MarkDirty(D3D11ResourceManager *manager) const;