From 313677160a186efebf83fab4df7d08dd119a5cd2 Mon Sep 17 00:00:00 2001 From: cheneym2 Date: Thu, 5 Sep 2024 14:59:28 -0400 Subject: Initial -embed-spirv support (#4974) * Initial -embed-spirv support Add support for SPIR-V precompilation using the framework established for DXIL. Work on #4883 * SLANG_UNUSED * Add linkage attributes to exported spirv functions * Combine DXIL and SPIRV paths * Whitespace fix * Merge remaining precompiled spirv/dxil paths * Change inst accessors to return codegentarget * Add unit test for precompiled spirv --------- Co-authored-by: Yong He --- source/slang/slang-compiler-tu.cpp | 29 +++++++------- source/slang/slang-compiler.cpp | 33 +++++++++------- source/slang/slang-compiler.h | 8 ++-- source/slang/slang-emit-spirv.cpp | 26 +++++++++++++ source/slang/slang-emit.cpp | 58 +++++++++++++++++----------- source/slang/slang-ir-inst-defs.h | 4 +- source/slang/slang-ir-insts.h | 16 +++++++- source/slang/slang-ir-redundancy-removal.cpp | 29 +++++++------- source/slang/slang-ir-redundancy-removal.h | 3 +- source/slang/slang-ir.cpp | 6 +-- source/slang/slang-options.cpp | 15 +++++-- source/slang/slang.cpp | 27 +++++++------ 12 files changed, 161 insertions(+), 93 deletions(-) (limited to 'source') diff --git a/source/slang/slang-compiler-tu.cpp b/source/slang/slang-compiler-tu.cpp index fe778148b..57a1133fc 100644 --- a/source/slang/slang-compiler-tu.cpp +++ b/source/slang/slang-compiler-tu.cpp @@ -54,7 +54,7 @@ namespace Slang * Precompile the module for the given target. * * This function creates a target program and emits the precompiled blob as - * an embedded blob in the module IR, e.g. DXIL. + * an embedded blob in the module IR, e.g. DXIL, SPIR-V. * Because the IR for the Slang Module may violate the restrictions of the * target language, the emitted target blob may not be able to include the * full module, but rather only the subset that can be precompiled. For @@ -77,7 +77,7 @@ namespace Slang * in the linked IR which survived the additional pruning. * * Functions that are rejected after linking+legalization (inside - * emitPrecompiled*): + * emitPrecompiledDownstreamIR): * - (DXIL) Functions that return or take a HLSLStructuredBufferType * - (DXIL) Functions that return or take a Matrix type * @@ -86,17 +86,13 @@ namespace Slang * phase of filtering. * * The original module IR functions matching those are then marked with - * "AvailableIn*" (e.g. AvailableInDXILDecoration) to indicate to future + * "AvailableInDownstreamIRDecoration" to indicate to future * module users which functions are present in the precompiled blob. */ SLANG_NO_THROW SlangResult SLANG_MCALL Module::precompileForTarget( SlangCompileTarget target, slang::IBlob** outDiagnostics) { - if (target != SLANG_DXIL) - { - return SLANG_FAIL; - } CodeGenTarget targetEnum = CodeGenTarget(target); auto module = getIRModule(); @@ -130,10 +126,15 @@ namespace Slang { case CodeGenTarget::DXIL: tp.getOptionSet().add(CompilerOptionName::Profile, Profile::RawEnum::DX_Lib_6_6); - tp.getOptionSet().add(CompilerOptionName::EmbedDXIL, true); break; + case CodeGenTarget::SPIRV: + break; + default: + return SLANG_FAIL; } + tp.getOptionSet().add(CompilerOptionName::EmbedDownstreamIR, true); + CodeGenContext::EntryPointIndices entryPointIndices; entryPointIndices.setCount(entryPointCount); @@ -166,7 +167,7 @@ namespace Slang } ComPtr outArtifact; - SlangResult res = codeGenContext.emitPrecompiledDXIL(outArtifact); + SlangResult res = codeGenContext.emitPrecompiledDownstreamIR(outArtifact); sink.getBlobIfNeeded(outDiagnostics); if (res != SLANG_OK) @@ -183,7 +184,8 @@ namespace Slang for (const auto& mangledName : metadata->getExportedFunctionMangledNames()) { auto moduleInst = nameToFunction[mangledName]; - builder.addDecoration(moduleInst, kIROp_AvailableInDXILDecoration); + builder.addDecoration(moduleInst, kIROp_AvailableInDownstreamIRDecoration, + builder.getIntValue(builder.getIntType(), (int)targetReq->getTarget())); auto moduleDec = moduleInst->findDecoration(); moduleDec->removeAndDeallocate(); } @@ -207,12 +209,7 @@ namespace Slang // Add the precompiled blob to the module builder.setInsertInto(module); - switch (targetReq->getTarget()) - { - case CodeGenTarget::DXIL: - builder.emitEmbeddedDXIL(blob); - break; - } + builder.emitEmbeddedDownstreamIR(targetReq->getTarget(), blob); return SLANG_OK; } diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index 7d2dbed0d..4bb420fa7 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -767,9 +767,9 @@ namespace Slang # pragma warning(pop) #endif - SlangResult CodeGenContext::emitPrecompiledDXIL(ComPtr& outArtifact) + SlangResult CodeGenContext::emitPrecompiledDownstreamIR(ComPtr& outArtifact) { - return emitWithDownstreamForEntryPoints(outArtifact); + return _emitEntryPoints(outArtifact); } String GetHLSLProfileName(Profile profile) @@ -1257,10 +1257,7 @@ namespace Slang { CodeGenContext sourceCodeGenContext(this, sourceTarget, extensionTracker); - if (target == CodeGenTarget::DXILAssembly || target == CodeGenTarget::DXIL) - { - sourceCodeGenContext.removeAvailableInDXIL = true; - } + sourceCodeGenContext.removeAvailableInDownstreamIR = true; SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(sourceArtifact)); sourceCodeGenContext.maybeDumpIntermediate(sourceArtifact); @@ -1561,20 +1558,23 @@ namespace Slang // Load embedded precompiled libraries from IR into library artifacts program->enumerateIRModules([&](IRModule* irModule) { - for (auto inst : irModule->getModuleInst()->getChildren()) + for (auto globalInst : irModule->getModuleInst()->getChildren()) { if (target == CodeGenTarget::DXILAssembly || target == CodeGenTarget::DXIL) { - if (inst->getOp() == kIROp_EmbeddedDXIL) + if (auto inst = as(globalInst)) { - auto slice = static_cast(inst->getOperand(0))->getStringSlice(); - ArtifactDesc desc = ArtifactDescUtil::makeDescForCompileTarget(SLANG_DXIL); - desc.kind = ArtifactKind::Library; + if (inst->getTarget() == CodeGenTarget::DXIL) + { + auto slice = inst->getBlob()->getStringSlice(); + ArtifactDesc desc = ArtifactDescUtil::makeDescForCompileTarget(SLANG_DXIL); + desc.kind = ArtifactKind::Library; - auto library = ArtifactUtil::createArtifact(desc); + auto library = ArtifactUtil::createArtifact(desc); - library->addRepresentationUnknown(StringBlob::create(slice)); - libraries.add(library); + library->addRepresentationUnknown(StringBlob::create(slice)); + libraries.add(library); + } } } } @@ -2030,7 +2030,7 @@ namespace Slang { if (auto artifact = targetProgram->getExistingWholeProgramResult()) { - if (!targetProgram->getOptionSet().getBoolOption(CompilerOptionName::EmbedDXIL)) + if (!targetProgram->getOptionSet().getBoolOption(CompilerOptionName::EmbedDownstreamIR)) { artifacts.add(ComPtr(artifact)); } @@ -2285,6 +2285,9 @@ namespace Slang auto linkage = getLinkage(); for (auto targetReq : linkage->targets) { + if (targetReq->getOptionSet().getBoolOption(CompilerOptionName::EmbedDownstreamIR)) + continue; + auto targetProgram = program->getTargetProgram(targetReq); generateOutput(targetProgram); } diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 267fdeaf5..b8ee4dc9c 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -2733,13 +2733,13 @@ namespace Slang SlangResult emitEntryPoints(ComPtr& outArtifact); - SlangResult emitPrecompiledDXIL(ComPtr& outArtifact); + SlangResult emitPrecompiledDownstreamIR(ComPtr& outArtifact); void maybeDumpIntermediate(IArtifact* artifact); - // Used to cause instructions available in precompiled DXIL to be + // Used to cause instructions available in precompiled blobs to be // removed between IR linking and target source generation. - bool removeAvailableInDXIL = false; + bool removeAvailableInDownstreamIR = false; protected: CodeGenTarget m_targetFormat = CodeGenTarget::Unknown; @@ -2816,7 +2816,7 @@ namespace Slang virtual SLANG_NO_THROW void SLANG_MCALL setTargetForceGLSLScalarBufferLayout(int targetIndex, bool value) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL setTargetForceDXLayout(int targetIndex, bool value) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL setTargetGenerateWholeProgram(int targetIndex, bool value) SLANG_OVERRIDE; - virtual SLANG_NO_THROW void SLANG_MCALL setEmbedDXIL(bool value) SLANG_OVERRIDE; + virtual SLANG_NO_THROW void SLANG_MCALL setTargetEmbedDownstreamIR(int targetIndex, bool value) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL setMatrixLayoutMode(SlangMatrixLayoutMode mode) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL setDebugInfoLevel(SlangDebugInfoLevel level) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL setOptimizationLevel(SlangOptimizationLevel level) SLANG_OVERRIDE; diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 9088e959a..a2da4801e 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -3933,6 +3933,17 @@ struct SPIRVEmitContext } break; } + case kIROp_DownstreamModuleExportDecoration: + { + requireSPIRVCapability(SpvCapabilityLinkage); + auto name = decoration->getParent()->findDecoration()->getMangledName(); + emitInst(getSection(SpvLogicalSectionID::Annotations), + decoration, + SpvOpDecorate, + dstID, + SpvDecorationLinkageAttributes, name, SpvLinkageTypeExport); + break; + } // ... } @@ -6847,12 +6858,27 @@ SlangResult emitSPIRVFromIR( #endif auto shouldPreserveParams = codeGenContext->getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::PreserveParameters); + auto generateWholeProgram = codeGenContext->getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::GenerateWholeProgram); for (auto inst : irModule->getGlobalInsts()) { if (as(inst)) + { context.ensureInst(inst); + } if (shouldPreserveParams && as(inst)) + { context.ensureInst(inst); + } + if (generateWholeProgram) + { + if (auto func = as(inst)) + { + if (func->findDecoration()) + { + context.ensureInst(inst); + } + } + } } // Emit source language info. diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index caa8ca8ea..ed9e90462 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -416,31 +416,47 @@ bool checkStaticAssert(IRInst* inst, DiagnosticSink* sink) return false; } -static void unexportNonEmbeddableDXIL(IRModule* irModule) +static void unexportNonEmbeddableIR(CodeGenTarget target, IRModule* irModule) { for (auto inst : irModule->getGlobalInsts()) { if (inst->getOp() == kIROp_Func) { - // DXIL does not permit HLSLStructureBufferType in exported functions - // or sadly Matrices (https://github.com/shader-slang/slang/issues/4880) - auto type = as(inst->getFullType()); - auto argCount = type->getOperandCount(); - for (UInt aa = 0; aa < argCount; ++aa) + bool remove = false; + if (target == CodeGenTarget::HLSL) { - auto operand = type->getOperand(aa); - if (operand->getOp() == kIROp_HLSLStructuredBufferType || - operand->getOp() == kIROp_MatrixType) + // DXIL does not permit HLSLStructureBufferType in exported functions + // or sadly Matrices (https://github.com/shader-slang/slang/issues/4880) + auto type = as(inst->getFullType()); + auto argCount = type->getOperandCount(); + for (UInt aa = 0; aa < argCount; ++aa) { - if (auto dec = inst->findDecoration()) + auto operand = type->getOperand(aa); + if (operand->getOp() == kIROp_HLSLStructuredBufferType || + operand->getOp() == kIROp_MatrixType) { - dec->removeAndDeallocate(); + remove = true; + break; } - if (auto dec = inst->findDecoration()) - { - dec->removeAndDeallocate(); - } - break; + } + } + else if (target == CodeGenTarget::SPIRV) + { + // SPIR-V does not allow exporting entry points + if (inst->findDecoration()) + { + remove = true; + } + } + if (remove) + { + if (auto dec = inst->findDecoration()) + { + dec->removeAndDeallocate(); + } + if (auto dec = inst->findDecoration()) + { + dec->removeAndDeallocate(); } } } @@ -778,9 +794,9 @@ Result linkAndOptimizeIR( break; } - if (codeGenContext->removeAvailableInDXIL) + if (codeGenContext->removeAvailableInDownstreamIR) { - removeAvailableInDownstreamModuleDecorations(irModule); + removeAvailableInDownstreamModuleDecorations(target, irModule); } if (targetProgram->getOptionSet().shouldRunNonEssentialValidation()) @@ -1490,11 +1506,9 @@ Result linkAndOptimizeIR( auto metadata = new ArtifactPostEmitMetadata; outLinkedIR.metadata = metadata; - if (targetProgram->getOptionSet().getBoolOption(CompilerOptionName::EmbedDXIL)) + if (targetProgram->getOptionSet().getBoolOption(CompilerOptionName::EmbedDownstreamIR)) { - // We need to make sure that we don't try to export any functions that can't - // be part of a DXIL library interface, eg. with resources. - unexportNonEmbeddableDXIL(irModule); + unexportNonEmbeddableIR(target, irModule); } collectMetadata(irModule, *metadata); diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index 5afca48b3..afc09f480 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -806,7 +806,7 @@ INST_RANGE(BindingQuery, GetRegisterIndex, GetRegisterSpace) INST(NumThreadsDecoration, numThreads, 3, 0) INST(WaveSizeDecoration, waveSize, 1, 0) - INST(AvailableInDXILDecoration, availableInDXIL, 0, 0) + INST(AvailableInDownstreamIRDecoration, availableInDownstreamIR, 1, 0) // Added to IRParam parameters to an entry point /* GeometryInputPrimitiveTypeDecoration */ @@ -1244,7 +1244,7 @@ INST(DebugVar, DebugVar, 4, 0) INST(DebugValue, DebugValue, 2, 0) /* Embedded Precompiled Libraries */ -INST(EmbeddedDXIL, EmbeddedDXIL, 1, 0) +INST(EmbeddedDownstreamIR, EmbeddedDownstreamIR, 2, 0) /* Inline assembly */ diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index fc963697a..a0ed8ff0e 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -432,9 +432,14 @@ IR_SIMPLE_DECORATION(NonCopyableTypeDecoration) IR_SIMPLE_DECORATION(HLSLMeshPayloadDecoration) IR_SIMPLE_DECORATION(GlobalInputDecoration) IR_SIMPLE_DECORATION(GlobalOutputDecoration) -IR_SIMPLE_DECORATION(AvailableInDXILDecoration) IR_SIMPLE_DECORATION(DownstreamModuleExportDecoration) +struct IRAvailableInDownstreamIRDecoration : IRDecoration +{ + IR_LEAF_ISA(AvailableInDownstreamIRDecoration) + CodeGenTarget getTarget() { return static_cast(cast(getOperand(0))->getValue()); } +}; + struct IRGLSLLocationDecoration : IRDecoration { IR_LEAF_ISA(GLSLLocationDecoration) @@ -3340,6 +3345,13 @@ struct IRStaticAssert : IRInst IR_LEAF_ISA(StaticAssert) }; +struct IREmbeddedDownstreamIR : IRInst +{ + IR_LEAF_ISA(EmbeddedDownstreamIR) + CodeGenTarget getTarget() { return static_cast(cast(getOperand(0))->getValue()); } + IRBlobLit* getBlob() { return cast(getOperand(1)); } +}; + struct IRBuilderSourceLocRAII; struct IRBuilder @@ -4053,7 +4065,7 @@ public: IRInst* emitByteAddressBufferStore(IRInst* byteAddressBuffer, IRInst* offset, IRInst* value); IRInst* emitByteAddressBufferStore(IRInst* byteAddressBuffer, IRInst* offset, IRInst* alignment, IRInst* value); - IRInst* emitEmbeddedDXIL(ISlangBlob* blob); + IRInst* emitEmbeddedDownstreamIR(CodeGenTarget target, ISlangBlob* blob); IRFunc* createFunc(); IRGlobalVar* createGlobalVar( diff --git a/source/slang/slang-ir-redundancy-removal.cpp b/source/slang/slang-ir-redundancy-removal.cpp index 038412fbf..79b88ebcf 100644 --- a/source/slang/slang-ir-redundancy-removal.cpp +++ b/source/slang/slang-ir-redundancy-removal.cpp @@ -159,26 +159,29 @@ bool removeRedundancyInFunc(IRGlobalValueWithCode* func) return result; } -// Remove IR definitions from all [AvailableInDXIL] functions when compiling DXIL, -// as these functions are already defined in the embedded precompiled DXIL library. -void removeAvailableInDownstreamModuleDecorations(IRModule* module) +// Remove IR definitions from all AvailableInDownstreamIR functions where the +// languages match what we're currently targetting, as these functions are +// already defined in the embedded precompiled library. +void removeAvailableInDownstreamModuleDecorations(CodeGenTarget target, IRModule* module) { List toRemove; for (auto globalInst : module->getGlobalInsts()) { - auto funcInst = as(globalInst); - if (!funcInst) + if (auto funcInst = as(globalInst)) { - continue; - } - if (globalInst->findDecoration()) - { - // Gut the function definition, turning it into a declaration - for (auto inst : funcInst->getChildren()) + if (auto dec = globalInst->findDecoration()) { - if (inst->getOp() == kIROp_Block) + if ((dec->getTarget() == CodeGenTarget::DXIL && target == CodeGenTarget::HLSL) || + (dec->getTarget() == target)) { - toRemove.add(inst); + // Gut the function definition, turning it into a declaration + for (auto inst : funcInst->getChildren()) + { + if (inst->getOp() == kIROp_Block) + { + toRemove.add(inst); + } + } } } } diff --git a/source/slang/slang-ir-redundancy-removal.h b/source/slang/slang-ir-redundancy-removal.h index 117f52708..8b006c683 100644 --- a/source/slang/slang-ir-redundancy-removal.h +++ b/source/slang/slang-ir-redundancy-removal.h @@ -1,5 +1,6 @@ // slang-ir-redundancy-removal.h #pragma once +#include "slang-compiler.h" namespace Slang { @@ -11,5 +12,5 @@ namespace Slang bool eliminateRedundantLoadStore(IRGlobalValueWithCode* func); - void removeAvailableInDownstreamModuleDecorations(IRModule* module); + void removeAvailableInDownstreamModuleDecorations(CodeGenTarget target, IRModule* module); } diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index d02c01105..9305d1783 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -3863,11 +3863,11 @@ namespace Slang return nullptr; } - IRInst* IRBuilder::emitEmbeddedDXIL(ISlangBlob *blob) + IRInst* IRBuilder::emitEmbeddedDownstreamIR(CodeGenTarget target, ISlangBlob *blob) { - IRInst* args[] = { getBlobValue(blob) }; + IRInst* args[] = { getIntValue(getIntType(), (int)target), getBlobValue(blob) }; - return emitIntrinsicInst(getVoidType(), kIROp_EmbeddedDXIL, 1, args); + return emitIntrinsicInst(getVoidType(), kIROp_EmbeddedDownstreamIR, 2, args); } enum class TypeCastStyle diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index f12a66790..c02a00957 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -354,8 +354,6 @@ void initCommandOptions(CommandOptions& options) { OptionKind::DisableShortCircuit, "-disable-short-circuit", nullptr, "Disable short-circuiting for \"&&\" and \"||\" operations" }, { OptionKind::UnscopedEnum, "-unscoped-enum", nullptr, "Treat enums types as unscoped by default."}, { OptionKind::PreserveParameters, "-preserve-params", nullptr, "Preserve all resource parameters in the output code, even if they are not used by the shader."}, - { OptionKind::EmbedDXIL, "-embed-dxil", nullptr, - "Embed DXIL into emitted slang-modules for faster linking" }, }; _addOptions(makeConstArrayView(generalOpts), options); @@ -431,6 +429,7 @@ void initCommandOptions(CommandOptions& options) "A path to a specific spirv.core.grammar.json to use when generating SPIR-V output" }, { OptionKind::IncompleteLibrary, "-incomplete-library", nullptr, "Allow generating code from incomplete libraries with unresolved external functions" }, + { OptionKind::EmbedDownstreamIR, "-embed-downstream-ir", nullptr, "Embed downstream IR into emitted slang IR" }, }; _addOptions(makeConstArrayView(targetOpts), options); @@ -1931,7 +1930,11 @@ SlangResult OptionsParser::_parse( linkage->m_optionSet.set(optionKind, compressionType); break; } - case OptionKind::EmbedDXIL: m_compileRequest->setEmbedDXIL(true); break; + case OptionKind::EmbedDownstreamIR: + { + getCurrentTarget()->optionSet.add(CompilerOptionName::EmbedDownstreamIR, true); + break; + } case OptionKind::Target: { CommandLineArg name; @@ -2778,6 +2781,12 @@ SlangResult OptionsParser::_parse( { m_compileRequest->setTargetGenerateWholeProgram(targetID, true); } + + if (rawTarget.optionSet.getBoolOption(CompilerOptionName::EmbedDownstreamIR)) + { + m_compileRequest->setTargetEmbedDownstreamIR(targetID, true); + } + } // Next we need to sort out the output files specified with `-o`, and diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index b0898b1a0..91ed3de5f 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -3305,18 +3305,21 @@ SlangResult EndToEndCompileRequest::executeActionsInner() return SLANG_OK; } - // If requested, attempt to compile the translation unit all the way down to the target language - // and stash the result blob in an IR op. - if (getOptionSet().getBoolOption(CompilerOptionName::EmbedDXIL)) + // If requested, attempt to compile the translation unit all the way down to the target language(s) + // and stash the result blobs in IR. + for (auto target : getLinkage()->targets) { - auto frontEndReq = getFrontEndReq(); - - for (auto translationUnit : frontEndReq->translationUnits) + SlangCompileTarget targetEnum = SlangCompileTarget(target->getTarget()); + if (target->getOptionSet().getBoolOption(CompilerOptionName::EmbedDownstreamIR)) { - SlangCompileTarget target = SlangCompileTarget(SlangCompileTarget::SLANG_DXIL); - SLANG_RETURN_ON_FAIL(translationUnit->getModule()->precompileForTarget( - target, - nullptr)); + auto frontEndReq = getFrontEndReq(); + + for (auto translationUnit : frontEndReq->translationUnits) + { + SLANG_RETURN_ON_FAIL(translationUnit->getModule()->precompileForTarget( + targetEnum, + nullptr)); + } } } @@ -5939,9 +5942,9 @@ void EndToEndCompileRequest::setTargetGenerateWholeProgram(int targetIndex, bool getTargetOptionSet(targetIndex).set(CompilerOptionName::GenerateWholeProgram, value); } -void EndToEndCompileRequest::setEmbedDXIL(bool value) +void EndToEndCompileRequest::setTargetEmbedDownstreamIR(int targetIndex, bool value) { - getOptionSet().set(CompilerOptionName::EmbedDXIL, value); + getTargetOptionSet(targetIndex).set(CompilerOptionName::EmbedDownstreamIR, value); } void EndToEndCompileRequest::setTargetLineDirectiveMode( -- cgit v1.2.3