diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 63 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 20 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 21 | ||||
| -rw-r--r-- | source/slang/slang-emit-spirv.cpp | 21 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-ir-insts.h | 5 | ||||
| -rw-r--r-- | source/slang/slang-ir-legalize-types.cpp | 28 |
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: |
