summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-10-09 14:03:43 -0700
committerGitHub <noreply@github.com>2023-10-09 14:03:43 -0700
commit67e186f0169591c48d24bd8ff7e4e4e715e8fa45 (patch)
tree9b46dc35145d18d5b25d9b3b16759c9b7343615c
parent17c7163c2ae8fc290e70b43d8700b68ef18b1ee1 (diff)
Run curated spirv-opt passes through slang-glslang. (#3266)
* Run curated spirv-opt passes through slang-glslang. * Cleanup. * Replace spirv-dis downstream compiler with glslang. * delete slang-spirv-opt.cpp. --------- Co-authored-by: Yong He <yhe@nvidia.com>
-rw-r--r--.github/workflows/windows-selfhosted.yml1
-rw-r--r--.github/workflows/windows.yml1
-rw-r--r--build/visual-studio/compiler-core/compiler-core.vcxproj2
-rw-r--r--build/visual-studio/compiler-core/compiler-core.vcxproj.filters6
-rw-r--r--build/visual-studio/slang/slang.vcxproj2
-rw-r--r--build/visual-studio/slang/slang.vcxproj.filters6
-rw-r--r--github_test.sh1
-rw-r--r--slang.h1
-rw-r--r--source/compiler-core/slang-downstream-compiler-util.cpp5
-rw-r--r--source/compiler-core/slang-downstream-compiler-util.h1
-rw-r--r--source/compiler-core/slang-glslang-compiler.cpp43
-rw-r--r--source/compiler-core/slang-glslang-compiler.h11
-rw-r--r--source/compiler-core/slang-spirv-dis-compiler.cpp105
-rw-r--r--source/compiler-core/slang-spirv-dis-compiler.h26
-rw-r--r--source/core/slang-type-text-util.cpp3
-rw-r--r--source/slang-glslang/slang-glslang.cpp30
-rw-r--r--source/slang-glslang/slang-glslang.h8
-rw-r--r--source/slang/slang-compiler.cpp122
-rwxr-xr-xsource/slang/slang-compiler.h3
-rw-r--r--source/slang/slang-emit-spirv.cpp24
-rw-r--r--source/slang/slang-emit.cpp32
-rw-r--r--source/slang/slang-ir-inline.cpp29
-rw-r--r--source/slang/slang-ir-inline.h3
-rw-r--r--source/slang/slang-spirv-opt.cpp66
-rw-r--r--source/slang/slang-spirv-opt.h10
-rw-r--r--tools/gfx/slang.slang2
26 files changed, 204 insertions, 339 deletions
diff --git a/.github/workflows/windows-selfhosted.yml b/.github/workflows/windows-selfhosted.yml
index 6daab9673..f726db8b6 100644
--- a/.github/workflows/windows-selfhosted.yml
+++ b/.github/workflows/windows-selfhosted.yml
@@ -42,6 +42,7 @@ jobs:
$ErrorActionPreference = "SilentlyContinue"
where.exe spirv-dis
spirv-dis --version
+ $env:SLANG_RUN_SPIRV_VALIDATION='1'
.\bin\windows-${{matrix.testPlatform}}\${{matrix.configuration}}\slang-test.exe tests/ -use-test-server -server-count 8 -emit-spirv-directly -expected-failure-list tests/expected-failure.txt -api vk 2>&1
- name: test
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 182ac3867..9f48ccd0a 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -65,6 +65,7 @@ jobs:
$slangTestBinDir = ".\bin\windows-${{matrix.testPlatform}}\${{matrix.configuration}}\";
$spirvToolsBinDir = ".\external\slang-binaries\spirv-tools\windows-${{matrix.testPlatform}}\bin\";
$env:Path += ";$slangTestBinDir;$spirvToolsBinDir";
+ $env:SLANG_RUN_SPIRV_VALIDATION='1';
Expand-Archive "vk_swiftshader_windows_${{matrix.testPlatform}}.zip" -DestinationPath $slangTestBinDir;
& "$slangTestBinDir\slang-test.exe" -api all-dx12 -appveyor -bindir "$slangTestBinDir\" -platform ${{matrix.testPlatform}} -configuration ${{matrix.configuration}} -category ${{matrix.testCategory}} -expected-failure-list tests/expected-failure-github.txt 2>&1;
diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj b/build/visual-studio/compiler-core/compiler-core.vcxproj
index e5b9c5fdb..e2202aaca 100644
--- a/build/visual-studio/compiler-core/compiler-core.vcxproj
+++ b/build/visual-studio/compiler-core/compiler-core.vcxproj
@@ -312,7 +312,6 @@
<ClInclude Include="..\..\..\source\compiler-core\slang-source-loc.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-source-map.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-spirv-core-grammar.h" />
- <ClInclude Include="..\..\..\source\compiler-core\slang-spirv-dis-compiler.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-test-server-protocol.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-token-defs.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-token.h" />
@@ -361,7 +360,6 @@
<ClCompile Include="..\..\..\source\compiler-core\slang-source-loc.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-source-map.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-spirv-core-grammar.cpp" />
- <ClCompile Include="..\..\..\source\compiler-core\slang-spirv-dis-compiler.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-test-server-protocol.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-token.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-visual-studio-compiler-util.cpp" />
diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
index 14c7aa7da..2d4e3663d 100644
--- a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
+++ b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
@@ -150,9 +150,6 @@
<ClInclude Include="..\..\..\source\compiler-core\slang-spirv-core-grammar.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\source\compiler-core\slang-spirv-dis-compiler.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="..\..\..\source\compiler-core\slang-test-server-protocol.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -293,9 +290,6 @@
<ClCompile Include="..\..\..\source\compiler-core\slang-spirv-core-grammar.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\source\compiler-core\slang-spirv-dis-compiler.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\..\source\compiler-core\slang-test-server-protocol.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/build/visual-studio/slang/slang.vcxproj b/build/visual-studio/slang/slang.vcxproj
index 52db5fb4b..2e180e9ed 100644
--- a/build/visual-studio/slang/slang.vcxproj
+++ b/build/visual-studio/slang/slang.vcxproj
@@ -506,7 +506,6 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClInclude Include="..\..\..\source\slang\slang-serialize-types.h" />
<ClInclude Include="..\..\..\source\slang\slang-serialize-value-type-info.h" />
<ClInclude Include="..\..\..\source\slang\slang-serialize.h" />
- <ClInclude Include="..\..\..\source\slang\slang-spirv-opt.h" />
<ClInclude Include="..\..\..\source\slang\slang-spirv-val.h" />
<ClInclude Include="..\..\..\source\slang\slang-stdlib-textures.h" />
<ClInclude Include="..\..\..\source\slang\slang-syntax.h" />
@@ -719,7 +718,6 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClCompile Include="..\..\..\source\slang\slang-serialize-types.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-serialize.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-spirv-core-grammar-embed.cpp" />
- <ClCompile Include="..\..\..\source\slang\slang-spirv-opt.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-spirv-val.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-stdlib-api.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-stdlib-textures.cpp" />
diff --git a/build/visual-studio/slang/slang.vcxproj.filters b/build/visual-studio/slang/slang.vcxproj.filters
index 67e22c3ea..10cc7c103 100644
--- a/build/visual-studio/slang/slang.vcxproj.filters
+++ b/build/visual-studio/slang/slang.vcxproj.filters
@@ -606,9 +606,6 @@
<ClInclude Include="..\..\..\source\slang\slang-serialize.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\source\slang\slang-spirv-opt.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="..\..\..\source\slang\slang-spirv-val.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -1241,9 +1238,6 @@
<ClCompile Include="..\..\..\source\slang\slang-spirv-core-grammar-embed.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\source\slang\slang-spirv-opt.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\..\source\slang\slang-spirv-val.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/github_test.sh b/github_test.sh
index cb8dff723..a970454d0 100644
--- a/github_test.sh
+++ b/github_test.sh
@@ -38,4 +38,5 @@ SLANG_TEST=${OUTPUTDIR}slang-test
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$OUTPUTDIR
export PATH=$PATH:${OUTPUTDIR}
+export SLANG_RUN_SPIRV_VALIDATION=1
${SLANG_TEST} -bindir ${OUTPUTDIR} -travis -category ${SLANG_TEST_CATEGORY} ${SLANG_TEST_FLAGS} -api all-vk -expected-failure-list tests/expected-failure-github.txt
diff --git a/slang.h b/slang.h
index 14e9a30e2..78b56c546 100644
--- a/slang.h
+++ b/slang.h
@@ -640,6 +640,7 @@ extern "C"
SLANG_PASS_THROUGH_GENERIC_C_CPP, ///< Generic C or C++ compiler, which is decided by the source type
SLANG_PASS_THROUGH_NVRTC, ///< NVRTC Cuda compiler
SLANG_PASS_THROUGH_LLVM, ///< LLVM 'compiler' - includes LLVM and Clang
+ SLANG_PASS_THROUGH_SPIRV_OPT, ///< SPIRV-opt
SLANG_PASS_THROUGH_COUNT_OF,
};
diff --git a/source/compiler-core/slang-downstream-compiler-util.cpp b/source/compiler-core/slang-downstream-compiler-util.cpp
index 44d750be8..52bf03acc 100644
--- a/source/compiler-core/slang-downstream-compiler-util.cpp
+++ b/source/compiler-core/slang-downstream-compiler-util.cpp
@@ -23,7 +23,6 @@
#include "slang-dxc-compiler.h"
#include "slang-glslang-compiler.h"
#include "slang-llvm-compiler.h"
-#include "slang-spirv-dis-compiler.h"
namespace Slang
{
@@ -55,6 +54,7 @@ struct DownstreamCompilerInfos
infos.infos[int(SLANG_PASS_THROUGH_DXC)] = Info(SourceLanguageFlag::HLSL);
infos.infos[int(SLANG_PASS_THROUGH_FXC)] = Info(SourceLanguageFlag::HLSL);
infos.infos[int(SLANG_PASS_THROUGH_GLSLANG)] = Info(SourceLanguageFlag::GLSL);
+ infos.infos[int(SLANG_PASS_THROUGH_SPIRV_OPT)] = Info(SourceLanguageFlag::SPIRV);
return infos;
}
@@ -327,8 +327,9 @@ DownstreamCompilerMatchVersion DownstreamCompilerUtil::getCompiledVersion()
outFuncs[int(SLANG_PASS_THROUGH_DXC)] = &DXCDownstreamCompilerUtil::locateCompilers;
outFuncs[int(SLANG_PASS_THROUGH_FXC)] = &FXCDownstreamCompilerUtil::locateCompilers;
outFuncs[int(SLANG_PASS_THROUGH_GLSLANG)] = &GlslangDownstreamCompilerUtil::locateCompilers;
+ outFuncs[int(SLANG_PASS_THROUGH_SPIRV_OPT)] = &SpirvOptDownstreamCompilerUtil::locateCompilers;
outFuncs[int(SLANG_PASS_THROUGH_LLVM)] = &LLVMDownstreamCompilerUtil::locateCompilers;
- outFuncs[int(SLANG_PASS_THROUGH_SPIRV_DIS)] = &SPIRVDisDownstreamCompilerUtil::locateCompilers;
+ outFuncs[int(SLANG_PASS_THROUGH_SPIRV_DIS)] = &SpirvDisDownstreamCompilerUtil::locateCompilers;
}
static String _getParentPath(const String& path)
diff --git a/source/compiler-core/slang-downstream-compiler-util.h b/source/compiler-core/slang-downstream-compiler-util.h
index 6aad1ca90..84b8edcca 100644
--- a/source/compiler-core/slang-downstream-compiler-util.h
+++ b/source/compiler-core/slang-downstream-compiler-util.h
@@ -24,6 +24,7 @@ struct DownstreamCompilerInfo
C = SourceLanguageFlags(1) << SLANG_SOURCE_LANGUAGE_C,
CPP = SourceLanguageFlags(1) << SLANG_SOURCE_LANGUAGE_CPP,
CUDA = SourceLanguageFlags(1) << SLANG_SOURCE_LANGUAGE_CUDA,
+ SPIRV = SourceLanguageFlags(1) << SLANG_SOURCE_LANGUAGE_SPIRV,
};
};
diff --git a/source/compiler-core/slang-glslang-compiler.cpp b/source/compiler-core/slang-glslang-compiler.cpp
index 4c0bc74d7..0335c33b4 100644
--- a/source/compiler-core/slang-glslang-compiler.cpp
+++ b/source/compiler-core/slang-glslang-compiler.cpp
@@ -52,7 +52,7 @@ public:
/// Must be called before use
SlangResult init(ISlangSharedLibrary* library);
- GlslangDownstreamCompiler() {}
+ GlslangDownstreamCompiler(SlangPassThrough compilerType) : m_compilerType(compilerType) {}
protected:
@@ -63,6 +63,8 @@ protected:
glslang_CompileFunc_1_2 m_compile_1_2 = nullptr;
ComPtr<ISlangSharedLibrary> m_sharedLibrary;
+
+ SlangPassThrough m_compilerType;
};
SlangResult GlslangDownstreamCompiler::init(ISlangSharedLibrary* library)
@@ -80,7 +82,7 @@ SlangResult GlslangDownstreamCompiler::init(ISlangSharedLibrary* library)
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);
+ m_desc = Desc(m_compilerType);
Slang::String filename;
if (m_compile_1_2)
@@ -173,9 +175,9 @@ SlangResult GlslangDownstreamCompiler::compile(const CompileOptions& inOptions,
IArtifact* sourceArtifact = options.sourceArtifacts[0];
- if (options.sourceLanguage != SLANG_SOURCE_LANGUAGE_GLSL || options.targetType != SLANG_SPIRV)
+ if (options.targetType != SLANG_SPIRV)
{
- SLANG_ASSERT(!"Can only compile GLSL to SPIR-V");
+ SLANG_ASSERT(!"Can only compile to SPIR-V");
return SLANG_FAIL;
}
@@ -199,7 +201,19 @@ SlangResult GlslangDownstreamCompiler::compile(const CompileOptions& inOptions,
memset(&request, 0, sizeof(request));
request.sizeInBytes = sizeof(request);
- request.action = GLSLANG_ACTION_COMPILE_GLSL_TO_SPIRV;
+ switch (options.sourceLanguage)
+ {
+ case SLANG_SOURCE_LANGUAGE_GLSL:
+ request.action = GLSLANG_ACTION_COMPILE_GLSL_TO_SPIRV;
+ break;
+ case SLANG_SOURCE_LANGUAGE_SPIRV:
+ request.action = GLSLANG_ACTION_OPTIMIZE_SPIRV;
+ break;
+ default:
+ SLANG_ASSERT(!"Can only handle GLSL or SPIR-V as input.");
+ return SLANG_FAIL;
+ }
+
request.sourcePath = sourcePath.getBuffer();
request.slangStage = options.stage;
@@ -340,7 +354,7 @@ SlangResult GlslangDownstreamCompiler::getVersionString(slang::IBlob** outVersio
return SLANG_OK;
}
-/* static */SlangResult GlslangDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set)
+static SlangResult locateGlslangSpirvDownstreamCompiler(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set, SlangPassThrough compilerType)
{
ComPtr<ISlangSharedLibrary> library;
@@ -367,7 +381,7 @@ SlangResult GlslangDownstreamCompiler::getVersionString(slang::IBlob** outVersio
return SLANG_FAIL;
}
- auto compiler = new GlslangDownstreamCompiler;
+ auto compiler = new GlslangDownstreamCompiler(compilerType);
ComPtr<IDownstreamCompiler> compilerIntf(compiler);
SLANG_RETURN_ON_FAIL(compiler->init(library));
@@ -375,6 +389,21 @@ SlangResult GlslangDownstreamCompiler::getVersionString(slang::IBlob** outVersio
return SLANG_OK;
}
+SlangResult GlslangDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set)
+{
+ return locateGlslangSpirvDownstreamCompiler(path, loader, set, SLANG_PASS_THROUGH_GLSLANG);
+}
+
+SlangResult SpirvOptDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set)
+{
+ return locateGlslangSpirvDownstreamCompiler(path, loader, set, SLANG_PASS_THROUGH_SPIRV_OPT);
+}
+
+SlangResult SpirvDisDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set)
+{
+ return locateGlslangSpirvDownstreamCompiler(path, loader, set, SLANG_PASS_THROUGH_SPIRV_DIS);
+}
+
#else // SLANG_ENABLE_GLSLANG_SUPPORT
/* static */SlangResult GlslangDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set)
diff --git a/source/compiler-core/slang-glslang-compiler.h b/source/compiler-core/slang-glslang-compiler.h
index ea4352a0b..577bcaacc 100644
--- a/source/compiler-core/slang-glslang-compiler.h
+++ b/source/compiler-core/slang-glslang-compiler.h
@@ -13,6 +13,17 @@ struct GlslangDownstreamCompilerUtil
static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set);
};
+
+struct SpirvOptDownstreamCompilerUtil
+{
+ static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set);
+};
+
+struct SpirvDisDownstreamCompilerUtil
+{
+ static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set);
+};
+
}
#endif
diff --git a/source/compiler-core/slang-spirv-dis-compiler.cpp b/source/compiler-core/slang-spirv-dis-compiler.cpp
deleted file mode 100644
index 9b40254ce..000000000
--- a/source/compiler-core/slang-spirv-dis-compiler.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-#include "slang-spirv-dis-compiler.h"
-#include "../core/slang-common.h"
-#include "../core/slang-string-util.h"
-#include "../core/slang-string.h"
-#include "slang-artifact-desc-util.h"
-#include "slang-artifact-representation.h"
-#include "slang-artifact-util.h"
-#include "slang-artifact-representation-impl.h"
-namespace Slang
-{
-
-SlangResult SPIRVDisDownstreamCompilerUtil::locateCompilers(
- const String&,
- ISlangSharedLibraryLoader*,
- DownstreamCompilerSet* set)
-{
- // TODO: We could check that the compiler is actually present in PATH (or
- // explicitly given)
- ComPtr<IDownstreamCompiler> com(
- new SPIRVDisDownstreamCompiler(DownstreamCompilerDesc(SLANG_PASS_THROUGH_SPIRV_DIS)));
- set->addCompiler(com);
-
- return SLANG_OK;
-}
-
-SlangResult SLANG_MCALL SPIRVDisDownstreamCompiler::convert(
- IArtifact* from,
- const ArtifactDesc& to,
- IArtifact** outArtifact) noexcept
-{
- const auto& fromDesc = from->getDesc();
- if(to.kind != ArtifactKind::Assembly ||
- to.payload != ArtifactPayload::SPIRV ||
- to.flags != 0 ||
- fromDesc.kind != ArtifactKind::Executable ||
- fromDesc.payload != ArtifactPayload::SPIRV ||
- fromDesc.flags != 0)
- return SLANG_E_INVALID_ARG;
-
- ISlangBlob* fromBlob;
- SLANG_RETURN_ON_FAIL(from->loadBlob(ArtifactKeep::No, &fromBlob));
-
- // Set up our process
- CommandLine commandLine;
- commandLine.m_executableLocation.setName("spirv-dis");
- commandLine.addArg("--comment");
-
- RefPtr<Process> p;
- SLANG_RETURN_ON_FAIL(Process::create(commandLine, 0, p));
-
- auto inputStream = p->getStream(StdStreamType::In);
- if (!inputStream)
- return SLANG_FAIL;
-
- auto outputStream = p->getStream(StdStreamType::Out);
- List<uint8_t> outBytes;
- const auto err = p->getStream(StdStreamType::ErrorOut);
- List<Byte> errData;
-
- SLANG_RETURN_ON_FAIL(StreamUtil::readAndWrite(
- inputStream,
- ArrayView<Byte>((Byte*)fromBlob->getBufferPointer(), (Index)fromBlob->getBufferSize()),
- outputStream,
- outBytes,
- err,
- errData));
-
- // Wait for it to finish
- if(!p->waitForTermination(1000))
- return SLANG_FAIL;
-
- if (errData.getCount())
- fwrite(errData.getBuffer(), 1, (size_t)errData.getCount(), stderr);
-
- StringBuilder sbOutput;
- List<UnownedStringSlice> lines;
- StringUtil::calcLines(StringUtil::trimEndOfLine(UnownedStringSlice((const char*)outBytes.getBuffer())), lines);
- for (auto line : lines)
- {
- sbOutput << StringUtil::trimEndOfLine(line) << "\n";
- }
- // If spirv-dis failed, we fail
- const auto ret = p->getReturnValue();
- if(ret != 0)
- return SLANG_FAIL;
-
- // Return as a file artifact
-
- auto disassemblyBlob = StringBlob::moveCreate(sbOutput);
-
- auto artifact = ArtifactUtil::createArtifact(to);
- artifact->addRepresentationUnknown(disassemblyBlob);
-
- *outArtifact = artifact.detach();
- return SLANG_OK;
-}
-
-SlangResult SLANG_MCALL SPIRVDisDownstreamCompiler::compile(
- const CompileOptions&,
- IArtifact**) noexcept
-{
- SLANG_UNIMPLEMENTED_X(__func__);
-}
-
-}
diff --git a/source/compiler-core/slang-spirv-dis-compiler.h b/source/compiler-core/slang-spirv-dis-compiler.h
deleted file mode 100644
index fb01627cd..000000000
--- a/source/compiler-core/slang-spirv-dis-compiler.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include "slang-downstream-compiler-util.h"
-
-#include "../core/slang-platform.h"
-
-namespace Slang
-{
-
-struct SPIRVDisDownstreamCompilerUtil
-{
- static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set);
-};
-
-class SPIRVDisDownstreamCompiler : public DownstreamCompilerBase
-{
-public:
- SPIRVDisDownstreamCompiler(const Desc& desc) : DownstreamCompilerBase(desc) {}
-
- virtual SlangResult SLANG_MCALL convert(IArtifact* from, const ArtifactDesc& to, IArtifact** outArtifact) noexcept override;
-
- virtual bool SLANG_MCALL isFileBased() noexcept override { return true; }
- virtual SlangResult SLANG_MCALL compile(const CompileOptions& options, IArtifact** outArtifact) noexcept override;
-};
-
-}
diff --git a/source/core/slang-type-text-util.cpp b/source/core/slang-type-text-util.cpp
index 2196fbaa8..e6305c3ec 100644
--- a/source/core/slang-type-text-util.cpp
+++ b/source/core/slang-type-text-util.cpp
@@ -80,12 +80,13 @@ static const NamesDescriptionValue s_compilerInfos[] =
{ SLANG_PASS_THROUGH_DXC, "dxc", "DXC HLSL compiler" },
{ SLANG_PASS_THROUGH_GLSLANG, "glslang", "GLSLANG GLSL compiler" },
{ SLANG_PASS_THROUGH_SPIRV_DIS, "spirv-dis", "spirv-tools SPIRV disassembler" },
- { SLANG_PASS_THROUGH_VISUAL_STUDIO, "visualstudio,vs", "Visual Studio C/C++ compiler" },
{ SLANG_PASS_THROUGH_CLANG, "clang", "Clang C/C++ compiler" },
+ { SLANG_PASS_THROUGH_VISUAL_STUDIO, "visualstudio,vs", "Visual Studio C/C++ compiler" },
{ SLANG_PASS_THROUGH_GCC, "gcc", "GCC C/C++ compiler" },
{ SLANG_PASS_THROUGH_GENERIC_C_CPP, "genericcpp,c,cpp", "A generic C++ compiler (can be any one of visual studio, clang or gcc depending on system and availability)" },
{ SLANG_PASS_THROUGH_NVRTC, "nvrtc", "NVRTC CUDA compiler" },
{ SLANG_PASS_THROUGH_LLVM, "llvm", "LLVM/Clang `slang-llvm`" },
+ { SLANG_PASS_THROUGH_SPIRV_OPT, "spirv-opt", "spirv-tools SPIRV optimizer" },
};
static const NamesDescriptionValue s_archiveTypeInfos[] =
diff --git a/source/slang-glslang/slang-glslang.cpp b/source/slang-glslang/slang-glslang.cpp
index 32834232f..fcaa9e70d 100644
--- a/source/slang-glslang/slang-glslang.cpp
+++ b/source/slang-glslang/slang-glslang.cpp
@@ -413,6 +413,32 @@ static void glslang_optimizeSPIRV(spv_target_env targetEnv, const glslang_Compil
}
}
+static int spirv_Optimize_1_2(const glslang_CompileRequest_1_2& request)
+{
+ std::vector<SPIRVOptimizationDiagnostic> diagnostics;
+ std::vector<uint32_t> spirvBuffer;
+ size_t inputBlobSize = (char*)request.inputEnd - (char*)request.inputBegin;
+ spirvBuffer.resize(inputBlobSize / sizeof(uint32_t));
+ memcpy(spirvBuffer.data(), request.inputBegin, inputBlobSize);
+
+ glslang_optimizeSPIRV(SPV_ENV_UNIVERSAL_1_5, request, diagnostics, spirvBuffer);
+ if (request.outputFunc)
+ {
+ request.outputFunc(spirvBuffer.data(), spirvBuffer.size() * sizeof(uint32_t), request.outputUserData);
+ }
+ if (request.diagnosticFunc)
+ {
+ for (auto& diagnostic : diagnostics)
+ {
+ request.diagnosticFunc(
+ (void*)diagnostic.message.c_str(),
+ diagnostic.message.size() * sizeof(char),
+ request.diagnosticUserData);
+ }
+ }
+ return SLANG_OK;
+}
+
static glslang::EShTargetLanguageVersion _makeTargetLanguageVersion(int majorVersion, int minorVersion)
{
return glslang::EShTargetLanguageVersion((uint32_t(majorVersion) << 16) | (uint32_t(minorVersion) << 8));
@@ -770,6 +796,10 @@ static int _compile(const glslang_CompileRequest_1_2& request)
case GLSLANG_ACTION_DISSASSEMBLE_SPIRV:
result = glslang_dissassembleSPIRV(request);
break;
+
+ case GLSLANG_ACTION_OPTIMIZE_SPIRV:
+ result = spirv_Optimize_1_2(request);
+ break;
}
return result;
diff --git a/source/slang-glslang/slang-glslang.h b/source/slang-glslang/slang-glslang.h
index 40c574e08..68c24d889 100644
--- a/source/slang-glslang/slang-glslang.h
+++ b/source/slang-glslang/slang-glslang.h
@@ -12,6 +12,7 @@ enum
{
GLSLANG_ACTION_COMPILE_GLSL_TO_SPIRV,
GLSLANG_ACTION_DISSASSEMBLE_SPIRV,
+ GLSLANG_ACTION_OPTIMIZE_SPIRV,
};
struct glsl_SPIRVVersion
@@ -128,17 +129,17 @@ struct glslang_CompileRequest_1_2
const char* entryPointName; // The name of the entrypoint that will appear in output spirv.
};
-void glslang_CompileRequest_1_0::set(const glslang_CompileRequest_1_1& in)
+inline void glslang_CompileRequest_1_0::set(const glslang_CompileRequest_1_1& in)
{
SLANG_GLSLANG_COMPILE_REQUEST_1_0(SLANG_GLSLANG_FIELD_COPY)
}
-void glslang_CompileRequest_1_1::set(const glslang_CompileRequest_1_0& in)
+inline void glslang_CompileRequest_1_1::set(const glslang_CompileRequest_1_0& in)
{
SLANG_GLSLANG_COMPILE_REQUEST_1_0(SLANG_GLSLANG_FIELD_COPY)
}
-void glslang_CompileRequest_1_2::set(const glslang_CompileRequest_1_1& in)
+inline void glslang_CompileRequest_1_2::set(const glslang_CompileRequest_1_1& in)
{
memcpy(this, &in, sizeof(in));
}
@@ -147,5 +148,4 @@ typedef int (*glslang_CompileFunc_1_0)(glslang_CompileRequest_1_0* request);
typedef int (*glslang_CompileFunc_1_1)(glslang_CompileRequest_1_1* request);
typedef int (*glslang_CompileFunc_1_2)(glslang_CompileRequest_1_2* request);
-
#endif
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 9b14fd2f7..997466d49 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -953,6 +953,71 @@ namespace Slang
return false;
}
+ SlangResult passthroughDownstreamDiagnostics(DiagnosticSink* sink, IDownstreamCompiler* compiler, IArtifact* artifact)
+ {
+ auto diagnostics = findAssociatedRepresentation<IArtifactDiagnostics>(artifact);
+
+ if (!diagnostics)
+ return SLANG_OK;
+
+ if (diagnostics->getCount())
+ {
+ StringBuilder compilerText;
+ DownstreamCompilerUtil::appendAsText(compiler->getDesc(), compilerText);
+
+ StringBuilder builder;
+
+ auto const diagnosticCount = diagnostics->getCount();
+ for (Index i = 0; i < diagnosticCount; ++i)
+ {
+ const auto& diagnostic = *diagnostics->getAt(i);
+
+ builder.clear();
+
+ const Severity severity = _getDiagnosticSeverity(diagnostic.severity);
+
+ if (diagnostic.filePath.count == 0 && diagnostic.location.line == 0 && severity == Severity::Note)
+ {
+ // If theres no filePath line number and it's info, output severity and text alone
+ builder << getSeverityName(severity) << " : ";
+ }
+ else
+ {
+ if (diagnostic.filePath.count)
+ {
+ builder << asStringSlice(diagnostic.filePath);
+ }
+
+ if (diagnostic.location.line)
+ {
+ builder << "(" << diagnostic.location.line << ")";
+ }
+
+ builder << ": ";
+
+ if (diagnostic.stage == ArtifactDiagnostic::Stage::Link)
+ {
+ builder << "link ";
+ }
+
+ builder << getSeverityName(severity);
+ builder << " " << asStringSlice(diagnostic.code) << ": ";
+ }
+
+ builder << asStringSlice(diagnostic.text);
+ reportExternalCompileError(compilerText.getBuffer(), severity, SLANG_OK, builder.getUnownedSlice(), sink);
+ }
+ }
+
+ // If any errors are emitted, then we are done
+ if (diagnostics->hasOfAtLeastSeverity(ArtifactDiagnostic::Severity::Error))
+ {
+ return SLANG_FAIL;
+ }
+
+ return SLANG_OK;
+ }
+
SlangResult CodeGenContext::emitWithDownstreamForEntryPoints(ComPtr<IArtifact>& outArtifact)
{
outArtifact.setNull();
@@ -1421,62 +1486,7 @@ namespace Slang
(std::chrono::high_resolution_clock::now() - downstreamStartTime).count() * 0.000000001;
getSession()->addDownstreamCompileTime(downstreamElapsedTime);
- auto diagnostics = findAssociatedRepresentation<IArtifactDiagnostics>(artifact);
-
- if (diagnostics->getCount())
- {
- StringBuilder compilerText;
- DownstreamCompilerUtil::appendAsText(compiler->getDesc(), compilerText);
-
- StringBuilder builder;
-
- auto const diagnosticCount = diagnostics->getCount();
- for (Index i = 0; i < diagnosticCount; ++i)
- {
- const auto& diagnostic = *diagnostics->getAt(i);
-
- builder.clear();
-
- const Severity severity = _getDiagnosticSeverity(diagnostic.severity);
-
- if (diagnostic.filePath.count == 0 && diagnostic.location.line == 0 && severity == Severity::Note)
- {
- // If theres no filePath line number and it's info, output severity and text alone
- builder << getSeverityName(severity) << " : ";
- }
- else
- {
- if (diagnostic.filePath.count)
- {
- builder << asStringSlice(diagnostic.filePath);
- }
-
- if (diagnostic.location.line)
- {
- builder << "(" << diagnostic.location.line <<")";
- }
-
- builder << ": ";
-
- if (diagnostic.stage == ArtifactDiagnostic::Stage::Link)
- {
- builder << "link ";
- }
-
- builder << getSeverityName(severity);
- builder << " " << asStringSlice(diagnostic.code) << ": ";
- }
-
- builder << asStringSlice(diagnostic.text);
- reportExternalCompileError(compilerText.getBuffer(), severity, SLANG_OK, builder.getUnownedSlice(), sink);
- }
- }
-
- // If any errors are emitted, then we are done
- if (diagnostics->hasOfAtLeastSeverity(ArtifactDiagnostic::Severity::Error))
- {
- return SLANG_FAIL;
- }
+ SLANG_RETURN_ON_FAIL(passthroughDownstreamDiagnostics(getSink(), compiler, artifact));
// Copy over all of the information associated with the source into the output
if (sourceArtifact)
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index c5bd3348c..c3f2d8e70 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -1197,6 +1197,7 @@ namespace Slang
GenericCCpp = SLANG_PASS_THROUGH_GENERIC_C_CPP, ///< Generic C/C++ compiler
NVRTC = SLANG_PASS_THROUGH_NVRTC, ///< NVRTC CUDA compiler
LLVM = SLANG_PASS_THROUGH_LLVM, ///< LLVM 'compiler'
+ SpirvOpt = SLANG_PASS_THROUGH_SPIRV_OPT, ///< pass thorugh spirv to spirv-opt
CountOf = SLANG_PASS_THROUGH_COUNT_OF,
};
void printDiagnosticArg(StringBuilder& sb, PassThroughMode val);
@@ -3153,6 +3154,8 @@ namespace Slang
DiagnosticSink* sink,
const LoadedModuleDictionary* additionalLoadedModules);
+ SlangResult passthroughDownstreamDiagnostics(DiagnosticSink* sink, IDownstreamCompiler* compiler, IArtifact* artifact);
+
//
// The following functions are utilties to convert between
// matching "external" (public API) and "internal" (implementation)
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 6d71f1a2c..16a88b8af 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -4815,18 +4815,22 @@ SlangResult emitSPIRVFromIR(
(uint8_t const*) context.m_words.getBuffer(),
context.m_words.getCount() * Index(sizeof(context.m_words[0])));
- const auto validationResult = debugValidateSPIRV(spirvOut);
- // If validation isn't available, don't say it failed, it's just a debug
- // feature so we can skip
- if(SLANG_FAILED(validationResult) && validationResult != SLANG_E_NOT_AVAILABLE)
+ StringBuilder runSpirvValEnvVar;
+ PlatformUtil::getEnvironmentVariable(UnownedStringSlice("SLANG_RUN_SPIRV_VALIDATION"), runSpirvValEnvVar);
+ if (runSpirvValEnvVar.getUnownedSlice() == "1")
{
- codeGenContext->getSink()->diagnoseWithoutSourceView(
- SourceLoc{},
- Diagnostics::spirvValidationFailed
- );
- return validationResult;
+ const auto validationResult = debugValidateSPIRV(spirvOut);
+ // If validation isn't available, don't say it failed, it's just a debug
+ // feature so we can skip
+ if (SLANG_FAILED(validationResult) && validationResult != SLANG_E_NOT_AVAILABLE)
+ {
+ codeGenContext->getSink()->diagnoseWithoutSourceView(
+ SourceLoc{},
+ Diagnostics::spirvValidationFailed
+ );
+ return validationResult;
+ }
}
-
return SLANG_OK;
}
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 86136a010..57ca736e3 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -73,7 +73,6 @@
#include "slang-legalize-types.h"
#include "slang-lower-to-ir.h"
#include "slang-mangle.h"
-#include "slang-spirv-opt.h"
#include "slang-syntax.h"
#include "slang-type-layout.h"
#include "slang-visitor.h"
@@ -931,8 +930,7 @@ Result linkAndOptimizeIR(
if (isKhronosTarget(targetRequest) && targetRequest->shouldEmitSPIRVDirectly())
{
- //performIntrinsicFunctionFunctionInlining(irModule);
- performSpirvInlining(irModule);
+ performIntrinsicFunctionFunctionInlining(irModule);
eliminateDeadCode(irModule);
}
eliminateMultiLevelBreak(irModule);
@@ -1289,10 +1287,36 @@ SlangResult emitSPIRVForEntryPointsDirectly(
spirv = _Move(outSpirv);
}
#endif
-
auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(codeGenContext->getTargetFormat()));
artifact->addRepresentationUnknown(ListBlob::moveCreate(spirv));
+ IDownstreamCompiler* compiler = codeGenContext->getSession()->getOrLoadDownstreamCompiler(
+ PassThroughMode::SpirvOpt, codeGenContext->getSink());
+ if (compiler)
+ {
+ ComPtr<IArtifact> optimizedArtifact;
+ DownstreamCompileOptions downstreamOptions;
+ downstreamOptions.sourceArtifacts = makeSlice(artifact.readRef(), 1);
+ downstreamOptions.targetType = SLANG_SPIRV;
+ downstreamOptions.sourceLanguage = SLANG_SOURCE_LANGUAGE_SPIRV;
+ auto linkage = codeGenContext->getLinkage();
+ switch (linkage->optimizationLevel)
+ {
+ case OptimizationLevel::None: downstreamOptions.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::None; break;
+ case OptimizationLevel::Default: downstreamOptions.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::Default; break;
+ case OptimizationLevel::High: downstreamOptions.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::High; break;
+ case OptimizationLevel::Maximal: downstreamOptions.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::Maximal; break;
+ default: SLANG_ASSERT(!"Unhandled optimization level"); break;
+ }
+
+ if (SLANG_SUCCEEDED(compiler->compile(downstreamOptions, optimizedArtifact.writeRef())))
+ {
+ artifact = _Move(optimizedArtifact);
+ }
+
+ SLANG_RETURN_ON_FAIL(passthroughDownstreamDiagnostics(codeGenContext->getSink(), compiler, artifact));
+ }
+
ArtifactUtil::addAssociated(artifact, linkedIR.metadata);
outArtifact.swap(artifact);
diff --git a/source/slang/slang-ir-inline.cpp b/source/slang/slang-ir-inline.cpp
index 3b01d7dde..01dfdc42d 100644
--- a/source/slang/slang-ir-inline.cpp
+++ b/source/slang/slang-ir-inline.cpp
@@ -1019,33 +1019,4 @@ bool inlineCall(IRCall* call)
return pass.considerCallSite(call);
}
-
-struct SpirvInliningPass : InliningPassBase
-{
- typedef InliningPassBase Super;
-
- SpirvInliningPass(IRModule* module)
- : Super(module)
- {}
-
- bool shouldInline(CallSiteInfo const& info)
- {
- if (!info.callee->findDecoration<IREntryPointDecoration>())
- return true;
- return false;
- }
-};
-
-void performSpirvInlining(IRModule* module)
-{
- SLANG_PROFILE;
- while (true)
- {
- SpirvInliningPass pass(module);
- if (pass.considerAllCallSites())
- continue;
- break;
- }
-}
-
} // namespace Slang
diff --git a/source/slang/slang-ir-inline.h b/source/slang/slang-ir-inline.h
index 5e888ad07..539bb26c0 100644
--- a/source/slang/slang-ir-inline.h
+++ b/source/slang/slang-ir-inline.h
@@ -34,9 +34,6 @@ namespace Slang
/// Inline simple intrinsic functions whose definition is a single asm block.
void performIntrinsicFunctionFunctionInlining(IRModule* module);
- /// Inline all functions for SPIRV emit.
- void performSpirvInlining(IRModule* module);
-
/// Inline a specific call.
bool inlineCall(IRCall* call);
}
diff --git a/source/slang/slang-spirv-opt.cpp b/source/slang/slang-spirv-opt.cpp
deleted file mode 100644
index 786358324..000000000
--- a/source/slang/slang-spirv-opt.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#include "slang-spirv-opt.h"
-#include "slang-spirv-val.h"
-
-namespace Slang
-{
-
-struct RemoveFileRAII
-{
- String fileName;
-
- RemoveFileRAII(String inFileName)
- :fileName(inFileName)
- {}
-
- ~RemoveFileRAII()
- {
- File::remove(fileName);
- }
-};
-
-SlangResult optimizeSPIRV(const List<uint8_t>& spirv, String& outErr, List<uint8_t>& outSpv)
-{
- // Set up our process
- CommandLine commandLine;
- commandLine.m_executableLocation.setName("spirv-opt");
- commandLine.addArg("--eliminate-dead-functions");
- commandLine.addArg("--eliminate-local-single-block");
- commandLine.addArg("--eliminate-local-single-store");
- commandLine.addArg("--eliminate-dead-code-aggressive");
-
- commandLine.addArg("-o");
- String outFileName;
- File::generateTemporary(UnownedStringSlice("out_spv"), outFileName);
- RemoveFileRAII removeFile(outFileName);
-
- commandLine.addArg(outFileName);
-
- RefPtr<Process> p;
-
- // If we failed to even start the process, then spirv-opt isn't available
- SLANG_RETURN_ON_FAIL(Process::create(commandLine, 0, p));
- const auto in = p->getStream(StdStreamType::In);
- const auto out = p->getStream(StdStreamType::Out);
- const auto err = p->getStream(StdStreamType::ErrorOut);
-
- List<Byte> outErrData;
- SLANG_RETURN_ON_FAIL(StreamUtil::readAndWrite(in, spirv.getArrayView(), out, outSpv, err, outErrData));
-
- outSpv.clear();
- File::readAllBytes(outFileName, outSpv);
-
- SLANG_RETURN_ON_FAIL(p->waitForTermination(3600000));
-
- outErr = String(
- reinterpret_cast<const char*>(outErrData.begin()),
- reinterpret_cast<const char*>(outErrData.end())
- );
-
- const auto ret = p->getReturnValue();
- if (ret != 0)
- return SLANG_FAIL;
-
- return debugValidateSPIRV(outSpv);
-}
-
-}
diff --git a/source/slang/slang-spirv-opt.h b/source/slang/slang-spirv-opt.h
deleted file mode 100644
index c7dfde157..000000000
--- a/source/slang/slang-spirv-opt.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-#include <cstdint>
-#include "slang-compiler.h"
-
-namespace Slang
-{
-SlangResult optimizeSPIRV(const List<uint8_t>& spirv, String& outErr, List<uint8_t>& outSpv);
-}
-
diff --git a/tools/gfx/slang.slang b/tools/gfx/slang.slang
index 1fd06560f..aa28fae82 100644
--- a/tools/gfx/slang.slang
+++ b/tools/gfx/slang.slang
@@ -84,12 +84,14 @@ enum SlangPassThrough : int
SLANG_PASS_THROUGH_FXC,
SLANG_PASS_THROUGH_DXC,
SLANG_PASS_THROUGH_GLSLANG,
+ SLANG_PASS_THROUGH_SPIRV_DIS,
SLANG_PASS_THROUGH_CLANG, ///< Clang C/C++ compiler
SLANG_PASS_THROUGH_VISUAL_STUDIO, ///< Visual studio C/C++ compiler
SLANG_PASS_THROUGH_GCC, ///< GCC C/C++ compiler
SLANG_PASS_THROUGH_GENERIC_C_CPP, ///< Generic C or C++ compiler, which is decided by the source type
SLANG_PASS_THROUGH_NVRTC, ///< NVRTC Cuda compiler
SLANG_PASS_THROUGH_LLVM, ///< LLVM 'compiler' - includes LLVM and Clang
+ SLANG_PASS_THROUGH_SPIRV_OPT,
SLANG_PASS_THROUGH_COUNT_OF,
};