summaryrefslogtreecommitdiffstats
path: root/source/compiler-core
diff options
context:
space:
mode:
Diffstat (limited to 'source/compiler-core')
-rw-r--r--source/compiler-core/slang-downstream-compiler.cpp72
-rw-r--r--source/compiler-core/slang-downstream-compiler.h40
-rw-r--r--source/compiler-core/slang-dxc-compiler.cpp57
-rw-r--r--source/compiler-core/slang-fxc-compiler.cpp63
-rw-r--r--source/compiler-core/slang-glslang-compiler.cpp300
-rw-r--r--source/compiler-core/slang-glslang-compiler.h18
-rw-r--r--source/compiler-core/slang-nvrtc-compiler.cpp1
7 files changed, 393 insertions, 158 deletions
diff --git a/source/compiler-core/slang-downstream-compiler.cpp b/source/compiler-core/slang-downstream-compiler.cpp
index 9721b45d3..f5f1b84c9 100644
--- a/source/compiler-core/slang-downstream-compiler.cpp
+++ b/source/compiler-core/slang-downstream-compiler.cpp
@@ -10,6 +10,7 @@
#include "../core/slang-io.h"
#include "../core/slang-shared-library.h"
#include "../core/slang-blob.h"
+#include "../core/slang-char-util.h"
#ifdef SLANG_VC
# include "windows/slang-win-visual-studio-util.h"
@@ -20,6 +21,7 @@
#include "slang-nvrtc-compiler.h"
#include "slang-fxc-compiler.h"
#include "slang-dxc-compiler.h"
+#include "slang-glslang-compiler.h"
namespace Slang
{
@@ -114,9 +116,57 @@ void DownstreamCompiler::Desc::appendAsText(StringBuilder& out) const
return SLANG_OK;
}
+/* static */SlangResult DownstreamDiagnostic::splitColonDelimitedLine(const UnownedStringSlice& line, Int pathIndex, List<UnownedStringSlice>& outSlices)
+{
+ StringUtil::split(line, ':', outSlices);
+
+ // Now we want to fix up a path as might have drive letter, and therefore :
+ // If this is the situation then we need to have a slice after the one at the index
+ if (outSlices.getCount() > pathIndex + 1)
+ {
+ const UnownedStringSlice pathStart = outSlices[pathIndex].trim();
+ if (pathStart.getLength() == 1 && CharUtil::isAlpha(pathStart[0]))
+ {
+ // Splice back together
+ outSlices[pathIndex] = UnownedStringSlice(outSlices[pathIndex].begin(), outSlices[pathIndex + 1].end());
+ outSlices.removeAt(pathIndex + 1);
+ }
+ }
+
+ return SLANG_OK;
+}
+
+/* static */SlangResult DownstreamDiagnostic::parseColonDelimitedDiagnostics(const UnownedStringSlice& inText, Int pathIndex, LineParser lineParser, List<DownstreamDiagnostic>& outDiagnostics)
+{
+ List<UnownedStringSlice> splitLine;
+
+ UnownedStringSlice text(inText), line;
+ while (StringUtil::extractLine(text, line))
+ {
+ SLANG_RETURN_ON_FAIL(splitColonDelimitedLine(line, pathIndex, splitLine));
+
+ DownstreamDiagnostic diagnostic;
+ diagnostic.severity = DownstreamDiagnostic::Severity::Error;
+ diagnostic.stage = DownstreamDiagnostic::Stage::Compile;
+ diagnostic.fileLine = 0;
+
+ if (SLANG_SUCCEEDED(lineParser(line, splitLine, diagnostic)))
+ {
+ outDiagnostics.add(diagnostic);
+ }
+ else
+ {
+ // If couldn't parse, just add as a note
+ DownstreamDiagnostics::addNote(line, outDiagnostics);
+ }
+ }
+
+ return SLANG_OK;
+}
+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamCompiler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
-SlangResult DownstreamCompiler::dissassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out)
+SlangResult DownstreamCompiler::disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out)
{
SLANG_UNUSED(sourceBlobTarget);
SLANG_UNUSED(blob);
@@ -676,24 +726,6 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
}
}
-static SlangResult _locateGlslangCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set)
-{
-#if SLANG_UNIX_FAMILY
- // On unix systems we need to ensure pthread is loaded first.
- ComPtr<ISlangSharedLibrary> pthreadLibrary;
- DefaultSharedLibraryLoader::load(loader, path, "pthread", pthreadLibrary.writeRef());
-#endif
- 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;
@@ -702,7 +734,7 @@ static SlangResult _locateGlslangCompilers(const String& path, ISlangSharedLibra
outFuncs[int(SLANG_PASS_THROUGH_NVRTC)] = &NVRTCDownstreamCompilerUtil::locateCompilers;
outFuncs[int(SLANG_PASS_THROUGH_DXC)] = &DXCDownstreamCompilerUtil::locateCompilers;
outFuncs[int(SLANG_PASS_THROUGH_FXC)] = &FXCDownstreamCompilerUtil::locateCompilers;
- outFuncs[int(SLANG_PASS_THROUGH_GLSLANG)] = &_locateGlslangCompilers;
+ outFuncs[int(SLANG_PASS_THROUGH_GLSLANG)] = &GlslangDownstreamCompilerUtil::locateCompilers;
}
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamCompilerSet !!!!!!!!!!!!!!!!!!!!!!*/
diff --git a/source/compiler-core/slang-downstream-compiler.h b/source/compiler-core/slang-downstream-compiler.h
index b3af8a506..22ad5e20c 100644
--- a/source/compiler-core/slang-downstream-compiler.h
+++ b/source/compiler-core/slang-downstream-compiler.h
@@ -59,6 +59,14 @@ struct DownstreamDiagnostic
/// Given a path, that holds line number and potentially column number in () after path, writes result into outDiagnostic
static SlangResult splitPathLocation(const UnownedStringSlice& pathLocation, DownstreamDiagnostic& outDiagnostic);
+ /// Split the line (separated by :), where a path is at pathIndex
+ static SlangResult splitColonDelimitedLine(const UnownedStringSlice& line, Int pathIndex, List<UnownedStringSlice>& outSlices);
+
+ typedef SlangResult (*LineParser)(const UnownedStringSlice& line, List<UnownedStringSlice>& lineSlices, DownstreamDiagnostic& outDiagnostic);
+
+ /// Given diagnostics in inText that are colon delimited, use lineParser to do per line parsing.
+ static SlangResult parseColonDelimitedDiagnostics(const UnownedStringSlice& inText, Int pathIndex, LineParser lineParser, List<DownstreamDiagnostic>& outDiagnostics);
+
Severity severity; ///< The severity of error
Stage stage; ///< The stage the error came from
String text; ///< The text of the error
@@ -241,6 +249,7 @@ public:
enum class Kind
{
CUDASM, ///< What the version is for
+ SPIRV,
};
Kind kind;
SemanticVersion version;
@@ -296,7 +305,10 @@ public:
String entryPointName;
/// Profile name to use, only required for compiles that need to compile against a a specific profiles.
/// Profile names are tied to compilers and targets.
- String profileName;
+ String profileName;
+
+ /// The stage being compiled for
+ SlangStage stage = SLANG_STAGE_NONE;
/// NOTE! Not all downstream compilers can use the fileSystemExt/sourceManager. This option will be ignored in those scenarios.
ISlangFileSystemExt* fileSystemExt = nullptr;
@@ -331,13 +343,10 @@ 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; }
-
/// Some compilers have support converting a binary blob into disassembly. Output disassembly is held in the output blob
- virtual SlangResult dissassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out);
+ virtual SlangResult disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out);
- /// True if underlying compiler uses file system to pass source
+ /// True if underlying compiler uses file system to communicate source
virtual bool isFileBased() = 0;
/// Get info for a compiler type
@@ -422,25 +431,6 @@ 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 bool isFileBased() SLANG_OVERRIDE { return true; }
- 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:
diff --git a/source/compiler-core/slang-dxc-compiler.cpp b/source/compiler-core/slang-dxc-compiler.cpp
index 281b6173d..7e7850780 100644
--- a/source/compiler-core/slang-dxc-compiler.cpp
+++ b/source/compiler-core/slang-dxc-compiler.cpp
@@ -126,8 +126,7 @@ public:
// DownstreamCompiler
virtual SlangResult compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE;
- virtual ISlangSharedLibrary* getSharedLibrary() SLANG_OVERRIDE { return m_sharedLibrary; }
- virtual SlangResult dissassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out) SLANG_OVERRIDE;
+ virtual SlangResult disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out) SLANG_OVERRIDE;
virtual bool isFileBased() SLANG_OVERRIDE { return false; }
/// Must be called before use
@@ -184,55 +183,6 @@ static SlangResult _parseDiagnosticLine(const UnownedStringSlice& line, List<Uno
return SLANG_OK;
}
-static SlangResult _splitDiagnosticLine(const UnownedStringSlice& line, List<UnownedStringSlice>& outSlices)
-{
- StringUtil::split(line, ':', outSlices);
- const Int pathIndex = 0;
-
- // Now we want to fix up a path as might have drive letter, and therefore :
- // If this is the situation then we need to have a slice after the one at the index
- if (outSlices.getCount() > pathIndex + 1)
- {
- const UnownedStringSlice pathStart = outSlices[pathIndex].trim();
- if (pathStart.getLength() == 1 && CharUtil::isAlpha(pathStart[0]))
- {
- // Splice back together
- outSlices[pathIndex] = UnownedStringSlice(outSlices[pathIndex].begin(), outSlices[pathIndex + 1].end());
- outSlices.removeAt(pathIndex + 1);
- }
- }
-
- return SLANG_OK;
-}
-
-static SlangResult _parseDiagnostics(const UnownedStringSlice& inText, List<DownstreamDiagnostic>& outDiagnostics)
-{
- List<UnownedStringSlice> splitLine;
-
- UnownedStringSlice text(inText), line;
- while (StringUtil::extractLine(text, line))
- {
- SLANG_RETURN_ON_FAIL(_splitDiagnosticLine(line, splitLine));
-
- DownstreamDiagnostic diagnostic;
- diagnostic.severity = DownstreamDiagnostic::Severity::Error;
- diagnostic.stage = DownstreamDiagnostic::Stage::Compile;
- diagnostic.fileLine = 0;
-
- if (SLANG_SUCCEEDED(_parseDiagnosticLine(line, splitLine, diagnostic)))
- {
- outDiagnostics.add(diagnostic);
- }
- else
- {
- // If couldn't parse, just add as a note
- DownstreamDiagnostics::addNote(line, outDiagnostics);
- }
- }
-
- return SLANG_OK;
-}
-
SlangResult DXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult)
{
// This compiler doesn't read files, they should be read externally and stored in sourceContents/sourceContentsPath
@@ -383,7 +333,8 @@ SlangResult DXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr
{
diagnostics.rawDiagnostics = String(diagnosticsSlice);
- SlangResult diagnosticParseRes = _parseDiagnostics(diagnosticsSlice, diagnostics.diagnostics);
+ SlangResult diagnosticParseRes = DownstreamDiagnostic::parseColonDelimitedDiagnostics(diagnosticsSlice, 0, _parseDiagnosticLine, diagnostics.diagnostics);
+
SLANG_UNUSED(diagnosticParseRes);
SLANG_ASSERT(SLANG_SUCCEEDED(diagnosticParseRes));
}
@@ -408,7 +359,7 @@ SlangResult DXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr
return SLANG_OK;
}
-SlangResult DXCDownstreamCompiler::dissassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out)
+SlangResult DXCDownstreamCompiler::disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out)
{
// Can only disassemble blobs that are DXIL
if (sourceBlobTarget != SLANG_DXIL)
diff --git a/source/compiler-core/slang-fxc-compiler.cpp b/source/compiler-core/slang-fxc-compiler.cpp
index 60d50a13e..b0a117d1a 100644
--- a/source/compiler-core/slang-fxc-compiler.cpp
+++ b/source/compiler-core/slang-fxc-compiler.cpp
@@ -114,8 +114,7 @@ public:
// DownstreamCompiler
virtual SlangResult compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE;
- virtual ISlangSharedLibrary* getSharedLibrary() SLANG_OVERRIDE { return m_sharedLibrary; }
- virtual SlangResult dissassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out) SLANG_OVERRIDE;
+ virtual SlangResult disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out) SLANG_OVERRIDE;
virtual bool isFileBased() SLANG_OVERRIDE { return false; }
/// Must be called before use
@@ -176,60 +175,6 @@ static SlangResult _parseDiagnosticLine(const UnownedStringSlice& line, List<Uno
return SLANG_OK;
}
-static SlangResult _splitDiagnosticLine(const UnownedStringSlice& line, List<UnownedStringSlice>& outSlices)
-{
- StringUtil::split(line, ':', outSlices);
-
- /*
- tests/diagnostics/syntax-error-intrinsic.slang(14,2): error X3000: syntax error: unexpected token '@'
- */
-
- const Int pathIndex = 0;
-
- // Now we want to fix up a path as might have drive letter, and therefore :
- // If this is the situation then we need to have a slice after the one at the index
- if (outSlices.getCount() > pathIndex + 1)
- {
- const UnownedStringSlice pathStart = outSlices[pathIndex].trim();
- if (pathStart.getLength() == 1 && CharUtil::isAlpha(pathStart[0]))
- {
- // Splice back together
- outSlices[pathIndex] = UnownedStringSlice(outSlices[pathIndex].begin(), outSlices[pathIndex + 1].end());
- outSlices.removeAt(pathIndex + 1);
- }
- }
-
- return SLANG_OK;
-}
-
-static SlangResult _parseDiagnostics(const UnownedStringSlice& inText, List<DownstreamDiagnostic>& outDiagnostics)
-{
- List<UnownedStringSlice> splitLine;
-
- UnownedStringSlice text(inText), line;
- while (StringUtil::extractLine(text, line))
- {
- SLANG_RETURN_ON_FAIL(_splitDiagnosticLine(line, splitLine));
-
- DownstreamDiagnostic diagnostic;
- diagnostic.severity = DownstreamDiagnostic::Severity::Error;
- diagnostic.stage = DownstreamDiagnostic::Stage::Compile;
- diagnostic.fileLine = 0;
-
- if (SLANG_SUCCEEDED(_parseDiagnosticLine(line, splitLine, diagnostic)))
- {
- outDiagnostics.add(diagnostic);
- }
- else
- {
- // If couldn't parse, just add as a note
- DownstreamDiagnostics::addNote(line, outDiagnostics);
- }
- }
-
- return SLANG_OK;
-}
-
SlangResult FXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult)
{
// This compiler doesn't read files, they should be read externally and stored in sourceContents/sourceContentsPath
@@ -348,8 +293,8 @@ SlangResult FXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr
{
UnownedStringSlice diagnosticText = _getSlice(diagnosticsBlob);
diagnostics.rawDiagnostics = diagnosticText;
-
- SlangResult diagnosticParseRes = _parseDiagnostics(diagnosticText, diagnostics.diagnostics);
+
+ SlangResult diagnosticParseRes = DownstreamDiagnostic::parseColonDelimitedDiagnostics(diagnosticText, 0, _parseDiagnosticLine, diagnostics.diagnostics);
SLANG_UNUSED(diagnosticParseRes);
SLANG_ASSERT(SLANG_SUCCEEDED(diagnosticParseRes));
}
@@ -361,7 +306,7 @@ SlangResult FXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr
return SLANG_OK;
}
-SlangResult FXCDownstreamCompiler::dissassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out)
+SlangResult FXCDownstreamCompiler::disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out)
{
// Can only disassemble blobs that are DXBC
if (sourceBlobTarget != SLANG_DXBC)
diff --git a/source/compiler-core/slang-glslang-compiler.cpp b/source/compiler-core/slang-glslang-compiler.cpp
new file mode 100644
index 000000000..8a8712024
--- /dev/null
+++ b/source/compiler-core/slang-glslang-compiler.cpp
@@ -0,0 +1,300 @@
+// slang-glslang-compiler.cpp
+#include "slang-glslang-compiler.h"
+
+#include "../core/slang-common.h"
+#include "../../slang-com-helper.h"
+
+#include "../core/slang-blob.h"
+
+#include "../core/slang-string-util.h"
+#include "../core/slang-string-slice-pool.h"
+
+#include "../core/slang-io.h"
+#include "../core/slang-shared-library.h"
+#include "../core/slang-semantic-version.h"
+#include "../core/slang-char-util.h"
+
+#include "slang-include-system.h"
+#include "slang-source-loc.h"
+
+#include "../core/slang-shared-library.h"
+
+// Enable calling through to `glslang` on
+// all platforms.
+#ifndef SLANG_ENABLE_GLSLANG_SUPPORT
+# define SLANG_ENABLE_GLSLANG_SUPPORT 1
+#endif
+
+#if SLANG_ENABLE_GLSLANG_SUPPORT
+# include "../slang-glslang/slang-glslang.h"
+#endif
+
+namespace Slang
+{
+
+#if SLANG_ENABLE_GLSLANG_SUPPORT
+
+class GlslangDownstreamCompiler : public DownstreamCompiler
+{
+public:
+ typedef DownstreamCompiler Super;
+
+ // DownstreamCompiler
+ virtual SlangResult compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE;
+ virtual SlangResult disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out) SLANG_OVERRIDE;
+ virtual bool isFileBased() SLANG_OVERRIDE { return false; }
+
+ /// Must be called before use
+ SlangResult init(ISlangSharedLibrary* library);
+
+ GlslangDownstreamCompiler() {}
+
+protected:
+
+ SlangResult _invoke(glslang_CompileRequest_1_1& request);
+
+ glslang_CompileFunc_1_0 m_compile_1_0 = nullptr;
+ glslang_CompileFunc_1_1 m_compile_1_1 = nullptr;
+
+ ComPtr<ISlangSharedLibrary> m_sharedLibrary;
+};
+
+SlangResult GlslangDownstreamCompiler::init(ISlangSharedLibrary* library)
+{
+ m_compile_1_0 = (glslang_CompileFunc_1_0)library->findFuncByName("glslang_compile");
+ m_compile_1_1 = (glslang_CompileFunc_1_1)library->findFuncByName("glslang_compile_1_1");
+
+ if (m_compile_1_0 == nullptr && m_compile_1_1 == nullptr)
+ {
+ return SLANG_FAIL;
+ }
+
+ m_sharedLibrary = library;
+
+ // It's not clear how to query for a version, but we can get a version number from the header
+ m_desc = Desc(SLANG_PASS_THROUGH_GLSLANG);
+
+ return SLANG_OK;
+}
+
+SlangResult GlslangDownstreamCompiler::_invoke(glslang_CompileRequest_1_1& request)
+{
+ int err = 1;
+ if (m_compile_1_1)
+ {
+ err = m_compile_1_1(&request);
+ }
+ else if (m_compile_1_0)
+ {
+ glslang_CompileRequest_1_0 request_1_0;
+ request_1_0.set(request);
+ err = m_compile_1_0(&request_1_0);
+ }
+
+ return err ? SLANG_FAIL : SLANG_OK;
+}
+
+static SlangResult _parseDiagnosticLine(const UnownedStringSlice& line, List<UnownedStringSlice>& lineSlices, DownstreamDiagnostic& outDiagnostic)
+{
+ /* ERROR: tests/diagnostics/syntax-error-intrinsic.slang:13: '@' : unexpected token */
+
+ if (lineSlices.getCount() < 4)
+ {
+ return SLANG_FAIL;
+ }
+ {
+ const UnownedStringSlice severitySlice = lineSlices[0].trim();
+
+ outDiagnostic.severity = DownstreamDiagnostic::Severity::Error;
+ if (severitySlice.caseInsensitiveEquals(UnownedStringSlice::fromLiteral("warning")))
+ {
+ outDiagnostic.severity = DownstreamDiagnostic::Severity::Warning;
+ }
+ }
+
+ outDiagnostic.filePath = lineSlices[1];
+
+ SLANG_RETURN_ON_FAIL(StringUtil::parseInt(lineSlices[2], outDiagnostic.fileLine));
+ outDiagnostic.text = UnownedStringSlice(lineSlices[3].begin(), line.end());
+ return SLANG_OK;
+}
+
+
+
+SlangResult GlslangDownstreamCompiler::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;
+ }
+
+ if (options.sourceLanguage != SLANG_SOURCE_LANGUAGE_GLSL || options.targetType != SLANG_SPIRV)
+ {
+ SLANG_ASSERT(!"Can only compile GLSL to SPIR-V");
+ return SLANG_FAIL;
+ }
+
+ StringBuilder diagnosticOutput;
+ auto diagnosticOutputFunc = [](void const* data, size_t size, void* userData)
+ {
+ (*(StringBuilder*)userData).append((char const*)data, (char const*)data + size);
+ };
+ List<uint8_t> spirv;
+ auto outputFunc = [](void const* data, size_t size, void* userData)
+ {
+ ((List<uint8_t>*)userData)->addRange((uint8_t*)data, size);
+ };
+
+
+ glslang_CompileRequest_1_1 request;
+ memset(&request, 0, sizeof(request));
+ request.sizeInBytes = sizeof(request);
+
+ request.action = GLSLANG_ACTION_COMPILE_GLSL_TO_SPIRV;
+ request.sourcePath = options.sourceContentsPath.getBuffer();
+
+ request.slangStage = options.stage;
+
+ request.inputBegin = options.sourceContents.begin();
+ request.inputEnd = options.sourceContents.end();
+
+ // Find the SPIR-V version if set
+ SemanticVersion spirvVersion;
+ for (const auto& capabilityVersion : options.requiredCapabilityVersions)
+ {
+ if (capabilityVersion.kind == DownstreamCompiler::CapabilityVersion::Kind::SPIRV)
+ {
+ if (capabilityVersion.version > spirvVersion)
+ {
+ spirvVersion = capabilityVersion.version;
+ }
+ }
+ }
+
+ request.spirvVersion.major = spirvVersion.m_major;
+ request.spirvVersion.minor = spirvVersion.m_minor;
+ request.spirvVersion.patch = spirvVersion.m_patch;
+
+ request.outputFunc = outputFunc;
+ request.outputUserData = &spirv;
+
+ request.diagnosticFunc = diagnosticOutputFunc;
+ request.diagnosticUserData = &diagnosticOutput;
+
+ request.optimizationLevel = (unsigned)options.optimizationLevel;
+ request.debugInfoType = (unsigned)options.debugInfoType;
+
+ const SlangResult invokeResult = _invoke(request);
+
+ DownstreamDiagnostics diagnostics;
+
+ // Set the diagnostics result
+ diagnostics.result = invokeResult;
+
+ if (SLANG_FAILED(invokeResult))
+ {
+ diagnostics.rawDiagnostics = diagnosticOutput;
+
+ SlangResult diagnosticParseRes = DownstreamDiagnostic::parseColonDelimitedDiagnostics(diagnosticOutput.getUnownedSlice(), 1, _parseDiagnosticLine, diagnostics.diagnostics);
+ SLANG_UNUSED(diagnosticParseRes);
+
+ diagnostics.requireErrorDiagnostic();
+
+ outResult = new BlobDownstreamCompileResult(diagnostics, nullptr);
+ return SLANG_OK;
+ }
+
+ RefPtr<ListBlob> spirvBlob = ListBlob::moveCreate(spirv);
+ outResult = new BlobDownstreamCompileResult(diagnostics, spirvBlob);
+
+ return SLANG_OK;
+}
+
+SlangResult GlslangDownstreamCompiler::disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out)
+{
+ // Can only disassemble blobs that are DXBC
+ if (sourceBlobTarget != SLANG_SPIRV)
+ {
+ return SLANG_FAIL;
+ }
+
+ StringBuilder builder;
+
+ String output;
+ auto outputFunc = [](void const* data, size_t size, void* userData)
+ {
+ (*(StringBuilder*)userData).append((char const*)data, (char const*)data + size);
+ };
+
+ glslang_CompileRequest_1_1 request;
+ memset(&request, 0, sizeof(request));
+ request.sizeInBytes = sizeof(request);
+
+ request.action = GLSLANG_ACTION_DISSASSEMBLE_SPIRV;
+
+ request.sourcePath = nullptr;
+
+ request.inputBegin = blob;
+ request.inputEnd = (char*)blob + blobSize;
+
+ request.outputFunc = outputFunc;
+ request.outputUserData = &output;
+
+ SLANG_RETURN_ON_FAIL(_invoke(request));
+
+ ComPtr<ISlangBlob> disassemblyBlob = StringUtil::createStringBlob(builder);
+ *out = disassemblyBlob.detach();
+
+ return SLANG_OK;
+}
+
+/* static */SlangResult GlslangDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set)
+{
+ ComPtr<ISlangSharedLibrary> library;
+
+#if SLANG_UNIX_FAMILY
+ // On unix systems we need to ensure pthread is loaded first.
+ // TODO(JS):
+ // There is an argument that this should be performed through the loader....
+ ComPtr<ISlangSharedLibrary> pthreadLibrary;
+ DefaultSharedLibraryLoader::load(loader, path, "pthread", pthreadLibrary.writeRef());
+#endif
+
+ // If the user supplies a path to their preferred version of FXC,
+ // we just use this.
+ if (path.getLength() != 0)
+ {
+ SLANG_RETURN_ON_FAIL(loader->loadSharedLibrary(path.getBuffer(), library.writeRef()));
+ }
+ else
+ {
+ SLANG_RETURN_ON_FAIL(loader->loadSharedLibrary("slang-glslang", library.writeRef()));
+ }
+
+ SLANG_ASSERT(library);
+ if (!library)
+ {
+ return SLANG_FAIL;
+ }
+
+ RefPtr<GlslangDownstreamCompiler> compiler(new GlslangDownstreamCompiler);
+ SLANG_RETURN_ON_FAIL(compiler->init(library));
+
+ set->addCompiler(compiler);
+ return SLANG_OK;
+}
+
+#else // SLANG_ENABLE_GLSLANG_SUPPORT
+
+/* static */SlangResult GlslangDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set)
+{
+ SLANG_UNUSED(path);
+ SLANG_UNUSED(loader);
+ SLANG_UNUSED(set);
+ return SLANG_E_NOT_AVAILABLE;
+}
+
+#endif // SLANG_ENABLE_GLSLANG_SUPPORT
+
+}
diff --git a/source/compiler-core/slang-glslang-compiler.h b/source/compiler-core/slang-glslang-compiler.h
new file mode 100644
index 000000000..917315af8
--- /dev/null
+++ b/source/compiler-core/slang-glslang-compiler.h
@@ -0,0 +1,18 @@
+#ifndef SLANG_GLSLANG_COMPILER_UTIL_H
+#define SLANG_GLSLANG_COMPILER_UTIL_H
+
+#include "slang-downstream-compiler.h"
+
+#include "../core/slang-platform.h"
+
+namespace Slang
+{
+
+struct GlslangDownstreamCompilerUtil
+{
+ static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set);
+};
+
+}
+
+#endif
diff --git a/source/compiler-core/slang-nvrtc-compiler.cpp b/source/compiler-core/slang-nvrtc-compiler.cpp
index 029f3c71b..f5014acbc 100644
--- a/source/compiler-core/slang-nvrtc-compiler.cpp
+++ b/source/compiler-core/slang-nvrtc-compiler.cpp
@@ -99,7 +99,6 @@ public:
// DownstreamCompiler
virtual SlangResult compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE;
- virtual ISlangSharedLibrary* getSharedLibrary() SLANG_OVERRIDE { return m_sharedLibrary; }
virtual bool isFileBased() SLANG_OVERRIDE { return false; }
/// Must be called before use