mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-16 11:36:48 +00:00
DXIL Debugger Use DXIL Signature for the Inputs
Use the DXIL Signature input register and element linkage to extract the correct data from the initial values
This commit is contained in:
@@ -3078,6 +3078,8 @@ struct PSInitialData
|
||||
DXILDebug::GlobalState &globalState = debugger->GetGlobalState();
|
||||
DXILDebug::ThreadState &activeState = debugger->GetActiveLane();
|
||||
rdcarray<ShaderVariable> &ins = activeState.m_Input.members;
|
||||
const rdcarray<DXIL::EntryPointInterface::Signature> &dxilInputs =
|
||||
debugger->GetDXILEntryPointInputs();
|
||||
|
||||
// Fetch constant buffer data from root signature
|
||||
DXILDebug::FetchConstantBufferData(m_pDevice, dxbc->GetDXILByteCode(), rs.graphics, refl,
|
||||
@@ -3086,15 +3088,35 @@ struct PSInitialData
|
||||
// TODO SAMPLE EVALUTE MASK
|
||||
// globalState.sampleEvalRegisterMask = sampleEvalRegisterMask;
|
||||
|
||||
// The initial values are packed into register and elements
|
||||
// DXIL Inputs are not packed and contain the register and element linkage
|
||||
rdcarray<DXILDebug::PSInputData> psInputDatas;
|
||||
for(int i = 0; i < initialValues.count(); i++)
|
||||
{
|
||||
PSInputElement &elem = initialValues[i];
|
||||
if(elem.reg >= 0)
|
||||
psInputDatas.emplace_back(i, elem.numwords, elem.sysattribute, elem.included, data);
|
||||
PSInputElement &inputElement = initialValues[i];
|
||||
int packedRegister = inputElement.reg;
|
||||
if(packedRegister >= 0)
|
||||
{
|
||||
int dxilInputIdx = -1;
|
||||
int packedElement = inputElement.elem;
|
||||
// Find the DXIL Input index and element from that matches the register and element
|
||||
for(int j = 0; j < dxilInputs.count(); ++j)
|
||||
{
|
||||
const DXIL::EntryPointInterface::Signature &dxilParam = dxilInputs[j];
|
||||
if((dxilParam.startRow == (int32_t)packedRegister) && (dxilParam.startCol == packedElement))
|
||||
{
|
||||
dxilInputIdx = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
RDCASSERT(dxilInputIdx >= 0);
|
||||
|
||||
if(elem.included)
|
||||
data += elem.numwords;
|
||||
psInputDatas.emplace_back(dxilInputIdx, inputElement.numwords, inputElement.sysattribute,
|
||||
inputElement.included, data);
|
||||
}
|
||||
|
||||
if(inputElement.included)
|
||||
data += inputElement.numwords;
|
||||
}
|
||||
|
||||
{
|
||||
@@ -3110,26 +3132,27 @@ struct PSInitialData
|
||||
int32_t *rawout = NULL;
|
||||
|
||||
ShaderVariable &invar = ins[psInput.input];
|
||||
int outElement = 0;
|
||||
|
||||
if(psInput.sysattribute == ShaderBuiltin::PrimitiveIndex)
|
||||
{
|
||||
invar.value.u32v[0] = pHit->primitive;
|
||||
invar.value.u32v[outElement] = pHit->primitive;
|
||||
}
|
||||
else if(psInput.sysattribute == ShaderBuiltin::MSAASampleIndex)
|
||||
{
|
||||
invar.value.u32v[0] = pHit->sample;
|
||||
invar.value.u32v[outElement] = pHit->sample;
|
||||
}
|
||||
else if(psInput.sysattribute == ShaderBuiltin::MSAACoverage)
|
||||
{
|
||||
invar.value.u32v[0] = pHit->coverage;
|
||||
invar.value.u32v[outElement] = pHit->coverage;
|
||||
}
|
||||
else if(psInput.sysattribute == ShaderBuiltin::IsFrontFace)
|
||||
{
|
||||
invar.value.u32v[0] = pHit->isFrontFace ? ~0U : 0;
|
||||
invar.value.u32v[outElement] = pHit->isFrontFace ? ~0U : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawout = &invar.value.s32v[0];
|
||||
rawout = &invar.value.s32v[outElement];
|
||||
memcpy(rawout, psInput.data, psInput.numwords * 4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5710,11 +5710,23 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
|
||||
ParseDebugData();
|
||||
|
||||
// Add inputs to the shader trace
|
||||
const rdcarray<SigParameter> &inParams = dxbcContainer->GetReflection()->InputSig;
|
||||
// Use the DXIL reflection data to map the input signature to input variables
|
||||
const EntryPointInterface *entryPointIf = NULL;
|
||||
for(size_t e = 0; e < m_Program->m_EntryPointInterfaces.size(); ++e)
|
||||
{
|
||||
if(entryFunction == m_Program->m_EntryPointInterfaces[e].name)
|
||||
{
|
||||
entryPointIf = &m_Program->m_EntryPointInterfaces[e];
|
||||
break;
|
||||
}
|
||||
}
|
||||
RDCASSERT(entryPointIf);
|
||||
m_EntryPointInterface = entryPointIf;
|
||||
const rdcarray<EntryPointInterface::Signature> &inputs = m_EntryPointInterface->inputs;
|
||||
|
||||
// TODO: compute this from DXIL
|
||||
// TODO: compute coverage from DXIL
|
||||
const bool inputCoverage = false;
|
||||
const uint32_t countInParams = (uint32_t)inParams.size();
|
||||
const uint32_t countInParams = (uint32_t)inputs.size();
|
||||
|
||||
if(countInParams || inputCoverage)
|
||||
{
|
||||
@@ -5726,46 +5738,42 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
|
||||
inStruct.type = VarType::Struct;
|
||||
inStruct.members.resize(countInParams + (inputCoverage ? 1 : 0));
|
||||
|
||||
for(uint32_t sigIdx = 0; sigIdx < countInParams; sigIdx++)
|
||||
const rdcarray<SigParameter> &dxbcInParams = dxbcContainer->GetReflection()->InputSig;
|
||||
for(uint32_t i = 0; i < countInParams; ++i)
|
||||
{
|
||||
const SigParameter &sig = inParams[sigIdx];
|
||||
const EntryPointInterface::Signature &sig = inputs[i];
|
||||
|
||||
ShaderVariable v;
|
||||
v.name = sig.semanticIdxName;
|
||||
v.rows = 1;
|
||||
v.columns = (uint8_t)sig.compCount;
|
||||
v.type = sig.varType;
|
||||
ShaderVariable &v = inStruct.members[i];
|
||||
|
||||
ShaderVariable &dst = inStruct.members[sigIdx];
|
||||
|
||||
// if the variable hasn't been initialised, just assign. If it has, we're in a situation
|
||||
// where two input parameters are assigned to the same variable overlapping, so just update
|
||||
// the number of columns to the max of both. The source mapping (either from debug info or
|
||||
// our own below) will handle distinguishing better.
|
||||
if(dst.name.empty())
|
||||
dst = v;
|
||||
// Get the name from the DXBC reflection
|
||||
SigParameter sigParam;
|
||||
if(FindSigParameter(dxbcInParams, sig, sigParam))
|
||||
{
|
||||
v.name = sigParam.semanticIdxName;
|
||||
}
|
||||
else
|
||||
dst.columns = RDCMAX(dst.columns, v.columns);
|
||||
{
|
||||
v.name = sig.name;
|
||||
}
|
||||
v.rows = (uint8_t)sig.rows;
|
||||
v.columns = (uint8_t)sig.cols;
|
||||
v.type = VarTypeForComponentType(sig.type);
|
||||
|
||||
SourceVariableMapping inputMapping;
|
||||
inputMapping.name = v.name;
|
||||
inputMapping.type = v.type;
|
||||
inputMapping.rows = 1;
|
||||
inputMapping.columns = sig.compCount;
|
||||
inputMapping.signatureIndex = sigIdx;
|
||||
inputMapping.variables.reserve(sig.compCount);
|
||||
for(uint32_t c = 0; c < 4; c++)
|
||||
inputMapping.rows = sig.rows;
|
||||
inputMapping.columns = sig.cols;
|
||||
inputMapping.variables.reserve(sig.cols);
|
||||
inputMapping.signatureIndex = sig.startRow;
|
||||
for(uint32_t c = 0; c < sig.cols; ++c)
|
||||
{
|
||||
if(sig.regChannelMask & (1 << c))
|
||||
{
|
||||
DebugVariableReference ref;
|
||||
ref.type = DebugVariableType::Input;
|
||||
ref.name = inStruct.name + "." + v.name;
|
||||
ref.component = c;
|
||||
inputMapping.variables.push_back(ref);
|
||||
}
|
||||
DebugVariableReference ref;
|
||||
ref.type = DebugVariableType::Input;
|
||||
ref.name = inStruct.name + "." + v.name;
|
||||
ref.component = c;
|
||||
inputMapping.variables.push_back(ref);
|
||||
}
|
||||
// ret->sourceVars.push_back(inputMapping);
|
||||
|
||||
// Put the coverage mask at the end
|
||||
if(inputCoverage)
|
||||
@@ -5830,10 +5838,6 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
|
||||
|
||||
ShaderVariable &dst = outStruct.members[sigIdx];
|
||||
|
||||
// if the variable hasn't been initialised, just assign. If it has, we're in a situation where
|
||||
// two input parameters are assigned to the same variable overlapping, so just update the
|
||||
// number of columns to the max of both. The source mapping (either from debug info or our own
|
||||
// below) will handle distinguishing better.
|
||||
if(dst.name.empty())
|
||||
dst = v;
|
||||
else
|
||||
|
||||
@@ -424,6 +424,10 @@ public:
|
||||
const DXBC::DXBCContainer *const GetDXBCContainer() { return m_DXBC; }
|
||||
uint32_t GetEventId() { return m_EventId; }
|
||||
const FunctionInfo *GetFunctionInfo(const DXIL::Function *function) const;
|
||||
const rdcarray<DXIL::EntryPointInterface::Signature> &GetDXILEntryPointInputs(void) const
|
||||
{
|
||||
return m_EntryPointInterface->inputs;
|
||||
}
|
||||
|
||||
private:
|
||||
void CalcActiveMask(rdcarray<bool> &activeMask);
|
||||
@@ -456,6 +460,7 @@ private:
|
||||
const DXBC::DXBCContainer *m_DXBC = NULL;
|
||||
const DXIL::Program *m_Program = NULL;
|
||||
const DXIL::Function *m_EntryPointFunction = NULL;
|
||||
const DXIL::EntryPointInterface *m_EntryPointInterface = NULL;
|
||||
ShaderStage m_Stage;
|
||||
|
||||
uint32_t m_EventId = 0;
|
||||
|
||||
Reference in New Issue
Block a user