From 1dc32b8bf8dd14e607d306c160b1bedf46067910 Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Fri, 11 Jul 2025 13:47:33 -0700 Subject: Add DebugGlobalVariable instructions to SPIR-V output (#7686) * Add DebugGlobalVariable instructions to SPIR-V output Implements generation of DebugGlobalVariable instructions for global variables like Texture2D and SamplerState in SPIR-V debug information output. Adds debug type support for texture and sampler types using DebugTypeComposite. * Handle two more types for DebugGlobalVariable kIROp_RaytracingAccelerationStructureType and kIROp_SamplerComparisonStateType had to be handled in `emitDebugTypeImpl()` * Fix format * Refactor debug type emission to reduce duplication Use IRSamplerStateTypeBase type check and fallback pattern instead of separate cases for each opcode type. * Fix compiler warning * Simplify `emitDebugTypeImpl()` more --- source/slang/slang-emit-spirv-ops-debug-info-ext.h | 36 +++++++++++++ source/slang/slang-emit-spirv.cpp | 59 +++++++++++++++++++++- 2 files changed, 94 insertions(+), 1 deletion(-) (limited to 'source') diff --git a/source/slang/slang-emit-spirv-ops-debug-info-ext.h b/source/slang/slang-emit-spirv-ops-debug-info-ext.h index 138204af7..ab2d7b730 100644 --- a/source/slang/slang-emit-spirv-ops-debug-info-ext.h +++ b/source/slang/slang-emit-spirv-ops-debug-info-ext.h @@ -554,6 +554,42 @@ SpvInst* emitOpDebugLocalVariable( flags); } +template +SpvInst* emitOpDebugGlobalVariable( + SpvInstParent* parent, + IRInst* inst, + const T& idResultType, + SpvInst* set, + IRInst* name, + SpvInst* type, + IRInst* source, + IRInst* line, + IRInst* col, + SpvInst* scope, + IRInst* linkageName, + SpvInst* variable, + IRInst* flags) +{ + static_assert(isSingular); + return emitInst( + parent, + inst, + SpvOpExtInst, + idResultType, + kResultID, + set, + SpvWord(18), // DebugGlobalVariable opcode in NonSemantic.Shader.DebugInfo.100 + name, + type, + source, + line, + col, + scope, + linkageName, + variable, + flags); +} + template SpvInst* emitOpDebugInlinedVariable( SpvInstParent* parent, diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 28862f5b8..376a828cd 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -3215,6 +3215,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex if (layout) emitVarLayout(param, varInst, layout); emitDecorations(param, getID(varInst)); + maybeEmitDebugGlobalVariable(param, varInst); return varInst; } @@ -3237,6 +3238,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex if (layout) emitVarLayout(globalVar, varInst, layout); emitDecorations(globalVar, getID(varInst)); + maybeEmitDebugGlobalVariable(globalVar, varInst); return varInst; } @@ -3893,6 +3895,39 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex return nullptr; } + void maybeEmitDebugGlobalVariable(IRInst* globalInst, SpvInst* spvVar) + { + auto scope = findDebugScope(globalInst->getModule()->getModuleInst()); + if (!scope) + return; + + auto name = getName(globalInst); + IRBuilder builder(globalInst); + auto varType = tryGetPointedToType(&builder, globalInst->getDataType()); + auto debugType = emitDebugType(varType); + + // Use default debug source and line info similar to struct debug type emission + auto loc = globalInst->findDecoration(); + IRInst* source = loc ? loc->getSource() : m_defaultDebugSource; + IRInst* line = loc ? loc->getLine() : builder.getIntValue(builder.getUIntType(), 0); + IRInst* col = loc ? loc->getCol() : line; + + emitOpDebugGlobalVariable( + getSection(SpvLogicalSectionID::GlobalVariables), + nullptr, // Don't associate with IR inst to avoid duplicate registration + m_voidType, + getNonSemanticDebugInfoExtInst(), + name, + debugType, + source, + line, + col, + scope, + name, // linkageName same as name + spvVar, + builder.getIntValue(builder.getUIntType(), 0)); // flags + } + SpvInst* emitMakeUInt64(SpvInstParent* parent, IRInst* inst) { IRBuilder builder(inst); @@ -8524,7 +8559,29 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex debugBaseType, builder.getIntValue(builder.getUIntType(), kDebugTypeAtomicQualifier)); } - return ensureInst(m_voidType); + + // Fallback for texture types, raytracing types, and other composite types + // Declare variables for debug location like struct handling does + IRInst* source = m_defaultDebugSource; + IRInst* line = builder.getIntValue(builder.getUIntType(), 0); + IRInst* col = line; + + // Emit a composite debug type (struct-like for most types) + return emitOpDebugTypeComposite( + getSection(SpvLogicalSectionID::ConstantsAndTypes), + nullptr, + m_voidType, + getNonSemanticDebugInfoExtInst(), + name, + builder.getIntValue(builder.getUIntType(), 0), + source, + line, + col, + scope, + name, + builder.getIntValue(builder.getUIntType(), 0), // Size (unknown) + builder.getIntValue(builder.getUIntType(), kUnknownPhysicalLayout), + List()); // No members } SpvInst* emitDebugType(IRType* type) -- cgit v1.2.3