From f521c2002e6b664944c6c39bab767dca1802887a Mon Sep 17 00:00:00 2001 From: cheneym2 Date: Fri, 4 Oct 2024 10:20:57 -0400 Subject: Add interfaces for retrieving separate linkable downstream binaries (#5128) * Implement separate downstream library interface Create a new com interface to house the methods for precompiling slang modules to target code. Add methods to count dependent modules and scrape them for downstream target binaries such that the downstream target binaries are linkabe outside of slang, e.g. via spirv-link or dxc. Fixes #5147 * Rename to _Experimental Clearly identify this as an interface subject to change. --- source/slang-record-replay/record/slang-module.cpp | 11 --- source/slang-record-replay/record/slang-module.h | 3 - source/slang/slang-compiler-tu.cpp | 80 ++++++++++++++++++++++ source/slang/slang-compiler.h | 38 +++++++++- source/slang/slang.cpp | 4 ++ 5 files changed, 121 insertions(+), 15 deletions(-) (limited to 'source') diff --git a/source/slang-record-replay/record/slang-module.cpp b/source/slang-record-replay/record/slang-module.cpp index 1ad04d4dc..5f624a2e0 100644 --- a/source/slang-record-replay/record/slang-module.cpp +++ b/source/slang-record-replay/record/slang-module.cpp @@ -213,17 +213,6 @@ namespace SlangRecord return res; } - SLANG_NO_THROW SlangResult ModuleRecorder::precompileForTarget( - SlangCompileTarget target, - ISlangBlob** outDiagnostics) - { - // TODO: We should record this call - // https://github.com/shader-slang/slang/issues/4853 - slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__); - SlangResult res = m_actualModule->precompileForTarget(target, outDiagnostics); - return res; - } - IEntryPointRecorder* ModuleRecorder::getEntryPointRecorder(slang::IEntryPoint* entryPoint) { IEntryPointRecorder* entryPointRecord = nullptr; diff --git a/source/slang-record-replay/record/slang-module.h b/source/slang-record-replay/record/slang-module.h index ce009eac8..2a22bd214 100644 --- a/source/slang-record-replay/record/slang-module.h +++ b/source/slang-record-replay/record/slang-module.h @@ -46,9 +46,6 @@ namespace SlangRecord virtual SLANG_NO_THROW SlangInt32 SLANG_MCALL getDependencyFileCount() override; virtual SLANG_NO_THROW char const* SLANG_MCALL getDependencyFilePath( SlangInt32 index) override; - virtual SLANG_NO_THROW SlangResult SLANG_MCALL precompileForTarget( - SlangCompileTarget target, - ISlangBlob** outDiagnostics) override; // Interfaces for `IComponentType` virtual SLANG_NO_THROW slang::ISession* SLANG_MCALL getSession() override diff --git a/source/slang/slang-compiler-tu.cpp b/source/slang/slang-compiler-tu.cpp index 57a1133fc..8ae06a419 100644 --- a/source/slang/slang-compiler-tu.cpp +++ b/source/slang/slang-compiler-tu.cpp @@ -210,7 +210,87 @@ namespace Slang builder.setInsertInto(module); builder.emitEmbeddedDownstreamIR(targetReq->getTarget(), blob); + return SLANG_OK; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL Module::getPrecompiledTargetCode( + SlangCompileTarget target, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) + { + SLANG_UNUSED(outDiagnostics); + for (auto globalInst : getIRModule()->getModuleInst()->getChildren()) + { + if (auto inst = as(globalInst)) + { + static_assert(CodeGenTarget::DXIL == static_cast(SLANG_DXIL)); + static_assert(CodeGenTarget::SPIRV == static_cast(SLANG_SPIRV)); + if (inst->getTarget() == static_cast(target)) + { + auto slice = inst->getBlob()->getStringSlice(); + auto blob = StringBlob::create(slice); + *outCode = blob.detach(); + return SLANG_OK; + } + } + } + return SLANG_FAIL; + } + + SLANG_NO_THROW SlangInt SLANG_MCALL Module::getModuleDependencyCount() + { + return 0; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL Module::getModuleDependency( + SlangInt dependencyIndex, + IModule** outModule, + slang::IBlob** outDiagnostics) + { + SLANG_UNUSED(dependencyIndex); + SLANG_UNUSED(outModule); + SLANG_UNUSED(outDiagnostics); + return SLANG_OK; + } + // ComponentType + + SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::precompileForTarget( + SlangCompileTarget target, + slang::IBlob** outDiagnostics) + { + SLANG_UNUSED(target); + SLANG_UNUSED(outDiagnostics); + return SLANG_FAIL; + } + + SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getPrecompiledTargetCode( + SlangCompileTarget target, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics) + { + SLANG_UNUSED(target); + SLANG_UNUSED(outCode); + SLANG_UNUSED(outDiagnostics); + return SLANG_FAIL; + } + + SLANG_NO_THROW SlangInt SLANG_MCALL ComponentType::getModuleDependencyCount() + { + return getModuleDependencies().getCount(); + } + + SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getModuleDependency( + SlangInt dependencyIndex, + slang::IModule** outModule, + slang::IBlob** outDiagnostics) + { + SLANG_UNUSED(outDiagnostics); + if (dependencyIndex < 0 || dependencyIndex >= getModuleDependencies().getCount()) + { + return SLANG_E_INVALID_ARG; + } + *outModule = getModuleDependencies()[dependencyIndex]; return SLANG_OK; } } diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 17501163f..7271c2e19 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -294,7 +294,7 @@ namespace Slang /// Base class for "component types" that represent the pieces a final /// shader program gets linked together from. /// - class ComponentType : public RefObject, public slang::IComponentType + class ComponentType : public RefObject, public slang::IComponentType, public slang::IModulePrecompileService_Experimental { public: // @@ -370,6 +370,27 @@ namespace Slang slang::CompilerOptionEntry* entries, ISlangBlob** outDiagnostics) override; + + // + // slang::IModulePrecompileService interface + // + SLANG_NO_THROW SlangResult SLANG_MCALL precompileForTarget( + SlangCompileTarget target, + slang::IBlob** outDiagnostics) SLANG_OVERRIDE; + + SLANG_NO_THROW SlangResult SLANG_MCALL getPrecompiledTargetCode( + SlangCompileTarget target, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics = nullptr) SLANG_OVERRIDE; + + SLANG_NO_THROW SlangInt SLANG_MCALL getModuleDependencyCount() + SLANG_OVERRIDE; + + SLANG_NO_THROW SlangResult SLANG_MCALL getModuleDependency( + SlangInt dependencyIndex, + slang::IModule** outModule, + slang::IBlob** outDiagnostics = nullptr) SLANG_OVERRIDE; + CompilerOptionSet& getOptionSet() { return m_optionSet; } /// Get the linkage (aka "session" in the public API) for this component type. @@ -1550,11 +1571,26 @@ namespace Slang virtual SLANG_NO_THROW char const* SLANG_MCALL getDependencyFilePath( SlangInt32 index) override; + + // IModulePrecompileService_Experimental /// Precompile TU to target language virtual SLANG_NO_THROW SlangResult SLANG_MCALL precompileForTarget( SlangCompileTarget target, slang::IBlob** outDiagnostics) override; + virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPrecompiledTargetCode( + SlangCompileTarget target, + slang::IBlob** outCode, + slang::IBlob** outDiagnostics = nullptr) override; + + virtual SLANG_NO_THROW SlangInt SLANG_MCALL getModuleDependencyCount() + SLANG_OVERRIDE; + + virtual SLANG_NO_THROW SlangResult SLANG_MCALL getModuleDependency( + SlangInt dependencyIndex, + slang::IModule** outModule, + slang::IBlob** outDiagnostics = nullptr) SLANG_OVERRIDE; + virtual void buildHash(DigestBuilder& builder) SLANG_OVERRIDE; virtual slang::DeclReflection* getModuleReflection() SLANG_OVERRIDE; diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index c9717272b..d0fe28185 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -4284,6 +4284,8 @@ ISlangUnknown* Module::getInterface(const Guid& guid) { if(guid == IModule::getTypeGuid()) return asExternal(this); + if (guid == IModulePrecompileService_Experimental::getTypeGuid()) + return static_cast(this); return Super::getInterface(guid); } @@ -4500,6 +4502,8 @@ ISlangUnknown* ComponentType::getInterface(Guid const& guid) { return static_cast(this); } + if(guid == IModulePrecompileService_Experimental::getTypeGuid()) + return static_cast(this); return nullptr; } -- cgit v1.2.3