summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-10-17 22:22:34 -0700
committerGitHub <noreply@github.com>2024-10-17 22:22:34 -0700
commit12e891ed9ac934adbcc4160da6a05938cc38b529 (patch)
treea519a57b0e7a53c17f47bf43989a51e88f911f66 /source
parenta618b8c5e249b0f20e6c0c95f9da1b5cbfdbf08b (diff)
Cleanup definition of `printf`. (#5330)
* Cleanup definition of `printf`. * Fix. * Fix spirv generation. * Fix. * enhance test.
Diffstat (limited to 'source')
-rw-r--r--source/slang/hlsl.meta.slang63
-rw-r--r--source/slang/slang-emit-c-like.cpp20
-rw-r--r--source/slang/slang-emit-glsl.cpp21
-rw-r--r--source/slang/slang-emit-spirv.cpp21
-rw-r--r--source/slang/slang-ir-inst-defs.h1
-rw-r--r--source/slang/slang-ir-insts.h5
-rw-r--r--source/slang/slang-ir-legalize-types.cpp28
7 files changed, 113 insertions, 46 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 1c01c2f6b..ed011320c 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -10788,53 +10788,24 @@ vector<T, N> powr(vector<T, N> x, vector<T, N> y)
// Output message
// TODO: add check to ensure format is const literal.
-${{{{
-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)
+/// Print a message to the debug output.
+/// @param T The variadic type pack parameter for the arguments to be printed.
+/// @param format The format string.
+/// @param args (optional) The arguments to be printed.
+/// @remarks The function maps to `printf` for HLSL, CPU and CUDA targets, and maps to `OpDebugPrintf` for SPIR-V target,
+/// and maps to `debugPrintfEXT` for GLSL target. Depending on the target and execution environment, the function may have
+/// no effect.
+/// @example
+/// ```cpp
+/// void test(int x, float y)
+/// {
+/// printf("hello world!\n");
+/// printf(R"(x = "%d", y = "%f")", x, y);
+/// }
+/// ```
[require(cpp_cuda_glsl_hlsl_spirv, printf)]
-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);
- };
- }
-}
-${{{{
-}
-}}}}
+__intrinsic_op($(kIROp_Printf))
+void printf<each T>(NativeString format, expand each T args);
// Tessellation factor fixup routines
/// @category tessellation Tessellation functions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index 79a9b1a56..dd5cb88d3 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -2847,6 +2847,26 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
}
break;
}
+ case kIROp_Printf:
+ {
+ m_writer->emit("printf(");
+ emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
+ if (inst->getOperandCount() == 2)
+ {
+ auto operand = inst->getOperand(1);
+ if (auto makeStruct = as<IRMakeStruct>(operand))
+ {
+ // Flatten the tuple resulting from the variadic pack.
+ for (UInt bb = 0; bb < makeStruct->getOperandCount(); ++bb)
+ {
+ m_writer->emit(", ");
+ emitOperand(makeStruct->getOperand(bb), getInfo(EmitOp::General));
+ }
+ }
+ }
+ m_writer->emit(")");
+ break;
+ }
case kIROp_RequireGLSLExtension:
{
break; //should already have set requirement; case covered for empty intrinsic block
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index 7f8bc14b4..3ba967e20 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -2146,6 +2146,27 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
m_writer->emit("endInvocationInterlockARB()");
return true;
}
+ case kIROp_Printf:
+ {
+ m_glslExtensionTracker->requireExtension(toSlice("GL_EXT_debug_printf"));
+ m_writer->emit("debugPrintfEXT(");
+ emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
+ if (inst->getOperandCount() == 2)
+ {
+ auto operand = inst->getOperand(1);
+ if (auto makeStruct = as<IRMakeStruct>(operand))
+ {
+ // Flatten the tuple resulting from the variadic pack.
+ for (UInt bb = 0; bb < makeStruct->getOperandCount(); ++bb)
+ {
+ m_writer->emit(", ");
+ emitOperand(makeStruct->getOperand(bb), getInfo(EmitOp::General));
+ }
+ }
+ }
+ m_writer->emit(")");
+ return true;
+ }
default: break;
}
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 62819e6d5..321c547be 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -3426,6 +3426,27 @@ struct SPIRVEmitContext
emitInst(parent, inst, SpvOpControlBarrier, executionScope, memoryScope, memorySemantics);
}
break;
+ case kIROp_Printf:
+ {
+ List<IRInst*> operands;
+ operands.add(inst->getOperand(0));
+ if (inst->getOperandCount() == 2)
+ {
+ auto operand = inst->getOperand(1);
+ if (auto makeStruct = as<IRMakeStruct>(operand))
+ {
+ // Flatten the tuple resulting from the variadic pack.
+ for (UInt bb = 0; bb < makeStruct->getOperandCount(); ++bb)
+ {
+ operands.add(makeStruct->getOperand(bb));
+ }
+ }
+ }
+ ensureExtensionDeclaration(toSlice("SPV_KHR_non_semantic_info"));
+ result = emitInst(parent, inst, SpvOpExtInst, inst->getFullType(), kResultID,
+ getNonSemanticDebugPrintfExtInst(), SpvLiteralInteger::from32(1), operands.getArrayView());
+ }
+ break;
}
if (result)
emitDecorations(inst, getID(result));
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index dc4f7dff4..7fe521486 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -649,6 +649,7 @@ INST(RequirePrelude, RequirePrelude, 1, 0)
INST(RequireGLSLExtension, RequireGLSLExtension, 1, 0)
INST(RequireComputeDerivative, RequireComputeDerivative, 0, 0)
INST(StaticAssert, StaticAssert, 2, 0)
+INST(Printf, Printf, 1, 0)
// TODO: We should consider splitting the basic arithmetic/comparison
// ops into cases for signed integers, unsigned integers, and floating-point
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index eef9b86bc..fc8bf99d0 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -2930,6 +2930,11 @@ struct IRMakeValuePack : IRInst
IR_LEAF_ISA(MakeValuePack)
};
+struct IRMakeStruct : IRInst
+{
+ IR_LEAF_ISA(MakeStruct)
+};
+
struct IRMakeWitnessPack : IRInst
{
IR_LEAF_ISA(MakeWitnessPack)
diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp
index 4d7759881..073b7216b 100644
--- a/source/slang/slang-ir-legalize-types.cpp
+++ b/source/slang/slang-ir-legalize-types.cpp
@@ -817,6 +817,31 @@ static LegalVal legalizeLoad(
}
}
+static LegalVal legalizePrintf(IRTypeLegalizationContext* context, ArrayView<LegalVal> args)
+{
+ ShortList<IRInst*> legalArgs;
+ for (auto arg : args)
+ {
+ switch (arg.flavor)
+ {
+ case LegalVal::Flavor::none:
+ break;
+ case LegalVal::Flavor::simple:
+ legalArgs.add(arg.getSimple());
+ break;
+ case LegalVal::Flavor::pair:
+ legalArgs.add(arg.getPair()->ordinaryVal.getSimple());
+ break;
+ default:
+ SLANG_UNIMPLEMENTED_X("Unknown legalized val flavor for printf operand");
+ }
+ }
+ return LegalVal::simple(context->builder->emitIntrinsicInst(context->builder->getVoidType(),
+ kIROp_Printf,
+ (UInt)legalArgs.getCount(),
+ legalArgs.getArrayView().getBuffer()));
+}
+
static LegalVal legalizeDebugVar(IRTypeLegalizationContext* context, LegalType type, IRDebugVar* originalInst)
{
// For now we just discard any special part and keep the ordinary part.
@@ -2167,6 +2192,9 @@ static LegalVal legalizeInst(
case kIROp_loop:
result = legalizeUnconditionalBranch(context, args, (IRUnconditionalBranch*)inst);
break;
+ case kIROp_Printf:
+ result = legalizePrintf(context, args);
+ break;
case kIROp_undefined:
return LegalVal();
case kIROp_GpuForeach: