diff options
Diffstat (limited to 'source/slang/slang-emit.cpp')
| -rw-r--r-- | source/slang/slang-emit.cpp | 63 |
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; |
