diff options
Diffstat (limited to 'source/compiler-core')
| -rw-r--r-- | source/compiler-core/slang-downstream-compiler.cpp | 72 | ||||
| -rw-r--r-- | source/compiler-core/slang-downstream-compiler.h | 40 | ||||
| -rw-r--r-- | source/compiler-core/slang-dxc-compiler.cpp | 57 | ||||
| -rw-r--r-- | source/compiler-core/slang-fxc-compiler.cpp | 63 | ||||
| -rw-r--r-- | source/compiler-core/slang-glslang-compiler.cpp | 300 | ||||
| -rw-r--r-- | source/compiler-core/slang-glslang-compiler.h | 18 | ||||
| -rw-r--r-- | source/compiler-core/slang-nvrtc-compiler.cpp | 1 |
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 |
