Updated spirv-cross.

This commit is contained in:
Бранимир Караџић 2019-02-09 12:44:48 -08:00
parent a91c5a877e
commit 812af5e6f1
41 changed files with 982 additions and 379 deletions

View File

@ -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

View File

@ -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)

View File

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

View File

@ -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;

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)));

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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];

View File

@ -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];

View File

@ -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);
}

View File

@ -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];

View File

@ -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];

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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

View File

@ -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.

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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()
{

View File

@ -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;
}
}

View File

@ -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)
{
auto &blk = get<SPIRBlock>(blk_id);
if (blk.terminator == SPIRBlock::Return)
blk.return_value = rtn_id;
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
{
// 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;

View File

@ -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;

View File

@ -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)