summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/slang/hlsl.meta.slang106
-rw-r--r--source/slang/slang-ast-expr.h1
-rw-r--r--source/slang/slang-emit-spirv.cpp20
-rw-r--r--source/slang/slang-ir-inst-defs.h2
-rw-r--r--source/slang/slang-ir-insts.h1
-rw-r--r--source/slang/slang-ir.cpp12
-rw-r--r--source/slang/slang-lower-to-ir.cpp4
-rw-r--r--source/slang/slang-parser.cpp4
-rw-r--r--tests/spirv/debug-printf.slang11
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_]+}}
+}