summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-12-12 11:39:19 -0500
committerGitHub <noreply@github.com>2019-12-12 11:39:19 -0500
commit6e6a876a6b5ad3d2ef402757d2e20641f5a2b49b (patch)
tree29eab69c4982537376d7eaf422d9090c849e95f7 /source/core
parent79ec0cfdb5f3461c763e0bf712cf42eb87fccb90 (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.vcxproj2
-rw-r--r--source/core/core.vcxproj.filters6
-rw-r--r--source/core/slang-downstream-compiler.cpp74
-rw-r--r--source/core/slang-downstream-compiler.h35
-rw-r--r--source/core/slang-hex-dump-util.cpp7
-rw-r--r--source/core/slang-nvrtc-compiler.cpp369
-rw-r--r--source/core/slang-nvrtc-compiler.h20
-rw-r--r--source/core/slang-shared-library.cpp17
-rw-r--r--source/core/slang-shared-library.h5
-rw-r--r--source/core/slang-visual-studio-compiler-util.cpp4
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