Fix issues with MSAA quad overdraw overlays

This commit is contained in:
baldurk
2020-10-21 18:00:32 +01:00
parent 3a68721702
commit d503363279
9 changed files with 334 additions and 152 deletions
+15 -8
View File
@@ -938,7 +938,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
uint32_t height = 1080 >> 1;
D3D11_TEXTURE2D_DESC overrideDepthDesc = {};
ID3D11Texture2D *depthTex = NULL;
ID3D11Texture2D *origDepthTex = NULL;
{
ID3D11Resource *res = NULL;
@@ -981,7 +981,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
overrideDepthDesc.ArraySize = texdesc.SampleDesc.Count;
overrideDepthDesc.SampleDesc.Count = 1;
overrideDepthDesc.SampleDesc.Quality = 0;
depthTex = ((ID3D11Texture2D *)res);
origDepthTex = ((ID3D11Texture2D *)res);
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
state->OM.DepthView->GetDesc(&dsvDesc);
@@ -1007,22 +1007,24 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
}
ID3D11DepthStencilView *depthOverride = NULL;
ID3D11Texture2D *depthOverrideTex = NULL;
if(overrideDepthDesc.Width > 0)
{
ID3D11Texture2D *tex = NULL;
m_pDevice->CreateTexture2D(&overrideDepthDesc, NULL, &tex);
m_pDevice->CreateTexture2D(&overrideDepthDesc, NULL, &depthOverrideTex);
D3D11_DEPTH_STENCIL_VIEW_DESC viewDesc = {};
viewDesc.Format = overrideDepthDesc.Format;
viewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
viewDesc.Texture2DArray.ArraySize = 1;
m_pDevice->GetDebugManager()->CopyTex2DMSToArray(UNWRAP(WrappedID3D11Texture2D1, tex),
UNWRAP(WrappedID3D11Texture2D1, depthTex));
if(overlay != DebugOverlay::QuadOverdrawPass)
m_pDevice->GetDebugManager()->CopyTex2DMSToArray(
UNWRAP(WrappedID3D11Texture2D1, depthOverrideTex),
UNWRAP(WrappedID3D11Texture2D1, origDepthTex));
m_pDevice->CreateDepthStencilView(tex, &viewDesc, &depthOverride);
SAFE_RELEASE(tex);
m_pDevice->CreateDepthStencilView(depthOverrideTex, &viewDesc, &depthOverride);
depthOverrideTex->Release();
}
D3D11_TEXTURE2D_DESC uavTexDesc = {
@@ -1119,6 +1121,11 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
m_pImmediateContext->PSSetShader(m_Overlay.QuadOverdrawPS, NULL, 0);
if(overlay == DebugOverlay::QuadOverdrawPass && depthOverrideTex)
m_pDevice->GetDebugManager()->CopyTex2DMSToArray(
UNWRAP(WrappedID3D11Texture2D1, depthOverrideTex),
UNWRAP(WrappedID3D11Texture2D1, origDepthTex));
m_pDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw);
oldstate.ApplyState(m_pImmediateContext);
+30 -6
View File
@@ -352,6 +352,11 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
rm->SetInternalResource(m_DebugAlloc);
m_pDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), (void **)&m_DebugFence);
m_pDevice->InternalRef();
rm->SetInternalResource(m_DebugFence);
ID3D12GraphicsCommandList *list = NULL;
hr = m_pDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_DebugAlloc, NULL,
@@ -402,6 +407,12 @@ D3D12DebugManager::~D3D12DebugManager()
for(size_t p = 0; p < MeshDisplayPipelines::ePipe_Count; p++)
SAFE_RELEASE(it->second.pipes[p]);
for(auto it = m_MS2ArrayPSOCache.begin(); it != m_MS2ArrayPSOCache.end(); ++it)
{
SAFE_RELEASE(it->second.first);
SAFE_RELEASE(it->second.second);
}
SAFE_RELEASE(dsvHeap);
SAFE_RELEASE(rtvHeap);
SAFE_RELEASE(cbvsrvuavHeap);
@@ -440,6 +451,7 @@ D3D12DebugManager::~D3D12DebugManager()
SAFE_RELEASE(m_DebugAlloc);
SAFE_RELEASE(m_DebugList);
SAFE_RELEASE(m_DebugFence);
for(auto it = m_DiscardPipes.begin(); it != m_DiscardPipes.end(); it++)
if(it->second)
@@ -1769,12 +1781,23 @@ void D3D12Replay::OverlayRendering::Init(WrappedID3D12Device *device, D3D12Debug
pipeDesc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
pipeDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
hr = device->CreateGraphicsPipelineState(&pipeDesc, __uuidof(ID3D12PipelineState),
(void **)&QuadResolvePipe);
if(FAILED(hr))
for(size_t i = 0; i < ARRAY_COUNT(QuadResolvePipe); i++)
{
RDCERR("Couldn't create m_QuadResolvePipe! HRESULT: %s", ToStr(hr).c_str());
pipeDesc.SampleDesc.Count = UINT(1 << i);
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS check = {};
check.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
check.SampleCount = pipeDesc.SampleDesc.Count;
device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &check, sizeof(check));
if(check.NumQualityLevels == 0)
continue;
hr = device->CreateGraphicsPipelineState(&pipeDesc, __uuidof(ID3D12PipelineState),
(void **)&QuadResolvePipe[i]);
if(FAILED(hr))
RDCERR("Couldn't create QuadResolvePipe[%zu]! HRESULT: %s", i, ToStr(hr).c_str());
}
SAFE_RELEASE(FullscreenVS);
@@ -1792,7 +1815,8 @@ void D3D12Replay::OverlayRendering::Release()
SAFE_RELEASE(QuadOverdrawWritePS);
SAFE_RELEASE(QuadOverdrawWriteDXILPS);
SAFE_RELEASE(QuadResolveRootSig);
SAFE_RELEASE(QuadResolvePipe);
for(size_t i = 0; i < ARRAY_COUNT(QuadResolvePipe); i++)
SAFE_RELEASE(QuadResolvePipe[i]);
SAFE_RELEASE(Texture);
}
+8 -1
View File
@@ -167,12 +167,18 @@ public:
MeshDisplayPipelines CacheMeshDisplayPipelines(const MeshFormat &primary,
const MeshFormat &secondary);
void CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Resource *srcMS);
void CopyTex2DMSToArray(ID3D12GraphicsCommandList *list, ID3D12Resource *destArray,
ID3D12Resource *srcMS);
void CopyArrayToTex2DMS(ID3D12Resource *destMS, ID3D12Resource *srcArray, UINT selectedSlice);
private:
bool CreateMathIntrinsicsResources();
rdcpair<ID3D12PipelineState *, ID3D12PipelineState *> D3D12DebugManager::GetMSToArrayPSOs(
DXGI_FORMAT format);
std::map<DXGI_FORMAT, rdcpair<ID3D12PipelineState *, ID3D12PipelineState *>> m_MS2ArrayPSOCache;
WrappedID3D12Device *m_pDevice = NULL;
// heaps
@@ -221,6 +227,7 @@ private:
// Debug lists
ID3D12GraphicsCommandListX *m_DebugList = NULL;
ID3D12CommandAllocator *m_DebugAlloc = NULL;
ID3D12Fence *m_DebugFence = NULL;
// Discard pattern rendering
ID3DBlob *m_DiscardPS = NULL;
+1 -1
View File
@@ -254,7 +254,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
m_Device->FlushLists();
// expand multisamples out to array
m_Device->GetDebugManager()->CopyTex2DMSToArray(arrayTexture, r->GetReal());
m_Device->GetDebugManager()->CopyTex2DMSToArray(NULL, arrayTexture, r->GetReal());
// open the initial state list again for the remainder of the work
list = Unwrap(m_Device->GetInitialStateList());
+124 -90
View File
@@ -30,11 +30,109 @@
#include "driver/dx/official/d3dcompiler.h"
void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Resource *srcMS)
rdcpair<ID3D12PipelineState *, ID3D12PipelineState *> D3D12DebugManager::GetMSToArrayPSOs(
DXGI_FORMAT format)
{
rdcpair<ID3D12PipelineState *, ID3D12PipelineState *> &cache = m_MS2ArrayPSOCache[format];
if(cache.first == NULL)
{
const bool stencil = IsDepthAndStencilFormat(format);
D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeDesc = {};
pipeDesc.pRootSignature = Unwrap(m_ArrayMSAARootSig);
pipeDesc.VS.BytecodeLength = m_FullscreenVS->GetBufferSize();
pipeDesc.VS.pShaderBytecode = m_FullscreenVS->GetBufferPointer();
pipeDesc.PS.BytecodeLength = m_FloatMS2Array->GetBufferSize();
pipeDesc.PS.pShaderBytecode = m_FloatMS2Array->GetBufferPointer();
if(IsDepthFormat(format))
{
pipeDesc.PS.BytecodeLength = m_DepthMS2Array->GetBufferSize();
pipeDesc.PS.pShaderBytecode = m_DepthMS2Array->GetBufferPointer();
pipeDesc.NumRenderTargets = 0;
pipeDesc.RTVFormats[0] = DXGI_FORMAT_UNKNOWN;
pipeDesc.DSVFormat = format;
pipeDesc.DepthStencilState.DepthEnable = TRUE;
pipeDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
pipeDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
}
else if(IsUIntFormat(format) || IsIntFormat(format))
{
pipeDesc.NumRenderTargets = 1;
pipeDesc.RTVFormats[0] = format;
pipeDesc.DSVFormat = DXGI_FORMAT_UNKNOWN;
pipeDesc.PS.BytecodeLength = m_IntMS2Array->GetBufferSize();
pipeDesc.PS.pShaderBytecode = m_IntMS2Array->GetBufferPointer();
}
pipeDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
pipeDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
pipeDesc.SampleMask = 0xFFFFFFFF;
pipeDesc.SampleDesc.Count = 1;
pipeDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
pipeDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
pipeDesc.BlendState.RenderTarget[0].BlendEnable = FALSE;
pipeDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
pipeDesc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
pipeDesc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
pipeDesc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA;
pipeDesc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
pipeDesc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
pipeDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
HRESULT hr = m_pDevice->GetReal()->CreateGraphicsPipelineState(
&pipeDesc, __uuidof(ID3D12PipelineState), (void **)&cache.first);
if(FAILED(hr))
{
RDCERR("Couldn't create MSAA conversion pipeline for %s! HRESULT: %s", ToStr(format).c_str(),
ToStr(hr).c_str());
SAFE_RELEASE(cache.first);
SAFE_RELEASE(cache.second);
return cache;
}
if(stencil)
{
pipeDesc.DepthStencilState.DepthEnable = FALSE;
pipeDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
pipeDesc.DepthStencilState.StencilEnable = TRUE;
pipeDesc.DepthStencilState.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
pipeDesc.DepthStencilState.FrontFace.StencilPassOp = D3D12_STENCIL_OP_REPLACE;
pipeDesc.DepthStencilState.FrontFace.StencilFailOp = D3D12_STENCIL_OP_REPLACE;
pipeDesc.DepthStencilState.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_REPLACE;
pipeDesc.DepthStencilState.BackFace = pipeDesc.DepthStencilState.FrontFace;
pipeDesc.DepthStencilState.StencilReadMask = 0xff;
pipeDesc.DepthStencilState.StencilWriteMask = 0xff;
hr = m_pDevice->GetReal()->CreateGraphicsPipelineState(
&pipeDesc, __uuidof(ID3D12PipelineState), (void **)&cache.second);
if(FAILED(hr))
{
RDCERR("Couldn't create MSAA stencil conversion pipeline for %s! HRESULT: %s",
ToStr(format).c_str(), ToStr(hr).c_str());
SAFE_RELEASE(cache.first);
SAFE_RELEASE(cache.second);
return cache;
}
}
}
return cache;
}
void D3D12DebugManager::CopyTex2DMSToArray(ID3D12GraphicsCommandList *list,
ID3D12Resource *destArray, ID3D12Resource *srcMS)
{
// this function operates during capture so we work on unwrapped objects
const bool externalList = list != NULL;
D3D12MarkerRegion renderoverlay(m_pDevice->GetQueue(), "CopyTex2DMSToArray");
D3D12MarkerRegion renderoverlay =
externalList ? D3D12MarkerRegion(list, "CopyTex2DMSToArray")
: D3D12MarkerRegion(m_pDevice->GetQueue(), "CopyTex2DMSToArray");
D3D12_RESOURCE_DESC descMS = srcMS->GetDesc();
D3D12_RESOURCE_DESC descArr = destArray->GetDesc();
@@ -62,12 +160,12 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso
dsvDesc.Texture2DArray.FirstArraySlice = 0;
dsvDesc.Texture2DArray.MipSlice = 0;
bool isDepth = IsDepthFormat(rtvDesc.Format) ||
(descMS.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) != 0 ||
(descArr.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) != 0;
bool intFormat = IsUIntFormat(rtvDesc.Format) || IsIntFormat(rtvDesc.Format);
const bool isDepth = IsDepthFormat(rtvDesc.Format) ||
(descMS.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) != 0 ||
(descArr.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) != 0;
const bool intFormat = IsUIntFormat(rtvDesc.Format) || IsIntFormat(rtvDesc.Format);
bool stencil = false;
const bool stencil = IsDepthAndStencilFormat(rtvDesc.Format);
DXGI_FORMAT stencilFormat = DXGI_FORMAT_UNKNOWN;
if(isDepth)
@@ -88,7 +186,6 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
stencilFormat = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
stencil = true;
break;
case DXGI_FORMAT_D24_UNORM_S8_UINT:
@@ -98,7 +195,6 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso
dsvDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
stencilFormat = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
stencil = true;
break;
case DXGI_FORMAT_D16_UNORM:
@@ -109,6 +205,12 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso
default: break;
}
rtvDesc.Format = dsvDesc.Format;
}
else
{
dsvDesc.Format = DXGI_FORMAT_UNKNOWN;
}
for(CBVUAVSRVSlot slot : {MSAA_SRV2x, MSAA_SRV4x, MSAA_SRV8x, MSAA_SRV16x, MSAA_SRV32x})
@@ -132,64 +234,16 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso
D3D12_CPU_DESCRIPTOR_HANDLE rtv = Unwrap(GetCPUHandle(MSAA_RTV));
D3D12_CPU_DESCRIPTOR_HANDLE dsv = Unwrap(GetCPUHandle(MSAA_DSV));
D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeDesc = {};
pipeDesc.pRootSignature = Unwrap(m_ArrayMSAARootSig);
pipeDesc.VS.BytecodeLength = m_FullscreenVS->GetBufferSize();
pipeDesc.VS.pShaderBytecode = m_FullscreenVS->GetBufferPointer();
pipeDesc.PS.BytecodeLength = m_FloatMS2Array->GetBufferSize();
pipeDesc.PS.pShaderBytecode = m_FloatMS2Array->GetBufferPointer();
pipeDesc.NumRenderTargets = 1;
pipeDesc.RTVFormats[0] = rtvDesc.Format;
pipeDesc.DSVFormat = DXGI_FORMAT_UNKNOWN;
if(isDepth)
{
pipeDesc.PS.BytecodeLength = m_DepthMS2Array->GetBufferSize();
pipeDesc.PS.pShaderBytecode = m_DepthMS2Array->GetBufferPointer();
pipeDesc.NumRenderTargets = 0;
pipeDesc.RTVFormats[0] = DXGI_FORMAT_UNKNOWN;
pipeDesc.DSVFormat = dsvDesc.Format;
pipeDesc.DepthStencilState.DepthEnable = TRUE;
pipeDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
pipeDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
}
else if(intFormat)
{
pipeDesc.PS.BytecodeLength = m_IntMS2Array->GetBufferSize();
pipeDesc.PS.pShaderBytecode = m_IntMS2Array->GetBufferPointer();
}
pipeDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
pipeDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
pipeDesc.SampleMask = 0xFFFFFFFF;
pipeDesc.SampleDesc.Count = 1;
pipeDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
pipeDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
pipeDesc.BlendState.RenderTarget[0].BlendEnable = FALSE;
pipeDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
pipeDesc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
pipeDesc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
pipeDesc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA;
pipeDesc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
pipeDesc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
pipeDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
ID3D12PipelineState *pso = NULL, *psoStencil = NULL;
HRESULT hr = m_pDevice->GetReal()->CreateGraphicsPipelineState(
&pipeDesc, __uuidof(ID3D12PipelineState), (void **)&pso);
rdctie(pso, psoStencil) = GetMSToArrayPSOs(rtvDesc.Format);
if(FAILED(hr))
if(!externalList)
{
RDCERR("Couldn't create MSAA conversion pipeline! HRESULT: %s", ToStr(hr).c_str());
return;
list = Unwrap(m_DebugList);
list->Reset(Unwrap(m_DebugAlloc), NULL);
}
ID3D12GraphicsCommandList *list = Unwrap(m_DebugList);
list->Reset(Unwrap(m_DebugAlloc), NULL);
D3D12_VIEWPORT viewport = {0, 0, (float)descArr.Width, (float)descArr.Height, 0.0f, 1.0f};
D3D12_RECT scissor = {0, 0, (LONG)descArr.Width, (LONG)descArr.Height};
list->RSSetViewports(1, &viewport);
@@ -233,21 +287,6 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso
if(stencil)
{
pipeDesc.DepthStencilState.DepthEnable = FALSE;
pipeDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
pipeDesc.DepthStencilState.StencilEnable = TRUE;
pipeDesc.DepthStencilState.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
pipeDesc.DepthStencilState.FrontFace.StencilPassOp = D3D12_STENCIL_OP_REPLACE;
pipeDesc.DepthStencilState.FrontFace.StencilFailOp = D3D12_STENCIL_OP_REPLACE;
pipeDesc.DepthStencilState.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_REPLACE;
pipeDesc.DepthStencilState.BackFace = pipeDesc.DepthStencilState.FrontFace;
pipeDesc.DepthStencilState.StencilReadMask = 0xff;
pipeDesc.DepthStencilState.StencilWriteMask = 0xff;
hr = m_pDevice->GetReal()->CreateGraphicsPipelineState(&pipeDesc, __uuidof(ID3D12PipelineState),
(void **)&psoStencil);
RDCASSERTEQUAL(hr, S_OK);
list->SetPipelineState(psoStencil);
dsvDesc.Flags = D3D12_DSV_FLAG_READ_ONLY_DEPTH;
@@ -279,20 +318,15 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso
}
}
list->Close();
if(!externalList)
{
list->Close();
ID3D12Fence *tmpFence = NULL;
m_pDevice->GetReal()->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence),
(void **)&tmpFence);
ID3D12CommandList *l = list;
m_pDevice->GetQueue()->GetReal()->ExecuteCommandLists(1, &l);
m_pDevice->GPUSync(m_pDevice->GetQueue()->GetReal(), tmpFence);
m_DebugAlloc->Reset();
SAFE_RELEASE(tmpFence);
SAFE_RELEASE(pso);
SAFE_RELEASE(psoStencil);
ID3D12CommandList *l = list;
m_pDevice->GetQueue()->GetReal()->ExecuteCommandLists(1, &l);
m_pDevice->GPUSync(m_pDevice->GetQueue()->GetReal(), Unwrap(m_DebugFence));
m_DebugAlloc->Reset();
}
}
void D3D12DebugManager::CopyArrayToTex2DMS(ID3D12Resource *destMS, ID3D12Resource *srcArray,
+80 -3
View File
@@ -44,11 +44,15 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback
{
D3D12QuadOverdrawCallback(WrappedID3D12Device *dev, D3D12_SHADER_BYTECODE quadWrite,
D3D12_SHADER_BYTECODE quadWriteDXIL, const rdcarray<uint32_t> &events,
ID3D12Resource *depth, ID3D12Resource *msdepth, PortableHandle dsv,
PortableHandle uav)
: m_pDevice(dev),
m_QuadWritePS(quadWrite),
m_QuadWriteDXILPS(quadWriteDXIL),
m_Events(events),
m_Depth(depth),
m_MSDepth(msdepth),
m_DSV(dsv),
m_UAV(uav)
{
m_pDevice->GetQueue()->GetCommandData()->m_DrawcallCallback = this;
@@ -136,6 +140,10 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback
pipeDesc.DepthStencilState.BackFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP;
pipeDesc.DepthStencilState.StencilWriteMask = 0;
// disable any multisampling
pipeDesc.SampleDesc.Count = 1;
pipeDesc.SampleDesc.Quality = 0;
bool dxil =
DXBC::DXBCContainer::CheckForDXIL(pipeDesc.VS.pShaderBytecode, pipeDesc.VS.BytecodeLength);
@@ -166,6 +174,28 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback
rs.pipe = GetResID(cache.pipe);
rs.graphics.rootsig = GetResID(cache.sig);
rs.rts.clear();
if(m_Depth)
{
rs.dsv = *DescriptorFromPortableHandle(m_pDevice->GetResourceManager(), m_DSV);
D3D12_RESOURCE_BARRIER b = {};
b.Transition.pResource = m_Depth;
b.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
b.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON;
b.Transition.StateAfter = D3D12_RESOURCE_STATE_DEPTH_WRITE;
cmd->ResourceBarrier(1, &b);
b.Transition.pResource = m_MSDepth;
b.Transition.StateBefore = D3D12_RESOURCE_STATE_DEPTH_WRITE;
b.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
cmd->ResourceBarrier(1, &b);
m_pDevice->GetDebugManager()->CopyTex2DMSToArray(Unwrap(cmd), Unwrap(m_Depth),
Unwrap(m_MSDepth));
}
AddDebugDescriptorsToRenderState(m_pDevice, rs, {m_UAV}, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
cache.sigElem, m_CopiedHeaps);
@@ -180,6 +210,22 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback
if(!m_Events.contains(eid))
return false;
if(m_Depth)
{
D3D12_RESOURCE_BARRIER b = {};
b.Transition.pResource = m_Depth;
b.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
b.Transition.StateBefore = D3D12_RESOURCE_STATE_DEPTH_WRITE;
b.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
cmd->ResourceBarrier(1, &b);
b.Transition.pResource = m_MSDepth;
b.Transition.StateBefore = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
b.Transition.StateAfter = D3D12_RESOURCE_STATE_DEPTH_WRITE;
cmd->ResourceBarrier(1, &b);
}
// restore the render state and go ahead with the real draw
m_pDevice->GetQueue()->GetCommandData()->GetCurRenderState() = m_PrevState;
@@ -209,6 +255,8 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback
D3D12_SHADER_BYTECODE m_QuadWriteDXILPS;
const rdcarray<uint32_t> &m_Events;
PortableHandle m_UAV;
PortableHandle m_DSV;
ID3D12Resource *m_Depth, *m_MSDepth;
// cache modified pipelines
struct CachedPipeline
@@ -1056,7 +1104,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
pipe->Fill(pipeDesc);
pipeDesc.pRootSignature = GetDebugManager()->GetMeshRootSig();
pipeDesc.SampleMask = 0xFFFFFFFF;
pipeDesc.SampleDesc.Count = 1;
pipeDesc.SampleDesc = overlayTexDesc.SampleDesc;
pipeDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
RDCEraseEl(pipeDesc.RTVFormats.RTFormats);
@@ -1314,8 +1362,36 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
quadWriteDXIL.pShaderBytecode = m_Overlay.QuadOverdrawWriteDXILPS->GetBufferPointer();
}
ID3D12Resource *overrideDepth = NULL;
ResourceId res = rs.GetDSVID();
ID3D12Resource *curDepth = m_pDevice->GetResourceManager()->GetCurrentAs<ID3D12Resource>(res);
D3D12_RESOURCE_DESC curDepthDesc = curDepth ? curDepth->GetDesc() : D3D12_RESOURCE_DESC();
if(curDepthDesc.SampleDesc.Count > 1)
{
curDepthDesc.Alignment = 0;
curDepthDesc.DepthOrArraySize *= (UINT16)curDepthDesc.SampleDesc.Count;
curDepthDesc.SampleDesc.Count = 1;
curDepthDesc.SampleDesc.Quality = 0;
hr = m_pDevice->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &curDepthDesc,
D3D12_RESOURCE_STATE_COMMON, NULL,
__uuidof(ID3D12Resource), (void **)&overrideDepth);
if(FAILED(hr))
{
RDCERR("Failed to create overrideDepth HRESULT: %s", ToStr(hr).c_str());
return m_Overlay.resourceId;
}
dsv = GetDebugManager()->GetCPUHandle(OVERLAY_DSV);
m_pDevice->CreateDepthStencilView(overrideDepth, NULL, dsv);
}
// declare callback struct here
D3D12QuadOverdrawCallback cb(m_pDevice, quadWrite, quadWriteDXIL, events,
D3D12QuadOverdrawCallback cb(m_pDevice, quadWrite, quadWriteDXIL, events, overrideDepth,
overrideDepth ? curDepth : NULL,
overrideDepth ? ToPortableHandle(dsv) : PortableHandle(),
ToPortableHandle(GetDebugManager()->GetCPUHandle(OVERDRAW_UAV)));
m_pDevice->ReplayLog(events.front(), events.back(), eReplay_Full);
@@ -1348,7 +1424,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
list->SetPipelineState(m_Overlay.QuadResolvePipe);
list->SetPipelineState(m_Overlay.QuadResolvePipe[Log2Floor(overlayTexDesc.SampleDesc.Count)]);
list->SetGraphicsRootSignature(m_Overlay.QuadResolveRootSig);
@@ -1372,6 +1448,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
}
SAFE_RELEASE(overdrawTex);
SAFE_RELEASE(overrideDepth);
}
if(overlay == DebugOverlay::QuadOverdrawPass)
+1 -1
View File
@@ -3346,7 +3346,7 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub,
m_pDevice->FlushLists();
// expand multisamples out to array
GetDebugManager()->CopyTex2DMSToArray(Unwrap(arrayTexture), Unwrap(srcTexture));
GetDebugManager()->CopyTex2DMSToArray(NULL, Unwrap(arrayTexture), Unwrap(srcTexture));
tmpTexture = srcTexture = arrayTexture;
+1 -1
View File
@@ -368,7 +368,7 @@ private:
ID3DBlob *QuadOverdrawWritePS = NULL;
ID3DBlob *QuadOverdrawWriteDXILPS = NULL;
ID3D12RootSignature *QuadResolveRootSig = NULL;
ID3D12PipelineState *QuadResolvePipe = NULL;
ID3D12PipelineState *QuadResolvePipe[8] = {NULL};
ID3D12Resource *Texture = NULL;
ResourceId resourceId;
+74 -41
View File
@@ -1812,28 +1812,29 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
if(!events.empty())
{
GLuint replacefbo = 0;
GLuint quadtexs[3] = {0};
GLuint overridedepth = 0;
GLuint quadtexs[2] = {0};
drv.glGenFramebuffers(1, &replacefbo);
drv.glBindFramebuffer(eGL_FRAMEBUFFER, replacefbo);
drv.glGenTextures(3, quadtexs);
drv.glGenTextures(2, quadtexs);
// image for quad usage
drv.glBindTexture(eGL_TEXTURE_2D_ARRAY, quadtexs[2]);
drv.glTextureImage3DEXT(quadtexs[2], eGL_TEXTURE_2D_ARRAY, 0, eGL_R32UI,
drv.glBindTexture(eGL_TEXTURE_2D_ARRAY, quadtexs[1]);
drv.glTextureImage3DEXT(quadtexs[1], eGL_TEXTURE_2D_ARRAY, 0, eGL_R32UI,
RDCMAX(1, outWidth >> 1), RDCMAX(1, outHeight >> 1), 4, 0,
eGL_RED_INTEGER, eGL_UNSIGNED_INT, NULL);
drv.glTextureParameteriEXT(quadtexs[2], eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0);
drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0);
// temporarily attach to FBO to clear it
GLint zero[4] = {0};
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 0);
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[1], 0, 0);
drv.glClearBufferiv(eGL_COLOR, 0, zero);
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 1);
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[1], 0, 1);
drv.glClearBufferiv(eGL_COLOR, 0, zero);
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 2);
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[1], 0, 2);
drv.glClearBufferiv(eGL_COLOR, 0, zero);
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 3);
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[1], 0, 3);
drv.glClearBufferiv(eGL_COLOR, 0, zero);
drv.glBindTexture(eGL_TEXTURE_2D, quadtexs[0]);
@@ -1849,28 +1850,56 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_2D,
quadtexs[0], 0);
GLuint curdrawfbo = 0, curreadfbo = 0;
GLuint curDepth = 0, depthType = 0;
if(overlay == DebugOverlay::QuadOverdrawPass)
ReplayLog(events[0], eReplay_WithoutDraw);
else
rs.ApplyState(m_pDriver);
drv.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&curdrawfbo);
drv.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&curreadfbo);
// TODO handle non-2D depth/stencil attachments and fetch slice or cubemap face
GLint mip = 0;
drv.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT,
drv.glGetNamedFramebufferAttachmentParameterivEXT(curdrawfbo, eGL_DEPTH_ATTACHMENT,
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
(GLint *)&curDepth);
drv.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT,
drv.glGetNamedFramebufferAttachmentParameterivEXT(curdrawfbo, eGL_DEPTH_ATTACHMENT,
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
(GLint *)&depthType);
GLenum fmt = eGL_DEPTH32F_STENCIL8;
GLenum depthEnum = eGL_TEXTURE_2D;
uint32_t depthSlices = 1, depthSamples = 1;
if(curDepth)
{
if(depthType == eGL_TEXTURE)
{
drv.glGetNamedFramebufferAttachmentParameterivEXT(
rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL,
&mip);
drv.glGetTextureLevelParameterivEXT(curDepth, eGL_TEXTURE_2D, mip,
ResourceId id = m_pDriver->GetResourceManager()->GetResID(TextureRes(ctx, curDepth));
WrappedOpenGL::TextureData &depthdetails = m_pDriver->m_Textures[id];
depthSamples = depthdetails.samples;
depthSlices = depthdetails.depth;
if(depthdetails.samples > 1)
depthEnum = depthdetails.depth > 1 ? eGL_TEXTURE_2D_MULTISAMPLE_ARRAY
: eGL_TEXTURE_2D_MULTISAMPLE;
else
depthEnum = depthdetails.depth > 1 ? eGL_TEXTURE_2D_ARRAY : eGL_TEXTURE_2D;
if(depthEnum == eGL_TEXTURE_2D_MULTISAMPLE ||
depthEnum == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
mip = 0;
else
drv.glGetNamedFramebufferAttachmentParameterivEXT(
curdrawfbo, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &mip);
drv.glGetTextureLevelParameterivEXT(curDepth, depthEnum, mip,
eGL_TEXTURE_INTERNAL_FORMAT, (GLint *)&fmt);
}
else
@@ -1880,34 +1909,40 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
}
}
drv.glBindTexture(eGL_TEXTURE_2D, quadtexs[1]);
drv.glTextureImage2DEXT(quadtexs[1], eGL_TEXTURE_2D, 0, fmt, outWidth, outHeight, 0,
GetBaseFormat(fmt), GetDataType(fmt), NULL);
drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 0);
drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S,
eGL_CLAMP_TO_EDGE);
drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T,
eGL_CLAMP_TO_EDGE);
GLenum dsAttach = eGL_DEPTH_STENCIL_ATTACHMENT;
if(GetBaseFormat(fmt) == eGL_DEPTH_COMPONENT)
dsAttach = eGL_DEPTH_ATTACHMENT;
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, dsAttach, eGL_TEXTURE_2D, quadtexs[1], 0);
drv.glBindFramebuffer(eGL_FRAMEBUFFER, replacefbo);
if(overlay == DebugOverlay::QuadOverdrawPass)
ReplayLog(events[0], eReplay_WithoutDraw);
else
rs.ApplyState(m_pDriver);
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, dsAttach, depthEnum, curDepth, 0);
if(depthEnum == eGL_TEXTURE_2D_MULTISAMPLE || depthEnum == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
{
drv.CopyTex2DMSToArray(overridedepth, curDepth, outWidth, outHeight, depthSlices,
depthSamples, fmt);
drv.glTextureParameteriEXT(overridedepth, eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0);
drv.glTextureParameteriEXT(overridedepth, eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MIN_FILTER,
eGL_NEAREST);
drv.glTextureParameteriEXT(overridedepth, eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAG_FILTER,
eGL_NEAREST);
drv.glTextureParameteriEXT(overridedepth, eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_WRAP_S,
eGL_CLAMP_TO_EDGE);
drv.glTextureParameteriEXT(overridedepth, eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_WRAP_T,
eGL_CLAMP_TO_EDGE);
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, dsAttach, overridedepth, 0, 0);
}
drv.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curdrawfbo);
drv.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curreadfbo);
for(size_t i = 0; i < events.size(); i++)
{
GLint depthwritemask = 1;
GLint stencilfmask = 0xff, stencilbmask = 0xff;
GLuint curdrawfbo = 0, curreadfbo = 0;
struct
{
GLuint name;
@@ -1943,7 +1978,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
// bind our FBO
drv.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, replacefbo);
// bind image
drv.glBindImageTexture(0, quadtexs[2], 0, GL_TRUE, 0, eGL_READ_WRITE, eGL_R32UI);
drv.glBindImageTexture(0, quadtexs[1], 0, GL_TRUE, 0, eGL_READ_WRITE, eGL_R32UI);
GLuint prog = 0, pipe = 0;
drv.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&prog);
@@ -1966,9 +2001,9 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
RDCERR("Couldn't get location of overdrawImage");
}
drv.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curdrawfbo);
SafeBlitFramebuffer(0, 0, outWidth, outHeight, 0, 0, outWidth, outHeight,
GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST);
if(overlay == DebugOverlay::QuadOverdrawPass && overridedepth)
drv.CopyTex2DMSToArray(overridedepth, curDepth, outWidth, outHeight, depthSlices,
depthSamples, fmt);
m_pDriver->ReplayLog(0, events[i], eReplay_OnlyDraw);
@@ -2035,7 +2070,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
drv.glStencilMask(0);
drv.glViewport(0, 0, outWidth, outHeight);
drv.glBindImageTexture(0, quadtexs[2], 0, GL_TRUE, 0, eGL_READ_WRITE, eGL_R32UI);
drv.glBindImageTexture(0, quadtexs[1], 0, GL_TRUE, 0, eGL_READ_WRITE, eGL_R32UI);
GLuint emptyVAO = 0;
drv.glGenVertexArrays(1, &emptyVAO);
@@ -2043,13 +2078,11 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
drv.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4);
drv.glBindVertexArray(0);
drv.glDeleteVertexArrays(1, &emptyVAO);
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_2D,
quadtexs[0], 0);
}
drv.glDeleteFramebuffers(1, &replacefbo);
drv.glDeleteTextures(3, quadtexs);
drv.glDeleteTextures(2, quadtexs);
drv.glDeleteTextures(1, &overridedepth);
if(overlay == DebugOverlay::QuadOverdrawPass)
ReplayLog(eventId, eReplay_WithoutDraw);