summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorcheneym2 <acheney@nvidia.com>2024-09-05 14:59:28 -0400
committerGitHub <noreply@github.com>2024-09-05 11:59:28 -0700
commit313677160a186efebf83fab4df7d08dd119a5cd2 (patch)
treee12e159846f0b7b0e3567d028ad4a57cd9f001aa /source/slang
parent33e8bfd43f66613f6f834fb0e1816ef43071f2e4 (diff)
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 <yonghe@outlook.com>
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-compiler-tu.cpp29
-rw-r--r--source/slang/slang-compiler.cpp33
-rwxr-xr-xsource/slang/slang-compiler.h8
-rw-r--r--source/slang/slang-emit-spirv.cpp26
-rw-r--r--source/slang/slang-emit.cpp58
-rw-r--r--source/slang/slang-ir-inst-defs.h4
-rw-r--r--source/slang/slang-ir-insts.h16
-rw-r--r--source/slang/slang-ir-redundancy-removal.cpp29
-rw-r--r--source/slang/slang-ir-redundancy-removal.h3
-rw-r--r--source/slang/slang-ir.cpp6
-rw-r--r--source/slang/slang-options.cpp15
-rw-r--r--source/slang/slang.cpp27
12 files changed, 161 insertions, 93 deletions
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<IArtifact> 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<IRDownstreamModuleExportDecoration>();
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<IArtifact>& outArtifact)
+ SlangResult CodeGenContext::emitPrecompiledDownstreamIR(ComPtr<IArtifact>& 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<IREmbeddedDownstreamIR>(globalInst))
{
- auto slice = static_cast<IRBlobLit*>(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<IArtifact>(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<IArtifact>& outArtifact);
- SlangResult emitPrecompiledDXIL(ComPtr<IArtifact>& outArtifact);
+ SlangResult emitPrecompiledDownstreamIR(ComPtr<IArtifact>& 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<IRExportDecoration>()->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<IRDebugSource>(inst))
+ {
context.ensureInst(inst);
+ }
if (shouldPreserveParams && as<IRGlobalParam>(inst))
+ {
context.ensureInst(inst);
+ }
+ if (generateWholeProgram)
+ {
+ if (auto func = as<IRFunc>(inst))
+ {
+ if (func->findDecoration<IRDownstreamModuleExportDecoration>())
+ {
+ 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<IRFuncType>(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<IRFuncType>(inst->getFullType());
+ auto argCount = type->getOperandCount();
+ for (UInt aa = 0; aa < argCount; ++aa)
{
- if (auto dec = inst->findDecoration<IRPublicDecoration>())
+ auto operand = type->getOperand(aa);
+ if (operand->getOp() == kIROp_HLSLStructuredBufferType ||
+ operand->getOp() == kIROp_MatrixType)
{
- dec->removeAndDeallocate();
+ remove = true;
+ break;
}
- if (auto dec = inst->findDecoration<IRDownstreamModuleExportDecoration>())
- {
- dec->removeAndDeallocate();
- }
- break;
+ }
+ }
+ else if (target == CodeGenTarget::SPIRV)
+ {
+ // SPIR-V does not allow exporting entry points
+ if (inst->findDecoration<IREntryPointDecoration>())
+ {
+ remove = true;
+ }
+ }
+ if (remove)
+ {
+ if (auto dec = inst->findDecoration<IRPublicDecoration>())
+ {
+ dec->removeAndDeallocate();
+ }
+ if (auto dec = inst->findDecoration<IRDownstreamModuleExportDecoration>())
+ {
+ 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<CodeGenTarget>(cast<IRIntLit>(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<CodeGenTarget>(cast<IRIntLit>(getOperand(0))->getValue()); }
+ IRBlobLit* getBlob() { return cast<IRBlobLit>(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<IRInst*> toRemove;
for (auto globalInst : module->getGlobalInsts())
{
- auto funcInst = as<IRFunc>(globalInst);
- if (!funcInst)
+ if (auto funcInst = as<IRFunc>(globalInst))
{
- continue;
- }
- if (globalInst->findDecoration<IRAvailableInDXILDecoration>())
- {
- // Gut the function definition, turning it into a declaration
- for (auto inst : funcInst->getChildren())
+ if (auto dec = globalInst->findDecoration<IRAvailableInDownstreamIRDecoration>())
{
- 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(