summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-04-19 21:02:32 -0700
committerGitHub <noreply@github.com>2024-04-19 21:02:32 -0700
commitbeae3a9d219dac1e4e3da9c357b25d06370388f3 (patch)
treeca4eb2a8e9ca67a130e3894c517114709576af75
parentf9bcad35562c1f08638e6d3eb397d370d7d2f8f8 (diff)
Add metal downstream compiler + metallib target. (#3990)
* Add metal downstream compiler + metallib target. * Add more comments. * Add missing override.
-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--slang.h2
-rw-r--r--source/compiler-core/slang-artifact-desc-util.cpp7
-rw-r--r--source/compiler-core/slang-downstream-compiler-util.cpp2
-rw-r--r--source/compiler-core/slang-gcc-compiler-util.cpp11
-rw-r--r--source/compiler-core/slang-metal-compiler.cpp80
-rw-r--r--source/compiler-core/slang-metal-compiler.h18
-rw-r--r--source/core/slang-type-text-util.cpp5
-rw-r--r--source/slang/slang-capabilities.capdef10
-rw-r--r--source/slang/slang-compiler.cpp10
-rwxr-xr-xsource/slang/slang-compiler.h2
-rw-r--r--source/slang/slang-emit-c-like.cpp2
-rw-r--r--source/slang/slang-ir-link.cpp2
-rw-r--r--source/slang/slang-options.cpp3
-rw-r--r--source/slang/slang-profile-defs.h8
-rw-r--r--source/slang/slang-type-layout.cpp4
-rw-r--r--source/slang/slang.cpp14
-rw-r--r--tests/metal/simple-compute.slang3
-rw-r--r--tools/slang-test/slang-test-main.cpp6
-rw-r--r--tools/slang-test/test-context.h1
21 files changed, 192 insertions, 6 deletions
diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj b/build/visual-studio/compiler-core/compiler-core.vcxproj
index 22a19abb9..8fab69523 100644
--- a/build/visual-studio/compiler-core/compiler-core.vcxproj
+++ b/build/visual-studio/compiler-core/compiler-core.vcxproj
@@ -302,6 +302,7 @@
<ClInclude Include="..\..\..\source\compiler-core\slang-lexer-diagnostic-defs.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-lexer.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-llvm-compiler.h" />
+ <ClInclude Include="..\..\..\source\compiler-core\slang-metal-compiler.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-misc-diagnostic-defs.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-name-convention-util.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-name.h" />
@@ -352,6 +353,7 @@
<ClCompile Include="..\..\..\source\compiler-core\slang-language-server-protocol.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-lexer.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-llvm-compiler.cpp" />
+ <ClCompile Include="..\..\..\source\compiler-core\slang-metal-compiler.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-name-convention-util.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-name.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-nvrtc-compiler.cpp" />
diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
index eb1d52dfb..4b4b7eed6 100644
--- a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
+++ b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
@@ -120,6 +120,9 @@
<ClInclude Include="..\..\..\source\compiler-core\slang-llvm-compiler.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\compiler-core\slang-metal-compiler.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\compiler-core\slang-misc-diagnostic-defs.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -266,6 +269,9 @@
<ClCompile Include="..\..\..\source\compiler-core\slang-llvm-compiler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\compiler-core\slang-metal-compiler.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\compiler-core\slang-name-convention-util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/slang.h b/slang.h
index 1b7737f18..b0007d1d3 100644
--- a/slang.h
+++ b/slang.h
@@ -610,6 +610,8 @@ extern "C"
SLANG_HOST_HOST_CALLABLE, ///< Host callable host code (ie non kernel/shader)
SLANG_CPP_PYTORCH_BINDING, ///< C++ PyTorch binding code.
SLANG_METAL, ///< Metal shading language
+ SLANG_METAL_LIB, ///< Metal library
+ SLANG_METAL_LIB_ASM, ///< Metal library assembly
SLANG_TARGET_COUNT_OF,
};
diff --git a/source/compiler-core/slang-artifact-desc-util.cpp b/source/compiler-core/slang-artifact-desc-util.cpp
index 2646555bc..7e3f61915 100644
--- a/source/compiler-core/slang-artifact-desc-util.cpp
+++ b/source/compiler-core/slang-artifact-desc-util.cpp
@@ -287,6 +287,8 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL
case SLANG_OBJECT_CODE: return Desc::make(Kind::ObjectCode, Payload::HostCPU, Style::Kernel, 0);
case SLANG_HOST_HOST_CALLABLE: return Desc::make(Kind::HostCallable, Payload::HostCPU, Style::Host, 0);
case SLANG_METAL: return Desc::make(Kind::Source, Payload::Metal, Style::Kernel, 0);
+ 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);
default: break;
}
@@ -328,6 +330,7 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL
case Payload::C: return SLANG_C_SOURCE;
case Payload::Cpp: return (desc.style == Style::Host) ? SLANG_HOST_CPP_SOURCE : SLANG_CPP_SOURCE;
case Payload::CUDA: return SLANG_CUDA_SOURCE;
+ case Payload::Metal: return SLANG_METAL;
default: break;
}
break;
@@ -340,6 +343,7 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL
case Payload::DXIL: return SLANG_DXIL_ASM;
case Payload::DXBC: return SLANG_DXBC_ASM;
case Payload::PTX: return SLANG_PTX;
+ case Payload::MetalAIR: return SLANG_METAL_LIB_ASM;
default: break;
}
}
@@ -367,6 +371,7 @@ SLANG_HIERARCHICAL_ENUM(ArtifactStyle, SLANG_ARTIFACT_STYLE, SLANG_ARTIFACT_STYL
case Payload::DXIL: return SLANG_DXIL;
case Payload::DXBC: return SLANG_DXBC;
case Payload::PTX: return SLANG_PTX;
+ case Payload::MetalAIR: return SLANG_METAL_LIB_ASM;
default: break;
}
}
@@ -638,7 +643,7 @@ static UnownedStringSlice _getPayloadExtension(ArtifactPayload payload)
case Payload::SlangIR: return toSlice("slang-ir");
- case Payload::MetalAIR: return toSlice("air");
+ case Payload::MetalAIR: return toSlice("metallib");
case Payload::PdbDebugInfo: return toSlice("pdb");
case Payload::SourceMap: return toSlice("map");
diff --git a/source/compiler-core/slang-downstream-compiler-util.cpp b/source/compiler-core/slang-downstream-compiler-util.cpp
index 52bf03acc..70ecb8ad7 100644
--- a/source/compiler-core/slang-downstream-compiler-util.cpp
+++ b/source/compiler-core/slang-downstream-compiler-util.cpp
@@ -23,6 +23,7 @@
#include "slang-dxc-compiler.h"
#include "slang-glslang-compiler.h"
#include "slang-llvm-compiler.h"
+#include "slang-metal-compiler.h"
namespace Slang
{
@@ -330,6 +331,7 @@ DownstreamCompilerMatchVersion DownstreamCompilerUtil::getCompiledVersion()
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_METAL)] = &MetalDownstreamCompilerUtil::locateCompilers;
}
static String _getParentPath(const String& path)
diff --git a/source/compiler-core/slang-gcc-compiler-util.cpp b/source/compiler-core/slang-gcc-compiler-util.cpp
index 79aefc71d..2bcdfcbfa 100644
--- a/source/compiler-core/slang-gcc-compiler-util.cpp
+++ b/source/compiler-core/slang-gcc-compiler-util.cpp
@@ -107,12 +107,15 @@ SlangResult GCCDownstreamCompilerUtil::calcVersion(const ExecutableLocation& exe
UnownedStringSlice::fromLiteral("clang version"),
UnownedStringSlice::fromLiteral("gcc version"),
UnownedStringSlice::fromLiteral("Apple LLVM version"),
+ UnownedStringSlice::fromLiteral("Apple metal version"),
+
};
const SlangPassThrough types[] =
{
SLANG_PASS_THROUGH_CLANG,
SLANG_PASS_THROUGH_GCC,
SLANG_PASS_THROUGH_CLANG,
+ SLANG_PASS_THROUGH_METAL,
};
SLANG_COMPILE_TIME_ASSERT(SLANG_COUNT_OF(prefixes) == SLANG_COUNT_OF(types));
@@ -262,8 +265,9 @@ static SlangResult _parseGCCFamilyLine(SliceAllocator& allocator, const UnownedS
const auto split1 = split[1].trim();
const auto text = split[2].trim();
- // Check for special handling for clang (Can be Clang or clang apparently)
+ // Check for special handling for clang or metal
if (split0.startsWith(UnownedStringSlice::fromLiteral("clang")) ||
+ split0.startsWith(UnownedStringSlice::fromLiteral("metal")) ||
split0.startsWith(UnownedStringSlice::fromLiteral("Clang")) ||
split0 == UnownedStringSlice::fromLiteral("g++") ||
split0 == UnownedStringSlice::fromLiteral("gcc"))
@@ -469,6 +473,11 @@ static SlangResult _parseGCCFamilyLine(SliceAllocator& allocator, const UnownedS
// C++17 since we share headers with slang itself (which uses c++17)
cmdLine.addArg("-std=c++17");
}
+
+ if (targetDesc.payload == ArtifactDesc::Payload::MetalAIR)
+ {
+ cmdLine.addArg("-std=macos-metal2.3");
+ }
// Our generated code very often casts between dissimilar types with the
// knowledge that they have the same representation. This is strictly
diff --git a/source/compiler-core/slang-metal-compiler.cpp b/source/compiler-core/slang-metal-compiler.cpp
new file mode 100644
index 000000000..04bcf0f57
--- /dev/null
+++ b/source/compiler-core/slang-metal-compiler.cpp
@@ -0,0 +1,80 @@
+#include "slang-metal-compiler.h"
+#include "slang-gcc-compiler-util.h"
+#include "slang-artifact-desc-util.h"
+#include "slang-artifact-util.h"
+#include "slang-artifact-representation.h"
+
+namespace Slang
+{
+
+ class MetalDownstreamCompiler : public DownstreamCompilerBase
+ {
+ public:
+ // Because the metal compiler shares the same commandline interface with clang,
+ // we will use GccDownstreamCompilerUtil, which implements both gcc and clang,
+ // to create the inner compiler and wrap it here.
+ //
+ ComPtr<IDownstreamCompiler> cppCompiler;
+ String executablePath;
+
+ MetalDownstreamCompiler(ComPtr<IDownstreamCompiler>& innerCompiler, String path)
+ : DownstreamCompilerBase(innerCompiler->getDesc())
+ , cppCompiler(innerCompiler)
+ , executablePath(path)
+ {
+ }
+
+ virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased() override { return true; }
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, IArtifact** outArtifact)
+ {
+ // All compile requests should be routed directly to the inner compiler.
+ return cppCompiler->compile(options, outArtifact);
+ }
+
+ virtual SLANG_NO_THROW bool SLANG_MCALL canConvert(const ArtifactDesc& from, const ArtifactDesc& to) override
+ {
+ // Report that we can convert Metal IR to disassembly.
+ return ArtifactDescUtil::isDisassembly(from, to) && from.payload == ArtifactPayload::MetalAIR;
+ }
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL convert(IArtifact* from, const ArtifactDesc& to, IArtifact** outArtifact) override
+ {
+ // Use metal-objdump to disassemble the Metal IR.
+
+ ExecutableLocation exeLocation(executablePath, "metal-objdump");
+ CommandLine cmdLine;
+ cmdLine.setExecutableLocation(exeLocation);
+ cmdLine.addArg("--disassemble");
+ ComPtr<IOSFileArtifactRepresentation> srcFile;
+ SLANG_RETURN_ON_FAIL(from->requireFile(IArtifact::Keep::No, srcFile.writeRef()));
+ cmdLine.addArg(String(srcFile->getPath()));
+
+ ExecuteResult exeRes;
+ SLANG_RETURN_ON_FAIL(ProcessUtil::execute(cmdLine, exeRes));
+ auto artifact = ArtifactUtil::createArtifact(to);
+ artifact->addRepresentationUnknown(StringBlob::create(exeRes.standardOutput));
+ *outArtifact = artifact.detach();
+ return SLANG_OK;
+ }
+ };
+
+ static SlangResult locateMetalCompiler(const String& path, DownstreamCompilerSet* set)
+ {
+ ComPtr<IDownstreamCompiler> innerCppCompiler;
+ ExecutableLocation exeLocation(path, "metal");
+ SLANG_RETURN_ON_FAIL(GCCDownstreamCompilerUtil::createCompiler(exeLocation, innerCppCompiler));
+
+ ComPtr<IDownstreamCompiler> compiler = ComPtr<IDownstreamCompiler>(
+ new MetalDownstreamCompiler(innerCppCompiler, path));
+ set->addCompiler(compiler);
+ return SLANG_OK;
+ }
+
+ SlangResult MetalDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set)
+ {
+ SLANG_UNUSED(loader);
+ return locateMetalCompiler(path, set);
+ }
+
+}
diff --git a/source/compiler-core/slang-metal-compiler.h b/source/compiler-core/slang-metal-compiler.h
new file mode 100644
index 000000000..7a14e5fa9
--- /dev/null
+++ b/source/compiler-core/slang-metal-compiler.h
@@ -0,0 +1,18 @@
+#ifndef SLANG_METAL_COMPILER_UTIL_H
+#define SLANG_METAL_COMPILER_UTIL_H
+
+#include "slang-downstream-compiler-util.h"
+
+#include "../core/slang-platform.h"
+
+namespace Slang
+{
+
+ struct MetalDownstreamCompilerUtil
+ {
+ static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set);
+ };
+
+}
+
+#endif
diff --git a/source/core/slang-type-text-util.cpp b/source/core/slang-type-text-util.cpp
index 7e1ffc439..f2f408b28 100644
--- a/source/core/slang-type-text-util.cpp
+++ b/source/core/slang-type-text-util.cpp
@@ -61,7 +61,9 @@ static const TypeTextUtil::CompileTargetInfo s_compileTargetInfos[] =
{ SLANG_SHADER_HOST_CALLABLE, "", "host-callable,callable", "Host callable" },
{ SLANG_OBJECT_CODE, "obj,o", "object-code", "Object code" },
{ SLANG_HOST_HOST_CALLABLE, "", "host-host-callable", "Host callable for host execution" },
- { SLANG_METAL, "metal", "metal", "Metal shader source"},
+ { SLANG_METAL, "metal", "metal", "Metal shader source" },
+ { SLANG_METAL_LIB, "metallib", "metallib", "Metal Library Bytecode" },
+ { SLANG_METAL_LIB_ASM, "metallib-asm" "metallib-asm", "Metal Library Bytecode assembly" },
};
static const NamesDescriptionValue s_languageInfos[] =
@@ -88,6 +90,7 @@ static const NamesDescriptionValue s_compilerInfos[] =
{ 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" },
+ { SLANG_PASS_THROUGH_METAL, "metal", "Metal shader compiler" },
};
static const NamesDescriptionValue s_archiveTypeInfos[] =
diff --git a/source/slang/slang-capabilities.capdef b/source/slang/slang-capabilities.capdef
index 4e31948a2..fe11be4b2 100644
--- a/source/slang/slang-capabilities.capdef
+++ b/source/slang/slang-capabilities.capdef
@@ -95,6 +95,10 @@ def glsl_spirv_1_4 : glsl_spirv_1_3;
def glsl_spirv_1_5 : glsl_spirv_1_4;
def glsl_spirv_1_6 : glsl_spirv_1_5;
+def metallib_2_3 : metal;
+def metallib_2_4 : metallib_2_3;
+
+
abstract stage;
def vertex : stage;
def fragment : stage;
@@ -572,6 +576,10 @@ alias DX_6_5 = sm_6_5;
alias DX_6_6 = sm_6_6;
alias DX_6_7 = sm_6_7;
+
+alias METAL_2_3 = metallib_2_3;
+alias METAL_2_4 = metallib_2_4;
+
alias sm_2_0_GLSL_140 = sm_4_0 | glsl | spirv_1_0 | cuda | cpp;
alias sm_2_0_GLSL_400 = sm_4_0 | glsl | spirv_1_0 | cuda | cpp;
alias appendstructuredbuffer = sm_5_0 + raytracing_stages_compute_fragment;
@@ -679,4 +687,4 @@ alias all = _sm_6_7 + hlsl_nvapi
+ _GL_NV_ray_tracing_motion_blur + _GL_NV_shader_texture_footprint
| spirv_1_5 + sm_6_7
+ ser + shaderclock + texturefootprint + fragmentshaderinterlock + spvGroupNonUniformPartitionedNV
- + spvRayTracingMotionBlurNV + spvRayTracingMotionBlurNV; \ No newline at end of file
+ + spvRayTracingMotionBlurNV + spvRayTracingMotionBlurNV;
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 04536c81a..851e3115b 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -530,6 +530,11 @@ namespace Slang
{
return PassThroughMode::Glslang;
}
+ case CodeGenTarget::MetalLib:
+ case CodeGenTarget::MetalLibAssembly:
+ {
+ return PassThroughMode::MetalC;
+ }
case CodeGenTarget::ShaderHostCallable:
case CodeGenTarget::ShaderSharedLibrary:
case CodeGenTarget::HostExecutable:
@@ -957,6 +962,7 @@ namespace Slang
case CodeGenTarget::DXBytecode: return CodeGenTarget::HLSL;
case CodeGenTarget::DXIL: return CodeGenTarget::HLSL;
case CodeGenTarget::SPIRV: return CodeGenTarget::GLSL;
+ case CodeGenTarget::MetalLib: return CodeGenTarget::Metal;
default: break;
}
return CodeGenTarget::Unknown;
@@ -1546,6 +1552,7 @@ namespace Slang
case CodeGenTarget::SPIRVAssembly:
case CodeGenTarget::DXBytecodeAssembly:
case CodeGenTarget::DXILAssembly:
+ case CodeGenTarget::MetalLibAssembly:
{
// First compile to an intermediate target for the corresponding binary format.
const CodeGenTarget intermediateTarget = _getIntermediateTarget(target);
@@ -1573,6 +1580,7 @@ namespace Slang
[[fallthrough]];
case CodeGenTarget::DXIL:
case CodeGenTarget::DXBytecode:
+ case CodeGenTarget::MetalLib:
case CodeGenTarget::PTX:
case CodeGenTarget::ShaderHostCallable:
case CodeGenTarget::ShaderSharedLibrary:
@@ -1602,6 +1610,8 @@ namespace Slang
case CodeGenTarget::SPIRV:
case CodeGenTarget::DXIL:
case CodeGenTarget::DXBytecode:
+ case CodeGenTarget::MetalLib:
+ case CodeGenTarget::MetalLibAssembly:
case CodeGenTarget::PTX:
case CodeGenTarget::HostHostCallable:
case CodeGenTarget::ShaderHostCallable:
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 7f7903f8b..266c503ae 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -93,6 +93,8 @@ namespace Slang
ObjectCode = SLANG_OBJECT_CODE,
HostHostCallable = SLANG_HOST_HOST_CALLABLE,
Metal = SLANG_METAL,
+ MetalLib = SLANG_METAL_LIB,
+ MetalLibAssembly = SLANG_METAL_LIB_ASM,
CountOf = SLANG_TARGET_COUNT_OF,
};
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index 1926cbdcb..38708ae5e 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -74,6 +74,8 @@ struct CLikeSourceEmitter::ComputeEmitActionsContext
case CodeGenTarget::DXBytecodeAssembly:
case CodeGenTarget::DXIL:
case CodeGenTarget::DXILAssembly:
+ case CodeGenTarget::MetalLib:
+ case CodeGenTarget::MetalLibAssembly:
{
return SourceLanguage::Unknown;
}
diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp
index 86e255705..4871062d4 100644
--- a/source/slang/slang-ir-link.cpp
+++ b/source/slang/slang-ir-link.cpp
@@ -1468,6 +1468,8 @@ static bool doesTargetAllowUnresolvedFuncSymbol(TargetRequest* req)
{
case CodeGenTarget::HLSL:
case CodeGenTarget::Metal:
+ case CodeGenTarget::MetalLib:
+ case CodeGenTarget::MetalLibAssembly:
case CodeGenTarget::DXIL:
case CodeGenTarget::DXILAssembly:
case CodeGenTarget::HostCPPSource:
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index 896388db0..13a11f10b 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -2816,6 +2816,9 @@ SlangResult OptionsParser::_parse(
case CodeGenTarget::ShaderSharedLibrary:
case CodeGenTarget::PyTorchCppBinding:
case CodeGenTarget::DXIL:
+ case CodeGenTarget::MetalLib:
+ case CodeGenTarget::MetalLibAssembly:
+ case CodeGenTarget::Metal:
rawOutput.isWholeProgram = true;
break;
case CodeGenTarget::SPIRV:
diff --git a/source/slang/slang-profile-defs.h b/source/slang/slang-profile-defs.h
index 9a9c128a5..826555d1b 100644
--- a/source/slang/slang-profile-defs.h
+++ b/source/slang/slang-profile-defs.h
@@ -49,7 +49,7 @@ LANGUAGE(SPIRV, spirv)
LANGUAGE(SPIRV_GL, spirv_gl)
LANGUAGE(C, c)
LANGUAGE(CPP, cpp)
-
+LANGUAGE(METAL, metal)
LANGUAGE_ALIAS(GLSL, glsl_gl)
LANGUAGE_ALIAS(SPIRV, spirv_vk)
@@ -86,6 +86,7 @@ PROFILE_STAGE_ALIAS(Fragment, fragment, Pixel)
PROFILE_FAMILY(DX)
PROFILE_FAMILY(GLSL)
+PROFILE_FAMILY(METAL)
// Profile versions
PROFILE_VERSION(DX_4_0, DX)
@@ -111,6 +112,9 @@ PROFILE_VERSION(GLSL_440, GLSL)
PROFILE_VERSION(GLSL_450, GLSL)
PROFILE_VERSION(GLSL_460, GLSL)
+PROFILE_VERSION(METAL_2_3, METAL)
+PROFILE_VERSION(METAL_2_4, METAL)
+
// Specific profiles
PROFILE(DX_Compute_4_0, cs_4_0, Compute, DX_4_0)
@@ -229,6 +233,8 @@ PROFILE_ALIAS(DX_None_6_5, DX_Lib_6_5, sm_6_5)
PROFILE_ALIAS(DX_None_6_6, DX_Lib_6_6, sm_6_6)
PROFILE_ALIAS(DX_None_6_7, DX_Lib_6_7, sm_6_7)
+PROFILE(METAL_LIB_2_3, metallib_2_3, Unknown, METAL_2_3)
+PROFILE(METAL_LIB_2_4, metallib_2_4, Unknown, METAL_2_4)
// Define all the GLSL profiles
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index a350226c8..00f365ac3 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -1550,6 +1550,8 @@ LayoutRulesFamilyImpl* getDefaultLayoutRulesFamilyForTarget(TargetRequest* targe
case CodeGenTarget::CPPSource:
case CodeGenTarget::CSource:
case CodeGenTarget::Metal:
+ case CodeGenTarget::MetalLib:
+ case CodeGenTarget::MetalLibAssembly:
{
// For now lets use some fairly simple CPU binding rules
@@ -1820,6 +1822,8 @@ SourceLanguage getIntermediateSourceLanguageForTarget(TargetProgram* targetProgr
return SourceLanguage::HLSL;
}
case CodeGenTarget::Metal:
+ case CodeGenTarget::MetalLib:
+ case CodeGenTarget::MetalLibAssembly:
{
return SourceLanguage::Metal;
}
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 437f0cd63..971d6056f 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -257,11 +257,13 @@ void Session::_initCodeGenTransitionMap()
map.addTransition(CodeGenTarget::HLSL, CodeGenTarget::DXBytecode, PassThroughMode::Fxc);
map.addTransition(CodeGenTarget::HLSL, CodeGenTarget::DXIL, PassThroughMode::Dxc);
map.addTransition(CodeGenTarget::GLSL, CodeGenTarget::SPIRV, PassThroughMode::Glslang);
-
+ map.addTransition(CodeGenTarget::Metal, CodeGenTarget::MetalLib, PassThroughMode::MetalC);
// To assembly
map.addTransition(CodeGenTarget::SPIRV, CodeGenTarget::SPIRVAssembly, PassThroughMode::Glslang);
map.addTransition(CodeGenTarget::DXIL, CodeGenTarget::DXILAssembly, PassThroughMode::Dxc);
map.addTransition(CodeGenTarget::DXBytecode, CodeGenTarget::DXBytecodeAssembly, PassThroughMode::Fxc);
+ map.addTransition(CodeGenTarget::MetalLib, CodeGenTarget::MetalLibAssembly, PassThroughMode::MetalC);
+
}
void Session::addBuiltins(
@@ -930,6 +932,14 @@ Profile getEffectiveProfile(EntryPoint* entryPoint, TargetRequest* target)
targetProfile.setVersion(ProfileVersion::DX_5_1);
}
break;
+ case CodeGenTarget::Metal:
+ case CodeGenTarget::MetalLib:
+ case CodeGenTarget::MetalLibAssembly:
+ if (targetProfile.getFamily() != ProfileFamily::METAL)
+ {
+ targetProfile.setVersion(ProfileVersion::METAL_2_3);
+ }
+ break;
}
auto entryPointProfileVersion = entryPointProfile.getVersion();
@@ -1710,6 +1720,8 @@ CapabilitySet TargetRequest::getTargetCaps()
break;
case CodeGenTarget::Metal:
+ case CodeGenTarget::MetalLib:
+ case CodeGenTarget::MetalLibAssembly:
atoms.add(CapabilityName::metal);
break;
diff --git a/tests/metal/simple-compute.slang b/tests/metal/simple-compute.slang
index fe797dc2c..56d8fefd4 100644
--- a/tests/metal/simple-compute.slang
+++ b/tests/metal/simple-compute.slang
@@ -1,9 +1,12 @@
//TEST:SIMPLE(filecheck=CHECK): -target metal
+//TEST:SIMPLE(filecheck=CHECK-ASM): -target metallib
uniform RWStructuredBuffer<float> outputBuffer;
// CHECK: {{.*}}kernel{{.*}} void main_kernel(float device* {{.*}})
+// CHECK-ASM: define void @main_kernel
+
void func(float v)
{
outputBuffer[0] = v;
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index cb77c8830..eca103339 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -987,6 +987,12 @@ static PassThroughFlags _getPassThroughFlagsForTarget(SlangCompileTarget target)
return PassThroughFlag::Dxc;
}
+ case SLANG_METAL_LIB:
+ case SLANG_METAL_LIB_ASM:
+ {
+ return PassThroughFlag::Metal;
+ }
+
case SLANG_SHADER_HOST_CALLABLE:
case SLANG_HOST_HOST_CALLABLE:
diff --git a/tools/slang-test/test-context.h b/tools/slang-test/test-context.h
index aa27f7d96..7006ec905 100644
--- a/tools/slang-test/test-context.h
+++ b/tools/slang-test/test-context.h
@@ -37,6 +37,7 @@ struct PassThroughFlag
Generic_C_CPP = 1 << int(SLANG_PASS_THROUGH_GENERIC_C_CPP),
NVRTC = 1 << int(SLANG_PASS_THROUGH_NVRTC),
LLVM = 1 << int(SLANG_PASS_THROUGH_LLVM),
+ Metal = 1 << int(SLANG_PASS_THROUGH_METAL)
};
};