diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-12-12 14:53:44 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-12-12 14:53:44 -0500 |
| commit | 15335549340c54fd7b89b28104ddc907e9c64638 (patch) | |
| tree | 02c4705fc7784c3003d14fc661894b5f88c05875 /source | |
| parent | 6e6a876a6b5ad3d2ef402757d2e20641f5a2b49b (diff) | |
Use DownstreamCompiler for all downstream compilers (#1152)
* CPPCompiler -> DownstreamCompiler
* Added DownstreamCompileResult to start abstraction such that we don't need files.
* * Split out slang-blob.cpp
* Made CompileResult hold a DownstreamCompileResult - for access to binary or ISlangSharedLibrary
* Keep temporary files in scope.
* Add a hash to the hex dump stream.
* Move all file tracking into DownstreamCompiler.
* WIP support for nvrtc.
* WIP: Adding support for nvrtc compiler.
Adding enum types, wiring up the nvrtc into slang.
* Fix remaining CPPCompiler references.
* Fix order issue on target string matching.
* Use ISlangSharedLibrary for nvrtc.
* Use DownstreamCompiler for nvrtc.
* WIP first pass at compilation win nvrtc.
* Added testing if file is on file system into CommandLineDownstreamCompiler.
Added sourceContentsPath.
* Make test cuda-compile.cu work by just compiling not comparing output.
* Genearlize DownstreamCompiler usage.
* Fix warning on clang.
* Remove CompilerType from DownstreamCompiler.
* Use DownstreamCompiler interface for all compilers.
NOTE for FXC, DXC and GLSLANG this doesn't mean using 'compile' - it's still extracting functions from shared library.
* Fix compiling on gcc/clang for DownstreamCompiler.
* Fix problem on non-vc builds with not having return on locateCompilers for VS.
* Change so no warning for code not reachable on locateCompilers for vs.
Diffstat (limited to 'source')
| -rw-r--r-- | source/core/slang-downstream-compiler.cpp | 196 | ||||
| -rw-r--r-- | source/core/slang-downstream-compiler.h | 69 | ||||
| -rw-r--r-- | source/core/slang-gcc-compiler-util.cpp | 49 | ||||
| -rw-r--r-- | source/core/slang-gcc-compiler-util.h | 8 | ||||
| -rw-r--r-- | source/core/slang-nvrtc-compiler.cpp | 21 | ||||
| -rw-r--r-- | source/core/slang-nvrtc-compiler.h | 3 | ||||
| -rw-r--r-- | source/core/slang-shared-library.cpp | 78 | ||||
| -rw-r--r-- | source/core/slang-shared-library.h | 53 | ||||
| -rw-r--r-- | source/core/slang-visual-studio-compiler-util.cpp | 20 | ||||
| -rw-r--r-- | source/core/slang-visual-studio-compiler-util.h | 2 | ||||
| -rw-r--r-- | source/core/windows/slang-win-visual-studio-util.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-check.cpp | 199 | ||||
| -rw-r--r-- | source/slang/slang-compiler.cpp | 76 | ||||
| -rw-r--r-- | source/slang/slang-compiler.h | 37 | ||||
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-dxc-support.cpp | 11 | ||||
| -rw-r--r-- | source/slang/slang-emit.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 90 |
18 files changed, 448 insertions, 470 deletions
diff --git a/source/core/slang-downstream-compiler.cpp b/source/core/slang-downstream-compiler.cpp index 9532cf17f..6ce526ef0 100644 --- a/source/core/slang-downstream-compiler.cpp +++ b/source/core/slang-downstream-compiler.cpp @@ -9,8 +9,7 @@ #include "slang-shared-library.h" #include "slang-blob.h" -// if Visual Studio import the visual studio platform specific header -#if SLANG_VC +#ifdef SLANG_VC # include "windows/slang-win-visual-studio-util.h" #endif @@ -26,10 +25,15 @@ namespace Slang void DownstreamCompiler::Desc::appendAsText(StringBuilder& out) const { out << getCompilerTypeAsText(type); - out << " "; - out << majorVersion; - out << "."; - out << minorVersion; + + // Append the version if there is a version + if (majorVersion || minorVersion) + { + out << " "; + out << majorVersion; + out << "."; + out << minorVersion; + } } /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamDiagnostic !!!!!!!!!!!!!!!!!!!!!!!!*/ @@ -47,18 +51,19 @@ void DownstreamCompiler::Desc::appendAsText(StringBuilder& out) const /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamCompiler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ -/* static */UnownedStringSlice DownstreamCompiler::getCompilerTypeAsText(CompilerType type) +/* static */UnownedStringSlice DownstreamCompiler::getCompilerTypeAsText(SlangPassThrough type) { switch (type) { default: - case CompilerType::Unknown: return UnownedStringSlice::fromLiteral("Unknown"); - case CompilerType::VisualStudio:return UnownedStringSlice::fromLiteral("Visual Studio"); - case CompilerType::GCC: return UnownedStringSlice::fromLiteral("GCC"); - case CompilerType::Clang: return UnownedStringSlice::fromLiteral("Clang"); - case CompilerType::SNC: return UnownedStringSlice::fromLiteral("SNC"); - case CompilerType::GHS: return UnownedStringSlice::fromLiteral("GHS"); - case CompilerType::NVRTC: return UnownedStringSlice::fromLiteral("NVRTC"); + case SLANG_PASS_THROUGH_NONE: return UnownedStringSlice::fromLiteral("Unknown"); + case SLANG_PASS_THROUGH_VISUAL_STUDIO: return UnownedStringSlice::fromLiteral("Visual Studio"); + case SLANG_PASS_THROUGH_GCC: return UnownedStringSlice::fromLiteral("GCC"); + case SLANG_PASS_THROUGH_CLANG: return UnownedStringSlice::fromLiteral("Clang"); + case SLANG_PASS_THROUGH_NVRTC: return UnownedStringSlice::fromLiteral("NVRTC"); + case SLANG_PASS_THROUGH_FXC: return UnownedStringSlice::fromLiteral("fxc"); + case SLANG_PASS_THROUGH_DXC: return UnownedStringSlice::fromLiteral("dxc"); + case SLANG_PASS_THROUGH_GLSLANG: return UnownedStringSlice::fromLiteral("glslang"); } } @@ -357,24 +362,21 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio static DownstreamCompiler::Desc _calcCompiledWithDesc() { - DownstreamCompiler::Desc desc = {}; + DownstreamCompiler::Desc desc; #if SLANG_VC desc = WinVisualStudioUtil::getDesc(WinVisualStudioUtil::getCompiledVersion()); #elif SLANG_CLANG - desc.type = DownstreamCompiler::CompilerType::Clang; + desc.type = SLANG_PASS_THROUGH_CLANG; desc.majorVersion = Int(__clang_major__); desc.minorVersion = Int(__clang_minor__); -#elif SLANG_SNC - desc.type = DownstreamCompiler::CompilerType::SNC; -#elif SLANG_GHS - desc.type = DownstreamCompiler::CompilerType::GHS; #elif SLANG_GCC - desc.type = DownstreamCompiler::CompilerType::GCC; + desc.type = SLANG_PASS_THROUGH_GCC; desc.majorVersion = Int(__GNUC__); desc.minorVersion = Int(__GNUC_MINOR__); #else - desc.type = DownstreamCompiler::CompilerType::Unknown; + // TODO(JS): Hmmm None is not quite the same as unknown. It works for now, but we might want to have a distinct enum for unknown. + desc.type = SLANG_PASS_THROUGH_NONE; #endif return desc; @@ -397,14 +399,26 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc() /* static */DownstreamCompiler* DownstreamCompilerUtil::findCompiler(const List<DownstreamCompiler*>& compilers, MatchType matchType, const DownstreamCompiler::Desc& desc) { + if (compilers.getCount() <= 0) + { + return nullptr; + } + Int bestIndex = -1; - const DownstreamCompiler::CompilerType type = desc.type; + const SlangPassThrough type = desc.type; Int maxVersionValue = 0; Int minVersionDiff = 0x7fffffff; - const auto descVersionValue = desc.getVersionValue(); + Int descVersionValue = desc.getVersionValue(); + + // If we don't have version set, then anything 0 or above is good enough, and just take newest + if (descVersionValue == 0) + { + maxVersionValue = -1; + matchType = MatchType::Newest; + } for (Index i = 0; i < compilers.getCount(); ++i) { @@ -469,10 +483,10 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc() } // If we are gcc, we can try clang and vice versa - if (desc.type == DownstreamCompiler::CompilerType::GCC || desc.type == DownstreamCompiler::CompilerType::Clang) + if (desc.type == SLANG_PASS_THROUGH_GCC || desc.type == SLANG_PASS_THROUGH_CLANG) { DownstreamCompiler::Desc compatible = desc; - compatible.type = (compatible.type == DownstreamCompiler::CompilerType::Clang) ? DownstreamCompiler::CompilerType::GCC : DownstreamCompiler::CompilerType::Clang; + compatible.type = (compatible.type == SLANG_PASS_THROUGH_CLANG) ? SLANG_PASS_THROUGH_GCC : SLANG_PASS_THROUGH_CLANG; compiler = findCompiler(compilers, MatchType::MinGreaterEqual, compatible); if (compiler) @@ -489,23 +503,6 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc() return nullptr; } -static void _addGCCFamilyCompiler(const String& path, const String& inExeName, DownstreamCompilerSet* compilerSet) -{ - String exeName(inExeName); - if (path.getLength() > 0) - { - exeName = Path::combine(path, inExeName); - } - - DownstreamCompiler::Desc desc; - if (SLANG_SUCCEEDED(GCCDownstreamCompilerUtil::calcVersion(exeName, desc))) - { - RefPtr<CommandLineDownstreamCompiler> compiler(new GCCDownstreamCompiler(desc)); - compiler->m_cmdLine.setExecutableFilename(exeName); - compilerSet->addCompiler(compiler); - } -} - /* static */DownstreamCompiler* DownstreamCompilerUtil::findClosestCompiler(const DownstreamCompilerSet* set, const DownstreamCompiler::Desc& desc) { DownstreamCompiler* compiler = set->getCompiler(desc); @@ -518,41 +515,94 @@ static void _addGCCFamilyCompiler(const String& path, const String& inExeName, D return findClosestCompiler(compilers, desc); } -/* static */SlangResult DownstreamCompilerUtil::initializeSet(const InitializeSetDesc& desc, DownstreamCompilerSet* set) +/* static */void DownstreamCompilerUtil::updateDefault(DownstreamCompilerSet* set, DownstreamCompiler::SourceType type) { -#if SLANG_WINDOWS_FAMILY - WinVisualStudioUtil::find(set); -#endif - - _addGCCFamilyCompiler(desc.getPath(CompilerType::Clang), "clang", set); - _addGCCFamilyCompiler(desc.getPath(CompilerType::GCC), "g++", set); + DownstreamCompiler* compiler = nullptr; + switch (type) { - DownstreamCompiler* cppCompiler = findClosestCompiler(set, getCompiledWithDesc()); + case DownstreamCompiler::SourceType::CPP: + case DownstreamCompiler::SourceType::C: + { + compiler = findClosestCompiler(set, getCompiledWithDesc()); + break; + } + case DownstreamCompiler::SourceType::CUDA: + { + DownstreamCompiler::Desc desc; + desc.type = SLANG_PASS_THROUGH_NVRTC; + compiler = findCompiler(set, MatchType::Newest, desc); + break; + } + default: break; + } - // Set the default to the compiler closest to how this source was compiled - set->setDefaultCompiler(DownstreamCompiler::SourceType::CPP, cppCompiler); - set->setDefaultCompiler(DownstreamCompiler::SourceType::C, cppCompiler); + set->setDefaultCompiler(type, compiler); +} + +/* static */void DownstreamCompilerUtil::updateDefaults(DownstreamCompilerSet* set) +{ + for (Index i = 0; i < Index(DownstreamCompiler::SourceType::CountOf); ++i) + { + updateDefault(set, DownstreamCompiler::SourceType(i)); } +} + +static SlangResult _locateDXCCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set) +{ + // First try dxil, so it's loaded from the same path if it's there + ComPtr<ISlangSharedLibrary> dxil; + DefaultSharedLibraryLoader::load(loader, path, "dxil", dxil.writeRef()); - // Lets see if we have NVRTC. + ComPtr<ISlangSharedLibrary> sharedLibrary; + if (SLANG_SUCCEEDED(DefaultSharedLibraryLoader::load(loader, path, "dxcompiler", sharedLibrary.writeRef()))) { - ISlangSharedLibrary* sharedLibrary = desc.sharedLibraries[int(CompilerType::NVRTC)]; - if (sharedLibrary) - { - RefPtr<DownstreamCompiler> compiler; - if (SLANG_SUCCEEDED(NVRTCDownstreamCompilerUtil::createCompiler(sharedLibrary, compiler))) - { - set->addCompiler(compiler); + // Can we determine the version? + DownstreamCompiler::Desc desc(SLANG_PASS_THROUGH_DXC); + RefPtr<DownstreamCompiler> compiler(new SharedLibraryDownstreamCompiler(desc, sharedLibrary)); - set->setDefaultCompiler(DownstreamCompiler::SourceType::CUDA, compiler); - } - } + set->addCompiler(compiler); } + return SLANG_OK; +} +static SlangResult _locateFXCCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set) +{ + ComPtr<ISlangSharedLibrary> sharedLibrary; + if (SLANG_SUCCEEDED(DefaultSharedLibraryLoader::load(loader, path, "d3dcompiler_47", sharedLibrary.writeRef()))) + { + // Can we determine the version? + DownstreamCompiler::Desc desc(SLANG_PASS_THROUGH_FXC); + RefPtr<DownstreamCompiler> compiler(new SharedLibraryDownstreamCompiler(desc, sharedLibrary)); + set->addCompiler(compiler); + } return SLANG_OK; } +static SlangResult _locateGlslangCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set) +{ + ComPtr<ISlangSharedLibrary> sharedLibrary; + if (SLANG_SUCCEEDED(DefaultSharedLibraryLoader::load(loader, path, "slang-glslang", sharedLibrary.writeRef()))) + { + // Can we determine the version? + DownstreamCompiler::Desc desc(SLANG_PASS_THROUGH_GLSLANG); + RefPtr<DownstreamCompiler> compiler(new SharedLibraryDownstreamCompiler(desc, sharedLibrary)); + set->addCompiler(compiler); + } + return SLANG_OK; +} + +/* static */void DownstreamCompilerUtil::setDefaultLocators(DownstreamCompilerLocatorFunc outFuncs[int(SLANG_PASS_THROUGH_COUNT_OF)]) +{ + outFuncs[int(SLANG_PASS_THROUGH_VISUAL_STUDIO)] = &VisualStudioCompilerUtil::locateCompilers; + outFuncs[int(SLANG_PASS_THROUGH_CLANG)] = &GCCDownstreamCompilerUtil::locateClangCompilers; + outFuncs[int(SLANG_PASS_THROUGH_GCC)] = &GCCDownstreamCompilerUtil::locateGCCCompilers; + outFuncs[int(SLANG_PASS_THROUGH_NVRTC)] = &NVRTCDownstreamCompilerUtil::locateCompilers; + outFuncs[int(SLANG_PASS_THROUGH_DXC)] = &_locateDXCCompilers; + outFuncs[int(SLANG_PASS_THROUGH_FXC)] = &_locateFXCCompilers; + outFuncs[int(SLANG_PASS_THROUGH_GLSLANG)] = &_locateGlslangCompilers; +} + /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamCompilerSet !!!!!!!!!!!!!!!!!!!!!!*/ void DownstreamCompilerSet::getCompilerDescs(List<DownstreamCompiler::Desc>& outCompilerDescs) const @@ -589,7 +639,7 @@ void DownstreamCompilerSet::getCompilers(List<DownstreamCompiler*>& outCompilers outCompilers.addRange((DownstreamCompiler*const*)m_compilers.begin(), m_compilers.getCount()); } -bool DownstreamCompilerSet::hasCompiler(DownstreamCompiler::CompilerType compilerType) const +bool DownstreamCompilerSet::hasCompiler(SlangPassThrough compilerType) const { for (DownstreamCompiler* compiler : m_compilers) { @@ -602,6 +652,20 @@ bool DownstreamCompilerSet::hasCompiler(DownstreamCompiler::CompilerType compile return false; } + +void DownstreamCompilerSet::remove(SlangPassThrough compilerType) +{ + for (Index i = 0; i < m_compilers.getCount(); ++i) + { + DownstreamCompiler* compiler = m_compilers[i]; + if (compiler->getDesc().type == compilerType) + { + m_compilers.fastRemoveAt(i); + i--; + } + } +} + void DownstreamCompilerSet::addCompiler(DownstreamCompiler* compiler) { const Index index = _findIndex(compiler->getDesc()); diff --git a/source/core/slang-downstream-compiler.h b/source/core/slang-downstream-compiler.h index 99bcfd29f..075f8f26a 100644 --- a/source/core/slang-downstream-compiler.h +++ b/source/core/slang-downstream-compiler.h @@ -120,17 +120,6 @@ public: typedef DownstreamCompileResult CompileResult; - enum class CompilerType - { - Unknown, - VisualStudio, - GCC, - Clang, - SNC, - GHS, - NVRTC, - CountOf, - }; enum class SourceType { C, ///< C source @@ -151,11 +140,13 @@ public: Int getVersionValue() const { return majorVersion * 100 + minorVersion; } void appendAsText(StringBuilder& out) const; + /// true if has a version set + bool hasVersion() const { return majorVersion || minorVersion; } /// Ctor - Desc(CompilerType inType = CompilerType::Unknown, Int inMajorVersion = 0, Int inMinorVersion = 0):type(inType), majorVersion(inMajorVersion), minorVersion(inMinorVersion) {} + explicit Desc(SlangPassThrough inType = SLANG_PASS_THROUGH_NONE, Int inMajorVersion = 0, Int inMinorVersion = 0):type(inType), majorVersion(inMajorVersion), minorVersion(inMinorVersion) {} - CompilerType type; ///< The type of the compiler + SlangPassThrough type; ///< The type of the compiler Int majorVersion; ///< Major version (interpretation is type specific) Int minorVersion; ///< Minor version }; @@ -265,9 +256,11 @@ public: const Desc& getDesc() const { return m_desc; } /// Compile using the specified options. The result is in resOut virtual SlangResult compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) = 0; - + /// Some downstream compilers are backed by a shared library. This allows access to the shared library to access internal functions. + virtual ISlangSharedLibrary* getSharedLibrary() { return nullptr; } + /// Return the compiler type as name - static UnownedStringSlice getCompilerTypeAsText(CompilerType type); + static UnownedStringSlice getCompilerTypeAsText(SlangPassThrough type); protected: @@ -341,6 +334,24 @@ public: CommandLine m_cmdLine; }; +class SharedLibraryDownstreamCompiler: public DownstreamCompiler +{ +public: + typedef DownstreamCompiler Super; + + // DownstreamCompiler + virtual SlangResult compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE { SLANG_UNUSED(options); SLANG_UNUSED(outResult); return SLANG_E_NOT_IMPLEMENTED; } + virtual ISlangSharedLibrary* getSharedLibrary() SLANG_OVERRIDE { return m_library; } + + SharedLibraryDownstreamCompiler(const Desc& desc, ISlangSharedLibrary* library): + Super(desc), + m_library(library) + { + } +protected: + ComPtr<ISlangSharedLibrary> m_library; +}; + class DownstreamCompilerSet : public RefObject { public: @@ -363,7 +374,11 @@ public: void setDefaultCompiler(DownstreamCompiler::SourceType sourceType, DownstreamCompiler* compiler) { m_defaultCompilers[int(sourceType)] = compiler; } /// True if has a compiler of the specified type - bool hasCompiler(DownstreamCompiler::CompilerType compilerType) const; + bool hasCompiler(SlangPassThrough compilerType) const; + + void remove(SlangPassThrough compilerType); + + void clear() { m_compilers.clear(); } protected: @@ -375,6 +390,8 @@ protected: List<RefPtr<DownstreamCompiler>> m_compilers; }; +typedef SlangResult (*DownstreamCompilerLocatorFunc)(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set); + /* Only purpose of having base-class here is to make all the DownstreamCompiler types available directly in derived Utils */ struct DownstreamCompilerBaseUtil { @@ -383,8 +400,7 @@ struct DownstreamCompilerBaseUtil typedef DownstreamCompiler::TargetType TargetType; typedef DownstreamCompiler::DebugInfoType DebugInfoType; typedef DownstreamCompiler::SourceType SourceType; - typedef DownstreamCompiler::CompilerType CompilerType; - + typedef DownstreamDiagnostics::Diagnostic Diagnostic; typedef DownstreamCompiler::FloatingPointMode FloatingPointMode; @@ -401,17 +417,6 @@ struct DownstreamCompilerUtil: public DownstreamCompilerBaseUtil Newest, }; - struct InitializeSetDesc - { - const String& getPath(CompilerType type) const { return paths[int(type)]; } - void setPath(CompilerType type, const String& path) { paths[int(type)] = path; } - - InitializeSetDesc() { memset(sharedLibraries, 0, sizeof(sharedLibraries)); } - - String paths[int(DownstreamCompiler::CompilerType::CountOf)]; - ISlangSharedLibrary* sharedLibraries[int(DownstreamCompiler::CompilerType::CountOf)]; - }; - /// Find a compiler static DownstreamCompiler* findCompiler(const DownstreamCompilerSet* set, MatchType matchType, const DownstreamCompiler::Desc& desc); static DownstreamCompiler* findCompiler(const List<DownstreamCompiler*>& compilers, MatchType matchType, const DownstreamCompiler::Desc& desc); @@ -423,8 +428,10 @@ struct DownstreamCompilerUtil: public DownstreamCompilerBaseUtil /// Get the information on the compiler used to compile this source static const DownstreamCompiler::Desc& getCompiledWithDesc(); - /// Given a set, registers compilers found through standard means and determines a reasonable default compiler if possible - static SlangResult initializeSet(const InitializeSetDesc& desc, DownstreamCompilerSet* set); + static void updateDefault(DownstreamCompilerSet* set, DownstreamCompiler::SourceType type); + static void updateDefaults(DownstreamCompilerSet* set); + + static void setDefaultLocators(DownstreamCompilerLocatorFunc outFuncs[int(SLANG_PASS_THROUGH_COUNT_OF)]); }; } diff --git a/source/core/slang-gcc-compiler-util.cpp b/source/core/slang-gcc-compiler-util.cpp index ba077e0c5..7c2ec3775 100644 --- a/source/core/slang-gcc-compiler-util.cpp +++ b/source/core/slang-gcc-compiler-util.cpp @@ -70,11 +70,11 @@ SlangResult GCCDownstreamCompilerUtil::calcVersion(const String& exeName, Downst UnownedStringSlice::fromLiteral("gcc version"), UnownedStringSlice::fromLiteral("Apple LLVM version"), }; - const DownstreamCompiler::CompilerType types[] = + const SlangPassThrough types[] = { - DownstreamCompiler::CompilerType::Clang, - DownstreamCompiler::CompilerType::GCC, - DownstreamCompiler::CompilerType::Clang, + SLANG_PASS_THROUGH_CLANG, + SLANG_PASS_THROUGH_GCC, + SLANG_PASS_THROUGH_CLANG, }; SLANG_COMPILE_TIME_ASSERT(SLANG_COUNT_OF(prefixes) == SLANG_COUNT_OF(types)); @@ -581,4 +581,45 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse return SLANG_OK; } +/* static */SlangResult GCCDownstreamCompilerUtil::createCompiler(const String& path, const String& inExeName, RefPtr<DownstreamCompiler>& outCompiler) +{ + String exeName(inExeName); + if (path.getLength() > 0) + { + exeName = Path::combine(path, inExeName); + } + + DownstreamCompiler::Desc desc; + SLANG_RETURN_ON_FAIL(GCCDownstreamCompilerUtil::calcVersion(exeName, desc)); + + RefPtr<CommandLineDownstreamCompiler> compiler(new GCCDownstreamCompiler(desc)); + compiler->m_cmdLine.setExecutableFilename(exeName); + + outCompiler = compiler; + return SLANG_OK; +} + +/* static */SlangResult GCCDownstreamCompilerUtil::locateGCCCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set) +{ + SLANG_UNUSED(loader); + RefPtr<DownstreamCompiler> compiler; + if (SLANG_SUCCEEDED(createCompiler(path, "g++", compiler))) + { + set->addCompiler(compiler); + } + return SLANG_OK; +} + +/* static */SlangResult GCCDownstreamCompilerUtil::locateClangCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set) +{ + SLANG_UNUSED(loader); + + RefPtr<DownstreamCompiler> compiler; + if (SLANG_SUCCEEDED(createCompiler(path, "clang", compiler))) + { + set->addCompiler(compiler); + } + return SLANG_OK; +} + } diff --git a/source/core/slang-gcc-compiler-util.h b/source/core/slang-gcc-compiler-util.h index ead527e0d..b97144e35 100644 --- a/source/core/slang-gcc-compiler-util.h +++ b/source/core/slang-gcc-compiler-util.h @@ -26,6 +26,14 @@ struct GCCDownstreamCompilerUtil : public DownstreamCompilerBaseUtil /// Given options, calculate paths to products produced for a compilation static SlangResult calcCompileProducts(const CompileOptions& options, ProductFlags flags, List<String>& outPaths); + + /// Given a path and an exe name, detects if compiler is present, and if so adds to compiler set. + static SlangResult createCompiler(const String& path, const String& inExeName, RefPtr<DownstreamCompiler>& outCompiler); + + static SlangResult locateGCCCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set); + + static SlangResult locateClangCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set); + }; class GCCDownstreamCompiler : public CommandLineDownstreamCompiler diff --git a/source/core/slang-nvrtc-compiler.cpp b/source/core/slang-nvrtc-compiler.cpp index e812a2ab9..1bb2669b8 100644 --- a/source/core/slang-nvrtc-compiler.cpp +++ b/source/core/slang-nvrtc-compiler.cpp @@ -95,6 +95,7 @@ public: // DownstreamCompiler virtual SlangResult compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE; + virtual ISlangSharedLibrary* getSharedLibrary() SLANG_OVERRIDE { return m_sharedLibrary; } /// Must be called before use SlangResult init(ISlangSharedLibrary* library); @@ -139,7 +140,7 @@ SlangResult NVRTCDownstreamCompiler::init(ISlangSharedLibrary* library) m_sharedLibrary = library; - m_desc.type = CompilerType::NVRTC; + m_desc.type = SLANG_PASS_THROUGH_NVRTC; int major, minor; m_nvrtcVersion(&major, &minor); @@ -356,14 +357,26 @@ SlangResult NVRTCDownstreamCompiler::compile(const CompileOptions& options, RefP return SLANG_OK; } -/* static */SlangResult NVRTCDownstreamCompilerUtil::createCompiler(ISlangSharedLibrary* library, RefPtr<DownstreamCompiler>& outCompiler) +/* static */SlangResult NVRTCDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set) { - RefPtr<NVRTCDownstreamCompiler> compiler(new NVRTCDownstreamCompiler); + ComPtr<ISlangSharedLibrary> library; + if (path.getLength() != 0) + { + SLANG_RETURN_ON_FAIL(loader->loadSharedLibrary(path.getBuffer(), library.writeRef())); + } + else + { + const char* libraryName = "nvrtc64_102_0"; + SLANG_RETURN_ON_FAIL(loader->loadSharedLibrary(libraryName, library.writeRef())); + } + + RefPtr<NVRTCDownstreamCompiler> compiler(new NVRTCDownstreamCompiler); SLANG_RETURN_ON_FAIL(compiler->init(library)); - outCompiler = compiler; + set->addCompiler(compiler); return SLANG_OK; } + } diff --git a/source/core/slang-nvrtc-compiler.h b/source/core/slang-nvrtc-compiler.h index 91cd92b8c..48c6d4da6 100644 --- a/source/core/slang-nvrtc-compiler.h +++ b/source/core/slang-nvrtc-compiler.h @@ -11,8 +11,7 @@ namespace Slang struct NVRTCDownstreamCompilerUtil { - /// Create a NVRTC downstream compiler. Note on success the created compiler will own the shared library handle. - static SlangResult createCompiler(ISlangSharedLibrary* library, RefPtr<DownstreamCompiler>& outCompiler); + static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set); }; } diff --git a/source/core/slang-shared-library.cpp b/source/core/slang-shared-library.cpp index 2b18ad6aa..b09f345c7 100644 --- a/source/core/slang-shared-library.cpp +++ b/source/core/slang-shared-library.cpp @@ -15,31 +15,8 @@ static const Guid IID_ISlangSharedLibraryLoader = SLANG_UUID_ISlangSharedLibrary /* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibraryLoader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ -/* static */const char* DefaultSharedLibraryLoader::s_libraryNames[int(SharedLibraryType::CountOf)] = -{ - nullptr, // SharedLibraryType::Unknown - "dxcompiler", // SharedLibraryType::Dxc - "d3dcompiler_47", // SharedLibraryType::Fxc - "slang-glslang", // SharedLibraryType::Glslang - "dxil", // SharedLibraryType::Dxil - "nvrtc64_102_0", // SharedLibraryType::NVRTC -}; - /* static */DefaultSharedLibraryLoader DefaultSharedLibraryLoader::s_singleton; -/* static */SharedLibraryType DefaultSharedLibraryLoader::getSharedLibraryTypeFromName(const UnownedStringSlice& name) -{ - // Start from 1 to skip Unknown - for (int i = 1; i < SLANG_COUNT_OF(s_libraryNames); ++i) - { - if (name == s_libraryNames[i]) - { - return SharedLibraryType(i); - } - } - return SharedLibraryType::Unknown; -} - ISlangUnknown* DefaultSharedLibraryLoader::getInterface(const Guid& guid) { return (guid == IID_ISlangUnknown || guid == IID_ISlangSharedLibraryLoader) ? static_cast<ISlangSharedLibraryLoader*>(this) : nullptr; @@ -65,6 +42,19 @@ SlangResult DefaultSharedLibraryLoader::loadPlatformSharedLibrary(const char* pa return SLANG_OK; } +/* static */SlangResult DefaultSharedLibraryLoader::load(ISlangSharedLibraryLoader* loader, const String& path, const String& name, ISlangSharedLibrary** outLibrary) +{ + if (path.getLength()) + { + String combinedPath = Path::combine(path, name); + return loader->loadSharedLibrary(combinedPath.getBuffer(), outLibrary); + } + else + { + return loader->loadSharedLibrary(name.getBuffer(), outLibrary); + } +} + /* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ TemporarySharedLibrary::~TemporarySharedLibrary() @@ -97,46 +87,4 @@ SlangFuncPtr DefaultSharedLibrary::findFuncByName(char const* name) return SharedLibrary::findFuncByName(m_sharedLibraryHandle, name); } -/* !!!!!!!!!!!!!!!!!!!!!!!!!! ConfigurableSharedLibraryLoader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ - -ISlangUnknown* ConfigurableSharedLibraryLoader::getInterface(const Guid& guid) -{ - return (guid == IID_ISlangUnknown || guid == IID_ISlangSharedLibraryLoader) ? static_cast<ISlangSharedLibraryLoader*>(this) : nullptr; -} - -SlangResult ConfigurableSharedLibraryLoader::loadSharedLibrary(const char* path, ISlangSharedLibrary** sharedLibraryOut) -{ - Entry* entry = m_entryMap.TryGetValue(String(path)); - if (entry) - { - SharedLibrary::Handle handle; - SLANG_RETURN_ON_FAIL(entry->func(path, entry->entryString, handle)); - SLANG_ASSERT(handle); - - ComPtr<ISlangSharedLibrary> sharedLib(new DefaultSharedLibrary(handle)); - *sharedLibraryOut = sharedLib.detach(); - return SLANG_OK; - } - - return DefaultSharedLibraryLoader::getSingleton()->loadSharedLibrary(path, sharedLibraryOut); -} - -/* static */Result ConfigurableSharedLibraryLoader::replace(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut) -{ - SLANG_UNUSED(pathIn); - // The replacement is the *whole* string - return SharedLibrary::loadWithPlatformPath(entryString.begin(), handleOut); -} - -/* static */Result ConfigurableSharedLibraryLoader::changePath(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut ) -{ - // Okay we need to reconstruct the name and insert the path - StringBuilder builder; - SharedLibrary::appendPlatformFileName(UnownedStringSlice(pathIn), builder); - String path = Path::combine(entryString, builder); - - return SharedLibrary::loadWithPlatformPath(path.begin(), handleOut); -} - - } diff --git a/source/core/slang-shared-library.h b/source/core/slang-shared-library.h index 9c58d4e10..0b5c5b2d7 100644 --- a/source/core/slang-shared-library.h +++ b/source/core/slang-shared-library.h @@ -13,18 +13,6 @@ namespace Slang { -/* NOTE! Do not change this enum without making the appropriate changes to DefaultSharedLibraryLoader::s_libraryNames */ -enum class SharedLibraryType -{ - Unknown, ///< Unknown compiler - Dxc, ///< Dxc compiler - Fxc, ///< Fxc compiler - Glslang, ///< Slang specific glslang compiler - Dxil, ///< Dxil is used with dxc - NVRTC, ///< Nvrtc compiler - CountOf, -}; - class DefaultSharedLibraryLoader : public ISlangSharedLibraryLoader { public: @@ -44,14 +32,8 @@ public: /// Get the singleton static DefaultSharedLibraryLoader* getSingleton() { return &s_singleton; } - /// Get the type from the name - static SharedLibraryType getSharedLibraryTypeFromName(const UnownedStringSlice& name); - /// Get the name from the type, or nullptr if not known - static const char* getSharedLibraryNameFromType(SharedLibraryType type) { return s_libraryNames[int(type)]; } - - /// Make a shared library to it's name - static const char* s_libraryNames[int(SharedLibraryType::CountOf)]; + static SlangResult load(ISlangSharedLibraryLoader* loader, const String& path, const String& name, ISlangSharedLibrary** outLibrary); private: /// Make so not constructible @@ -112,39 +94,6 @@ protected: String m_path; }; -class ConfigurableSharedLibraryLoader: public ISlangSharedLibraryLoader, public RefObject -{ -public: - typedef Result (*Func)(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut); - - // IUnknown - SLANG_REF_OBJECT_IUNKNOWN_ALL - - // ISlangSharedLibraryLoader - virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadSharedLibrary(const char* path, ISlangSharedLibrary** sharedLibraryOut) SLANG_OVERRIDE; - - /// Function to replace the the path with entryString - static Result replace(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut); - /// Function to change the path using the entryString - static Result changePath(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut); - - void addEntry(const String& libName, Func func, const String& entryString) { m_entryMap.Add(libName, Entry{ func, entryString} ); } - void addEntry(SharedLibraryType libType, Func func, const String& entryString) { m_entryMap.Add(DefaultSharedLibraryLoader::getSharedLibraryNameFromType(libType), Entry { func, entryString} ); } - - virtual ~ConfigurableSharedLibraryLoader() {} - protected: - - struct Entry - { - Func func; - String entryString; - }; - - ISlangUnknown* getInterface(const Guid& guid); - - Dictionary<String, Entry> m_entryMap; -}; - } #endif // SLANG_SHARED_LIBRARY_H_INCLUDED diff --git a/source/core/slang-visual-studio-compiler-util.cpp b/source/core/slang-visual-studio-compiler-util.cpp index 356f21a25..1a42e9b6e 100644 --- a/source/core/slang-visual-studio-compiler-util.cpp +++ b/source/core/slang-visual-studio-compiler-util.cpp @@ -5,6 +5,11 @@ #include "../../slang-com-helper.h" #include "slang-string-util.h" +// if Visual Studio import the visual studio platform specific header +#if SLANG_VC +# include "windows/slang-win-visual-studio-util.h" +#endif + #include "slang-io.h" namespace Slang @@ -429,4 +434,19 @@ static SlangResult _parseVisualStudioLine(const UnownedStringSlice& line, Downst return SLANG_OK; } +/* static */SlangResult VisualStudioCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set) +{ + SLANG_UNUSED(loader); + + // TODO(JS): We don't support fixed path for visual studio just yet + if (path.getLength() == 0) + { +#if SLANG_VC + return WinVisualStudioUtil::find(set); +#endif + } + + return SLANG_OK; +} + } diff --git a/source/core/slang-visual-studio-compiler-util.h b/source/core/slang-visual-studio-compiler-util.h index 3571f4b42..018dde212 100644 --- a/source/core/slang-visual-studio-compiler-util.h +++ b/source/core/slang-visual-studio-compiler-util.h @@ -17,6 +17,8 @@ struct VisualStudioCompilerUtil : public DownstreamCompilerBaseUtil static SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath); static SlangResult calcCompileProducts(const CompileOptions& options, ProductFlags flags, List<String>& outPaths); + + static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set); }; class VisualStudioDownstreamCompiler : public CommandLineDownstreamCompiler diff --git a/source/core/windows/slang-win-visual-studio-util.h b/source/core/windows/slang-win-visual-studio-util.h index 1122fccb7..530d18582 100644 --- a/source/core/windows/slang-win-visual-studio-util.h +++ b/source/core/windows/slang-win-visual-studio-util.h @@ -55,7 +55,7 @@ struct WinVisualStudioUtil static DownstreamCompiler::Desc getDesc(Version version) { DownstreamCompiler::Desc desc; - desc.type = DownstreamCompiler::CompilerType::VisualStudio; + desc.type = SLANG_PASS_THROUGH_VISUAL_STUDIO; desc.majorVersion = Int(version) / 10; desc.minorVersion = Int(version) % 10; return desc; diff --git a/source/slang/slang-check.cpp b/source/slang/slang-check.cpp index db69a3155..50de73f07 100644 --- a/source/slang/slang-check.cpp +++ b/source/slang/slang-check.cpp @@ -13,86 +13,151 @@ namespace Slang struct FunctionInfo { const char* name; - SharedLibraryType libraryType; + PassThroughMode compilerType; }; + + const Guid IID_ISlangSharedLibraryLoader = SLANG_UUID_ISlangSharedLibraryLoader; + const Guid IID_ISlangUnknown = SLANG_UUID_ISlangUnknown; + + class SinkSharedLibraryLoader : public RefObject, public ISlangSharedLibraryLoader + { + public: + SLANG_REF_OBJECT_IUNKNOWN_ALL + + virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadSharedLibrary( + const char* path, + ISlangSharedLibrary** outSharedLibrary) SLANG_OVERRIDE + { + SlangResult res = m_loader->loadSharedLibrary(path, outSharedLibrary); + + // Special handling for failure... + if (SLANG_FAILED(res) && m_sink) + { + String filename = Path::getFileNameWithoutExt(path); + if (filename == "dxil") + { + m_sink->diagnose(SourceLoc(), Diagnostics::dxilNotFound); + } + else + { + m_sink->diagnose(SourceLoc(), Diagnostics::failedToLoadDynamicLibrary, path); + } + } + return res; + } + + SinkSharedLibraryLoader(ISlangSharedLibraryLoader* loader, DiagnosticSink* sink) : + m_loader(loader), + m_sink(sink) + { + } + + protected: + ISlangUnknown* getInterface(const Guid& guid) + { + return (guid == IID_ISlangUnknown || guid == IID_ISlangSharedLibraryLoader) ? static_cast<ISlangSharedLibraryLoader*>(this) : nullptr; + } + ISlangSharedLibraryLoader* m_loader; + DiagnosticSink* m_sink; + }; + } // anonymous static FunctionInfo _getFunctionInfo(Session::SharedLibraryFuncType funcType) { typedef Session::SharedLibraryFuncType FuncType; - typedef SharedLibraryType LibType; - + switch (funcType) { - case FuncType::Glslang_Compile: return { "glslang_compile", LibType::Glslang } ; - case FuncType::Fxc_D3DCompile: return { "D3DCompile", LibType::Fxc }; - case FuncType::Fxc_D3DDisassemble: return { "D3DDisassemble", LibType::Fxc }; - case FuncType::Dxc_DxcCreateInstance: return { "DxcCreateInstance", LibType::Dxc }; - default: return { nullptr, LibType::Unknown }; + case FuncType::Glslang_Compile: return { "glslang_compile", PassThroughMode::Glslang} ; + case FuncType::Fxc_D3DCompile: return { "D3DCompile", PassThroughMode::Fxc}; + case FuncType::Fxc_D3DDisassemble: return { "D3DDisassemble", PassThroughMode::Fxc }; + case FuncType::Dxc_DxcCreateInstance: return { "DxcCreateInstance", PassThroughMode::Dxc }; + default: return { nullptr, PassThroughMode::None }; } } - static PassThroughMode _toPassThroughMode(SharedLibraryType type) + void Session::setSharedLibraryLoader(ISlangSharedLibraryLoader* loader) { - switch (type) + if (m_sharedLibraryLoader != loader) { - case SharedLibraryType::Dxil: - case SharedLibraryType::Dxc: + // Need to clear all of the libraries + m_downstreamCompilerSet->clear(); + m_downstreamCompilerInitialized = 0; + + for (Index i = 0; i < Index(SLANG_PASS_THROUGH_COUNT_OF); ++i) { - return PassThroughMode::Dxc; + m_downstreamCompilers[i].setNull(); } - case SharedLibraryType::Fxc: return PassThroughMode::Fxc; - case SharedLibraryType::Glslang: return PassThroughMode::Glslang; - default: break; - } - return PassThroughMode::None; + // Clear all of the functions + ::memset(m_sharedLibraryFunctions, 0, sizeof(m_sharedLibraryFunctions)); + + // Set the loader + m_sharedLibraryLoader = loader; + } } - void Session::setSharedLibrary(SharedLibraryType type, ISlangSharedLibrary* library) + void Session::resetDownstreamCompiler(PassThroughMode type) { - sharedLibraries[int(type)] = library; + // Mark as initialized + m_downstreamCompilerInitialized &= ~(1 << int(type)); + m_downstreamCompilers[int(type)].setNull(); } - ISlangSharedLibrary* Session::getOrLoadSharedLibrary(SharedLibraryType type, DiagnosticSink* sink) + DownstreamCompiler* Session::getOrLoadDownstreamCompiler(PassThroughMode type, DiagnosticSink* sink) { - // If not loaded, try loading it - if (!sharedLibraries[int(type)]) + if (m_downstreamCompilerInitialized & (1 << int(type))) { - // Try to preload dxil first, if loading dxc - if (type == SharedLibraryType::Dxc) - { - // Pass nullptr as the sink, because if it fails we don't want to report as error - getOrLoadSharedLibrary(SharedLibraryType::Dxil, nullptr); - } + return m_downstreamCompilers[int(type)]; + } + + if (type == PassThroughMode::GenericCCpp) + { + // try loading all C/C++ compilers + getOrLoadDownstreamCompiler(PassThroughMode::Clang, sink); + getOrLoadDownstreamCompiler(PassThroughMode::Gcc, sink); + getOrLoadDownstreamCompiler(PassThroughMode::VisualStudio, sink); + } - const char* libName = DefaultSharedLibraryLoader::getSharedLibraryNameFromType(type); + // Mark that we have tried to load it + m_downstreamCompilerInitialized |= (1 << int(type)); + m_downstreamCompilers[int(type)].setNull(); - StringBuilder builder; - PassThroughMode passThrough = _toPassThroughMode(type); - if (passThrough != PassThroughMode::None && m_downstreamCompilerPaths[int(passThrough)].getLength() > 0) - { - Path::combineIntoBuilder(m_downstreamCompilerPaths[int(passThrough)].getUnownedSlice(), UnownedStringSlice(libName), builder); - libName = builder.getBuffer(); - } + // Do we have a locator + auto locator = m_downstreamCompilerLocators[int(type)]; + if (!locator) + { + return nullptr; + } - if (SLANG_FAILED(sharedLibraryLoader->loadSharedLibrary(libName, sharedLibraries[int(type)].writeRef()))) - { - if (sink) - { - sink->diagnose(SourceLoc(), Diagnostics::failedToLoadDynamicLibrary, libName); - } - return nullptr; - } + m_downstreamCompilerSet->remove(SlangPassThrough(type)); + + SinkSharedLibraryLoader loader(m_sharedLibraryLoader, sink); + locator(m_downstreamCompilerPaths[int(type)], &loader, m_downstreamCompilerSet); + + DownstreamCompilerUtil::updateDefaults(m_downstreamCompilerSet); + + if (type == PassThroughMode::GenericCCpp) + { + m_downstreamCompilers[int(type)] = m_downstreamCompilerSet->getDefaultCompiler(DownstreamCompiler::SourceType::CPP); } - return sharedLibraries[int(type)]; + else + { + DownstreamCompiler::Desc desc; + desc.type = SlangPassThrough(type); + + m_downstreamCompilers[int(type)] = DownstreamCompilerUtil::findCompiler(m_downstreamCompilerSet, DownstreamCompilerUtil::MatchType::Newest, desc); + } + + return m_downstreamCompilers[int(type)]; } SlangFuncPtr Session::getSharedLibraryFunc(SharedLibraryFuncType type, DiagnosticSink* sink) { - if (sharedLibraryFunctions[int(type)]) + if (m_sharedLibraryFunctions[int(type)]) { - return sharedLibraryFunctions[int(type)]; + return m_sharedLibraryFunctions[int(type)]; } // do we have the library FunctionInfo info = _getFunctionInfo(type); @@ -101,47 +166,31 @@ namespace Slang return nullptr; } // Try loading the library - ISlangSharedLibrary* sharedLib = getOrLoadSharedLibrary(info.libraryType, sink); - if (!sharedLib) + DownstreamCompiler* compiler = getOrLoadDownstreamCompiler(info.compilerType, sink); + if (!compiler) + { + return nullptr; + } + ISlangSharedLibrary* sharedLibrary = compiler->getSharedLibrary(); + if (!sharedLibrary) { return nullptr; } // Okay now access the func - SlangFuncPtr func = sharedLib->findFuncByName(info.name); + SlangFuncPtr func = sharedLibrary->findFuncByName(info.name); if (!func) { - const char* libName = DefaultSharedLibraryLoader::getSharedLibraryNameFromType(info.libraryType); - sink->diagnose(SourceLoc(), Diagnostics::failedToFindFunctionInSharedLibrary, info.name, libName); + UnownedStringSlice compilerName = DownstreamCompiler::getCompilerTypeAsText(SlangPassThrough(info.compilerType)); + sink->diagnose(SourceLoc(), Diagnostics::failedToFindFunctionForCompiler, info.name, compilerName); return nullptr; } // Store in the function cache - sharedLibraryFunctions[int(type)] = func; + m_sharedLibraryFunctions[int(type)] = func; return func; } - DownstreamCompilerSet* Session::requireDownstreamCompilerSet() - { - if (downstreamCompilerSet == nullptr) - { - downstreamCompilerSet = new DownstreamCompilerSet; - - typedef DownstreamCompiler::CompilerType CompilerType; - DownstreamCompilerUtil::InitializeSetDesc desc; - - desc.paths[int(CompilerType::GCC)] = m_downstreamCompilerPaths[int(PassThroughMode::Gcc)]; - desc.paths[int(CompilerType::Clang)] = m_downstreamCompilerPaths[int(PassThroughMode::Clang)]; - desc.paths[int(CompilerType::VisualStudio)] = m_downstreamCompilerPaths[int(PassThroughMode::VisualStudio)]; - - desc.sharedLibraries[int(CompilerType::NVRTC)] = getOrLoadSharedLibrary(SharedLibraryType::NVRTC, nullptr); - - DownstreamCompilerUtil::initializeSet(desc, downstreamCompilerSet); - } - SLANG_ASSERT(downstreamCompilerSet); - return downstreamCompilerSet; - } - TypeCheckingCache* Session::getTypeCheckingCache() { if (!typeCheckingCache) diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index cba25d7df..16d9a5546 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -427,6 +427,7 @@ namespace Slang { "glsl", SourceLanguage::GLSL }, { "c", SourceLanguage::C }, { "cxx", SourceLanguage::CPP }, + { "cuda", SourceLanguage::CUDA }, }; SourceLanguage findSourceLanguageByName(String const& name) @@ -444,6 +445,7 @@ namespace Slang SlangResult checkExternalCompilerSupport(Session* session, PassThroughMode passThrough) { + // Check if the type is supported on this compile switch (passThrough) { case PassThroughMode::None: @@ -451,54 +453,20 @@ namespace Slang // If no pass through -> that will always work! return SLANG_OK; } - case PassThroughMode::Dxc: - { -#if SLANG_ENABLE_DXIL_SUPPORT - // Must have dxc - return session->getOrLoadSharedLibrary(SharedLibraryType::Dxc, nullptr) ? SLANG_OK : SLANG_E_NOT_FOUND; +#if !SLANG_ENABLE_DXIL_SUPPORT + case PassThroughMode::Dxc: return SLANG_E_NOT_IMPLEMENTED; #endif - break; - } - case PassThroughMode::Fxc: - { -#if SLANG_ENABLE_DXBC_SUPPORT - // Must have fxc - return session->getOrLoadSharedLibrary(SharedLibraryType::Fxc, nullptr) ? SLANG_OK : SLANG_E_NOT_FOUND; +#if !SLANG_ENABLE_DXBC_SUPPORT + case PassThroughMode::Fxc: return SLANG_E_NOT_IMPLEMENTED; #endif - break; - } - case PassThroughMode::Glslang: - { -#if SLANG_ENABLE_GLSLANG_SUPPORT - return session->getOrLoadSharedLibrary(Slang::SharedLibraryType::Glslang, nullptr) ? SLANG_OK : SLANG_E_NOT_FOUND; +#if !SLANG_ENABLE_GLSLANG_SUPPORT + case PassThroughMode::Glslang: return SLANG_E_NOT_IMPLEMENTED; #endif - break; - } - case PassThroughMode::Clang: - { - return session->requireDownstreamCompilerSet()->hasCompiler(DownstreamCompiler::CompilerType::Clang) ? SLANG_OK: SLANG_E_NOT_FOUND; - } - case PassThroughMode::VisualStudio: - { - return session->requireDownstreamCompilerSet()->hasCompiler(DownstreamCompiler::CompilerType::VisualStudio) ? SLANG_OK: SLANG_E_NOT_FOUND; - } - case PassThroughMode::Gcc: - { - return session->requireDownstreamCompilerSet()->hasCompiler(DownstreamCompiler::CompilerType::GCC) ? SLANG_OK: SLANG_E_NOT_FOUND; - } - case PassThroughMode::GenericCCpp: - { - List<DownstreamCompiler::Desc> descs; - session->requireDownstreamCompilerSet()->getCompilerDescs(descs); - return descs.getCount() ? SLANG_OK: SLANG_E_NOT_FOUND; - } - case PassThroughMode::NVRTC: - { - return session->requireDownstreamCompilerSet()->hasCompiler(DownstreamCompiler::CompilerType::NVRTC) ? SLANG_OK: SLANG_E_NOT_FOUND; - } + default: break; } - return SLANG_E_NOT_IMPLEMENTED; + + return session->getOrLoadDownstreamCompiler(passThrough, nullptr) ? SLANG_OK: SLANG_E_NOT_FOUND; } PassThroughMode getDownstreamCompilerRequiredForTarget(CodeGenTarget target) @@ -561,20 +529,6 @@ namespace Slang return PassThroughMode::None; } - PassThroughMode getPassThroughModeForDownstreamCompiler(DownstreamCompiler::CompilerType type) - { - typedef DownstreamCompiler::CompilerType CompilerType; - - switch (type) - { - case CompilerType::VisualStudio: return PassThroughMode::VisualStudio; - case CompilerType::GCC: return PassThroughMode::Gcc; - case CompilerType::Clang: return PassThroughMode::Clang; - case CompilerType::NVRTC: return PassThroughMode::NVRTC; - default: return PassThroughMode::None; - } - } - SlangResult checkCompileTargetSupport(Session* session, CodeGenTarget target) { const PassThroughMode mode = getDownstreamCompilerRequiredForTarget(target); @@ -1290,7 +1244,7 @@ SlangResult dissassembleDXILUsingDXC( return SLANG_OK; } - SlangResult emitDownstreamForEntryPoint( + SlangResult emitWithDownstreamForEntryPoint( BackEndCompileRequest* slangRequest, Int entryPointIndex, TargetRequest* targetReq, @@ -1330,8 +1284,8 @@ SlangResult dissassembleDXILUsingDXC( } } - // Get the required downstream CPP compiler - DownstreamCompiler* compiler = session->getDownstreamCompiler(downstreamCompiler); + // Get the required downstream compiler + DownstreamCompiler* compiler = session->getOrLoadDownstreamCompiler(downstreamCompiler, sink); if (!compiler) { @@ -1714,7 +1668,7 @@ SlangResult dissassembleDXILUsingDXC( { RefPtr<DownstreamCompileResult> downstreamResult; - if (SLANG_SUCCEEDED(emitDownstreamForEntryPoint( + if (SLANG_SUCCEEDED(emitWithDownstreamForEntryPoint( compileRequest, entryPointIndex, targetReq, diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index be5251d14..884c1acbc 100644 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -769,7 +769,7 @@ namespace Slang Profile m_profile; }; - enum class PassThroughMode : SlangPassThrough + enum class PassThroughMode : SlangPassThroughIntegral { None = SLANG_PASS_THROUGH_NONE, ///< don't pass through: use Slang compiler Fxc = SLANG_PASS_THROUGH_FXC, ///< pass through HLSL to `D3DCompile` API @@ -1077,9 +1077,7 @@ namespace Slang /// Given a target returns the required downstream compiler PassThroughMode getDownstreamCompilerRequiredForTarget(CodeGenTarget target); - PassThroughMode getPassThroughModeForDownstreamCompiler(DownstreamCompiler::CompilerType type); - - + /// A context for loading and re-using code modules. class Linkage : public RefObject, public slang::ISession { @@ -1836,8 +1834,6 @@ namespace Slang SLANG_NO_THROW SlangPassThrough SLANG_MCALL getDefaultDownstreamCompiler(SlangSourceLanguage sourceLanguage) override; - /// Get the specified compiler - DownstreamCompiler* getDownstreamCompiler(PassThroughMode downstreamCompiler); /// Get the default cpp compiler for a language DownstreamCompiler* getDefaultDownstreamCompiler(SourceLanguage sourceLanguage); @@ -1895,12 +1891,7 @@ namespace Slang RefPtr<Type> stringType; RefPtr<Type> enumTypeType; - RefPtr<DownstreamCompilerSet> downstreamCompilerSet; ///< Information about available C/C++ compilers. null unless information is requested (because slow) - - ComPtr<ISlangSharedLibraryLoader> sharedLibraryLoader; ///< The shared library loader (never null) - ComPtr<ISlangSharedLibrary> sharedLibraries[int(SharedLibraryType::CountOf)]; ///< The loaded shared libraries - SlangFuncPtr sharedLibraryFunctions[int(SharedLibraryFuncType::CountOf)]; - + Dictionary<int, RefPtr<Type>> builtinTypes; Dictionary<String, Decl*> magicDecls; @@ -1963,22 +1954,18 @@ namespace Slang void destroyTypeCheckingCache(); // + void setSharedLibraryLoader(ISlangSharedLibraryLoader* loader); + /// Will try to load the library by specified name (using the set loader), if not one already available. - ISlangSharedLibrary* getOrLoadSharedLibrary(SharedLibraryType type, DiagnosticSink* sink); + DownstreamCompiler* getOrLoadDownstreamCompiler(PassThroughMode type, DiagnosticSink* sink); /// Will unload the specified shared library if it's currently loaded - void setSharedLibrary(SharedLibraryType type, ISlangSharedLibrary* library); - - /// Gets a shared library by type, or null if not loaded - ISlangSharedLibrary* getSharedLibrary(SharedLibraryType type) const { return sharedLibraries[int(type)]; } + void resetDownstreamCompiler(PassThroughMode type); SlangFuncPtr getSharedLibraryFunc(SharedLibraryFuncType type, DiagnosticSink* sink); /// Get the downstream compiler prelude const String& getDownstreamCompilerPrelude(PassThroughMode mode) { return m_downstreamCompilerPreludes[int(mode)]; } - /// Finds out what compilers are present and caches the result - DownstreamCompilerSet* requireDownstreamCompilerSet(); - Session(); void addBuiltinSource( @@ -1987,10 +1974,20 @@ namespace Slang String const& source); ~Session(); + ComPtr<ISlangSharedLibraryLoader> m_sharedLibraryLoader; ///< The shared library loader (never null) + SlangFuncPtr m_sharedLibraryFunctions[int(SharedLibraryFuncType::CountOf)]; ///< Functions from shared libraries + + int m_downstreamCompilerInitialized = 0; + + RefPtr<DownstreamCompilerSet> m_downstreamCompilerSet; ///< Information about all available downstream compilers. + RefPtr<DownstreamCompiler> m_downstreamCompilers[int(PassThroughMode::CountOf)]; ///< A downstream compiler for a pass through + DownstreamCompilerLocatorFunc m_downstreamCompilerLocators[int(PassThroughMode::CountOf)]; + private: SlangResult _loadRequest(EndToEndCompileRequest* request, const void* data, size_t size); + /// Linkage used for all built-in (stdlib) code. RefPtr<Linkage> m_builtinLinkage; diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index d7a45335e..8beb246e7 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -103,7 +103,7 @@ DIAGNOSTIC( 50, Error, duplicateTargets, "the target '$0' has been specified DIAGNOSTIC( 60, Error, cannotDeduceOutputFormatFromPath, "cannot infer an output format from the output path '$0'") DIAGNOSTIC( 61, Error, cannotMatchOutputFileToTarget, "no specified '-target' option matches the output path '$0', which implies the '$1' format") -DIAGNOSTIC( 62, Error, failedToFindFunctionInSharedLibrary, "failed to find function '$0' in shared/dynamic library '$1'") +DIAGNOSTIC( 62, Error, failedToFindFunctionForCompiler, "failed to find function '$0' for downstream compiler '$1'") DIAGNOSTIC( 70, Error, cannotMatchOutputFileToEntryPoint, "the output path '$0' is not associated with any entry point; a '-o' option for a compiled kernel must follow the '-entry' option for its corresponding entry point") diff --git a/source/slang/slang-dxc-support.cpp b/source/slang/slang-dxc-support.cpp index 816de5960..e0ca4df82 100644 --- a/source/slang/slang-dxc-support.cpp +++ b/source/slang/slang-dxc-support.cpp @@ -35,6 +35,8 @@ namespace Slang TargetRequest* targetReq, EndToEndCompileRequest* endToEndReq); + SlangResult locateDXCCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set); + static UnownedStringSlice _getSlice(IDxcBlob* blob) { if (blob) @@ -69,15 +71,6 @@ namespace Slang return SLANG_FAIL; } - { - if (!session->getSharedLibrary(SharedLibraryType::Dxil)) - { - // If can't load dxil - dxc will not be able to sign output - // Output a suitable warning to the user - sink->diagnose(SourceLoc(), Diagnostics::dxilNotFound); - } - } - ComPtr<IDxcCompiler> dxcCompiler; SLANG_RETURN_ON_FAIL(dxcCreateInstance( CLSID_DxcCompiler, diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 45eef5148..9aa7b1203 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -586,7 +586,7 @@ String emitEntryPointSource( DownstreamCompiler* compiler = session->getDefaultDownstreamCompiler(sourceLanguage); if (compiler) { - passThru = getPassThroughModeForDownstreamCompiler(compiler->getDesc().type); + passThru = PassThroughMode(compiler->getDesc().type); } } diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 0319d1f7d..de3c6b0a6 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -46,12 +46,16 @@ static const Guid IID_IModule = SLANG_UUID_IModule; Session::Session() { + ::memset(m_downstreamCompilerLocators, 0, sizeof(m_downstreamCompilerLocators)); + DownstreamCompilerUtil::setDefaultLocators(m_downstreamCompilerLocators); + m_downstreamCompilerSet = new DownstreamCompilerSet; + // Initialize name pool getNamePool()->setRootNamePool(getRootNamePool()); - sharedLibraryLoader = DefaultSharedLibraryLoader::getSingleton(); + m_sharedLibraryLoader = DefaultSharedLibraryLoader::getSingleton(); // Set all the shared library function pointers to nullptr - ::memset(sharedLibraryFunctions, 0, sizeof(sharedLibraryFunctions)); + ::memset(m_sharedLibraryFunctions, 0, sizeof(m_sharedLibraryFunctions)); // Initialize the lookup table of syntax classes: @@ -169,44 +173,8 @@ SLANG_NO_THROW void SLANG_MCALL Session::setDownstreamCompilerPath( if (m_downstreamCompilerPaths[int(passThrough)] != path) { - // If it's changed we should unload any shared libraries that use it - switch (passThrough) - { - case PassThroughMode::Dxc: - { - setSharedLibrary(SharedLibraryType::Dxc, nullptr); - setSharedLibrary(SharedLibraryType::Dxil, nullptr); - break; - } - case PassThroughMode::Fxc: - { - setSharedLibrary(SharedLibraryType::Fxc, nullptr); - break; - } - case PassThroughMode::Glslang: - { - setSharedLibrary(SharedLibraryType::Glslang, nullptr); - break; - } - case PassThroughMode::VisualStudio: - case PassThroughMode::Gcc: - case PassThroughMode::Clang: - case PassThroughMode::GenericCCpp: - { - // If any compiler path set changed, require all to be refreshed - downstreamCompilerSet.setNull(); - break; - } - case PassThroughMode::NVRTC: - { - // TODO(JS): We need a way to set the NVRTC path. - // We want to unload... and try again... - downstreamCompilerSet.setNull(); - break; - } - default: break; - } - + // Make access redetermine compiler + resetDownstreamCompiler(passThrough); // Set the path m_downstreamCompilerPaths[int(passThrough)] = path; } @@ -287,24 +255,9 @@ SlangPassThrough SLANG_MCALL Session::getDefaultDownstreamCompiler(SlangSourceLa return SlangPassThrough(m_defaultDownstreamCompilers[int(sourceLanguage)]); } -DownstreamCompiler* Session::getDownstreamCompiler(PassThroughMode compiler) -{ - DownstreamCompilerSet* compilerSet = requireDownstreamCompilerSet(); - switch (compiler) - { - case PassThroughMode::GenericCCpp: return compilerSet->getDefaultCompiler(DownstreamCompiler::SourceType::CPP); - case PassThroughMode::Clang: return DownstreamCompilerUtil::findCompiler(compilerSet, DownstreamCompilerUtil::MatchType::Newest, DownstreamCompiler::Desc(DownstreamCompiler::CompilerType::Clang)); - case PassThroughMode::VisualStudio: return DownstreamCompilerUtil::findCompiler(compilerSet, DownstreamCompilerUtil::MatchType::Newest, DownstreamCompiler::Desc(DownstreamCompiler::CompilerType::VisualStudio)); - case PassThroughMode::Gcc: return DownstreamCompilerUtil::findCompiler(compilerSet, DownstreamCompilerUtil::MatchType::Newest, DownstreamCompiler::Desc(DownstreamCompiler::CompilerType::GCC)); - case PassThroughMode::NVRTC: return compilerSet->getDefaultCompiler(DownstreamCompiler::SourceType::CUDA); - default: break; - } - return nullptr; -} - DownstreamCompiler* Session::getDefaultDownstreamCompiler(SourceLanguage sourceLanguage) { - return getDownstreamCompiler(m_defaultDownstreamCompilers[int(sourceLanguage)]); + return getOrLoadDownstreamCompiler(m_defaultDownstreamCompilers[int(sourceLanguage)], nullptr); } ISlangFileSystemExt* IncludeHandlerImpl::_getFileSystemExt() @@ -2618,34 +2571,15 @@ SLANG_API void spSessionSetSharedLibraryLoader( ISlangSharedLibraryLoader* loader) { auto s = Slang::asInternal(session); - - if (!loader) - { - // If null set the default - loader = Slang::DefaultSharedLibraryLoader::getSingleton(); - } - - if (s->sharedLibraryLoader != loader) - { - // Need to clear all of the libraries - for (int i = 0; i < SLANG_COUNT_OF(s->sharedLibraries); ++i) - { - s->sharedLibraries[i].setNull(); - } - - // Clear all of the functions - ::memset(s->sharedLibraryFunctions, 0, sizeof(s->sharedLibraryFunctions)); - - // Set the loader - s->sharedLibraryLoader = loader; - } + loader = loader ? loader : Slang::DefaultSharedLibraryLoader::getSingleton(); + s->setSharedLibraryLoader(loader); } SLANG_API ISlangSharedLibraryLoader* spSessionGetSharedLibraryLoader( SlangSession* session) { auto s = Slang::asInternal(session); - return (s->sharedLibraryLoader == Slang::DefaultSharedLibraryLoader::getSingleton()) ? nullptr : s->sharedLibraryLoader.get(); + return (s->m_sharedLibraryLoader == Slang::DefaultSharedLibraryLoader::getSingleton()) ? nullptr : s->m_sharedLibraryLoader.get(); } SLANG_API SlangResult spSessionCheckCompileTargetSupport( |
