소스 검색

Updated spirv-cross.

Бранимир Караџић 7 년 전
부모
커밋
812af5e6f1
41개의 변경된 파일982개의 추가작업 그리고 379개의 파일을 삭제
  1. 17 5
      3rdparty/spirv-cross/README.md
  2. 0 12
      3rdparty/spirv-cross/jni/Android.mk
  3. 0 2
      3rdparty/spirv-cross/jni/Application.mk
  4. 4 0
      3rdparty/spirv-cross/main.cpp
  5. 0 28
      3rdparty/spirv-cross/msvc/SPIRV-Cross.sln
  6. 0 156
      3rdparty/spirv-cross/msvc/SPIRV-Cross.vcxproj
  7. 0 93
      3rdparty/spirv-cross/msvc/SPIRV-Cross.vcxproj.filters
  8. 62 0
      3rdparty/spirv-cross/reference/opt/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag
  9. 40 0
      3rdparty/spirv-cross/reference/opt/shaders-msl/asm/frag/single-function-private-lut.asm.frag
  10. 1 1
      3rdparty/spirv-cross/reference/opt/shaders-msl/comp/force-recompile-hooks.swizzle.comp
  11. 29 0
      3rdparty/spirv-cross/reference/opt/shaders-msl/vert/basic.capture.vert
  12. 29 0
      3rdparty/spirv-cross/reference/opt/shaders-msl/vert/leaf-function.capture.vert
  13. 23 0
      3rdparty/spirv-cross/reference/opt/shaders/asm/frag/single-function-private-lut.asm.frag
  14. 65 0
      3rdparty/spirv-cross/reference/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag
  15. 2 7
      3rdparty/spirv-cross/reference/shaders-hlsl/frag/constant-composites.frag
  16. 1 1
      3rdparty/spirv-cross/reference/shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag
  17. 1 1
      3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-int.swizzle.frag
  18. 3 3
      3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag
  19. 1 1
      3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag
  20. 1 1
      3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag
  21. 3 3
      3rdparty/spirv-cross/reference/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag
  22. 56 0
      3rdparty/spirv-cross/reference/shaders-msl/asm/frag/single-function-private-lut.asm.frag
  23. 1 1
      3rdparty/spirv-cross/reference/shaders-msl/comp/force-recompile-hooks.swizzle.comp
  24. 2 4
      3rdparty/spirv-cross/reference/shaders-msl/frag/constant-composites.frag
  25. 29 0
      3rdparty/spirv-cross/reference/shaders-msl/vert/basic.capture.vert
  26. 36 0
      3rdparty/spirv-cross/reference/shaders-msl/vert/leaf-function.capture.vert
  27. 26 0
      3rdparty/spirv-cross/reference/shaders/asm/frag/single-function-private-lut.asm.frag
  28. 6 6
      3rdparty/spirv-cross/reference/shaders/frag/constant-composites.frag
  29. 86 0
      3rdparty/spirv-cross/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag
  30. 86 0
      3rdparty/spirv-cross/shaders-msl/asm/frag/single-function-private-lut.asm.frag
  31. 17 0
      3rdparty/spirv-cross/shaders-msl/vert/basic.capture.vert
  32. 22 0
      3rdparty/spirv-cross/shaders-msl/vert/leaf-function.capture.vert
  33. 86 0
      3rdparty/spirv-cross/shaders/asm/frag/single-function-private-lut.asm.frag
  34. 8 3
      3rdparty/spirv-cross/spirv_cross.cpp
  35. 2 1
      3rdparty/spirv-cross/spirv_cross.hpp
  36. 20 3
      3rdparty/spirv-cross/spirv_glsl.cpp
  37. 2 0
      3rdparty/spirv-cross/spirv_glsl.hpp
  38. 15 12
      3rdparty/spirv-cross/spirv_hlsl.cpp
  39. 173 34
      3rdparty/spirv-cross/spirv_msl.cpp
  40. 25 1
      3rdparty/spirv-cross/spirv_msl.hpp
  41. 2 0
      3rdparty/spirv-cross/test_shaders.py

+ 17 - 5
3rdparty/spirv-cross/README.md

@@ -24,17 +24,29 @@ However, most missing features are expected to be "trivial" improvements at this
 
 ## Building
 
-SPIRV-Cross has been tested on Linux, OSX and Windows.
-
-The make and CMake build flavors offer the option to treat exceptions as assertions. To disable exceptions for make just append `SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS=1` to the command line. For CMake append `-DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS=ON`. By default exceptions are enabled.
+SPIRV-Cross has been tested on Linux, iOS/OSX, Windows and Android. CMake is the main build system.
 
 ### Linux and macOS
 
-Just run `make` on the command line. A recent GCC (4.8+) or Clang (3.x+) compiler is required as SPIRV-Cross uses C++11 extensively.
+Building with CMake is recommended, as it is the only build system which is tested in continuous integration.
+It is also the only build system which has install commands and other useful build system features.
+
+However, you can just run `make` on the command line as a fallback if you only care about the CLI tool.
+
+A non-ancient GCC (4.8+) or Clang (3.x+) compiler is required as SPIRV-Cross uses C++11 extensively.
 
 ### Windows
 
-MinGW-w64 based compilation works with `make`, and an MSVC 2013 solution is also included.
+Building with CMake is recommended, which is the only way to target MSVC.
+MinGW-w64 based compilation works with `make` as a fallback.
+
+### Android
+
+SPIRV-Cross is only useful as a library here. Use the CMake build to link SPIRV-Cross to your project.
+
+### C++ exceptions
+
+The make and CMake build flavors offer the option to treat exceptions as assertions. To disable exceptions for make just append `SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS=1` to the command line. For CMake append `-DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS=ON`. By default exceptions are enabled.
 
 ## Usage
 

+ 0 - 12
3rdparty/spirv-cross/jni/Android.mk

@@ -1,12 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_CFLAGS += -std=c++11 -Wall -Wextra
-LOCAL_MODULE := spirv-cross
-LOCAL_SRC_FILES := ../spirv_cfg.cpp ../spirv_cross.cpp ../spirv_cross_util.cpp ../spirv_glsl.cpp ../spirv_hlsl.cpp ../spirv_msl.cpp ../spirv_cpp.cpp
-LOCAL_CPP_FEATURES := exceptions
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -D__STDC_LIMIT_MACROS
-
-include $(BUILD_STATIC_LIBRARY)

+ 0 - 2
3rdparty/spirv-cross/jni/Application.mk

@@ -1,2 +0,0 @@
-APP_STL := c++_static
-APP_ABI := armeabi-v7a

+ 4 - 0
3rdparty/spirv-cross/main.cpp

@@ -490,6 +490,7 @@ struct CLIArguments
 	bool yflip = false;
 	bool sso = false;
 	bool support_nonzero_baseinstance = true;
+	bool msl_capture_output_to_buffer = false;
 	bool msl_swizzle_texture_samples = false;
 	bool msl_ios = false;
 	bool msl_pad_fragment_output = false;
@@ -545,6 +546,7 @@ static void print_help()
 	                "\t[--cpp-interface-name <name>]\n"
 	                "\t[--msl]\n"
 	                "\t[--msl-version <MMmmpp>]\n"
+	                "\t[--msl-capture-output]\n"
 	                "\t[--msl-swizzle-texture-samples]\n"
 	                "\t[--msl-ios]\n"
 	                "\t[--msl-pad-fragment-output]\n"
@@ -714,6 +716,7 @@ static int main_inner(int argc, char *argv[])
 	cbs.add("--vulkan-semantics", [&args](CLIParser &) { args.vulkan_semantics = true; });
 	cbs.add("--flatten-multidimensional-arrays", [&args](CLIParser &) { args.flatten_multidimensional_arrays = true; });
 	cbs.add("--no-420pack-extension", [&args](CLIParser &) { args.use_420pack_extension = false; });
+	cbs.add("--msl-capture-output", [&args](CLIParser &) { args.msl_capture_output_to_buffer = true; });
 	cbs.add("--msl-swizzle-texture-samples", [&args](CLIParser &) { args.msl_swizzle_texture_samples = true; });
 	cbs.add("--msl-ios", [&args](CLIParser &) { args.msl_ios = true; });
 	cbs.add("--msl-pad-fragment-output", [&args](CLIParser &) { args.msl_pad_fragment_output = true; });
@@ -843,6 +846,7 @@ static int main_inner(int argc, char *argv[])
 		auto msl_opts = msl_comp->get_msl_options();
 		if (args.set_msl_version)
 			msl_opts.msl_version = args.msl_version;
+		msl_opts.capture_output_to_buffer = args.msl_capture_output_to_buffer;
 		msl_opts.swizzle_texture_samples = args.msl_swizzle_texture_samples;
 		if (args.msl_ios)
 			msl_opts.platform = CompilerMSL::Options::iOS;

+ 0 - 28
3rdparty/spirv-cross/msvc/SPIRV-Cross.sln

@@ -1,28 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Express 2013 for Windows Desktop
-VisualStudioVersion = 12.0.31101.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPIRV-Cross", "SPIRV-Cross.vcxproj", "{977E3701-1A21-4425-B7E5-6BDF5EA062CD}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
-		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{977E3701-1A21-4425-B7E5-6BDF5EA062CD}.Debug|Win32.ActiveCfg = Debug|Win32
-		{977E3701-1A21-4425-B7E5-6BDF5EA062CD}.Debug|Win32.Build.0 = Debug|Win32
-		{977E3701-1A21-4425-B7E5-6BDF5EA062CD}.Debug|x64.ActiveCfg = Debug|x64
-		{977E3701-1A21-4425-B7E5-6BDF5EA062CD}.Debug|x64.Build.0 = Debug|x64
-		{977E3701-1A21-4425-B7E5-6BDF5EA062CD}.Release|Win32.ActiveCfg = Release|Win32
-		{977E3701-1A21-4425-B7E5-6BDF5EA062CD}.Release|Win32.Build.0 = Release|Win32
-		{977E3701-1A21-4425-B7E5-6BDF5EA062CD}.Release|x64.ActiveCfg = Release|x64
-		{977E3701-1A21-4425-B7E5-6BDF5EA062CD}.Release|x64.Build.0 = Release|x64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal

+ 0 - 156
3rdparty/spirv-cross/msvc/SPIRV-Cross.vcxproj

@@ -1,156 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{977E3701-1A21-4425-B7E5-6BDF5EA062CD}</ProjectGuid>
-    <RootNamespace>SPIRV-Cross</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup />
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <SDLCheck>true</SDLCheck>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <SDLCheck>true</SDLCheck>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\main.cpp" />
-    <ClCompile Include="..\spirv_cpp.cpp" />
-    <ClCompile Include="..\spirv_cross.cpp" />
-    <ClCompile Include="..\spirv_glsl.cpp" />
-    <ClCompile Include="..\spirv_reflect.cpp" />
-    <ClCompile Include="..\spirv_hlsl.cpp" />
-    <ClCompile Include="..\spirv_msl.cpp" />
-    <ClCompile Include="..\spirv_cfg.cpp" />
-    <ClCompile Include="..\spirv_parser.cpp" />
-    <ClCompile Include="..\spirv_cross_parsed_ir.cpp" />
-    <ClCompile Include="..\spirv_cross_util.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\GLSL.std.450.h" />
-    <ClInclude Include="..\spirv_common.hpp" />
-    <ClInclude Include="..\spirv_cpp.hpp" />
-    <ClInclude Include="..\spirv_cross.hpp" />
-    <ClInclude Include="..\spirv_glsl.hpp" />
-    <ClInclude Include="..\spirv_reflect.hpp" />
-    <ClInclude Include="..\spirv.hpp" />
-    <ClInclude Include="..\spirv_hlsl.hpp" />
-    <ClInclude Include="..\spirv_msl.hpp" />
-    <ClInclude Include="..\spirv_cfg.hpp" />
-    <ClCompile Include="..\spirv_parser.hpp" />
-    <ClCompile Include="..\spirv_cross_parsed_ir.hpp" />
-    <ClInclude Include="..\spirv_cross_util.hpp" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>

+ 0 - 93
3rdparty/spirv-cross/msvc/SPIRV-Cross.vcxproj.filters

@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\main.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\spirv_cross.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\spirv_glsl.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\spirv_reflect.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\spirv_cpp.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\spirv_msl.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\spirv_cfg.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\spirv_parser.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\spirv_cross_parsed_ir.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\spirv_hlsl.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\spirv_cross_util.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\GLSL.std.450.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\spirv_cross.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\spirv_glsl.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\spirv_reflect.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\spirv.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\spirv_common.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\spirv_cpp.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\spirv_msl.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\spirv_cfg.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClCompile Include="..\spirv_parser.hpp">
-      <Filter>Header Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\spirv_cross_parsed_ir.hpp">
-      <Filter>Header Files</Filter>
-    </ClCompile>
-    <ClInclude Include="..\spirv_hlsl.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\spirv_cross_util.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-</Project>

+ 62 - 0
3rdparty/spirv-cross/reference/opt/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag

@@ -0,0 +1,62 @@
+struct myType
+{
+    float data;
+};
+
+static const myType _18 = { 0.0f };
+static const myType _20 = { 1.0f };
+static const myType _21[5] = { { 0.0f }, { 1.0f }, { 0.0f }, { 1.0f }, { 0.0f } };
+
+static float4 gl_FragCoord;
+static float4 o_color;
+
+struct SPIRV_Cross_Input
+{
+    float4 gl_FragCoord : SV_Position;
+};
+
+struct SPIRV_Cross_Output
+{
+    float4 o_color : SV_Target0;
+};
+
+float mod(float x, float y)
+{
+    return x - y * floor(x / y);
+}
+
+float2 mod(float2 x, float2 y)
+{
+    return x - y * floor(x / y);
+}
+
+float3 mod(float3 x, float3 y)
+{
+    return x - y * floor(x / y);
+}
+
+float4 mod(float4 x, float4 y)
+{
+    return x - y * floor(x / y);
+}
+
+void frag_main()
+{
+    if (_21[int(mod(gl_FragCoord.x, 4.0f))].data > 0.0f)
+    {
+        o_color = float4(0.0f, 1.0f, 0.0f, 1.0f);
+    }
+    else
+    {
+        o_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
+    }
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+    gl_FragCoord = stage_input.gl_FragCoord;
+    frag_main();
+    SPIRV_Cross_Output stage_output;
+    stage_output.o_color = o_color;
+    return stage_output;
+}

+ 40 - 0
3rdparty/spirv-cross/reference/opt/shaders-msl/asm/frag/single-function-private-lut.asm.frag

@@ -0,0 +1,40 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct myType
+{
+    float data;
+};
+
+constant myType _21[5] = { myType{ 0.0 }, myType{ 1.0 }, myType{ 0.0 }, myType{ 1.0 }, myType{ 0.0 } };
+
+struct main0_out
+{
+    float4 o_color [[color(0)]];
+};
+
+// Implementation of the GLSL mod() function, which is slightly different than Metal fmod()
+template<typename Tx, typename Ty>
+Tx mod(Tx x, Ty y)
+{
+    return x - y * floor(x / y);
+}
+
+fragment main0_out main0(float4 gl_FragCoord [[position]])
+{
+    main0_out out = {};
+    if (_21[int(mod(gl_FragCoord.x, 4.0))].data > 0.0)
+    {
+        out.o_color = float4(0.0, 1.0, 0.0, 1.0);
+    }
+    else
+    {
+        out.o_color = float4(1.0, 0.0, 0.0, 1.0);
+    }
+    return out;
+}
+

+ 1 - 1
3rdparty/spirv-cross/reference/opt/shaders-msl/comp/force-recompile-hooks.swizzle.comp

@@ -130,7 +130,7 @@ inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... p
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-kernel void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
+kernel void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
 {
     constant uint32_t& fooSwzl = spvAuxBuffer.swizzleConst[0];
     bar.write(spvTextureSwizzle(foo.sample(fooSmplr, float2(1.0), level(0.0)), fooSwzl), uint2(int2(0)));

+ 29 - 0
3rdparty/spirv-cross/reference/opt/shaders-msl/vert/basic.capture.vert

@@ -0,0 +1,29 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct UBO
+{
+    float4x4 uMVP;
+};
+
+struct main0_out
+{
+    float3 vNormal [[user(locn0)]];
+    float4 gl_Position [[position]];
+};
+
+struct main0_in
+{
+    float4 aVertex [[attribute(0)]];
+    float3 aNormal [[attribute(1)]];
+};
+
+vertex void main0(main0_in in [[stage_in]], constant UBO& _16 [[buffer(0)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(28)]], device uint* spvIndirectParams [[buffer(29)]])
+{
+    device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvIndirectParams[0] + gl_VertexIndex - gl_BaseVertex];
+    out.gl_Position = _16.uMVP * in.aVertex;
+    out.vNormal = in.aNormal;
+}
+

+ 29 - 0
3rdparty/spirv-cross/reference/opt/shaders-msl/vert/leaf-function.capture.vert

@@ -0,0 +1,29 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct UBO
+{
+    float4x4 uMVP;
+};
+
+struct main0_out
+{
+    float3 vNormal [[user(locn0)]];
+    float4 gl_Position [[position]];
+};
+
+struct main0_in
+{
+    float4 aVertex [[attribute(0)]];
+    float3 aNormal [[attribute(1)]];
+};
+
+vertex void main0(main0_in in [[stage_in]], constant UBO& _18 [[buffer(0)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(28)]], device uint* spvIndirectParams [[buffer(29)]])
+{
+    device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvIndirectParams[0] + gl_VertexIndex - gl_BaseVertex];
+    out.gl_Position = _18.uMVP * in.aVertex;
+    out.vNormal = in.aNormal;
+}
+

+ 23 - 0
3rdparty/spirv-cross/reference/opt/shaders/asm/frag/single-function-private-lut.asm.frag

@@ -0,0 +1,23 @@
+#version 460
+
+struct myType
+{
+    float data;
+};
+
+const myType _21[5] = myType[](myType(0.0), myType(1.0), myType(0.0), myType(1.0), myType(0.0));
+
+layout(location = 0) out vec4 o_color;
+
+void main()
+{
+    if (_21[int(mod(gl_FragCoord.x, 4.0))].data > 0.0)
+    {
+        o_color = vec4(0.0, 1.0, 0.0, 1.0);
+    }
+    else
+    {
+        o_color = vec4(1.0, 0.0, 0.0, 1.0);
+    }
+}
+

+ 65 - 0
3rdparty/spirv-cross/reference/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag

@@ -0,0 +1,65 @@
+struct myType
+{
+    float data;
+};
+
+static const myType _18 = { 0.0f };
+static const myType _20 = { 1.0f };
+static const myType _21[5] = { { 0.0f }, { 1.0f }, { 0.0f }, { 1.0f }, { 0.0f } };
+
+static float4 gl_FragCoord;
+static float4 o_color;
+
+struct SPIRV_Cross_Input
+{
+    float4 gl_FragCoord : SV_Position;
+};
+
+struct SPIRV_Cross_Output
+{
+    float4 o_color : SV_Target0;
+};
+
+float mod(float x, float y)
+{
+    return x - y * floor(x / y);
+}
+
+float2 mod(float2 x, float2 y)
+{
+    return x - y * floor(x / y);
+}
+
+float3 mod(float3 x, float3 y)
+{
+    return x - y * floor(x / y);
+}
+
+float4 mod(float4 x, float4 y)
+{
+    return x - y * floor(x / y);
+}
+
+void frag_main()
+{
+    float2 uv = gl_FragCoord.xy;
+    int index = int(mod(uv.x, 4.0f));
+    myType elt = _21[index];
+    if (elt.data > 0.0f)
+    {
+        o_color = float4(0.0f, 1.0f, 0.0f, 1.0f);
+    }
+    else
+    {
+        o_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
+    }
+}
+
+SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
+{
+    gl_FragCoord = stage_input.gl_FragCoord;
+    frag_main();
+    SPIRV_Cross_Output stage_output;
+    stage_output.o_color = o_color;
+    return stage_output;
+}

+ 2 - 7
3rdparty/spirv-cross/reference/shaders-hlsl/frag/constant-composites.frag

@@ -22,15 +22,10 @@ struct SPIRV_Cross_Output
     float4 FragColor : SV_Target0;
 };
 
-static float lut[4];
-static Foo foos[2];
-
 void frag_main()
 {
-    lut = _16;
-    foos = _28;
-    FragColor = lut[_line].xxxx;
-    FragColor += (foos[_line].a * foos[1 - _line].a).xxxx;
+    FragColor = _16[_line].xxxx;
+    FragColor += (_28[_line].a * _28[1 - _line].a).xxxx;
 }
 
 SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)

+ 1 - 1
3rdparty/spirv-cross/reference/shaders-msl-no-opt/asm/frag/texture-access.swizzle.asm.frag

@@ -136,7 +136,7 @@ inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... p
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSamp [[sampler(0)]], sampler tex2dSamp [[sampler(1)]], sampler tex3dSamp [[sampler(2)]], sampler texCubeSamp [[sampler(3)]], sampler tex2dArraySamp [[sampler(4)]], sampler texCubeArraySamp [[sampler(5)]], sampler depth2dSamp [[sampler(7)]], sampler depthCubeSamp [[sampler(8)]], sampler depth2dArraySamp [[sampler(9)]], sampler depthCubeArraySamp [[sampler(10)]])
+fragment void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSamp [[sampler(0)]], sampler tex2dSamp [[sampler(1)]], sampler tex3dSamp [[sampler(2)]], sampler texCubeSamp [[sampler(3)]], sampler tex2dArraySamp [[sampler(4)]], sampler texCubeArraySamp [[sampler(5)]], sampler depth2dSamp [[sampler(7)]], sampler depthCubeSamp [[sampler(8)]], sampler depth2dArraySamp [[sampler(9)]], sampler depthCubeArraySamp [[sampler(10)]])
 {
     constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
     constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1];

+ 1 - 1
3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-int.swizzle.frag

@@ -136,7 +136,7 @@ inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... p
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d<int> tex1d [[texture(0)]], texture2d<int> tex2d [[texture(1)]], texture3d<int> tex3d [[texture(2)]], texturecube<int> texCube [[texture(3)]], texture2d_array<int> tex2dArray [[texture(4)]], texturecube_array<int> texCubeArray [[texture(5)]], texture2d<int> texBuffer [[texture(6)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]])
+fragment void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<int> tex1d [[texture(0)]], texture2d<int> tex2d [[texture(1)]], texture3d<int> tex3d [[texture(2)]], texturecube<int> texCube [[texture(3)]], texture2d_array<int> tex2dArray [[texture(4)]], texturecube_array<int> texCubeArray [[texture(5)]], texture2d<int> texBuffer [[texture(6)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]])
 {
     constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
     constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1];

+ 3 - 3
3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-leaf.swizzle.frag

@@ -136,7 +136,7 @@ inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... p
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-float4 doSwizzle(thread texture1d<float> tex1d, thread const sampler tex1dSmplr, constant uint32_t& tex1dSwzl, thread texture2d<float> tex2d, thread const sampler tex2dSmplr, constant uint32_t& tex2dSwzl, thread texture3d<float> tex3d, thread const sampler tex3dSmplr, constant uint32_t& tex3dSwzl, thread texturecube<float> texCube, thread const sampler texCubeSmplr, constant uint32_t& texCubeSwzl, thread texture2d_array<float> tex2dArray, thread const sampler tex2dArraySmplr, constant uint32_t& tex2dArraySwzl, thread texturecube_array<float> texCubeArray, thread const sampler texCubeArraySmplr, constant uint32_t& texCubeArraySwzl, thread depth2d<float> depth2d, thread const sampler depth2dSmplr, constant uint32_t& depth2dSwzl, thread depthcube<float> depthCube, thread const sampler depthCubeSmplr, constant uint32_t& depthCubeSwzl, thread depth2d_array<float> depth2dArray, thread const sampler depth2dArraySmplr, constant uint32_t& depth2dArraySwzl, thread depthcube_array<float> depthCubeArray, thread const sampler depthCubeArraySmplr, constant uint32_t& depthCubeArraySwzl, thread texture2d<float> texBuffer, constant spvAux& spvAuxBuffer)
+float4 doSwizzle(thread texture1d<float> tex1d, thread const sampler tex1dSmplr, constant uint32_t& tex1dSwzl, thread texture2d<float> tex2d, thread const sampler tex2dSmplr, constant uint32_t& tex2dSwzl, thread texture3d<float> tex3d, thread const sampler tex3dSmplr, constant uint32_t& tex3dSwzl, thread texturecube<float> texCube, thread const sampler texCubeSmplr, constant uint32_t& texCubeSwzl, thread texture2d_array<float> tex2dArray, thread const sampler tex2dArraySmplr, constant uint32_t& tex2dArraySwzl, thread texturecube_array<float> texCubeArray, thread const sampler texCubeArraySmplr, constant uint32_t& texCubeArraySwzl, thread depth2d<float> depth2d, thread const sampler depth2dSmplr, constant uint32_t& depth2dSwzl, thread depthcube<float> depthCube, thread const sampler depthCubeSmplr, constant uint32_t& depthCubeSwzl, thread depth2d_array<float> depth2dArray, thread const sampler depth2dArraySmplr, constant uint32_t& depth2dArraySwzl, thread depthcube_array<float> depthCubeArray, thread const sampler depthCubeArraySmplr, constant uint32_t& depthCubeArraySwzl, thread texture2d<float> texBuffer)
 {
     float4 c = spvTextureSwizzle(tex1d.sample(tex1dSmplr, 0.0), tex1dSwzl);
     c = spvTextureSwizzle(tex2d.sample(tex2dSmplr, float2(0.0)), tex2dSwzl);
@@ -183,7 +183,7 @@ float4 doSwizzle(thread texture1d<float> tex1d, thread const sampler tex1dSmplr,
     return c;
 }
 
-fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depth2dArraySmplr [[sampler(9)]], sampler depthCubeArraySmplr [[sampler(10)]])
+fragment void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depth2dArraySmplr [[sampler(9)]], sampler depthCubeArraySmplr [[sampler(10)]])
 {
     constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
     constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1];
@@ -195,6 +195,6 @@ fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d<float
     constant uint32_t& depthCubeSwzl = spvAuxBuffer.swizzleConst[8];
     constant uint32_t& depth2dArraySwzl = spvAuxBuffer.swizzleConst[9];
     constant uint32_t& depthCubeArraySwzl = spvAuxBuffer.swizzleConst[10];
-    float4 c = doSwizzle(tex1d, tex1dSmplr, tex1dSwzl, tex2d, tex2dSmplr, tex2dSwzl, tex3d, tex3dSmplr, tex3dSwzl, texCube, texCubeSmplr, texCubeSwzl, tex2dArray, tex2dArraySmplr, tex2dArraySwzl, texCubeArray, texCubeArraySmplr, texCubeArraySwzl, depth2d, depth2dSmplr, depth2dSwzl, depthCube, depthCubeSmplr, depthCubeSwzl, depth2dArray, depth2dArraySmplr, depth2dArraySwzl, depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, texBuffer, spvAuxBuffer);
+    float4 c = doSwizzle(tex1d, tex1dSmplr, tex1dSwzl, tex2d, tex2dSmplr, tex2dSwzl, tex3d, tex3dSmplr, tex3dSwzl, texCube, texCubeSmplr, texCubeSwzl, tex2dArray, tex2dArraySmplr, tex2dArraySwzl, texCubeArray, texCubeArraySmplr, texCubeArraySwzl, depth2d, depth2dSmplr, depth2dSwzl, depthCube, depthCubeSmplr, depthCubeSwzl, depth2dArray, depth2dArraySmplr, depth2dArraySwzl, depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, texBuffer);
 }
 

+ 1 - 1
3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access-uint.swizzle.frag

@@ -136,7 +136,7 @@ inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... p
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d<uint> tex1d [[texture(0)]], texture2d<uint> tex2d [[texture(1)]], texture3d<uint> tex3d [[texture(2)]], texturecube<uint> texCube [[texture(3)]], texture2d_array<uint> tex2dArray [[texture(4)]], texturecube_array<uint> texCubeArray [[texture(5)]], texture2d<uint> texBuffer [[texture(6)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]])
+fragment void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<uint> tex1d [[texture(0)]], texture2d<uint> tex2d [[texture(1)]], texture3d<uint> tex3d [[texture(2)]], texturecube<uint> texCube [[texture(3)]], texture2d_array<uint> tex2dArray [[texture(4)]], texturecube_array<uint> texCubeArray [[texture(5)]], texture2d<uint> texBuffer [[texture(6)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]])
 {
     constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
     constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1];

+ 1 - 1
3rdparty/spirv-cross/reference/shaders-msl-no-opt/frag/texture-access.swizzle.frag

@@ -136,7 +136,7 @@ inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... p
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-fragment void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depth2dArraySmplr [[sampler(9)]], sampler depthCubeArraySmplr [[sampler(10)]])
+fragment void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex2dSmplr [[sampler(1)]], sampler tex3dSmplr [[sampler(2)]], sampler texCubeSmplr [[sampler(3)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depth2dArraySmplr [[sampler(9)]], sampler depthCubeArraySmplr [[sampler(10)]])
 {
     constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
     constant uint32_t& tex2dSwzl = spvAuxBuffer.swizzleConst[1];

+ 3 - 3
3rdparty/spirv-cross/reference/shaders-msl-no-opt/vulkan/frag/texture-access-function.swizzle.vk.frag

@@ -141,7 +141,7 @@ inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... p
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-float4 do_samples(thread const texture1d<float> t1, thread const sampler t1Smplr, constant uint32_t& t1Swzl, thread const texture2d<float> t2, constant uint32_t& t2Swzl, thread const texture3d<float> t3, thread const sampler t3Smplr, constant uint32_t& t3Swzl, thread const texturecube<float> tc, constant uint32_t& tcSwzl, thread const texture2d_array<float> t2a, thread const sampler t2aSmplr, constant uint32_t& t2aSwzl, thread const texturecube_array<float> tca, thread const sampler tcaSmplr, constant uint32_t& tcaSwzl, thread const texture2d<float> tb, thread const depth2d<float> d2, thread const sampler d2Smplr, constant uint32_t& d2Swzl, thread const depthcube<float> dc, thread const sampler dcSmplr, constant uint32_t& dcSwzl, thread const depth2d_array<float> d2a, constant uint32_t& d2aSwzl, thread const depthcube_array<float> dca, thread const sampler dcaSmplr, constant uint32_t& dcaSwzl, thread sampler defaultSampler, thread sampler shadowSampler, constant spvAux& spvAuxBuffer)
+float4 do_samples(thread const texture1d<float> t1, thread const sampler t1Smplr, constant uint32_t& t1Swzl, thread const texture2d<float> t2, constant uint32_t& t2Swzl, thread const texture3d<float> t3, thread const sampler t3Smplr, constant uint32_t& t3Swzl, thread const texturecube<float> tc, constant uint32_t& tcSwzl, thread const texture2d_array<float> t2a, thread const sampler t2aSmplr, constant uint32_t& t2aSwzl, thread const texturecube_array<float> tca, thread const sampler tcaSmplr, constant uint32_t& tcaSwzl, thread const texture2d<float> tb, thread const depth2d<float> d2, thread const sampler d2Smplr, constant uint32_t& d2Swzl, thread const depthcube<float> dc, thread const sampler dcSmplr, constant uint32_t& dcSwzl, thread const depth2d_array<float> d2a, constant uint32_t& d2aSwzl, thread const depthcube_array<float> dca, thread const sampler dcaSmplr, constant uint32_t& dcaSwzl, thread sampler defaultSampler, thread sampler shadowSampler)
 {
     float4 c = spvTextureSwizzle(t1.sample(t1Smplr, 0.0), t1Swzl);
     c = spvTextureSwizzle(t2.sample(defaultSampler, float2(0.0)), t2Swzl);
@@ -188,7 +188,7 @@ float4 do_samples(thread const texture1d<float> t1, thread const sampler t1Smplr
     return c;
 }
 
-fragment main0_out main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex3dSmplr [[sampler(2)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depthCubeArraySmplr [[sampler(10)]], sampler defaultSampler [[sampler(11)]], sampler shadowSampler [[sampler(12)]])
+fragment main0_out main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture1d<float> tex1d [[texture(0)]], texture2d<float> tex2d [[texture(1)]], texture3d<float> tex3d [[texture(2)]], texturecube<float> texCube [[texture(3)]], texture2d_array<float> tex2dArray [[texture(4)]], texturecube_array<float> texCubeArray [[texture(5)]], texture2d<float> texBuffer [[texture(6)]], depth2d<float> depth2d [[texture(7)]], depthcube<float> depthCube [[texture(8)]], depth2d_array<float> depth2dArray [[texture(9)]], depthcube_array<float> depthCubeArray [[texture(10)]], sampler tex1dSmplr [[sampler(0)]], sampler tex3dSmplr [[sampler(2)]], sampler tex2dArraySmplr [[sampler(4)]], sampler texCubeArraySmplr [[sampler(5)]], sampler depth2dSmplr [[sampler(7)]], sampler depthCubeSmplr [[sampler(8)]], sampler depthCubeArraySmplr [[sampler(10)]], sampler defaultSampler [[sampler(11)]], sampler shadowSampler [[sampler(12)]])
 {
     main0_out out = {};
     constant uint32_t& tex1dSwzl = spvAuxBuffer.swizzleConst[0];
@@ -201,7 +201,7 @@ fragment main0_out main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture1d<
     constant uint32_t& depthCubeSwzl = spvAuxBuffer.swizzleConst[8];
     constant uint32_t& depth2dArraySwzl = spvAuxBuffer.swizzleConst[9];
     constant uint32_t& depthCubeArraySwzl = spvAuxBuffer.swizzleConst[10];
-    out.fragColor = do_samples(tex1d, tex1dSmplr, tex1dSwzl, tex2d, tex2dSwzl, tex3d, tex3dSmplr, tex3dSwzl, texCube, texCubeSwzl, tex2dArray, tex2dArraySmplr, tex2dArraySwzl, texCubeArray, texCubeArraySmplr, texCubeArraySwzl, texBuffer, depth2d, depth2dSmplr, depth2dSwzl, depthCube, depthCubeSmplr, depthCubeSwzl, depth2dArray, depth2dArraySwzl, depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, defaultSampler, shadowSampler, spvAuxBuffer);
+    out.fragColor = do_samples(tex1d, tex1dSmplr, tex1dSwzl, tex2d, tex2dSwzl, tex3d, tex3dSmplr, tex3dSwzl, texCube, texCubeSwzl, tex2dArray, tex2dArraySmplr, tex2dArraySwzl, texCubeArray, texCubeArraySmplr, texCubeArraySwzl, texBuffer, depth2d, depth2dSmplr, depth2dSwzl, depthCube, depthCubeSmplr, depthCubeSwzl, depth2dArray, depth2dArraySwzl, depthCubeArray, depthCubeArraySmplr, depthCubeArraySwzl, defaultSampler, shadowSampler);
     return out;
 }
 

+ 56 - 0
3rdparty/spirv-cross/reference/shaders-msl/asm/frag/single-function-private-lut.asm.frag

@@ -0,0 +1,56 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct myType
+{
+    float data;
+};
+
+constant myType _21[5] = { myType{ 0.0 }, myType{ 1.0 }, myType{ 0.0 }, myType{ 1.0 }, myType{ 0.0 } };
+
+struct main0_out
+{
+    float4 o_color [[color(0)]];
+};
+
+// Implementation of the GLSL mod() function, which is slightly different than Metal fmod()
+template<typename Tx, typename Ty>
+Tx mod(Tx x, Ty y)
+{
+    return x - y * floor(x / y);
+}
+
+// Implementation of an array copy function to cover GLSL's ability to copy an array via assignment.
+template<typename T, uint N>
+void spvArrayCopyFromStack1(thread T (&dst)[N], thread const T (&src)[N])
+{
+    for (uint i = 0; i < N; dst[i] = src[i], i++);
+}
+
+template<typename T, uint N>
+void spvArrayCopyFromConstant1(thread T (&dst)[N], constant T (&src)[N])
+{
+    for (uint i = 0; i < N; dst[i] = src[i], i++);
+}
+
+fragment main0_out main0(float4 gl_FragCoord [[position]])
+{
+    main0_out out = {};
+    float2 uv = gl_FragCoord.xy;
+    int index = int(mod(uv.x, 4.0));
+    myType elt = _21[index];
+    if (elt.data > 0.0)
+    {
+        out.o_color = float4(0.0, 1.0, 0.0, 1.0);
+    }
+    else
+    {
+        out.o_color = float4(1.0, 0.0, 0.0, 1.0);
+    }
+    return out;
+}
+

+ 1 - 1
3rdparty/spirv-cross/reference/shaders-msl/comp/force-recompile-hooks.swizzle.comp

@@ -130,7 +130,7 @@ inline vec<T, 4> spvGatherCompareSwizzle(sampler s, const thread Tex& t, Ts... p
     return t.gather_compare(s, spvForward<Ts>(params)...);
 }
 
-kernel void main0(constant spvAux& spvAuxBuffer [[buffer(0)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
+kernel void main0(constant spvAux& spvAuxBuffer [[buffer(30)]], texture2d<float> foo [[texture(0)]], texture2d<float, access::write> bar [[texture(1)]], sampler fooSmplr [[sampler(0)]])
 {
     constant uint32_t& fooSwzl = spvAuxBuffer.swizzleConst[0];
     float4 a = spvTextureSwizzle(foo.sample(fooSmplr, float2(1.0), level(0.0)), fooSwzl);

+ 2 - 4
3rdparty/spirv-cross/reference/shaders-msl/frag/constant-composites.frag

@@ -40,10 +40,8 @@ void spvArrayCopyFromConstant1(thread T (&dst)[N], constant T (&src)[N])
 fragment main0_out main0(main0_in in [[stage_in]])
 {
     main0_out out = {};
-    float lut[4] = { 1.0, 4.0, 3.0, 2.0 };
-    Foo foos[2] = { Foo{ 10.0, 20.0 }, Foo{ 30.0, 40.0 } };
-    out.FragColor = float4(lut[in.line]);
-    out.FragColor += float4(foos[in.line].a * foos[1 - in.line].a);
+    out.FragColor = float4(_16[in.line]);
+    out.FragColor += float4(_28[in.line].a * _28[1 - in.line].a);
     return out;
 }
 

+ 29 - 0
3rdparty/spirv-cross/reference/shaders-msl/vert/basic.capture.vert

@@ -0,0 +1,29 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct UBO
+{
+    float4x4 uMVP;
+};
+
+struct main0_out
+{
+    float3 vNormal [[user(locn0)]];
+    float4 gl_Position [[position]];
+};
+
+struct main0_in
+{
+    float4 aVertex [[attribute(0)]];
+    float3 aNormal [[attribute(1)]];
+};
+
+vertex void main0(main0_in in [[stage_in]], constant UBO& _16 [[buffer(0)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(28)]], device uint* spvIndirectParams [[buffer(29)]])
+{
+    device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvIndirectParams[0] + gl_VertexIndex - gl_BaseVertex];
+    out.gl_Position = _16.uMVP * in.aVertex;
+    out.vNormal = in.aNormal;
+}
+

+ 36 - 0
3rdparty/spirv-cross/reference/shaders-msl/vert/leaf-function.capture.vert

@@ -0,0 +1,36 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct UBO
+{
+    float4x4 uMVP;
+};
+
+struct main0_out
+{
+    float3 vNormal [[user(locn0)]];
+    float4 gl_Position [[position]];
+};
+
+struct main0_in
+{
+    float4 aVertex [[attribute(0)]];
+    float3 aNormal [[attribute(1)]];
+};
+
+void set_output(device float4& gl_Position, constant UBO& v_18, thread float4& aVertex, device float3& vNormal, thread float3& aNormal)
+{
+    gl_Position = v_18.uMVP * aVertex;
+    vNormal = aNormal;
+}
+
+vertex void main0(main0_in in [[stage_in]], constant UBO& v_18 [[buffer(0)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(28)]], device uint* spvIndirectParams [[buffer(29)]])
+{
+    device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvIndirectParams[0] + gl_VertexIndex - gl_BaseVertex];
+    set_output(out.gl_Position, v_18, in.aVertex, out.vNormal, in.aNormal);
+}
+

+ 26 - 0
3rdparty/spirv-cross/reference/shaders/asm/frag/single-function-private-lut.asm.frag

@@ -0,0 +1,26 @@
+#version 460
+
+struct myType
+{
+    float data;
+};
+
+const myType _21[5] = myType[](myType(0.0), myType(1.0), myType(0.0), myType(1.0), myType(0.0));
+
+layout(location = 0) out vec4 o_color;
+
+void main()
+{
+    vec2 uv = gl_FragCoord.xy;
+    int index = int(mod(uv.x, 4.0));
+    myType elt = _21[index];
+    if (elt.data > 0.0)
+    {
+        o_color = vec4(0.0, 1.0, 0.0, 1.0);
+    }
+    else
+    {
+        o_color = vec4(1.0, 0.0, 0.0, 1.0);
+    }
+}
+

+ 6 - 6
3rdparty/spirv-cross/reference/shaders/frag/constant-composites.frag

@@ -2,22 +2,22 @@
 precision mediump float;
 precision highp int;
 
+const float _16[4] = float[](1.0, 4.0, 3.0, 2.0);
+
 struct Foo
 {
     float a;
     float b;
 };
 
+const Foo _28[2] = Foo[](Foo(10.0, 20.0), Foo(30.0, 40.0));
+
 layout(location = 0) out vec4 FragColor;
 layout(location = 0) flat in mediump int line;
-float lut[4];
-Foo foos[2];
 
 void main()
 {
-    lut = float[](1.0, 4.0, 3.0, 2.0);
-    foos = Foo[](Foo(10.0, 20.0), Foo(30.0, 40.0));
-    FragColor = vec4(lut[line]);
-    FragColor += vec4(foos[line].a * foos[1 - line].a);
+    FragColor = vec4(_16[line]);
+    FragColor += vec4(_28[line].a * _28[1 - line].a);
 }
 

+ 86 - 0
3rdparty/spirv-cross/shaders-hlsl/asm/frag/single-function-private-lut.asm.frag

@@ -0,0 +1,86 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Khronos SPIR-V Tools Assembler; 0
+; Bound: 54
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %gl_FragCoord %o_color
+               OpExecutionMode %main OriginUpperLeft
+               OpSource GLSL 460
+               OpName %main "main"
+               OpName %myType "myType"
+               OpMemberName %myType 0 "data"
+               OpName %myData "myData"
+               OpName %uv "uv"
+               OpName %gl_FragCoord "gl_FragCoord"
+               OpName %index "index"
+               OpName %elt "elt"
+               OpName %o_color "o_color"
+               OpDecorate %gl_FragCoord BuiltIn FragCoord
+               OpDecorate %o_color Location 0
+       %void = OpTypeVoid
+         %11 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+     %myType = OpTypeStruct %float
+       %uint = OpTypeInt 32 0
+     %uint_5 = OpConstant %uint 5
+%_arr_myType_uint_5 = OpTypeArray %myType %uint_5
+%_ptr_Private__arr_myType_uint_5 = OpTypePointer Private %_arr_myType_uint_5
+     %myData = OpVariable %_ptr_Private__arr_myType_uint_5 Private
+    %float_0 = OpConstant %float 0
+         %18 = OpConstantComposite %myType %float_0
+    %float_1 = OpConstant %float 1
+         %20 = OpConstantComposite %myType %float_1
+         %21 = OpConstantComposite %_arr_myType_uint_5 %18 %20 %18 %20 %18
+    %v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+    %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+        %int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+     %uint_0 = OpConstant %uint 0
+%_ptr_Function_float = OpTypePointer Function %float
+    %float_4 = OpConstant %float 4
+%_ptr_Function_myType = OpTypePointer Function %myType
+%_ptr_Private_myType = OpTypePointer Private %myType
+      %int_0 = OpConstant %int 0
+       %bool = OpTypeBool
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+    %o_color = OpVariable %_ptr_Output_v4float Output
+         %36 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
+         %37 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+       %main = OpFunction %void None %11
+         %38 = OpLabel
+         %uv = OpVariable %_ptr_Function_v2float Function
+      %index = OpVariable %_ptr_Function_int Function
+        %elt = OpVariable %_ptr_Function_myType Function
+               OpStore %myData %21
+         %39 = OpLoad %v4float %gl_FragCoord
+         %40 = OpVectorShuffle %v2float %39 %39 0 1
+               OpStore %uv %40
+         %41 = OpAccessChain %_ptr_Function_float %uv %uint_0
+         %42 = OpLoad %float %41
+         %43 = OpFMod %float %42 %float_4
+         %44 = OpConvertFToS %int %43
+               OpStore %index %44
+         %45 = OpLoad %int %index
+         %46 = OpAccessChain %_ptr_Private_myType %myData %45
+         %47 = OpLoad %myType %46
+               OpStore %elt %47
+         %48 = OpAccessChain %_ptr_Function_float %elt %int_0
+         %49 = OpLoad %float %48
+         %50 = OpFOrdGreaterThan %bool %49 %float_0
+               OpSelectionMerge %51 None
+               OpBranchConditional %50 %52 %53
+         %52 = OpLabel
+               OpStore %o_color %36
+               OpBranch %51
+         %53 = OpLabel
+               OpStore %o_color %37
+               OpBranch %51
+         %51 = OpLabel
+               OpReturn
+               OpFunctionEnd

+ 86 - 0
3rdparty/spirv-cross/shaders-msl/asm/frag/single-function-private-lut.asm.frag

@@ -0,0 +1,86 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Khronos SPIR-V Tools Assembler; 0
+; Bound: 54
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %gl_FragCoord %o_color
+               OpExecutionMode %main OriginUpperLeft
+               OpSource GLSL 460
+               OpName %main "main"
+               OpName %myType "myType"
+               OpMemberName %myType 0 "data"
+               OpName %myData "myData"
+               OpName %uv "uv"
+               OpName %gl_FragCoord "gl_FragCoord"
+               OpName %index "index"
+               OpName %elt "elt"
+               OpName %o_color "o_color"
+               OpDecorate %gl_FragCoord BuiltIn FragCoord
+               OpDecorate %o_color Location 0
+       %void = OpTypeVoid
+         %11 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+     %myType = OpTypeStruct %float
+       %uint = OpTypeInt 32 0
+     %uint_5 = OpConstant %uint 5
+%_arr_myType_uint_5 = OpTypeArray %myType %uint_5
+%_ptr_Private__arr_myType_uint_5 = OpTypePointer Private %_arr_myType_uint_5
+     %myData = OpVariable %_ptr_Private__arr_myType_uint_5 Private
+    %float_0 = OpConstant %float 0
+         %18 = OpConstantComposite %myType %float_0
+    %float_1 = OpConstant %float 1
+         %20 = OpConstantComposite %myType %float_1
+         %21 = OpConstantComposite %_arr_myType_uint_5 %18 %20 %18 %20 %18
+    %v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+    %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+        %int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+     %uint_0 = OpConstant %uint 0
+%_ptr_Function_float = OpTypePointer Function %float
+    %float_4 = OpConstant %float 4
+%_ptr_Function_myType = OpTypePointer Function %myType
+%_ptr_Private_myType = OpTypePointer Private %myType
+      %int_0 = OpConstant %int 0
+       %bool = OpTypeBool
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+    %o_color = OpVariable %_ptr_Output_v4float Output
+         %36 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
+         %37 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+       %main = OpFunction %void None %11
+         %38 = OpLabel
+         %uv = OpVariable %_ptr_Function_v2float Function
+      %index = OpVariable %_ptr_Function_int Function
+        %elt = OpVariable %_ptr_Function_myType Function
+               OpStore %myData %21
+         %39 = OpLoad %v4float %gl_FragCoord
+         %40 = OpVectorShuffle %v2float %39 %39 0 1
+               OpStore %uv %40
+         %41 = OpAccessChain %_ptr_Function_float %uv %uint_0
+         %42 = OpLoad %float %41
+         %43 = OpFMod %float %42 %float_4
+         %44 = OpConvertFToS %int %43
+               OpStore %index %44
+         %45 = OpLoad %int %index
+         %46 = OpAccessChain %_ptr_Private_myType %myData %45
+         %47 = OpLoad %myType %46
+               OpStore %elt %47
+         %48 = OpAccessChain %_ptr_Function_float %elt %int_0
+         %49 = OpLoad %float %48
+         %50 = OpFOrdGreaterThan %bool %49 %float_0
+               OpSelectionMerge %51 None
+               OpBranchConditional %50 %52 %53
+         %52 = OpLabel
+               OpStore %o_color %36
+               OpBranch %51
+         %53 = OpLabel
+               OpStore %o_color %37
+               OpBranch %51
+         %51 = OpLabel
+               OpReturn
+               OpFunctionEnd

+ 17 - 0
3rdparty/spirv-cross/shaders-msl/vert/basic.capture.vert

@@ -0,0 +1,17 @@
+#version 310 es
+
+layout(std140) uniform UBO
+{
+    uniform mat4 uMVP;
+};
+
+layout(location = 0) in vec4 aVertex;
+layout(location = 1) in vec3 aNormal;
+
+layout(location = 0) out vec3 vNormal;
+
+void main()
+{
+    gl_Position = uMVP * aVertex;
+    vNormal = aNormal;
+}

+ 22 - 0
3rdparty/spirv-cross/shaders-msl/vert/leaf-function.capture.vert

@@ -0,0 +1,22 @@
+#version 310 es
+
+layout(std140) uniform UBO
+{
+    uniform mat4 uMVP;
+};
+
+layout(location = 0) in vec4 aVertex;
+layout(location = 1) in vec3 aNormal;
+
+layout(location = 0) out vec3 vNormal;
+
+void set_output()
+{
+    gl_Position = uMVP * aVertex;
+    vNormal = aNormal;
+}
+
+void main()
+{
+    set_output();
+}

+ 86 - 0
3rdparty/spirv-cross/shaders/asm/frag/single-function-private-lut.asm.frag

@@ -0,0 +1,86 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Khronos SPIR-V Tools Assembler; 0
+; Bound: 54
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %gl_FragCoord %o_color
+               OpExecutionMode %main OriginUpperLeft
+               OpSource GLSL 460
+               OpName %main "main"
+               OpName %myType "myType"
+               OpMemberName %myType 0 "data"
+               OpName %myData "myData"
+               OpName %uv "uv"
+               OpName %gl_FragCoord "gl_FragCoord"
+               OpName %index "index"
+               OpName %elt "elt"
+               OpName %o_color "o_color"
+               OpDecorate %gl_FragCoord BuiltIn FragCoord
+               OpDecorate %o_color Location 0
+       %void = OpTypeVoid
+         %11 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+     %myType = OpTypeStruct %float
+       %uint = OpTypeInt 32 0
+     %uint_5 = OpConstant %uint 5
+%_arr_myType_uint_5 = OpTypeArray %myType %uint_5
+%_ptr_Private__arr_myType_uint_5 = OpTypePointer Private %_arr_myType_uint_5
+     %myData = OpVariable %_ptr_Private__arr_myType_uint_5 Private
+    %float_0 = OpConstant %float 0
+         %18 = OpConstantComposite %myType %float_0
+    %float_1 = OpConstant %float 1
+         %20 = OpConstantComposite %myType %float_1
+         %21 = OpConstantComposite %_arr_myType_uint_5 %18 %20 %18 %20 %18
+    %v2float = OpTypeVector %float 2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+    %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+        %int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+     %uint_0 = OpConstant %uint 0
+%_ptr_Function_float = OpTypePointer Function %float
+    %float_4 = OpConstant %float 4
+%_ptr_Function_myType = OpTypePointer Function %myType
+%_ptr_Private_myType = OpTypePointer Private %myType
+      %int_0 = OpConstant %int 0
+       %bool = OpTypeBool
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+    %o_color = OpVariable %_ptr_Output_v4float Output
+         %36 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
+         %37 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+       %main = OpFunction %void None %11
+         %38 = OpLabel
+         %uv = OpVariable %_ptr_Function_v2float Function
+      %index = OpVariable %_ptr_Function_int Function
+        %elt = OpVariable %_ptr_Function_myType Function
+               OpStore %myData %21
+         %39 = OpLoad %v4float %gl_FragCoord
+         %40 = OpVectorShuffle %v2float %39 %39 0 1
+               OpStore %uv %40
+         %41 = OpAccessChain %_ptr_Function_float %uv %uint_0
+         %42 = OpLoad %float %41
+         %43 = OpFMod %float %42 %float_4
+         %44 = OpConvertFToS %int %43
+               OpStore %index %44
+         %45 = OpLoad %int %index
+         %46 = OpAccessChain %_ptr_Private_myType %myData %45
+         %47 = OpLoad %myType %46
+               OpStore %elt %47
+         %48 = OpAccessChain %_ptr_Function_float %elt %int_0
+         %49 = OpLoad %float %48
+         %50 = OpFOrdGreaterThan %bool %49 %float_0
+               OpSelectionMerge %51 None
+               OpBranchConditional %50 %52 %53
+         %52 = OpLabel
+               OpStore %o_color %36
+               OpBranch %51
+         %53 = OpLabel
+               OpStore %o_color %37
+               OpBranch %51
+         %51 = OpLabel
+               OpReturn
+               OpFunctionEnd

+ 8 - 3
3rdparty/spirv-cross/spirv_cross.cpp

@@ -3054,7 +3054,8 @@ bool Compiler::StaticExpressionAccessHandler::handle(spv::Op op, const uint32_t
 	return true;
 }
 
-void Compiler::find_function_local_luts(SPIRFunction &entry, const AnalyzeVariableScopeAccessHandler &handler)
+void Compiler::find_function_local_luts(SPIRFunction &entry, const AnalyzeVariableScopeAccessHandler &handler,
+                                        bool single_function)
 {
 	auto &cfg = *function_cfgs.find(entry.self)->second;
 
@@ -3066,7 +3067,10 @@ void Compiler::find_function_local_luts(SPIRFunction &entry, const AnalyzeVariab
 		auto &type = expression_type(accessed_var.first);
 
 		// Only consider function local variables here.
-		if (var.storage != StorageClassFunction)
+		// If we only have a single function in our CFG, private storage is also fine,
+		// since it behaves like a function local variable.
+		bool allow_lut = var.storage == StorageClassFunction || (single_function && var.storage == StorageClassPrivate);
+		if (!allow_lut)
 			continue;
 
 		// We cannot be a phi variable.
@@ -3651,13 +3655,14 @@ void Compiler::build_function_control_flow_graphs_and_analyze()
 	handler.function_cfgs[ir.default_entry_point].reset(new CFG(*this, get<SPIRFunction>(ir.default_entry_point)));
 	traverse_all_reachable_opcodes(get<SPIRFunction>(ir.default_entry_point), handler);
 	function_cfgs = move(handler.function_cfgs);
+	bool single_function = function_cfgs.size() <= 1;
 
 	for (auto &f : function_cfgs)
 	{
 		auto &func = get<SPIRFunction>(f.first);
 		AnalyzeVariableScopeAccessHandler scope_handler(*this, func);
 		analyze_variable_scope(func, scope_handler);
-		find_function_local_luts(func, scope_handler);
+		find_function_local_luts(func, scope_handler, single_function);
 
 		// Check if we can actually use the loop variables we found in analyze_variable_scope.
 		// To use multiple initializers, we need the same type and qualifiers.

+ 2 - 1
3rdparty/spirv-cross/spirv_cross.hpp

@@ -938,7 +938,8 @@ protected:
 	};
 
 	void analyze_variable_scope(SPIRFunction &function, AnalyzeVariableScopeAccessHandler &handler);
-	void find_function_local_luts(SPIRFunction &function, const AnalyzeVariableScopeAccessHandler &handler);
+	void find_function_local_luts(SPIRFunction &function, const AnalyzeVariableScopeAccessHandler &handler,
+	                              bool single_function);
 
 	void make_constant_null(uint32_t id, uint32_t type);
 

+ 20 - 3
3rdparty/spirv-cross/spirv_glsl.cpp

@@ -2137,6 +2137,20 @@ void CompilerGLSL::declare_undefined_values()
 		statement("");
 }
 
+bool CompilerGLSL::variable_is_lut(const SPIRVariable &var) const
+{
+	bool statically_assigned = var.statically_assigned && var.static_expression != 0 && var.remapped_variable;
+
+	if (statically_assigned)
+	{
+		auto *constant = maybe_get<SPIRConstant>(var.static_expression);
+		if (constant && constant->is_used_as_lut)
+			return true;
+	}
+
+	return false;
+}
+
 void CompilerGLSL::emit_resources()
 {
 	auto &execution = get_entry_point();
@@ -2347,9 +2361,12 @@ void CompilerGLSL::emit_resources()
 		auto &var = get<SPIRVariable>(global);
 		if (var.storage != StorageClassOutput)
 		{
-			add_resource_name(var.self);
-			statement(variable_decl(var), ";");
-			emitted = true;
+			if (!variable_is_lut(var))
+			{
+				add_resource_name(var.self);
+				statement(variable_decl(var), ";");
+				emitted = true;
+			}
 		}
 	}
 

+ 2 - 0
3rdparty/spirv-cross/spirv_glsl.hpp

@@ -638,6 +638,8 @@ protected:
 
 	uint32_t get_integer_width_for_instruction(const Instruction &instr) const;
 
+	bool variable_is_lut(const SPIRVariable &var) const;
+
 private:
 	void init()
 	{

+ 15 - 12
3rdparty/spirv-cross/spirv_hlsl.cpp

@@ -1327,21 +1327,24 @@ void CompilerHLSL::emit_resources()
 		auto &var = get<SPIRVariable>(global);
 		if (var.storage != StorageClassOutput)
 		{
-			add_resource_name(var.self);
-
-			const char *storage = nullptr;
-			switch (var.storage)
+			if (!variable_is_lut(var))
 			{
-			case StorageClassWorkgroup:
-				storage = "groupshared";
-				break;
+				add_resource_name(var.self);
 
-			default:
-				storage = "static";
-				break;
+				const char *storage = nullptr;
+				switch (var.storage)
+				{
+				case StorageClassWorkgroup:
+					storage = "groupshared";
+					break;
+
+				default:
+					storage = "static";
+					break;
+				}
+				statement(storage, " ", variable_decl(var), ";");
+				emitted = true;
 			}
-			statement(storage, " ", variable_decl(var), ";");
-			emitted = true;
 		}
 	}
 

+ 173 - 34
3rdparty/spirv-cross/spirv_msl.cpp

@@ -90,25 +90,55 @@ void CompilerMSL::set_fragment_output_components(uint32_t location, uint32_t com
 void CompilerMSL::build_implicit_builtins()
 {
 	bool need_sample_pos = active_input_builtins.get(BuiltInSamplePosition);
-	if (need_subpass_input || need_sample_pos)
+	if (need_subpass_input || need_sample_pos || capture_output_to_buffer)
 	{
 		bool has_frag_coord = false;
 		bool has_sample_id = false;
+		bool has_vertex_idx = false;
+		bool has_base_vertex = false;
+		bool has_instance_idx = false;
+		bool has_base_instance = false;
 
 		ir.for_each_typed_id<SPIRVariable>([&](uint32_t, SPIRVariable &var) {
-			if (need_subpass_input && var.storage == StorageClassInput && ir.meta[var.self].decoration.builtin &&
-			    ir.meta[var.self].decoration.builtin_type == BuiltInFragCoord)
+			if (var.storage != StorageClassInput || !ir.meta[var.self].decoration.builtin)
+				return;
+
+			if (need_subpass_input && ir.meta[var.self].decoration.builtin_type == BuiltInFragCoord)
 			{
 				builtin_frag_coord_id = var.self;
 				has_frag_coord = true;
 			}
 
-			if (need_sample_pos && var.storage == StorageClassInput && ir.meta[var.self].decoration.builtin &&
-			    ir.meta[var.self].decoration.builtin_type == BuiltInSampleId)
+			if (need_sample_pos && ir.meta[var.self].decoration.builtin_type == BuiltInSampleId)
 			{
 				builtin_sample_id_id = var.self;
 				has_sample_id = true;
 			}
+
+			if (capture_output_to_buffer)
+			{
+				switch (ir.meta[var.self].decoration.builtin_type)
+				{
+				case BuiltInVertexIndex:
+					builtin_vertex_idx_id = var.self;
+					has_vertex_idx = true;
+					break;
+				case BuiltInBaseVertex:
+					builtin_base_vertex_id = var.self;
+					has_base_vertex = true;
+					break;
+				case BuiltInInstanceIndex:
+					builtin_instance_idx_id = var.self;
+					has_instance_idx = true;
+					break;
+				case BuiltInBaseInstance:
+					builtin_base_instance_id = var.self;
+					has_base_instance = true;
+					break;
+				default:
+					break;
+				}
+			}
 		});
 
 		if (!has_frag_coord && need_subpass_input)
@@ -163,9 +193,67 @@ void CompilerMSL::build_implicit_builtins()
 			set_decoration(var_id, DecorationBuiltIn, BuiltInSampleId);
 			builtin_sample_id_id = var_id;
 		}
+
+		if (capture_output_to_buffer &&
+		    (!has_vertex_idx || !has_base_vertex || !has_instance_idx || !has_base_instance))
+		{
+			uint32_t offset = ir.increase_bound_by(2);
+			uint32_t type_id = offset;
+			uint32_t type_ptr_id = offset + 1;
+
+			SPIRType uint_type;
+			uint_type.basetype = SPIRType::UInt;
+			uint_type.width = 32;
+			set<SPIRType>(type_id, uint_type);
+
+			SPIRType uint_type_ptr;
+			uint_type_ptr = uint_type;
+			uint_type_ptr.pointer = true;
+			uint_type_ptr.parent_type = type_id;
+			uint_type_ptr.storage = StorageClassInput;
+			auto &ptr_type = set<SPIRType>(type_ptr_id, uint_type_ptr);
+			ptr_type.self = type_id;
+
+			if (!has_vertex_idx)
+			{
+				uint32_t var_id = ir.increase_bound_by(1);
+
+				// Create gl_VertexIndex.
+				set<SPIRVariable>(var_id, type_ptr_id, StorageClassInput);
+				set_decoration(var_id, DecorationBuiltIn, BuiltInVertexIndex);
+				builtin_vertex_idx_id = var_id;
+			}
+			if (!has_base_vertex)
+			{
+				uint32_t var_id = ir.increase_bound_by(1);
+
+				// Create gl_BaseVertex.
+				set<SPIRVariable>(var_id, type_ptr_id, StorageClassInput);
+				set_decoration(var_id, DecorationBuiltIn, BuiltInBaseVertex);
+				builtin_base_vertex_id = var_id;
+			}
+			if (!has_instance_idx)
+			{
+				uint32_t var_id = ir.increase_bound_by(1);
+
+				// Create gl_InstanceIndex.
+				set<SPIRVariable>(var_id, type_ptr_id, StorageClassInput);
+				set_decoration(var_id, DecorationBuiltIn, BuiltInInstanceIndex);
+				builtin_instance_idx_id = var_id;
+			}
+			if (!has_base_instance)
+			{
+				uint32_t var_id = ir.increase_bound_by(1);
+
+				// Create gl_BaseInstance.
+				set<SPIRVariable>(var_id, type_ptr_id, StorageClassInput);
+				set_decoration(var_id, DecorationBuiltIn, BuiltInBaseInstance);
+				builtin_base_instance_id = var_id;
+			}
+		}
 	}
 
-	if (msl_options.swizzle_texture_samples && has_sampled_images)
+	if (needs_aux_buffer_def)
 	{
 		uint32_t offset = ir.increase_bound_by(5);
 		uint32_t type_id = offset;
@@ -174,7 +262,7 @@ void CompilerMSL::build_implicit_builtins()
 		uint32_t struct_ptr_id = offset + 3;
 		uint32_t var_id = offset + 4;
 
-		// Create a buffer to hold the swizzle constants.
+		// Create a buffer to hold extra data, including the swizzle constants.
 		SPIRType uint_type;
 		uint_type.basetype = SPIRType::UInt;
 		uint_type.width = 32;
@@ -194,8 +282,8 @@ void CompilerMSL::build_implicit_builtins()
 		type.self = struct_id;
 		set_decoration(struct_id, DecorationBlock);
 		set_name(struct_id, "spvAux");
-		set_member_name(struct_id, 0, "swizzleConst");
-		set_member_decoration(struct_id, 0, DecorationOffset, 0);
+		set_member_name(struct_id, k_aux_mbr_idx_swizzle_const, "swizzleConst");
+		set_member_decoration(struct_id, k_aux_mbr_idx_swizzle_const, DecorationOffset, 0);
 
 		SPIRType struct_type_ptr = struct_type;
 		struct_type_ptr.pointer = true;
@@ -232,6 +320,12 @@ static string create_sampler_address(const char *prefix, MSLSamplerAddress addr)
 	}
 }
 
+SPIRType &CompilerMSL::get_stage_out_struct_type()
+{
+	auto &so_var = get<SPIRVariable>(stage_out_var_id);
+	return get_variable_data_type(so_var);
+}
+
 void CompilerMSL::emit_entry_point_declarations()
 {
 	// FIXME: Get test coverage here ...
@@ -409,7 +503,8 @@ string CompilerMSL::compile()
 	backend.allow_truncated_access_chain = true;
 	backend.array_is_value_type = false;
 
-	is_rasterization_disabled = msl_options.disable_rasterization;
+	capture_output_to_buffer = msl_options.capture_output_to_buffer;
+	is_rasterization_disabled = msl_options.disable_rasterization || capture_output_to_buffer;
 
 	replace_illegal_names();
 
@@ -534,7 +629,8 @@ void CompilerMSL::localize_global_variables()
 		auto &var = get<SPIRVariable>(v_id);
 		if (var.storage == StorageClassPrivate || var.storage == StorageClassWorkgroup)
 		{
-			entry_func.add_local_variable(v_id);
+			if (!variable_is_lut(var))
+				entry_func.add_local_variable(v_id);
 			iter = global_variables.erase(iter);
 		}
 		else
@@ -615,13 +711,6 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std::
 					added_arg_ids.insert(builtin_frag_coord_id);
 				}
 
-				if (msl_options.swizzle_texture_samples && has_sampled_images && is_sampled_image_type(type))
-				{
-					// Implicitly reads spvAuxBuffer.
-					assert(aux_buffer_id != 0);
-					added_arg_ids.insert(aux_buffer_id);
-				}
-
 				break;
 			}
 
@@ -1398,14 +1487,35 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage)
 		bool ep_should_return_output = !get_is_rasterization_disabled();
 		uint32_t rtn_id = ep_should_return_output ? ib_var_id : 0;
 		auto &entry_func = get<SPIRFunction>(ir.default_entry_point);
-		entry_func.add_local_variable(ib_var_id);
-		for (auto &blk_id : entry_func.blocks)
+		if (!capture_output_to_buffer)
+		{
+			entry_func.add_local_variable(ib_var_id);
+			for (auto &blk_id : entry_func.blocks)
+			{
+				auto &blk = get<SPIRBlock>(blk_id);
+				if (blk.terminator == SPIRBlock::Return)
+					blk.return_value = rtn_id;
+			}
+			vars_needing_early_declaration.push_back(ib_var_id);
+		}
+		else
 		{
-			auto &blk = get<SPIRBlock>(blk_id);
-			if (blk.terminator == SPIRBlock::Return)
-				blk.return_value = rtn_id;
+			// Instead of declaring a struct variable to hold the output and then
+			// copying that to the output buffer, we'll declare the output variable
+			// as a reference to the final output element in the buffer. Then we can
+			// avoid the extra copy.
+			entry_func.fixup_hooks_in.push_back([=]() {
+				if (stage_out_var_id)
+				{
+					// The first member of the indirect buffer is always the number of vertices
+					// to draw.
+					statement("device ", to_name(ir.default_entry_point), "_", ib_var_ref, "& ", ib_var_ref, " = ",
+					          output_buffer_var_name, "[(", to_expression(builtin_instance_idx_id), " - ",
+					          to_expression(builtin_base_instance_id), ") * spvIndirectParams[0] + ",
+					          to_expression(builtin_vertex_idx_id), " - ", to_expression(builtin_base_vertex_id), "];");
+				}
+			});
 		}
-		vars_needing_early_declaration.push_back(ib_var_id);
 		break;
 	}
 
@@ -4075,9 +4185,9 @@ void CompilerMSL::emit_fixup()
 	}
 }
 
-// Emit a structure member, padding and packing to maintain the correct memeber alignments.
-void CompilerMSL::emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
-                                     const string &qualifier, uint32_t)
+// Return a string defining a structure member, with padding and packing.
+string CompilerMSL::to_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
+                                     const string &qualifier)
 {
 	auto &membertype = get<SPIRType>(member_type_id);
 
@@ -4122,8 +4232,15 @@ void CompilerMSL::emit_struct_member(const SPIRType &type, uint32_t member_type_
 			pack_pfx = "packed_";
 	}
 
-	statement(pack_pfx, type_to_glsl(*effective_membertype), " ", qualifier, to_member_name(type, index),
-	          member_attribute_qualifier(type, index), type_to_array_glsl(*effective_membertype), ";");
+	return join(pack_pfx, type_to_glsl(*effective_membertype), " ", qualifier, to_member_name(type, index),
+	            member_attribute_qualifier(type, index), type_to_array_glsl(membertype), ";");
+}
+
+// Emit a structure member, padding and packing to maintain the correct memeber alignments.
+void CompilerMSL::emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
+                                     const string &qualifier, uint32_t)
+{
+	statement(to_struct_member(type, member_type_id, index, qualifier));
 }
 
 // Return a MSL qualifier for the specified function attribute member
@@ -4360,11 +4477,7 @@ string CompilerMSL::func_type_decl(SPIRType &type)
 	// If an outgoing interface block has been defined, and it should be returned, override the entry point return type
 	bool ep_should_return_output = !get_is_rasterization_disabled();
 	if (stage_out_var_id && ep_should_return_output)
-	{
-		auto &so_var = get<SPIRVariable>(stage_out_var_id);
-		auto &so_type = get_variable_data_type(so_var);
-		return_type = type_to_glsl(so_type) + type_to_array_glsl(type);
-	}
+		return_type = type_to_glsl(get_stage_out_struct_type()) + type_to_array_glsl(type);
 
 	// Prepend a entry type, based on the execution model
 	string entry_type;
@@ -4427,6 +4540,11 @@ string CompilerMSL::get_argument_address_space(const SPIRVariable &argument)
 		// No address space for plain values.
 		return type.pointer ? "thread" : "";
 
+	case StorageClassOutput:
+		if (capture_output_to_buffer)
+			return "device";
+		break;
+
 	default:
 		break;
 	}
@@ -4464,6 +4582,11 @@ string CompilerMSL::get_type_address_space(const SPIRType &type)
 		// No address space for plain values.
 		return type.pointer ? "thread" : "";
 
+	case StorageClassOutput:
+		if (capture_output_to_buffer)
+			return "device";
+		break;
+
 	default:
 		break;
 	}
@@ -4629,6 +4752,21 @@ string CompilerMSL::entry_point_args(bool append_comma)
 	if (needs_instance_idx_arg)
 		ep_args += built_in_func_arg(BuiltInInstanceIndex, !ep_args.empty());
 
+	if (capture_output_to_buffer)
+	{
+		// Add parameters to hold the indirect draw parameters and the shader output. This has to be handled
+		// specially because it needs to be a pointer, not a reference.
+		if (stage_out_var_id)
+		{
+			if (!ep_args.empty())
+				ep_args += ", ";
+			ep_args += join("device ", type_to_glsl(get_stage_out_struct_type()), "* ", output_buffer_var_name,
+			                " [[buffer(", msl_options.shader_output_buffer_index, ")]], ");
+			ep_args +=
+			    join("device uint* spvIndirectParams [[buffer(", msl_options.indirect_params_buffer_index, ")]]");
+		}
+	}
+
 	if (!ep_args.empty() && append_comma)
 		ep_args += ", ";
 
@@ -5843,6 +5981,7 @@ bool CompilerMSL::SampledImageScanner::handle(spv::Op opcode, const uint32_t *ar
 	case OpImageDrefGather:
 		compiler.has_sampled_images =
 		    compiler.has_sampled_images || compiler.is_sampled_image_type(compiler.expression_type(args[2]));
+		compiler.needs_aux_buffer_def = compiler.needs_aux_buffer_def || compiler.has_sampled_images;
 		break;
 	default:
 		break;

+ 25 - 1
3rdparty/spirv-cross/spirv_msl.hpp

@@ -147,6 +147,10 @@ static const uint32_t kPushConstDescSet = ~(0u);
 // element to indicate the bindings for the push constants.
 static const uint32_t kPushConstBinding = 0;
 
+// The current version of the aux buffer structure. It must be incremented any time a
+// new field is added to the aux buffer.
+#define SPIRV_CROSS_MSL_AUX_BUFFER_STRUCT_VERSION 1
+
 // Decompiles SPIR-V to Metal Shading Language
 class CompilerMSL : public CompilerGLSL
 {
@@ -163,9 +167,12 @@ public:
 		Platform platform = macOS;
 		uint32_t msl_version = make_msl_version(1, 2);
 		uint32_t texel_buffer_texture_width = 4096; // Width of 2D Metal textures used as 1D texel buffers
-		uint32_t aux_buffer_index = 0;
+		uint32_t aux_buffer_index = 30;
+		uint32_t indirect_params_buffer_index = 29;
+		uint32_t shader_output_buffer_index = 28;
 		bool enable_point_size_builtin = true;
 		bool disable_rasterization = false;
+		bool capture_output_to_buffer = false;
 		bool swizzle_texture_samples = false;
 
 		// Fragment output in MSL must have at least as many components as the render pass.
@@ -234,6 +241,13 @@ public:
 		return used_aux_buffer;
 	}
 
+	// Provide feedback to calling API to allow it to pass an output
+	// buffer if the shader needs it.
+	bool needs_output_buffer() const
+	{
+		return capture_output_to_buffer && stage_out_var_id != 0;
+	}
+
 	// An enum of SPIR-V functions that are implemented in additional
 	// source code that is added to the shader if necessary.
 	enum SPVFuncImpl
@@ -329,6 +343,8 @@ protected:
 	void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags) override;
 	void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
 	void emit_fixup() override;
+	std::string to_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
+	                             const std::string &qualifier = "");
 	void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
 	                        const std::string &qualifier = "", uint32_t base_offset = 0) override;
 	std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
@@ -415,6 +431,7 @@ protected:
 	MSLStructMemberKey get_struct_member_key(uint32_t type_id, uint32_t index);
 	std::string get_argument_address_space(const SPIRVariable &argument);
 	std::string get_type_address_space(const SPIRType &type);
+	SPIRType &get_stage_out_struct_type();
 	void emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, uint32_t mem_order_1,
 	                         uint32_t mem_order_2, bool has_mem_order_2, uint32_t op0, uint32_t op1 = 0,
 	                         bool op1_is_pointer = false, bool op1_is_literal = false, uint32_t op2 = 0);
@@ -427,6 +444,10 @@ protected:
 	void emit_entry_point_declarations() override;
 	uint32_t builtin_frag_coord_id = 0;
 	uint32_t builtin_sample_id_id = 0;
+	uint32_t builtin_vertex_idx_id = 0;
+	uint32_t builtin_base_vertex_id = 0;
+	uint32_t builtin_instance_idx_id = 0;
+	uint32_t builtin_base_instance_id = 0;
 	uint32_t aux_buffer_id = 0;
 
 	void bitcast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) override;
@@ -451,12 +472,15 @@ protected:
 	bool needs_vertex_idx_arg = false;
 	bool needs_instance_idx_arg = false;
 	bool is_rasterization_disabled = false;
+	bool capture_output_to_buffer = false;
+	bool needs_aux_buffer_def = false;
 	bool used_aux_buffer = false;
 	std::string qual_pos_var_name;
 	std::string stage_in_var_name = "in";
 	std::string stage_out_var_name = "out";
 	std::string sampler_name_suffix = "Smplr";
 	std::string swizzle_name_suffix = "Swzl";
+	std::string output_buffer_var_name = "spvOut";
 	spv::Op previous_instruction_opcode = spv::OpNop;
 
 	std::unordered_map<uint32_t, MSLConstexprSampler> constexpr_samplers;

+ 2 - 0
3rdparty/spirv-cross/test_shaders.py

@@ -154,6 +154,8 @@ def cross_compile_msl(shader, spirv, opt):
         msl_args.append('--msl-ios')
     if '.pad-fragment.' in shader:
         msl_args.append('--msl-pad-fragment-output')
+    if '.capture.' in shader:
+        msl_args.append('--msl-capture-output')
 
     subprocess.check_call(msl_args)