summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-emit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-emit.cpp')
-rw-r--r--source/slang/slang-emit.cpp63
1 files changed, 62 insertions, 1 deletions
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index ddb4ea67a..94ea66d71 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -2093,10 +2093,71 @@ SlangResult emitSPIRVForEntryPointsDirectly(
if (compiler)
{
#if 0
- // Dump the unoptimized SPIRV after lowering from slang IR -> SPIRV
+ // Dump the unoptimized/unlinked SPIRV after lowering from slang IR -> SPIRV
compiler->disassemble((uint32_t*)spirv.getBuffer(), int(spirv.getCount() / 4));
#endif
+ bool isPrecompilation = codeGenContext->getTargetProgram()->getOptionSet().getBoolOption(
+ CompilerOptionName::EmbedDownstreamIR);
+
+ if (!isPrecompilation && !codeGenContext->shouldSkipDownstreamLinking())
+ {
+ ComPtr<IArtifact> linkedArtifact;
+
+ // collect spirv files
+ List<uint32_t*> spirvFiles;
+ List<uint32_t> spirvSizes;
+
+ // Start with the SPIR-V we just generated.
+ // SPIRV-Tools-link expects the size in 32-bit words
+ // whereas the spirv blob size is in bytes.
+ spirvFiles.add((uint32_t*)spirv.getBuffer());
+ spirvSizes.add(int(spirv.getCount()) / 4);
+
+ // Iterate over all modules in the linkedIR. For each module, if it
+ // contains an embedded downstream ir instruction, add it to the list
+ // of spirv files.
+ auto program = codeGenContext->getProgram();
+
+ program->enumerateIRModules(
+ [&](IRModule* irModule)
+ {
+ for (auto globalInst : irModule->getModuleInst()->getChildren())
+ {
+ if (auto inst = as<IREmbeddedDownstreamIR>(globalInst))
+ {
+ if (inst->getTarget() == CodeGenTarget::SPIRV)
+ {
+ auto slice = inst->getBlob()->getStringSlice();
+ spirvFiles.add((uint32_t*)slice.begin());
+ spirvSizes.add(int(slice.getLength()) / 4);
+ }
+ }
+ }
+ });
+
+ SLANG_ASSERT(int(spirv.getCount()) % 4 == 0);
+ SLANG_ASSERT(spirvFiles.getCount() == spirvSizes.getCount());
+
+ if (spirvFiles.getCount() > 1)
+ {
+ SlangResult linkresult = compiler->link(
+ (const uint32_t**)spirvFiles.getBuffer(),
+ (const uint32_t*)spirvSizes.getBuffer(),
+ (uint32_t)spirvFiles.getCount(),
+ linkedArtifact.writeRef());
+
+ if (linkresult != SLANG_OK)
+ {
+ return SLANG_FAIL;
+ }
+
+ ComPtr<ISlangBlob> blob;
+ linkedArtifact->loadBlob(ArtifactKeep::No, blob.writeRef());
+ artifact = _Move(linkedArtifact);
+ }
+ }
+
if (!codeGenContext->shouldSkipSPIRVValidation())
{
StringBuilder runSpirvValEnvVar;