diff options
| -rw-r--r-- | source/slang/hlsl.meta.slang | 106 | ||||
| -rw-r--r-- | source/slang/slang-ast-expr.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-emit-spirv.cpp | 20 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-insts.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-ir.cpp | 12 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-parser.cpp | 4 | ||||
| -rw-r--r-- | tests/spirv/debug-printf.slang | 11 |
9 files changed, 100 insertions, 61 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 501723931..cfa3143de 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -5976,68 +5976,52 @@ matrix<T,N,M> pow(matrix<T,N,M> x, matrix<T,N,M> y) // Output message // TODO: add check to ensure format is const literal. -__target_intrinsic(hlsl) -__target_intrinsic(cpp) -__target_intrinsic(cuda) -__glsl_extension(GL_EXT_debug_printf) -__target_intrinsic(glsl, "debugPrintfEXT($0)") -void printf(NativeString format); - -__target_intrinsic(hlsl) -__target_intrinsic(cpp) -__target_intrinsic(cuda) -__glsl_extension(GL_EXT_debug_printf) -__target_intrinsic(glsl, "debugPrintfEXT($0, $1)") -void printf<T0>(NativeString format, T0 arg0); - -__target_intrinsic(hlsl) -__target_intrinsic(cpp) -__target_intrinsic(cuda) -__glsl_extension(GL_EXT_debug_printf) -__target_intrinsic(glsl, "debugPrintfEXT($0, $1, $2)") -void printf<T0, T1>(NativeString format, T0 arg0, T1 arg1); - -__target_intrinsic(hlsl) -__target_intrinsic(cpp) -__target_intrinsic(cuda) -__glsl_extension(GL_EXT_debug_printf) -__target_intrinsic(glsl, "debugPrintfEXT($0, $1, $2, $3)") -void printf<T0, T1, T2>(NativeString format, T0 arg0, T1 arg1, T2 arg2); - -__target_intrinsic(hlsl) -__target_intrinsic(cpp) -__target_intrinsic(cuda) -__glsl_extension(GL_EXT_debug_printf) -__target_intrinsic(glsl, "debugPrintfEXT($0, $1, $2, $3, $4)") -void printf<T0, T1, T2, T3>(NativeString format, T0 arg0, T1 arg1, T2 arg2, T3 arg3); - -__target_intrinsic(hlsl) -__target_intrinsic(cpp) -__target_intrinsic(cuda) -__glsl_extension(GL_EXT_debug_printf) -__target_intrinsic(glsl, "debugPrintfEXT($0, $1, $2, $3, $4, $5)") -void printf<T0, T1, T2, T3, T4>(NativeString format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4); - -__target_intrinsic(hlsl) -__target_intrinsic(cpp) -__target_intrinsic(cuda) -__glsl_extension(GL_EXT_debug_printf) -__target_intrinsic(glsl, "debugPrintfEXT($0, $1, $2, $3, $4, $5, $6)") -void printf<T0, T1, T2, T3, T4, T5>(NativeString format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); - -__target_intrinsic(hlsl) -__target_intrinsic(cpp) -__target_intrinsic(cuda) -__glsl_extension(GL_EXT_debug_printf) -__target_intrinsic(glsl, "debugPrintfEXT($0, $1, $2, $3, $4, $5, $6, $7)") -void printf<T0, T1, T2, T3, T4, T5, T6>(NativeString format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); - -__target_intrinsic(hlsl) -__target_intrinsic(cpp) -__target_intrinsic(cuda) +${{{{ +for (int argCount = 0; argCount < 12; argCount++) +{ + StringBuilder paramList; + StringBuilder argList; + StringBuilder spirvArgList; + StringBuilder genericParamList; + if (argCount > 0) + genericParamList << "<"; + for (int i = 0; i < argCount; i++) + { + if (i > 0) + genericParamList << ", "; + genericParamList << "T" << i; + + paramList << ", T" << i << " v" << i; + argList << ", $" << i+1; + spirvArgList << " $v" << i; + } + if (argCount > 0) + genericParamList << ">"; + auto params = paramList.toString(); + auto args = argList.toString(); + auto spirvArgs = spirvArgList.toString(); +}}}} __glsl_extension(GL_EXT_debug_printf) -__target_intrinsic(glsl, "debugPrintfEXT($0, $1, $2, $3, $4, $5, $6, $7, $8)") -void printf<T0, T1, T2, T3, T4, T5, T6, T7>(NativeString format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); +void printf$(genericParamList.toString())(NativeString format $(paramList)) +{ + __target_switch + { + case hlsl: + case cpp: + case cuda: + __intrinsic_asm "printf"; + case glsl: + __intrinsic_asm "debugPrintfEXT($0 $(argList))"; + case spirv: + spirv_asm { + OpExtension "SPV_KHR_non_semantic_info"; + result:$$void = OpExtInst debugPrintf 1 $format $(spirvArgs); + }; + } +} +${{{{ +} +}}}} // Tessellation factor fixup routines diff --git a/source/slang/slang-ast-expr.h b/source/slang/slang-ast-expr.h index b23b43430..88293a812 100644 --- a/source/slang/slang-ast-expr.h +++ b/source/slang/slang-ast-expr.h @@ -664,6 +664,7 @@ public: EntryPoint, // __entryPoint, a placeholder for the id of a referencing entryPoint. BuiltinVar, GLSL450Set, + NonSemanticDebugPrintfExtSet, }; // The flavour and token describes how this was parsed diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 869484ab9..d071328c4 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -1144,6 +1144,21 @@ struct SPIRVEmitContext return m_NonSemanticDebugInfoExtInst; } + /// The SPIRV OpExtInstImport inst that represents the NonSemantic debug info + /// extended instruction set. + SpvInst* m_NonSemanticDebugPrintfExtInst = nullptr; + + SpvInst* getNonSemanticDebugPrintfExtInst() + { + if (m_NonSemanticDebugPrintfExtInst) + return m_NonSemanticDebugPrintfExtInst; + m_NonSemanticDebugPrintfExtInst = emitOpExtInstImport( + getSection(SpvLogicalSectionID::ExtIntInstImports), + nullptr, + UnownedStringSlice("NonSemantic.DebugPrintf")); + return m_NonSemanticDebugPrintfExtInst; + } + // Now that we've gotten the core infrastructure out of the way, // let's start looking at emitting some instructions that make // up a SPIR-V module. @@ -4623,6 +4638,11 @@ struct SPIRVEmitContext emitOperand(getGLSL450ExtInst()); break; } + case kIROp_SPIRVAsmOperandDebugPrintfSet: + { + emitOperand(getNonSemanticDebugPrintfExtInst()); + break; + } default: SLANG_UNREACHABLE("Unhandled case in emitSPIRVAsm"); } diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index 23f922b5b..496c195d7 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -1111,6 +1111,8 @@ INST(SPIRVAsmInst, SPIRVAsmInst, 1, 0) INST(SPIRVAsmOperandBuiltinVar, SPIRVAsmOperandBuiltinVar, 1, HOISTABLE) // A reference to the glsl450 instruction set. INST(SPIRVAsmOperandGLSL450Set, SPIRVAsmOperandGLSL450Set, 0, HOISTABLE) + INST(SPIRVAsmOperandDebugPrintfSet, SPIRVAsmOperandDebugPrintfSet, 0, HOISTABLE) + // A string which is given a unique ID in the backend, used to refer to // results of other instrucions in the same asm block INST(SPIRVAsmOperandId, SPIRVAsmOperandId, 1, HOISTABLE) diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 86a7e2e04..1257b8971 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -4071,6 +4071,7 @@ public: IRSPIRVAsmOperand* emitSPIRVAsmOperandEnum(IRInst* inst, IRType* constantType); IRSPIRVAsmOperand* emitSPIRVAsmOperandBuiltinVar(IRInst* type, IRInst* builtinKind); IRSPIRVAsmOperand* emitSPIRVAsmOperandGLSL450Set(); + IRSPIRVAsmOperand* emitSPIRVAsmOperandDebugPrintfSet(); IRSPIRVAsmOperand* emitSPIRVAsmOperandSampledType(IRType* elementType); IRSPIRVAsmOperand* emitSPIRVAsmOperandImageType(IRInst* element); IRSPIRVAsmOperand* emitSPIRVAsmOperandSampledImageType(IRInst* element); diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index adac4cd10..833ce5bb5 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -5825,6 +5825,18 @@ namespace Slang return i; } + IRSPIRVAsmOperand* IRBuilder::emitSPIRVAsmOperandDebugPrintfSet() + { + SLANG_ASSERT(as<IRSPIRVAsm>(m_insertLoc.getParent())); + const auto i = createInst<IRSPIRVAsmOperand>( + this, + kIROp_SPIRVAsmOperandDebugPrintfSet, + getVoidType() + ); + addInst(i); + return i; + } + IRSPIRVAsmOperand* IRBuilder::emitSPIRVAsmOperandSampledType(IRType* elementType) { SLANG_ASSERT(as<IRSPIRVAsm>(m_insertLoc.getParent())); diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index e44419a45..206a47018 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -3932,6 +3932,10 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo> { return builder->emitSPIRVAsmOperandGLSL450Set(); } + case SPIRVAsmOperand::NonSemanticDebugPrintfExtSet: + { + return builder->emitSPIRVAsmOperandDebugPrintfSet(); + } case SPIRVAsmOperand::SlangValue: { IRInst* i; diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 52c91cfbe..10002ad97 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -6534,6 +6534,10 @@ namespace Slang { return SPIRVAsmOperand{ SPIRVAsmOperand::GLSL450Set, parser->ReadToken() }; } + else if (parser->LookAheadToken("debugPrintf")) + { + return SPIRVAsmOperand{ SPIRVAsmOperand::NonSemanticDebugPrintfExtSet, parser->ReadToken() }; + } // A regular identifier else if(parser->LookAheadToken(TokenType::Identifier)) { diff --git a/tests/spirv/debug-printf.slang b/tests/spirv/debug-printf.slang new file mode 100644 index 000000000..cf8bfafa3 --- /dev/null +++ b/tests/spirv/debug-printf.slang @@ -0,0 +1,11 @@ +//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage compute -entry main -emit-spirv-directly +//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage compute -entry main -emit-spirv-via-glsl + +void main() +{ + printf("test"); + printf("test1 %d", 5); + // CHECK: %[[SET:[0-9]+]] = OpExtInstImport "NonSemantic.DebugPrintf" + // CHECK: {{.*}} = OpExtInst %{{[a-zA-Z0-9_]+}} %[[SET]] 1 %{{[a-zA-Z0-9_]+}} + // CHECK: {{.*}} = OpExtInst %{{[a-zA-Z0-9_]+}} %[[SET]] 1 %{{[a-zA-Z0-9_]+}} %{{[a-zA-Z0-9_]+}} +} |
