From 0202af73da9404c526730e2754b710141efb70a1 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 6 Aug 2014 23:15:28 +0100 Subject: [PATCH] Fetch SV_Coverage value and fill in semantic data. Closes #74 --- renderdoc/driver/d3d11/d3d11_analyse.cpp | 218 ++++++++++-------- renderdoc/driver/d3d11/shaders/dxbc_debug.cpp | 5 + renderdoc/driver/d3d11/shaders/dxbc_debug.h | 1 + 3 files changed, 134 insertions(+), 90 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_analyse.cpp b/renderdoc/driver/d3d11/d3d11_analyse.cpp index 2a17f6f38..cfe3c5840 100644 --- a/renderdoc/driver/d3d11/d3d11_analyse.cpp +++ b/renderdoc/driver/d3d11/d3d11_analyse.cpp @@ -339,110 +339,136 @@ ShaderDebug::State D3D11DebugManager::CreateShaderDebugState(ShaderDebugTrace &t // use pixel shader here to get inputs - uint32_t maxReg = 0; + int32_t maxReg = -1; for(size_t i=0; i < dxbc->m_InputSig.size(); i++) - maxReg = RDCMAX(maxReg, dxbc->m_InputSig[i].regIndex); + maxReg = RDCMAX(maxReg, (int32_t)dxbc->m_InputSig[i].regIndex); - create_array(trace.inputs, maxReg+1); - for(size_t i=0; i < dxbc->m_InputSig.size(); i++) + bool inputCoverage = false; + + for(size_t i=0; i < dxbc->m_Declarations.size(); i++) { - char buf[64] = {0}; - - SigParameter &sig = dxbc->m_InputSig[i]; - - StringFormat::snprintf(buf, 63, "v%d", sig.regIndex); - - ShaderVariable v; - - v.name = StringFormat::Fmt("%hs (%hs)", buf, sig.semanticIdxName.elems); - v.rows = 1; - v.columns = - sig.regChannelMask & 0x8 ? 4 : - sig.regChannelMask & 0x4 ? 3 : - sig.regChannelMask & 0x2 ? 2 : - sig.regChannelMask & 0x1 ? 1 : - 0; - - if(sig.compType == eCompType_UInt) - v.type = eVar_UInt; - else if(sig.compType == eCompType_SInt) - v.type = eVar_Int; - - if(trace.inputs[sig.regIndex].columns == 0) - trace.inputs[sig.regIndex] = v; - else - trace.inputs[sig.regIndex].columns = RDCMAX(trace.inputs[sig.regIndex].columns, v.columns); + if(dxbc->m_Declarations[i].declaration == OPCODE_DCL_INPUT && + dxbc->m_Declarations[i].operand.type == TYPE_INPUT_COVERAGE_MASK) + { + inputCoverage = true; + break; + } } + if(maxReg >= 0 || inputCoverage) + { + create_array(trace.inputs, maxReg+1 + (inputCoverage?1:0)); + for(size_t i=0; i < dxbc->m_InputSig.size(); i++) + { + char buf[64] = {0}; + + SigParameter &sig = dxbc->m_InputSig[i]; + + StringFormat::snprintf(buf, 63, "v%d", sig.regIndex); + + ShaderVariable v; + + v.name = StringFormat::Fmt("%hs (%hs)", buf, sig.semanticIdxName.elems); + v.rows = 1; + v.columns = + sig.regChannelMask & 0x8 ? 4 : + sig.regChannelMask & 0x4 ? 3 : + sig.regChannelMask & 0x2 ? 2 : + sig.regChannelMask & 0x1 ? 1 : + 0; + + if(sig.compType == eCompType_UInt) + v.type = eVar_UInt; + else if(sig.compType == eCompType_SInt) + v.type = eVar_Int; + + if(trace.inputs[sig.regIndex].columns == 0) + trace.inputs[sig.regIndex] = v; + else + trace.inputs[sig.regIndex].columns = RDCMAX(trace.inputs[sig.regIndex].columns, v.columns); + } + + if(inputCoverage) + { + trace.inputs[maxReg+1] = ShaderVariable("vCoverage", 0U, 0U, 0U, 0U); + trace.inputs[maxReg+1].columns = 1; + } + } + uint32_t specialOutputs = 0; - maxReg = 0; + maxReg = -1; for(size_t i=0; i < dxbc->m_OutputSig.size(); i++) { if(dxbc->m_OutputSig[i].regIndex == ~0U) specialOutputs++; else - maxReg = RDCMAX(maxReg, dxbc->m_OutputSig[i].regIndex); - } - - create_array(initialState.outputs, maxReg+1 + specialOutputs); - for(size_t i=0; i < dxbc->m_OutputSig.size(); i++) - { - SigParameter &sig = dxbc->m_OutputSig[i]; - - if(sig.regIndex == ~0U) - continue; - - char buf[64] = {0}; - - StringFormat::snprintf(buf, 63, "o%d", sig.regIndex); - - ShaderVariable v; - - v.name = StringFormat::Fmt("%hs (%hs)", buf, sig.semanticIdxName.elems); - v.rows = 1; - v.columns = - sig.regChannelMask & 0x8 ? 4 : - sig.regChannelMask & 0x4 ? 3 : - sig.regChannelMask & 0x2 ? 2 : - sig.regChannelMask & 0x1 ? 1 : - 0; - - if(initialState.outputs[sig.regIndex].columns == 0) - initialState.outputs[sig.regIndex] = v; - else - initialState.outputs[sig.regIndex].columns = RDCMAX(initialState.outputs[sig.regIndex].columns, v.columns); + maxReg = RDCMAX(maxReg, (int32_t)dxbc->m_OutputSig[i].regIndex); } - for(size_t i=0; i < dxbc->m_OutputSig.size(); i++) + if(maxReg >= 0 || specialOutputs > 0) { - SigParameter &sig = dxbc->m_OutputSig[i]; - - if(sig.regIndex != ~0U) - continue; - - ShaderVariable v; - - if(sig.systemValue == eAttr_OutputControlPointIndex) v.name = "vOutputControlPointID"; - else if(sig.systemValue == eAttr_DepthOutput) v.name = "oDepth"; - else if(sig.systemValue == eAttr_DepthOutputLessEqual) v.name = "oDepthLessEqual"; - else if(sig.systemValue == eAttr_DepthOutputGreaterEqual) v.name = "oDepthGreaterEqual"; - else if(sig.systemValue == eAttr_MSAACoverage) v.name = "oMask"; - //if(sig.systemValue == TYPE_OUTPUT_CONTROL_POINT) str = "oOutputControlPoint"; - else + create_array(initialState.outputs, maxReg+1 + specialOutputs); + for(size_t i=0; i < dxbc->m_OutputSig.size(); i++) { - RDCERR("Unhandled output: %hs (%d)", sig.semanticName, sig.systemValue); - continue; + SigParameter &sig = dxbc->m_OutputSig[i]; + + if(sig.regIndex == ~0U) + continue; + + char buf[64] = {0}; + + StringFormat::snprintf(buf, 63, "o%d", sig.regIndex); + + ShaderVariable v; + + v.name = StringFormat::Fmt("%hs (%hs)", buf, sig.semanticIdxName.elems); + v.rows = 1; + v.columns = + sig.regChannelMask & 0x8 ? 4 : + sig.regChannelMask & 0x4 ? 3 : + sig.regChannelMask & 0x2 ? 2 : + sig.regChannelMask & 0x1 ? 1 : + 0; + + if(initialState.outputs[sig.regIndex].columns == 0) + initialState.outputs[sig.regIndex] = v; + else + initialState.outputs[sig.regIndex].columns = RDCMAX(initialState.outputs[sig.regIndex].columns, v.columns); } - v.rows = 1; - v.columns = - sig.regChannelMask & 0x8 ? 4 : - sig.regChannelMask & 0x4 ? 3 : - sig.regChannelMask & 0x2 ? 2 : - sig.regChannelMask & 0x1 ? 1 : - 0; + int32_t outIdx = maxReg+1; - initialState.outputs[maxReg+i] = v; + for(size_t i=0; i < dxbc->m_OutputSig.size(); i++) + { + SigParameter &sig = dxbc->m_OutputSig[i]; + + if(sig.regIndex != ~0U) + continue; + + ShaderVariable v; + + if(sig.systemValue == eAttr_OutputControlPointIndex) v.name = "vOutputControlPointID"; + else if(sig.systemValue == eAttr_DepthOutput) v.name = "oDepth"; + else if(sig.systemValue == eAttr_DepthOutputLessEqual) v.name = "oDepthLessEqual"; + else if(sig.systemValue == eAttr_DepthOutputGreaterEqual) v.name = "oDepthGreaterEqual"; + else if(sig.systemValue == eAttr_MSAACoverage) v.name = "oMask"; + //if(sig.systemValue == TYPE_OUTPUT_CONTROL_POINT) str = "oOutputControlPoint"; + else + { + RDCERR("Unhandled output: %hs (%d)", sig.semanticName, sig.systemValue); + continue; + } + + v.rows = 1; + v.columns = + sig.regChannelMask & 0x8 ? 4 : + sig.regChannelMask & 0x4 ? 3 : + sig.regChannelMask & 0x2 ? 2 : + sig.regChannelMask & 0x1 ? 1 : + 0; + + initialState.outputs[outIdx++] = v; + } } create_array(trace.cbuffers, dxbc->m_CBuffers.size()); @@ -585,6 +611,7 @@ struct DebugHit float posx; float posy; float depth; uint32_t primitive; + uint32_t coverage; uint32_t rawdata; // arbitrary, depending on shader }; @@ -1007,15 +1034,16 @@ ShaderDebugTrace D3D11DebugManager::DebugPixel(uint32_t frameID, uint32_t eventI uint32_t overdrawLevels = 100; // maximum number of overdraw levels - extractHlsl += "struct PSInitialData { uint hit; float3 pos; uint prim; PSInput IN; float derivValid; PSInput INddx; PSInput INddy; };\n\n"; + extractHlsl += "struct PSInitialData { uint hit; float3 pos; uint prim; uint covge; PSInput IN; float derivValid; PSInput INddx; PSInput INddy; };\n\n"; extractHlsl += "RWStructuredBuffer PSInitialBuffer : register(u0);\n\n"; - extractHlsl += "void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position, uint prim : SV_PrimitiveID)\n{\n"; + extractHlsl += "void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position, uint prim : SV_PrimitiveID, uint covge : SV_Coverage)\n{\n"; extractHlsl += "if(abs(debug_pixelPos.x - " + ToStr::Get(x) + ".5) < 2 && abs(debug_pixelPos.y - " + ToStr::Get(y) + ".5) < 2) {\n"; extractHlsl += "uint idx = 0;\n"; extractHlsl += "InterlockedAdd(PSInitialBuffer[0].hit, 1, idx);\n"; extractHlsl += "if(idx < " + ToStr::Get(overdrawLevels) + ") {\n"; extractHlsl += "PSInitialBuffer[idx].pos = debug_pixelPos.xyz;\n"; extractHlsl += "PSInitialBuffer[idx].prim = prim;\n"; + extractHlsl += "PSInitialBuffer[idx].covge = covge;\n"; extractHlsl += "PSInitialBuffer[idx].IN = IN;\n"; extractHlsl += "PSInitialBuffer[idx].derivValid = ddx(debug_pixelPos.x);\n"; extractHlsl += "PSInitialBuffer[idx].INddx = (PSInput)0;\n"; @@ -1030,8 +1058,12 @@ ShaderDebugTrace D3D11DebugManager::DebugPixel(uint32_t frameID, uint32_t eventI ID3D11PixelShader *extract = MakePShader(extractHlsl.c_str(), "ExtractInputsPS", "ps_5_0"); - // uint hit; float3 pos; uint prim; float derivValid; PSInput IN, INddx, INddy; - uint32_t structStride = sizeof(uint32_t) + sizeof(float)*3 + sizeof(uint32_t) + sizeof(float) + structureStride*3; + uint32_t structStride = sizeof(uint32_t) // uint hit; + + sizeof(float)*3 // float3 pos; + + sizeof(uint32_t) // uint prim; + + sizeof(uint32_t) // uint covge; + + sizeof(float) // float derivValid; + + structureStride*3; // PSInput IN, INddx, INddy; HRESULT hr = S_OK; @@ -1208,6 +1240,12 @@ ShaderDebugTrace D3D11DebugManager::DebugPixel(uint32_t frameID, uint32_t eventI State initialState = CreateShaderDebugState(traces[destIdx], destIdx, dxbc, cbufData); + rdctype::array &ins = traces[destIdx].inputs; + if(ins.count > 0 && !strcmp(ins[ins.count-1].name.elems, "vCoverage")) + ins[ins.count-1].value.u.x = hit->coverage; + + initialState.semantics.coverage = hit->coverage; + uint32_t *data = &hit->rawdata; for(size_t i=0; i < initialValues.size(); i++) diff --git a/renderdoc/driver/d3d11/shaders/dxbc_debug.cpp b/renderdoc/driver/d3d11/shaders/dxbc_debug.cpp index b534c5aa4..27d594299 100644 --- a/renderdoc/driver/d3d11/shaders/dxbc_debug.cpp +++ b/renderdoc/driver/d3d11/shaders/dxbc_debug.cpp @@ -946,6 +946,11 @@ ShaderVariable State::GetSrc(const ASMOperand &oper, const ASMOperation &op) con v = s = ShaderVariable("vThreadIDInGroupFlattened", flattened, flattened, flattened, flattened); break; } + case TYPE_INPUT_COVERAGE_MASK: + { + v = s = ShaderVariable("vCoverage", semantics.coverage, semantics.coverage, semantics.coverage, semantics.coverage); + break; + } default: { RDCERR("Currently unsupported operand type %d!", oper.type); diff --git a/renderdoc/driver/d3d11/shaders/dxbc_debug.h b/renderdoc/driver/d3d11/shaders/dxbc_debug.h index c604c18c5..3bc2eb091 100644 --- a/renderdoc/driver/d3d11/shaders/dxbc_debug.h +++ b/renderdoc/driver/d3d11/shaders/dxbc_debug.h @@ -114,6 +114,7 @@ class State : public ShaderDebugState { uint32_t GroupID[3]; uint32_t ThreadID[3]; + uint32_t coverage; } semantics; void Init();