diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-12-12 11:39:19 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-12-12 11:39:19 -0500 |
| commit | 6e6a876a6b5ad3d2ef402757d2e20641f5a2b49b (patch) | |
| tree | 29eab69c4982537376d7eaf422d9090c849e95f7 /source/core | |
| parent | 79ec0cfdb5f3461c763e0bf712cf42eb87fccb90 (diff) | |
Slang compiles CUDA source via NVRTC (#1151)
* 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.
* Fix warning on clang.
Diffstat (limited to 'source/core')
| -rw-r--r-- | source/core/core.vcxproj | 2 | ||||
| -rw-r--r-- | source/core/core.vcxproj.filters | 6 | ||||
| -rw-r--r-- | source/core/slang-downstream-compiler.cpp | 74 | ||||
| -rw-r--r-- | source/core/slang-downstream-compiler.h | 35 | ||||
| -rw-r--r-- | source/core/slang-hex-dump-util.cpp | 7 | ||||
| -rw-r--r-- | source/core/slang-nvrtc-compiler.cpp | 369 | ||||
| -rw-r--r-- | source/core/slang-nvrtc-compiler.h | 20 | ||||
| -rw-r--r-- | source/core/slang-shared-library.cpp | 17 | ||||
| -rw-r--r-- | source/core/slang-shared-library.h | 5 | ||||
| -rw-r--r-- | source/core/slang-visual-studio-compiler-util.cpp | 4 |
10 files changed, 525 insertions, 14 deletions
diff --git a/source/core/core.vcxproj b/source/core/core.vcxproj index b0f33f2a2..b10bcc683 100644 --- a/source/core/core.vcxproj +++ b/source/core/core.vcxproj @@ -188,6 +188,7 @@ <ClInclude Include="slang-list.h" /> <ClInclude Include="slang-math.h" /> <ClInclude Include="slang-memory-arena.h" /> + <ClInclude Include="slang-nvrtc-compiler.h" /> <ClInclude Include="slang-object-scope-manager.h" /> <ClInclude Include="slang-offset-container.h" /> <ClInclude Include="slang-platform.h" /> @@ -221,6 +222,7 @@ <ClCompile Include="slang-hex-dump-util.cpp" /> <ClCompile Include="slang-io.cpp" /> <ClCompile Include="slang-memory-arena.cpp" /> + <ClCompile Include="slang-nvrtc-compiler.cpp" /> <ClCompile Include="slang-object-scope-manager.cpp" /> <ClCompile Include="slang-offset-container.cpp" /> <ClCompile Include="slang-platform.cpp" /> diff --git a/source/core/core.vcxproj.filters b/source/core/core.vcxproj.filters index 44d199771..b296b23af 100644 --- a/source/core/core.vcxproj.filters +++ b/source/core/core.vcxproj.filters @@ -63,6 +63,9 @@ <ClInclude Include="slang-memory-arena.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="slang-nvrtc-compiler.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="slang-object-scope-manager.h"> <Filter>Header Files</Filter> </ClInclude> @@ -158,6 +161,9 @@ <ClCompile Include="slang-memory-arena.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="slang-nvrtc-compiler.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="slang-object-scope-manager.cpp"> <Filter>Source Files</Filter> </ClCompile> diff --git a/source/core/slang-downstream-compiler.cpp b/source/core/slang-downstream-compiler.cpp index 52ec2fcd7..9532cf17f 100644 --- a/source/core/slang-downstream-compiler.cpp +++ b/source/core/slang-downstream-compiler.cpp @@ -16,6 +16,7 @@ #include "slang-visual-studio-compiler-util.h" #include "slang-gcc-compiler-util.h" +#include "slang-nvrtc-compiler.h" namespace Slang { @@ -57,6 +58,7 @@ void DownstreamCompiler::Desc::appendAsText(StringBuilder& out) const 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"); } } @@ -212,6 +214,38 @@ SlangResult CommandLineDownstreamCompileResult::getBinary(ComPtr<ISlangBlob>& ou /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CommandLineDownstreamCompiler !!!!!!!!!!!!!!!!!!!!!!*/ +static bool _isContentsInFile(const DownstreamCompiler::CompileOptions& options) +{ + if (options.sourceContentsPath.getLength() <= 0) + { + return false; + } + + // We can see if we can load it + if (File::exists(options.sourceContentsPath)) + { + // Here we look for the file on the regular file system (as opposed to using the + // ISlangFileSystem. This is unfortunate but necessary - because when we call out + // to the compiler all it is able to (currently) see are files on the file system. + // + // Note that it could be coincidence that the filesystem has a file that's identical in + // contents/name. That being the case though, any includes wouldn't work for a generated + // file either from some specialized ISlangFileSystem, so this is probably as good as it gets + // until we can integrate directly to a C/C++ compiler through say a shared library where we can control + // file system access. + try + { + String readContents = File::readAllText(options.sourceContentsPath); + // We should see if they are the same + return options.sourceContents == readContents.getUnownedSlice(); + } + catch (const Slang::IOException&) + { + } + } + return false; +} + SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptions, RefPtr<DownstreamCompileResult>& out) { // Copy the command line options @@ -232,8 +266,12 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio SLANG_RETURN_ON_FAIL(File::generateTemporary(UnownedStringSlice::fromLiteral("slang-generated"), modulePath)); options.modulePath = modulePath; } - - if (options.sourceContents.getLength() != 0) + + if (_isContentsInFile(options)) + { + options.sourceFiles.add(options.sourceContentsPath); + } + else { String compileSourcePath = modulePath; @@ -264,10 +302,11 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio // Add it as a source file options.sourceFiles.add(compileSourcePath); - - // There is no source contents - options.sourceContents = String(); } + + // There is no source contents + options.sourceContents = String(); + options.sourceContentsPath = String(); } // Append command line args to the end of cmdLine using the target specific function for the specified options @@ -488,8 +527,29 @@ static void _addGCCFamilyCompiler(const String& path, const String& inExeName, D _addGCCFamilyCompiler(desc.getPath(CompilerType::Clang), "clang", set); _addGCCFamilyCompiler(desc.getPath(CompilerType::GCC), "g++", set); - // Set the default to the compiler closest to how this source was compiled - set->setDefaultCompiler(findClosestCompiler(set, getCompiledWithDesc())); + { + DownstreamCompiler* cppCompiler = findClosestCompiler(set, getCompiledWithDesc()); + + // 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); + } + + // Lets see if we have NVRTC. + { + ISlangSharedLibrary* sharedLibrary = desc.sharedLibraries[int(CompilerType::NVRTC)]; + if (sharedLibrary) + { + RefPtr<DownstreamCompiler> compiler; + if (SLANG_SUCCEEDED(NVRTCDownstreamCompilerUtil::createCompiler(sharedLibrary, compiler))) + { + set->addCompiler(compiler); + + set->setDefaultCompiler(DownstreamCompiler::SourceType::CUDA, compiler); + } + } + } + return SLANG_OK; } diff --git a/source/core/slang-downstream-compiler.h b/source/core/slang-downstream-compiler.h index 12cf54a91..99bcfd29f 100644 --- a/source/core/slang-downstream-compiler.h +++ b/source/core/slang-downstream-compiler.h @@ -94,6 +94,25 @@ protected: DownstreamDiagnostics m_diagnostics; }; + +class BlobDownstreamCompileResult : public DownstreamCompileResult +{ +public: + typedef DownstreamCompileResult Super; + + virtual SlangResult getHostCallableSharedLibrary(ComPtr<ISlangSharedLibrary>& outLibrary) SLANG_OVERRIDE { SLANG_UNUSED(outLibrary); return SLANG_FAIL; } + virtual SlangResult getBinary(ComPtr<ISlangBlob>& outBlob) SLANG_OVERRIDE { outBlob = m_blob; return m_blob ? SLANG_OK : SLANG_FAIL; } + + BlobDownstreamCompileResult(const DownstreamDiagnostics& diags, ISlangBlob* blob): + Super(diags), + m_blob(blob) + { + + } +protected: + ComPtr<ISlangBlob> m_blob; +}; + class DownstreamCompiler: public RefObject { public: @@ -109,12 +128,15 @@ public: Clang, SNC, GHS, + NVRTC, CountOf, }; enum class SourceType { C, ///< C source CPP, ///< C++ source + CUDA, ///< The CUDA language + CountOf, }; struct Desc @@ -205,6 +227,9 @@ public: /// The contents of the source to compile. This can be empty is sourceFiles is set. /// If the compiler is a commandLine file this source will be written to a temporary file. String sourceContents; + /// 'Path' that the contents originated from. NOTE! This is for reporting only and doesn't have to exist on file system + String sourceContentsPath; + /// The names/paths of source to compile. This can be empty if sourceContents is set. List<String> sourceFiles; @@ -249,6 +274,7 @@ protected: DownstreamCompiler(const Desc& desc) : m_desc(desc) {} + DownstreamCompiler() {} Desc m_desc; }; @@ -332,9 +358,9 @@ public: void addCompiler(DownstreamCompiler* compiler); /// Get a default compiler - DownstreamCompiler* getDefaultCompiler() const { return m_defaultCompiler; } + DownstreamCompiler* getDefaultCompiler(DownstreamCompiler::SourceType sourceType) const { return m_defaultCompilers[int(sourceType)]; } /// Set the default compiler - void setDefaultCompiler(DownstreamCompiler* compiler) { m_defaultCompiler = compiler; } + 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; @@ -343,7 +369,7 @@ protected: Index _findIndex(const DownstreamCompiler::Desc& desc) const; - RefPtr<DownstreamCompiler> m_defaultCompiler; + RefPtr<DownstreamCompiler> m_defaultCompilers[int(DownstreamCompiler::SourceType::CountOf)]; // This could be a dictionary/map - but doing a linear search is going to be fine and it makes // somethings easier. List<RefPtr<DownstreamCompiler>> m_compilers; @@ -380,7 +406,10 @@ struct DownstreamCompilerUtil: public DownstreamCompilerBaseUtil 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 diff --git a/source/core/slang-hex-dump-util.cpp b/source/core/slang-hex-dump-util.cpp index 1583d8461..b0bd6f923 100644 --- a/source/core/slang-hex-dump-util.cpp +++ b/source/core/slang-hex-dump-util.cpp @@ -75,6 +75,13 @@ static const char s_hex[] = "0123456789abcdef"; *dst++ = s_hex[byte & 0xf]; } + // If not a complete line write spaces + for (size_t i = count; i < size_t(maxBytesPerLine); ++i) + { + *dst++ = ' '; + *dst++ = ' '; + } + *dst++ = ' '; for (size_t i = 0; i < count; ++i) diff --git a/source/core/slang-nvrtc-compiler.cpp b/source/core/slang-nvrtc-compiler.cpp new file mode 100644 index 000000000..e812a2ab9 --- /dev/null +++ b/source/core/slang-nvrtc-compiler.cpp @@ -0,0 +1,369 @@ +// slang-nvrtc-compiler.cpp +#include "slang-nvrtc-compiler.h" + +#include "slang-common.h" +#include "../../slang-com-helper.h" + +#include "../core/slang-blob.h" + +#include "slang-string-util.h" + +#include "slang-io.h" +#include "slang-shared-library.h" + +namespace nvrtc +{ + +typedef enum { + NVRTC_SUCCESS = 0, + NVRTC_ERROR_OUT_OF_MEMORY = 1, + NVRTC_ERROR_PROGRAM_CREATION_FAILURE = 2, + NVRTC_ERROR_INVALID_INPUT = 3, + NVRTC_ERROR_INVALID_PROGRAM = 4, + NVRTC_ERROR_INVALID_OPTION = 5, + NVRTC_ERROR_COMPILATION = 6, + NVRTC_ERROR_BUILTIN_OPERATION_FAILURE = 7, + NVRTC_ERROR_NO_NAME_EXPRESSIONS_AFTER_COMPILATION = 8, + NVRTC_ERROR_NO_LOWERED_NAMES_BEFORE_COMPILATION = 9, + NVRTC_ERROR_NAME_EXPRESSION_NOT_VALID = 10, + NVRTC_ERROR_INTERNAL_ERROR = 11 +} nvrtcResult; + +typedef struct _nvrtcProgram *nvrtcProgram; + +#define SLANG_NVRTC_FUNCS(x) \ + x(const char*, nvrtcGetErrorString, (nvrtcResult result)) \ + x(nvrtcResult, nvrtcVersion, (int *major, int *minor)) \ + x(nvrtcResult, nvrtcCreateProgram, (nvrtcProgram *prog, const char *src, const char *name, int numHeaders, const char * const *headers, const char * const *includeNames)) \ + x(nvrtcResult, nvrtcDestroyProgram, (nvrtcProgram *prog)) \ + x(nvrtcResult, nvrtcCompileProgram, (nvrtcProgram prog, int numOptions, const char * const *options)) \ + x(nvrtcResult, nvrtcGetPTXSize, (nvrtcProgram prog, size_t *ptxSizeRet)) \ + x(nvrtcResult, nvrtcGetPTX, (nvrtcProgram prog, char *ptx)) \ + x(nvrtcResult, nvrtcGetProgramLogSize, (nvrtcProgram prog, size_t *logSizeRet)) \ + x(nvrtcResult, nvrtcGetProgramLog, (nvrtcProgram prog, char *log))\ + x(nvrtcResult, nvrtcAddNameExpression, (nvrtcProgram prog, const char * const name_expression)) \ + x(nvrtcResult, nvrtcGetLoweredName, (nvrtcProgram prog, const char *const name_expression, const char** lowered_name)) + +} // namespace nvrtc + +namespace Slang +{ +using namespace nvrtc; + +static SlangResult _asResult(nvrtcResult res) +{ + switch (res) + { + case NVRTC_SUCCESS: + { + return SLANG_OK; + } + case NVRTC_ERROR_OUT_OF_MEMORY: + { + return SLANG_E_OUT_OF_MEMORY; + } + case NVRTC_ERROR_PROGRAM_CREATION_FAILURE: + case NVRTC_ERROR_INVALID_INPUT: + case NVRTC_ERROR_INVALID_PROGRAM: + { + return SLANG_FAIL; + } + case NVRTC_ERROR_INVALID_OPTION: + { + return SLANG_E_INVALID_ARG; + } + case NVRTC_ERROR_COMPILATION: + case NVRTC_ERROR_BUILTIN_OPERATION_FAILURE: + case NVRTC_ERROR_NO_NAME_EXPRESSIONS_AFTER_COMPILATION: + case NVRTC_ERROR_NO_LOWERED_NAMES_BEFORE_COMPILATION: + case NVRTC_ERROR_NAME_EXPRESSION_NOT_VALID: + { + return SLANG_FAIL; + } + case NVRTC_ERROR_INTERNAL_ERROR: + { + return SLANG_E_INTERNAL_FAIL; + } + default: return SLANG_FAIL; + } +} + +class NVRTCDownstreamCompiler : public DownstreamCompiler +{ +public: + typedef DownstreamCompiler Super; + + // DownstreamCompiler + virtual SlangResult compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE; + + /// Must be called before use + SlangResult init(ISlangSharedLibrary* library); + + NVRTCDownstreamCompiler() {} + +protected: + + struct ScopeProgram + { + ScopeProgram(NVRTCDownstreamCompiler* compiler, nvrtcProgram program): + m_compiler(compiler), + m_program(program) + { + } + ~ScopeProgram() + { + m_compiler->m_nvrtcDestroyProgram(&m_program); + } + NVRTCDownstreamCompiler* m_compiler; + nvrtcProgram m_program; + }; + + +#define SLANG_NVTRC_MEMBER_FUNCS(ret, name, params) \ + ret (*m_##name) params; + + SLANG_NVRTC_FUNCS(SLANG_NVTRC_MEMBER_FUNCS); + + ComPtr<ISlangSharedLibrary> m_sharedLibrary; +}; + +#define SLANG_NVRTC_RETURN_ON_FAIL(x) { nvrtcResult _res = x; if (_res != NVRTC_SUCCESS) return _asResult(_res); } + +SlangResult NVRTCDownstreamCompiler::init(ISlangSharedLibrary* library) +{ +#define SLANG_NVTRC_GET_FUNC(ret, name, params) \ + m_##name = (ret (*) params)library->findFuncByName(#name); \ + if (m_##name == nullptr) return SLANG_FAIL; + + SLANG_NVRTC_FUNCS(SLANG_NVTRC_GET_FUNC) + + m_sharedLibrary = library; + + m_desc.type = CompilerType::NVRTC; + + int major, minor; + m_nvrtcVersion(&major, &minor); + m_desc.majorVersion = major; + m_desc.minorVersion = minor; + + return SLANG_OK; +} + +static SlangResult _parseLocation(const UnownedStringSlice& in, DownstreamDiagnostic& outDiagnostic) +{ + const Index startIndex = in.indexOf('('); + + if (startIndex >= 0) + { + outDiagnostic.filePath = UnownedStringSlice(in.begin(), in.begin() + startIndex); + UnownedStringSlice remaining(in.begin() + startIndex + 1, in.end()); + const Int endIndex = remaining.indexOf(')'); + + UnownedStringSlice lineText = UnownedStringSlice(remaining.begin(), remaining.begin() + endIndex); + + Int line; + SLANG_RETURN_ON_FAIL(StringUtil::parseInt(lineText, line)); + outDiagnostic.fileLine = line; + } + else + { + outDiagnostic.fileLine = 0; + outDiagnostic.filePath = in; + } + return SLANG_OK; +} + +static SlangResult _parseNVRTCLine(const UnownedStringSlice& line, DownstreamDiagnostic& outDiagnostic) +{ + typedef DownstreamDiagnostic Diagnostic; + typedef Diagnostic::Type Type; + + outDiagnostic.stage = Diagnostic::Stage::Compile; + + List<UnownedStringSlice> split; + StringUtil::split(line, ':', split); + + if (split.getCount() == 3) + { + // tests/cuda/cuda-compile.cu(7): warning: variable "c" is used before its value is set + + const auto split1 = split[1].trim(); + + if (split1 == "error") + { + outDiagnostic.type = Type::Error; + } + else if (split1 == "warning") + { + outDiagnostic.type = Type::Warning; + } + outDiagnostic.text = split[2].trim(); + + SLANG_RETURN_ON_FAIL(_parseLocation(split[0], outDiagnostic)); + return SLANG_OK; + } + + return SLANG_E_NOT_FOUND; +} + +SlangResult NVRTCDownstreamCompiler::compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) +{ + // This compiler doesn't read files, they should be read externally and stored in sourceContents/sourceContentsPath + if (options.sourceFiles.getCount() > 0) + { + return SLANG_FAIL; + } + + CommandLine cmdLine; + + switch (options.debugInfoType) + { + case DebugInfoType::None: + { + break; + } + default: + { + cmdLine.addArg("--device-debug"); + break; + } + case DebugInfoType::Maximal: + { + cmdLine.addArg("--device-debug"); + cmdLine.addArg("--generate-line-info"); + break; + } + } + + // Don't seem to have such a control, so ignore for now + //switch (options.optimizationLevel) + //{ + // default: break; + //} + + switch (options.floatingPointMode) + { + case FloatingPointMode::Default: break; + case FloatingPointMode::Precise: + { + break; + } + case FloatingPointMode::Fast: + { + cmdLine.addArg("--use_fast_math"); + break; + } + } + + // Add defines + for (const auto& define : options.defines) + { + StringBuilder builder; + builder << "-D"; + builder << define.nameWithSig; + if (define.value.getLength()) + { + builder << "=" << define.value; + } + + cmdLine.addArg(builder); + } + + // Add includes + for (const auto& include : options.includePaths) + { + cmdLine.addArg("-I"); + cmdLine.addArg(include); + } + + + nvrtcProgram program = nullptr; + nvrtcResult res = m_nvrtcCreateProgram(&program, options.sourceContents.getBuffer(), options.sourceContentsPath.getBuffer(), 0, nullptr, nullptr); + if (res != NVRTC_SUCCESS) + { + return _asResult(res); + } + ScopeProgram scope(this, program); + + List<const char*> dstOptions; + dstOptions.setCount(cmdLine.m_args.getCount()); + for (Index i = 0; i < cmdLine.m_args.getCount(); ++i) + { + dstOptions[i] = cmdLine.m_args[i].value.getBuffer(); + } + + res = m_nvrtcCompileProgram(program, int(dstOptions.getCount()), dstOptions.getBuffer()); + + RefPtr<ListBlob> blob; + DownstreamDiagnostics diagnostics; + + diagnostics.result = _asResult(res); + + { + String rawDiagnostics; + + size_t logSize = 0; + SLANG_NVRTC_RETURN_ON_FAIL(m_nvrtcGetProgramLogSize(program, &logSize)); + + if (logSize) + { + char* dst = rawDiagnostics.prepareForAppend(Index(logSize)); + SLANG_NVRTC_RETURN_ON_FAIL(m_nvrtcGetProgramLog(program, dst)); + rawDiagnostics.appendInPlace(dst, Index(logSize)); + + diagnostics.rawDiagnostics = rawDiagnostics; + } + + // Parse the diagnostics here + for (auto line : LineParser(diagnostics.rawDiagnostics.getUnownedSlice())) + { + DownstreamDiagnostic diagnostic; + SlangResult lineRes = _parseNVRTCLine(line, diagnostic); + + if (SLANG_SUCCEEDED(lineRes)) + { + diagnostics.diagnostics.add(diagnostic); + } + else if (lineRes != SLANG_E_NOT_FOUND) + { + return lineRes; + } + } + + // if it has a compilation error.. set on output + if (diagnostics.has(DownstreamDiagnostic::Type::Error)) + { + diagnostics.result = SLANG_FAIL; + } + } + + if (res == nvrtc::NVRTC_SUCCESS) + { + // We should parse the log to set up the diagnostics + size_t ptxSize; + SLANG_NVRTC_RETURN_ON_FAIL(m_nvrtcGetPTXSize(program, &ptxSize)); + + List<uint8_t> ptx; + ptx.setCount(Index(ptxSize)); + + SLANG_NVRTC_RETURN_ON_FAIL(m_nvrtcGetPTX(program, (char*)ptx.getBuffer())); + + blob = ListBlob::moveCreate(ptx); + } + + outResult = new BlobDownstreamCompileResult(diagnostics, blob); + + return SLANG_OK; +} + +/* static */SlangResult NVRTCDownstreamCompilerUtil::createCompiler(ISlangSharedLibrary* library, RefPtr<DownstreamCompiler>& outCompiler) +{ + RefPtr<NVRTCDownstreamCompiler> compiler(new NVRTCDownstreamCompiler); + + SLANG_RETURN_ON_FAIL(compiler->init(library)); + + outCompiler = compiler; + return SLANG_OK; +} + +} diff --git a/source/core/slang-nvrtc-compiler.h b/source/core/slang-nvrtc-compiler.h new file mode 100644 index 000000000..91cd92b8c --- /dev/null +++ b/source/core/slang-nvrtc-compiler.h @@ -0,0 +1,20 @@ +#ifndef SLANG_NVRTC_COMPILER_UTIL_H +#define SLANG_NVRTC_COMPILER_UTIL_H + +#include "slang-downstream-compiler.h" + +#include "../core/slang-platform.h" + +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); +}; + +} + +#endif diff --git a/source/core/slang-shared-library.cpp b/source/core/slang-shared-library.cpp index fd61ba0a0..2b18ad6aa 100644 --- a/source/core/slang-shared-library.cpp +++ b/source/core/slang-shared-library.cpp @@ -22,6 +22,7 @@ static const Guid IID_ISlangSharedLibraryLoader = SLANG_UUID_ISlangSharedLibrary "d3dcompiler_47", // SharedLibraryType::Fxc "slang-glslang", // SharedLibraryType::Glslang "dxil", // SharedLibraryType::Dxil + "nvrtc64_102_0", // SharedLibraryType::NVRTC }; /* static */DefaultSharedLibraryLoader DefaultSharedLibraryLoader::s_singleton; @@ -44,13 +45,23 @@ ISlangUnknown* DefaultSharedLibraryLoader::getInterface(const Guid& guid) return (guid == IID_ISlangUnknown || guid == IID_ISlangSharedLibraryLoader) ? static_cast<ISlangSharedLibraryLoader*>(this) : nullptr; } -SlangResult DefaultSharedLibraryLoader::loadSharedLibrary(const char* path, ISlangSharedLibrary** sharedLibraryOut) +SlangResult DefaultSharedLibraryLoader::loadSharedLibrary(const char* path, ISlangSharedLibrary** outSharedLibrary) { - *sharedLibraryOut = nullptr; + *outSharedLibrary = nullptr; // Try loading SharedLibrary::Handle handle; SLANG_RETURN_ON_FAIL(SharedLibrary::load(path, handle)); - *sharedLibraryOut = ComPtr<ISlangSharedLibrary>(new DefaultSharedLibrary(handle)).detach(); + *outSharedLibrary = ComPtr<ISlangSharedLibrary>(new DefaultSharedLibrary(handle)).detach(); + return SLANG_OK; +} + +SlangResult DefaultSharedLibraryLoader::loadPlatformSharedLibrary(const char* path, ISlangSharedLibrary** outSharedLibrary) +{ + *outSharedLibrary = nullptr; + // Try loading + SharedLibrary::Handle handle; + SLANG_RETURN_ON_FAIL(SharedLibrary::loadWithPlatformPath(path, handle)); + *outSharedLibrary = ComPtr<ISlangSharedLibrary>(new DefaultSharedLibrary(handle)).detach(); return SLANG_OK; } diff --git a/source/core/slang-shared-library.h b/source/core/slang-shared-library.h index 517292908..9c58d4e10 100644 --- a/source/core/slang-shared-library.h +++ b/source/core/slang-shared-library.h @@ -21,6 +21,7 @@ enum class SharedLibraryType Fxc, ///< Fxc compiler Glslang, ///< Slang specific glslang compiler Dxil, ///< Dxil is used with dxc + NVRTC, ///< Nvrtc compiler CountOf, }; @@ -36,7 +37,9 @@ public: // ISlangSharedLibraryLoader virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadSharedLibrary(const char* path, - ISlangSharedLibrary** sharedLibraryOut) SLANG_OVERRIDE; + ISlangSharedLibrary** outSharedLibrary) SLANG_OVERRIDE; + + SlangResult loadPlatformSharedLibrary(const char* path, ISlangSharedLibrary** outSharedLibrary); /// Get the singleton static DefaultSharedLibraryLoader* getSingleton() { return &s_singleton; } diff --git a/source/core/slang-visual-studio-compiler-util.cpp b/source/core/slang-visual-studio-compiler-util.cpp index 8797c3384..356f21a25 100644 --- a/source/core/slang-visual-studio-compiler-util.cpp +++ b/source/core/slang-visual-studio-compiler-util.cpp @@ -119,6 +119,10 @@ namespace Slang cmdLine.addArg("/MD"); break; } + case DebugInfoType::None: + { + break; + } case DebugInfoType::Maximal: { // Multithreaded statically linked *debug* runtime library |
