From 509409ef11e3b1abd1d7e1bfb540bc172aa1a817 Mon Sep 17 00:00:00 2001 From: Anders Leino Date: Mon, 7 Oct 2024 20:16:19 +0300 Subject: Add WGSL support for slang-test (#5174) * Use the assembly description as target when disassembling I believe this is a bugfix. It seems to have worked before because up until the WGSL case, the disassembler has been the same executable as the one producing the binary to be disassembled. * Add Tint as a downstream compiler This closes issue #5104. * Add downstream compiler for Tint. * Tint is wrapped in a shared library, 'slang-tint' available from [1]. * The header file for slang-tint.dll is added in external/slang-tint-headers. * Add some boilerplate for WGSL targets. * Add an entry point test for WGSL. [1] https://github.com/shader-slang/dawn/releases/tag/slang-tint-0 * Add WGSL_SPIRV as supported target for Glslang * Add WebGPU support to slang-test This helps to address issue #5051. * Disable lots of crashing compute tests for 'wgpu' This closes issue #5051. --------- Co-authored-by: Yong He --- source/compiler-core/slang-artifact-desc-util.cpp | 5 + source/compiler-core/slang-artifact.h | 1 + .../slang-downstream-compiler-util.cpp | 2 + source/compiler-core/slang-glslang-compiler.cpp | 4 +- source/compiler-core/slang-tint-compiler.cpp | 164 +++++++++++++++++++++ source/compiler-core/slang-tint-compiler.h | 17 +++ 6 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 source/compiler-core/slang-tint-compiler.cpp create mode 100644 source/compiler-core/slang-tint-compiler.h (limited to 'source/compiler-core') diff --git a/source/compiler-core/slang-artifact-desc-util.cpp b/source/compiler-core/slang-artifact-desc-util.cpp index 9794cc90e..ae7f84227 100644 --- a/source/compiler-core/slang-artifact-desc-util.cpp +++ b/source/compiler-core/slang-artifact-desc-util.cpp @@ -205,6 +205,7 @@ SLANG_HIERARCHICAL_ENUM(ArtifactKind, SLANG_ARTIFACT_KIND, SLANG_ARTIFACT_KIND_E x(PTX, KernelLike) \ x(CuBin, KernelLike) \ x(MetalAIR, KernelLike) \ + x(WGSL_SPIRV, KernelLike) \ x(CPULike, Base) \ x(UnknownCPU, CPULike) \ x(X86, CPULike) \ @@ -290,6 +291,8 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL case SLANG_METAL_LIB: return Desc::make(Kind::Executable, Payload::MetalAIR, Style::Kernel, 0); case SLANG_METAL_LIB_ASM: return Desc::make(Kind::Assembly, Payload::MetalAIR, Style::Kernel, 0); case SLANG_WGSL: return Desc::make(Kind::Source, Payload::WGSL, Style::Kernel, 0); + case SLANG_WGSL_SPIRV_ASM: return Desc::make(Kind::Assembly, Payload::WGSL_SPIRV, Style::Kernel, 0); + case SLANG_WGSL_SPIRV: return Desc::make(Kind::Executable, Payload::WGSL_SPIRV, Style::Kernel, 0); default: break; } @@ -346,6 +349,7 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL case Payload::DXBC: return SLANG_DXBC_ASM; case Payload::PTX: return SLANG_PTX; case Payload::MetalAIR: return SLANG_METAL_LIB_ASM; + case Payload::WGSL_SPIRV: return SLANG_WGSL_SPIRV_ASM; default: break; } } @@ -374,6 +378,7 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL case Payload::DXBC: return SLANG_DXBC; case Payload::PTX: return SLANG_PTX; case Payload::MetalAIR: return SLANG_METAL_LIB_ASM; + case Payload::WGSL_SPIRV: return SLANG_WGSL_SPIRV; default: break; } } diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h index 6d65aafba..d3784ca0a 100644 --- a/source/compiler-core/slang-artifact.h +++ b/source/compiler-core/slang-artifact.h @@ -153,6 +153,7 @@ enum class ArtifactPayload : uint8_t PTX, ///< PTX. NOTE! PTX is a text format, but is handable to CUDA API. MetalAIR, ///< Metal AIR CuBin, ///< CUDA binary + WGSL_SPIRV, ///< SPIR-V derived via WebGPU shading language CPULike, ///< CPU code diff --git a/source/compiler-core/slang-downstream-compiler-util.cpp b/source/compiler-core/slang-downstream-compiler-util.cpp index 70063b772..bf4c7cc04 100644 --- a/source/compiler-core/slang-downstream-compiler-util.cpp +++ b/source/compiler-core/slang-downstream-compiler-util.cpp @@ -24,6 +24,7 @@ #include "slang-glslang-compiler.h" #include "slang-llvm-compiler.h" #include "slang-metal-compiler.h" +#include "slang-tint-compiler.h" namespace Slang { @@ -332,6 +333,7 @@ DownstreamCompilerMatchVersion DownstreamCompilerUtil::getCompiledVersion() outFuncs[int(SLANG_PASS_THROUGH_LLVM)] = &LLVMDownstreamCompilerUtil::locateCompilers; outFuncs[int(SLANG_PASS_THROUGH_SPIRV_DIS)] = &SpirvDisDownstreamCompilerUtil::locateCompilers; outFuncs[int(SLANG_PASS_THROUGH_METAL)] = &MetalDownstreamCompilerUtil::locateCompilers; + outFuncs[int(SLANG_PASS_THROUGH_TINT)] = &TintDownstreamCompilerUtil::locateCompilers; } static String _getParentPath(const String& path) diff --git a/source/compiler-core/slang-glslang-compiler.cpp b/source/compiler-core/slang-glslang-compiler.cpp index 9ef8e7fb4..54635873a 100644 --- a/source/compiler-core/slang-glslang-compiler.cpp +++ b/source/compiler-core/slang-glslang-compiler.cpp @@ -301,7 +301,9 @@ SlangResult GlslangDownstreamCompiler::validate(const uint32_t* contents, int co bool GlslangDownstreamCompiler::canConvert(const ArtifactDesc& from, const ArtifactDesc& to) { // Can only disassemble blobs that are SPIR-V - return ArtifactDescUtil::isDisassembly(from, to) && from.payload == ArtifactPayload::SPIRV; + return ArtifactDescUtil::isDisassembly(from, to) && ( + (from.payload == ArtifactPayload::SPIRV) || + (from.payload == ArtifactPayload::WGSL_SPIRV)); } SlangResult GlslangDownstreamCompiler::convert(IArtifact* from, const ArtifactDesc& to, IArtifact** outArtifact) diff --git a/source/compiler-core/slang-tint-compiler.cpp b/source/compiler-core/slang-tint-compiler.cpp new file mode 100644 index 000000000..6319ecf9f --- /dev/null +++ b/source/compiler-core/slang-tint-compiler.cpp @@ -0,0 +1,164 @@ +#include "slang-tint-compiler.h" + +#include "slang-artifact-associated-impl.h" + +#include "../../external/slang-tint-headers/slang-tint.h" + +namespace Slang +{ + + class TintDownstreamCompiler : public DownstreamCompilerBase + { + + public: + + // IDownstreamCompiler + virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile( + const CompileOptions& options, IArtifact** outResult) SLANG_OVERRIDE; + + virtual SLANG_NO_THROW bool SLANG_MCALL canConvert( + const ArtifactDesc& from, const ArtifactDesc& to) SLANG_OVERRIDE; + + virtual SLANG_NO_THROW SlangResult SLANG_MCALL convert( + IArtifact* from, const ArtifactDesc& to, IArtifact** outArtifact) + SLANG_OVERRIDE; + + virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased() SLANG_OVERRIDE + { + return false; + } + + virtual SLANG_NO_THROW SlangResult SLANG_MCALL getVersionString( + slang::IBlob** outVersionString) SLANG_OVERRIDE; + + SlangResult compile(IArtifact *const sourceArtifact, IArtifact** outArtifact); + + SlangResult init(ISlangSharedLibrary* library); + + protected: + + ComPtr m_sharedLibrary; + + private: + + tint_CompileFunc m_compile; + tint_FreeResultFunc m_freeResult; + }; + + SlangResult TintDownstreamCompiler::init(ISlangSharedLibrary* library) + { + tint_CompileFunc compile = + (tint_CompileFunc)library->findFuncByName("tint_compile"); + if (compile == nullptr) + { + return SLANG_FAIL; + } + + tint_FreeResultFunc freeResult = + (tint_FreeResultFunc)library->findFuncByName("tint_free_result"); + if (freeResult == nullptr) + { + return SLANG_FAIL; + } + + m_sharedLibrary = library; + m_desc = Desc(SLANG_PASS_THROUGH_TINT); + m_compile = compile; + m_freeResult = freeResult; + return SLANG_OK; + } + + SlangResult TintDownstreamCompilerUtil::locateCompilers( + const String& path, + ISlangSharedLibraryLoader* loader, + DownstreamCompilerSet* set) + { + ComPtr library; + SLANG_RETURN_ON_FAIL(DownstreamCompilerUtil::loadSharedLibrary( + path, loader, nullptr, "slang-tint", library)); + SLANG_ASSERT(library); + + ComPtr compiler = ComPtr( + new TintDownstreamCompiler()); + SLANG_RETURN_ON_FAIL(static_cast( + compiler.get())->init(library)); + + set->addCompiler(compiler); + return SLANG_OK; + } + + SlangResult TintDownstreamCompiler::compile( + const CompileOptions& options, IArtifact** outArtifact) + { + IArtifact * sourceArtifact = options.sourceArtifacts[0]; + return compile(sourceArtifact, outArtifact); + } + + SlangResult TintDownstreamCompiler::compile( + IArtifact *const sourceArtifact, IArtifact** outArtifact) + { + tint_CompileRequest req = {}; + + if (sourceArtifact == nullptr) + return SLANG_FAIL; + + ComPtr sourceBlob; + SLANG_RETURN_FALSE_ON_FAIL(sourceArtifact->loadBlob( + ArtifactKeep::Yes, sourceBlob.writeRef())); + + String wgslCode( + (char*)sourceBlob->getBufferPointer(), + (char*)sourceBlob->getBufferPointer() + sourceBlob->getBufferSize()); + req.wgslCode = wgslCode.begin(); + req.wgslCodeLength = wgslCode.getLength(); + + tint_CompileResult result = {}; + SLANG_DEFER(m_freeResult(&result)); + bool compileSucceeded = m_compile(&req, &result) == 0; + + ComPtr spirvBlob = RawBlob::create(result.buffer, result.bufferSize); + result.buffer = nullptr; + + ComPtr resultArtifact = ArtifactUtil::createArtifactForCompileTarget( + SlangCompileTarget::SLANG_WGSL_SPIRV); + auto diagnostics = ArtifactDiagnostics::create(); + diagnostics->setResult(compileSucceeded ? SLANG_OK : SLANG_FAIL); + ArtifactUtil::addAssociated(resultArtifact, diagnostics); + if (compileSucceeded) + { + resultArtifact->addRepresentationUnknown(spirvBlob); + } + else + { + diagnostics->setRaw(CharSlice(result.error)); + diagnostics->requireErrorDiagnostic(); + } + + *outArtifact = resultArtifact.detach(); + return SLANG_OK; + } + + bool TintDownstreamCompiler::canConvert( + const ArtifactDesc& from, const ArtifactDesc& to) + { + return (from.payload == ArtifactPayload::WGSL) && + (to.payload == ArtifactPayload::SPIRV); + } + + SlangResult TintDownstreamCompiler::convert( + IArtifact* from, const ArtifactDesc& to, IArtifact** outArtifact) + { + if (!canConvert(from->getDesc(), to)) + return SLANG_FAIL; + return compile(from, outArtifact); + } + + SlangResult TintDownstreamCompiler::getVersionString( + slang::IBlob** /* outVersionString */) + { + // We just use Tint at whatever version is in our Dawn fork, so nobody should + // depend on the particular version at the moment. + return SLANG_FAIL; + } + +} diff --git a/source/compiler-core/slang-tint-compiler.h b/source/compiler-core/slang-tint-compiler.h new file mode 100644 index 000000000..d5e596d4d --- /dev/null +++ b/source/compiler-core/slang-tint-compiler.h @@ -0,0 +1,17 @@ +#pragma once + +#include "slang-downstream-compiler-util.h" +#include "../core/slang-platform.h" + +namespace Slang +{ + + struct TintDownstreamCompilerUtil + { + static SlangResult locateCompilers( + const String& path, + ISlangSharedLibraryLoader* loader, + DownstreamCompilerSet* set); + }; + +} -- cgit v1.2.3