Updated spirv-cross.

This commit is contained in:
Бранимир Караџић
2019-02-22 20:54:12 -08:00
parent 8324872ae9
commit 51cf3115fb
74 changed files with 2994 additions and 213 deletions

View File

@@ -494,6 +494,7 @@ struct CLIArguments
bool msl_swizzle_texture_samples = false;
bool msl_ios = false;
bool msl_pad_fragment_output = false;
bool msl_domain_lower_left = false;
vector<PLSArg> pls_in;
vector<PLSArg> pls_out;
vector<Remap> remaps;
@@ -550,6 +551,7 @@ static void print_help()
"\t[--msl-swizzle-texture-samples]\n"
"\t[--msl-ios]\n"
"\t[--msl-pad-fragment-output]\n"
"\t[--msl-domain-lower-left]\n"
"\t[--hlsl]\n"
"\t[--reflect]\n"
"\t[--shader-model]\n"
@@ -720,6 +722,7 @@ static int main_inner(int argc, char *argv[])
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; });
cbs.add("--msl-domain-lower-left", [&args](CLIParser &) { args.msl_domain_lower_left = true; });
cbs.add("--extension", [&args](CLIParser &parser) { args.extensions.push_back(parser.next_string()); });
cbs.add("--rename-entry-point", [&args](CLIParser &parser) {
auto old_name = parser.next_string();
@@ -851,6 +854,7 @@ static int main_inner(int argc, char *argv[])
if (args.msl_ios)
msl_opts.platform = CompilerMSL::Options::iOS;
msl_opts.pad_fragment_output_components = args.msl_pad_fragment_output;
msl_opts.tess_domain_origin_lower_left = args.msl_domain_lower_left;
msl_comp->set_msl_options(msl_opts);
}
else if (args.hlsl)

View File

@@ -0,0 +1,30 @@
Texture2D<float4> g_Texture : register(t0);
SamplerState g_Sampler : register(s0);
SamplerComparisonState g_CompareSampler : register(s1);
static float2 in_var_TEXCOORD0;
static float out_var_SV_Target;
struct SPIRV_Cross_Input
{
float2 in_var_TEXCOORD0 : TEXCOORD0;
};
struct SPIRV_Cross_Output
{
float out_var_SV_Target : SV_Target0;
};
void frag_main()
{
out_var_SV_Target = g_Texture.Sample(g_Sampler, in_var_TEXCOORD0).x + g_Texture.SampleCmpLevelZero(g_CompareSampler, in_var_TEXCOORD0, 0.5f);
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
in_var_TEXCOORD0 = stage_input.in_var_TEXCOORD0;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.out_var_SV_Target = out_var_SV_Target;
return stage_output;
}

View File

@@ -0,0 +1,45 @@
struct InstanceData
{
column_major float4x4 MATRIX_MVP;
float4 Color;
};
cbuffer gInstanceData : register(b0)
{
InstanceData gInstanceData_1_data[32] : packoffset(c0);
};
static float4 gl_Position;
static int gl_InstanceIndex;
static float3 PosL;
static float4 _entryPointOutput_Color;
struct SPIRV_Cross_Input
{
float3 PosL : TEXCOORD0;
uint gl_InstanceIndex : SV_InstanceID;
};
struct SPIRV_Cross_Output
{
float4 _entryPointOutput_Color : TEXCOORD0;
float4 gl_Position : SV_Position;
};
void vert_main()
{
gl_Position = mul(float4(PosL, 1.0f), gInstanceData_1_data[uint(gl_InstanceIndex)].MATRIX_MVP);
_entryPointOutput_Color = gInstanceData_1_data[uint(gl_InstanceIndex)].Color;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
gl_InstanceIndex = int(stage_input.gl_InstanceIndex);
PosL = stage_input.PosL;
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
stage_output._entryPointOutput_Color = _entryPointOutput_Color;
return stage_output;
}

View File

@@ -0,0 +1,22 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float out_var_SV_Target [[color(0)]];
};
struct main0_in
{
float2 in_var_TEXCOORD0 [[user(locn0)]];
};
fragment main0_out main0(main0_in in [[stage_in]], depth2d<float> g_Texture [[texture(0)]], sampler g_Sampler [[sampler(0)]], sampler g_CompareSampler [[sampler(1)]])
{
main0_out out = {};
out.out_var_SV_Target = float4(g_Texture.sample(g_Sampler, in.in_var_TEXCOORD0)).x + g_Texture.sample_compare(g_CompareSampler, in.in_var_TEXCOORD0, 0.5, level(0.0));
return out;
}

View File

@@ -0,0 +1,23 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct TessLevels
{
float inner0;
float inner1;
float outer0;
float outer1;
float outer2;
float outer3;
};
kernel void main0(const device TessLevels& sb_levels [[buffer(0)]], uint gl_InvocationID [[thread_index_in_threadgroup]], uint gl_PrimitiveID [[threadgroup_position_in_grid]], device uint* spvIndirectParams [[buffer(29)]], device MTLTriangleTessellationFactorsHalf* spvTessLevel [[buffer(26)]])
{
spvTessLevel[gl_PrimitiveID].insideTessellationFactor = half(sb_levels.inner0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[0] = half(sb_levels.outer0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[1] = half(sb_levels.outer1);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[2] = half(sb_levels.outer2);
}

View File

@@ -0,0 +1,35 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_patchIn
{
float gl_TessLevelInner_0 [[attribute(0)]];
float gl_TessLevelInner_1 [[attribute(1)]];
float gl_TessLevelOuter_0 [[attribute(2)]];
float gl_TessLevelOuter_1 [[attribute(3)]];
float gl_TessLevelOuter_2 [[attribute(4)]];
float gl_TessLevelOuter_3 [[attribute(5)]];
};
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
float gl_TessLevelInner[2] = {};
float gl_TessLevelOuter[4] = {};
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0;
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1;
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0;
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1;
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2;
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3;
out.gl_Position = float4(((gl_TessCoord.x * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[1])) + (((1.0 - gl_TessCoord.y) * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[3])), 0.0, 1.0);
return out;
}

View File

@@ -0,0 +1,35 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct InstanceData
{
float4x4 MATRIX_MVP;
float4 Color;
};
struct gInstanceData
{
InstanceData _data[1];
};
struct main0_out
{
float4 _entryPointOutput_Color [[user(locn0)]];
float4 gl_Position [[position]];
};
struct main0_in
{
float3 PosL [[attribute(0)]];
};
vertex main0_out main0(main0_in in [[stage_in]], const device gInstanceData& gInstanceData_1 [[buffer(0)]], uint gl_InstanceIndex [[instance_id]])
{
main0_out out = {};
out.gl_Position = float4(in.PosL, 1.0) * gInstanceData_1._data[gl_InstanceIndex].MATRIX_MVP;
out._entryPointOutput_Color = gInstanceData_1._data[gl_InstanceIndex].Color;
return out;
}

View File

@@ -15,7 +15,7 @@ struct SSBO1
kernel void main0(device SSBO0& _25 [[buffer(0)]], device SSBO1& _39 [[buffer(1)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]])
{
_39.outputs[gl_GlobalInvocationID.x].x = int(as_type<uint>(as_type<half2>(_25.inputs[gl_GlobalInvocationID.x].xy) + half2(1.0h)));
_39.outputs[gl_GlobalInvocationID.x].x = int(as_type<uint>(as_type<half2>(_25.inputs[gl_GlobalInvocationID.x].xy) + half2(half(1.0))));
_39.outputs[gl_GlobalInvocationID.x].y = as_type<int>(_25.inputs[gl_GlobalInvocationID.x].zw);
_39.outputs[gl_GlobalInvocationID.x].z = int(as_type<uint>(ushort2(_25.inputs[gl_GlobalInvocationID.x].xy)));
}

View File

@@ -0,0 +1,27 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_in
{
float4 gl_Position [[attribute(0)]];
};
struct main0_patchIn
{
patch_control_point<main0_in> gl_in;
};
[[ patch(triangle, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float3 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
out.gl_Position = ((patchIn.gl_in[0].gl_Position * gl_TessCoord.x) + (patchIn.gl_in[1].gl_Position * gl_TessCoord.y)) + (patchIn.gl_in[2].gl_Position * gl_TessCoord.z);
return out;
}

View File

@@ -13,7 +13,7 @@ struct main0_out
fragment main0_out main0()
{
main0_out out = {};
out.foo = 1.0h;
out.foo = half(1.0);
out.bar = 2;
out.baz = 3u;
return out;

View File

@@ -0,0 +1,28 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_in
{
float4 Floats [[attribute(0)]];
float4 Floats2 [[attribute(2)]];
};
struct main0_patchIn
{
patch_control_point<main0_in> gl_in;
};
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
out.gl_Position = (patchIn.gl_in[0].Floats * gl_TessCoord.x) + (patchIn.gl_in[1].Floats2 * gl_TessCoord.y);
return out;
}

View File

@@ -0,0 +1,80 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct Block
{
float4 a;
float4 b;
};
struct PatchBlock
{
float4 a;
float4 b;
};
struct Foo
{
float4 a;
float4 b;
};
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_in
{
float4 vColor [[attribute(0)]];
float4 Block_a [[attribute(4)]];
float4 Block_b [[attribute(5)]];
float4 Foo_a [[attribute(14)]];
float4 Foo_b [[attribute(15)]];
};
struct main0_patchIn
{
float4 vColors [[attribute(1)]];
float4 PatchBlock_a [[attribute(6)]];
float4 PatchBlock_b [[attribute(7)]];
float4 Foo_a [[attribute(8)]];
float4 Foo_b [[attribute(9)]];
patch_control_point<main0_in> gl_in;
};
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
{
main0_out out = {};
PatchBlock patch_block = {};
Foo vFoo = {};
patch_block.a = patchIn.PatchBlock_a;
patch_block.b = patchIn.PatchBlock_b;
vFoo.a = patchIn.Foo_a;
vFoo.b = patchIn.Foo_b;
out.gl_Position = patchIn.gl_in[0].Block_a;
out.gl_Position += patchIn.gl_in[0].Block_b;
out.gl_Position += patchIn.gl_in[1].Block_a;
out.gl_Position += patchIn.gl_in[1].Block_b;
out.gl_Position += patch_block.a;
out.gl_Position += patch_block.b;
out.gl_Position += patchIn.gl_in[0].vColor;
out.gl_Position += patchIn.gl_in[1].vColor;
out.gl_Position += patchIn.vColors;
out.gl_Position += vFoo.a;
out.gl_Position += vFoo.b;
Foo vFoos_202;
vFoos_202.a = patchIn.gl_in[0].Foo_a;
vFoos_202.b = patchIn.gl_in[0].Foo_b;
out.gl_Position += vFoos_202.a;
out.gl_Position += vFoos_202.b;
Foo vFoos_216;
vFoos_216.a = patchIn.gl_in[1].Foo_a;
vFoos_216.b = patchIn.gl_in[1].Foo_b;
out.gl_Position += vFoos_216.a;
out.gl_Position += vFoos_216.b;
return out;
}

View File

@@ -0,0 +1,36 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_patchIn
{
float gl_TessLevelInner_0 [[attribute(0)]];
float gl_TessLevelInner_1 [[attribute(1)]];
float gl_TessLevelOuter_0 [[attribute(2)]];
float gl_TessLevelOuter_1 [[attribute(3)]];
float gl_TessLevelOuter_2 [[attribute(4)]];
float gl_TessLevelOuter_3 [[attribute(5)]];
};
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
float gl_TessLevelInner[2] = {};
float gl_TessLevelOuter[4] = {};
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0;
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1;
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0;
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1;
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2;
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3;
gl_TessCoord.y = 1.0 - gl_TessCoord.y;
out.gl_Position = float4(((gl_TessCoord.x * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[3])) + (((1.0 - gl_TessCoord.y) * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[1])), 0.0, 1.0);
return out;
}

View File

@@ -0,0 +1,35 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_patchIn
{
float gl_TessLevelInner_0 [[attribute(0)]];
float gl_TessLevelInner_1 [[attribute(1)]];
float gl_TessLevelOuter_0 [[attribute(2)]];
float gl_TessLevelOuter_1 [[attribute(3)]];
float gl_TessLevelOuter_2 [[attribute(4)]];
float gl_TessLevelOuter_3 [[attribute(5)]];
};
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
float gl_TessLevelInner[2] = {};
float gl_TessLevelOuter[4] = {};
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0;
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1;
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0;
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1;
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2;
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3;
out.gl_Position = float4(((gl_TessCoord.x * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[1])) + (((1.0 - gl_TessCoord.y) * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[3])), 0.0, 1.0);
return out;
}

View File

@@ -0,0 +1,55 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct Block
{
float4 a;
float4 b;
};
struct Foo
{
float4 a;
float4 b;
};
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_in
{
float4 vColor [[attribute(0)]];
float4 Block_a [[attribute(2)]];
float4 Block_b [[attribute(3)]];
};
struct main0_patchIn
{
float4 vColors [[attribute(1)]];
float4 Foo_a [[attribute(4)]];
float4 Foo_b [[attribute(5)]];
patch_control_point<main0_in> gl_in;
};
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
{
main0_out out = {};
Foo vFoo = {};
vFoo.a = patchIn.Foo_a;
vFoo.b = patchIn.Foo_b;
out.gl_Position = patchIn.gl_in[0].Block_a;
out.gl_Position += patchIn.gl_in[0].Block_b;
out.gl_Position += patchIn.gl_in[1].Block_a;
out.gl_Position += patchIn.gl_in[1].Block_b;
out.gl_Position += patchIn.gl_in[0].vColor;
out.gl_Position += patchIn.gl_in[1].vColor;
out.gl_Position += patchIn.vColors;
out.gl_Position += vFoo.a;
out.gl_Position += vFoo.b;
return out;
}

View File

@@ -0,0 +1,17 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
[[ patch(triangle, 0) ]] vertex main0_out main0()
{
main0_out out = {};
out.gl_Position = float4(1.0);
return out;
}

View File

@@ -0,0 +1,45 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct UBO
{
float4x4 uMVP;
float4 uScale;
float2 uInvScale;
float3 uCamPos;
float2 uPatchSize;
float2 uInvHeightmapSize;
};
struct main0_out
{
float3 vWorld [[user(locn0)]];
float4 vGradNormalTex [[user(locn1)]];
float4 gl_Position [[position]];
};
struct main0_patchIn
{
float2 vOutPatchPosBase [[attribute(0)]];
float4 vPatchLods [[attribute(1)]];
};
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], constant UBO& _31 [[buffer(1)]], texture2d<float> uHeightmapDisplacement [[texture(0)]], sampler uHeightmapDisplacementSmplr [[sampler(0)]], float2 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
float2 _201 = patchIn.vOutPatchPosBase + (float3(gl_TessCoord, 0).xy * _31.uPatchSize);
float2 _214 = mix(patchIn.vPatchLods.yx, patchIn.vPatchLods.zw, float2(float3(gl_TessCoord, 0).x));
float _221 = mix(_214.x, _214.y, float3(gl_TessCoord, 0).y);
float _223 = floor(_221);
float2 _125 = _201 * _31.uInvHeightmapSize;
float2 _141 = _31.uInvHeightmapSize * exp2(_223);
out.vGradNormalTex = float4(_125 + (_31.uInvHeightmapSize * 0.5), _125 * _31.uScale.zw);
float3 _253 = mix(uHeightmapDisplacement.sample(uHeightmapDisplacementSmplr, (_125 + (_141 * 0.5)), level(_223)).xyz, uHeightmapDisplacement.sample(uHeightmapDisplacementSmplr, (_125 + (_141 * 1.0)), level(_223 + 1.0)).xyz, float3(_221 - _223));
float2 _171 = (_201 * _31.uScale.xy) + _253.yz;
out.vWorld = float3(_171.x, _253.x, _171.y);
out.gl_Position = _31.uMVP * float4(out.vWorld, 1.0);
return out;
}

View File

@@ -0,0 +1,13 @@
#version 450
uniform sampler2D SPIRV_Cross_Combinedg_Textureg_Sampler;
uniform sampler2DShadow SPIRV_Cross_Combinedg_Textureg_CompareSampler;
layout(location = 0) in vec2 in_var_TEXCOORD0;
layout(location = 0) out float out_var_SV_Target;
void main()
{
out_var_SV_Target = texture(SPIRV_Cross_Combinedg_Textureg_Sampler, in_var_TEXCOORD0).x + textureLod(SPIRV_Cross_Combinedg_Textureg_CompareSampler, vec3(in_var_TEXCOORD0, 0.5), 0.0);
}

View File

@@ -0,0 +1,23 @@
#version 450
struct InstanceData
{
mat4 MATRIX_MVP;
vec4 Color;
};
layout(binding = 0, std430) readonly buffer gInstanceData
{
layout(row_major) InstanceData _data[];
} gInstanceData_1;
layout(location = 0) in vec3 PosL;
uniform int SPIRV_Cross_BaseInstance;
layout(location = 0) out vec4 _entryPointOutput_Color;
void main()
{
gl_Position = gInstanceData_1._data[uint((gl_InstanceID + SPIRV_Cross_BaseInstance))].MATRIX_MVP * vec4(PosL, 1.0);
_entryPointOutput_Color = gInstanceData_1._data[uint((gl_InstanceID + SPIRV_Cross_BaseInstance))].Color;
}

View File

@@ -27,7 +27,7 @@ void main()
{
uint ident = gl_GlobalInvocationID.x;
f16vec2 a = int16BitsToFloat16(_25.inputs[ident].xy);
_39.outputs[ident].x = int(packFloat2x16(a + f16vec2(1.0hf)));
_39.outputs[ident].x = int(packFloat2x16(a + f16vec2(float16_t(1.0))));
_39.outputs[ident].y = packInt2x16(_25.inputs[ident].zw);
_39.outputs[ident].z = int(packUint2x16(u16vec2(_25.inputs[ident].xy)));
}

View File

@@ -30,19 +30,19 @@ f16mat3 test_mat3(f16vec3 a, f16vec3 b, f16vec3 c, f16vec3 d, f16vec3 e, f16vec3
void test_constants()
{
float16_t a = 1.0hf;
float16_t b = 1.5hf;
float16_t c = -1.5hf;
float16_t d = (0.0hf / 0.0hf);
float16_t e = (1.0hf / 0.0hf);
float16_t f = (-1.0hf / 0.0hf);
float16_t g = 1014.0hf;
float16_t h = 9.5367431640625e-07hf;
float16_t a = float16_t(1.0);
float16_t b = float16_t(1.5);
float16_t c = float16_t(-1.5);
float16_t d = float16_t(0.0 / 0.0);
float16_t e = float16_t(1.0 / 0.0);
float16_t f = float16_t(-1.0 / 0.0);
float16_t g = float16_t(1014.0);
float16_t h = float16_t(9.5367431640625e-07);
}
float16_t test_result()
{
return 1.0hf;
return float16_t(1.0);
}
void test_conversions()
@@ -50,7 +50,7 @@ void test_conversions()
float16_t one = test_result();
int a = int(one);
uint b = uint(one);
bool c = one != 0.0hf;
bool c = one != float16_t(0.0);
float d = float(one);
double e = double(one);
float16_t a2 = float16_t(a);

View File

@@ -18,7 +18,7 @@ layout(location = 2) out uint16_t baz;
void main()
{
foo = 1.0hf;
foo = float16_t(1.0);
bar = 2s;
baz = 3us;
}

View File

@@ -0,0 +1,30 @@
Texture2D<float4> g_Texture : register(t0);
SamplerState g_Sampler : register(s0);
SamplerComparisonState g_CompareSampler : register(s1);
static float2 in_var_TEXCOORD0;
static float out_var_SV_Target;
struct SPIRV_Cross_Input
{
float2 in_var_TEXCOORD0 : TEXCOORD0;
};
struct SPIRV_Cross_Output
{
float out_var_SV_Target : SV_Target0;
};
void frag_main()
{
out_var_SV_Target = g_Texture.Sample(g_Sampler, in_var_TEXCOORD0).x + g_Texture.SampleCmpLevelZero(g_CompareSampler, in_var_TEXCOORD0, 0.5f);
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
in_var_TEXCOORD0 = stage_input.in_var_TEXCOORD0;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.out_var_SV_Target = out_var_SV_Target;
return stage_output;
}

View File

@@ -0,0 +1,67 @@
struct V2F
{
float4 Position;
float4 Color;
};
struct InstanceData
{
column_major float4x4 MATRIX_MVP;
float4 Color;
};
cbuffer gInstanceData : register(b0)
{
InstanceData gInstanceData_1_data[32] : packoffset(c0);
};
static float4 gl_Position;
static int gl_InstanceIndex;
static float3 PosL;
static float4 _entryPointOutput_Color;
struct SPIRV_Cross_Input
{
float3 PosL : TEXCOORD0;
uint gl_InstanceIndex : SV_InstanceID;
};
struct SPIRV_Cross_Output
{
float4 _entryPointOutput_Color : TEXCOORD0;
float4 gl_Position : SV_Position;
};
V2F _VS(float3 PosL_1, uint instanceID)
{
InstanceData instData;
instData.MATRIX_MVP = gInstanceData_1_data[instanceID].MATRIX_MVP;
instData.Color = gInstanceData_1_data[instanceID].Color;
V2F v2f;
v2f.Position = mul(float4(PosL_1, 1.0f), instData.MATRIX_MVP);
v2f.Color = instData.Color;
return v2f;
}
void vert_main()
{
float3 PosL_1 = PosL;
uint instanceID = uint(gl_InstanceIndex);
float3 param = PosL_1;
uint param_1 = instanceID;
V2F flattenTemp = _VS(param, param_1);
gl_Position = flattenTemp.Position;
_entryPointOutput_Color = flattenTemp.Color;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
gl_InstanceIndex = int(stage_input.gl_InstanceIndex);
PosL = stage_input.PosL;
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
stage_output._entryPointOutput_Color = _entryPointOutput_Color;
return stage_output;
}

View File

@@ -0,0 +1,22 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float out_var_SV_Target [[color(0)]];
};
struct main0_in
{
float2 in_var_TEXCOORD0 [[user(locn0)]];
};
fragment main0_out main0(main0_in in [[stage_in]], depth2d<float> g_Texture [[texture(0)]], sampler g_Sampler [[sampler(0)]], sampler g_CompareSampler [[sampler(1)]])
{
main0_out out = {};
out.out_var_SV_Target = float4(g_Texture.sample(g_Sampler, in.in_var_TEXCOORD0)).x + g_Texture.sample_compare(g_CompareSampler, in.in_var_TEXCOORD0, 0.5, level(0.0));
return out;
}

View File

@@ -0,0 +1,23 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct TessLevels
{
float inner0;
float inner1;
float outer0;
float outer1;
float outer2;
float outer3;
};
kernel void main0(const device TessLevels& sb_levels [[buffer(0)]], uint gl_InvocationID [[thread_index_in_threadgroup]], uint gl_PrimitiveID [[threadgroup_position_in_grid]], device uint* spvIndirectParams [[buffer(29)]], device MTLTriangleTessellationFactorsHalf* spvTessLevel [[buffer(26)]])
{
spvTessLevel[gl_PrimitiveID].insideTessellationFactor = half(sb_levels.inner0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[0] = half(sb_levels.outer0);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[1] = half(sb_levels.outer1);
spvTessLevel[gl_PrimitiveID].edgeTessellationFactor[2] = half(sb_levels.outer2);
}

View File

@@ -0,0 +1,35 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_patchIn
{
float gl_TessLevelInner_0 [[attribute(0)]];
float gl_TessLevelInner_1 [[attribute(1)]];
float gl_TessLevelOuter_0 [[attribute(2)]];
float gl_TessLevelOuter_1 [[attribute(3)]];
float gl_TessLevelOuter_2 [[attribute(4)]];
float gl_TessLevelOuter_3 [[attribute(5)]];
};
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
float gl_TessLevelInner[2] = {};
float gl_TessLevelOuter[4] = {};
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0;
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1;
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0;
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1;
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2;
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3;
out.gl_Position = float4(((gl_TessCoord.x * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[1])) + (((1.0 - gl_TessCoord.y) * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[3])), 0.0, 1.0);
return out;
}

View File

@@ -0,0 +1,65 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct V2F
{
float4 Position;
float4 Color;
};
struct InstanceData
{
float4x4 MATRIX_MVP;
float4 Color;
};
struct InstanceData_1
{
float4x4 MATRIX_MVP;
float4 Color;
};
struct gInstanceData
{
InstanceData _data[1];
};
struct main0_out
{
float4 _entryPointOutput_Color [[user(locn0)]];
float4 gl_Position [[position]];
};
struct main0_in
{
float3 PosL [[attribute(0)]];
};
V2F _VS(thread const float3& PosL, thread const uint& instanceID, const device gInstanceData& gInstanceData_1)
{
InstanceData_1 instData;
instData.MATRIX_MVP = transpose(gInstanceData_1._data[instanceID].MATRIX_MVP);
instData.Color = gInstanceData_1._data[instanceID].Color;
V2F v2f;
v2f.Position = instData.MATRIX_MVP * float4(PosL, 1.0);
v2f.Color = instData.Color;
return v2f;
}
vertex main0_out main0(main0_in in [[stage_in]], const device gInstanceData& gInstanceData_1 [[buffer(0)]], uint gl_InstanceIndex [[instance_id]])
{
main0_out out = {};
float3 PosL = in.PosL;
uint instanceID = gl_InstanceIndex;
float3 param = PosL;
uint param_1 = instanceID;
V2F flattenTemp = _VS(param, param_1, gInstanceData_1);
out.gl_Position = flattenTemp.Position;
out._entryPointOutput_Color = flattenTemp.Color;
return out;
}

View File

@@ -17,7 +17,7 @@ kernel void main0(device SSBO0& _25 [[buffer(0)]], device SSBO1& _39 [[buffer(1)
{
uint ident = gl_GlobalInvocationID.x;
half2 a = as_type<half2>(_25.inputs[ident].xy);
_39.outputs[ident].x = int(as_type<uint>(a + half2(1.0h)));
_39.outputs[ident].x = int(as_type<uint>(a + half2(half(1.0))));
_39.outputs[ident].y = as_type<int>(_25.inputs[ident].zw);
_39.outputs[ident].z = int(as_type<uint>(ushort2(_25.inputs[ident].xy)));
}

View File

@@ -0,0 +1,27 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_in
{
float4 gl_Position [[attribute(0)]];
};
struct main0_patchIn
{
patch_control_point<main0_in> gl_in;
};
[[ patch(triangle, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float3 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
out.gl_Position = ((patchIn.gl_in[0].gl_Position * gl_TessCoord.x) + (patchIn.gl_in[1].gl_Position * gl_TessCoord.y)) + (patchIn.gl_in[2].gl_Position * gl_TessCoord.z);
return out;
}

View File

@@ -13,7 +13,7 @@ struct main0_out
fragment main0_out main0()
{
main0_out out = {};
out.foo = 1.0h;
out.foo = half(1.0);
out.bar = 2;
out.baz = 3u;
return out;

View File

@@ -52,19 +52,19 @@ half3x3 test_mat3(thread const half3& a, thread const half3& b, thread const hal
void test_constants()
{
half a = 1.0h;
half b = 1.5h;
half c = -1.5h;
half d = (0.0h / 0.0h);
half e = (1.0h / 0.0h);
half f = (-1.0h / 0.0h);
half g = 1014.0h;
half h = 9.5367431640625e-07h;
half a = half(1.0);
half b = half(1.5);
half c = half(-1.5);
half d = half(0.0 / 0.0);
half e = half(1.0 / 0.0);
half f = half(-1.0 / 0.0);
half g = half(1014.0);
half h = half(9.5367431640625e-07);
}
half test_result()
{
return 1.0h;
return half(1.0);
}
void test_conversions()
@@ -72,7 +72,7 @@ void test_conversions()
half one = test_result();
int a = int(one);
uint b = uint(one);
bool c = one != 0.0h;
bool c = one != half(0.0);
float d = float(one);
half a2 = half(a);
half b2 = half(b);

View File

@@ -0,0 +1,35 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_in
{
float4 Floats [[attribute(0)]];
float4 Floats2 [[attribute(2)]];
};
struct main0_patchIn
{
patch_control_point<main0_in> gl_in;
};
void set_position(thread float4& gl_Position, thread patch_control_point<main0_in>& gl_in, thread float2& gl_TessCoord)
{
gl_Position = (gl_in[0].Floats * gl_TessCoord.x) + (gl_in[1].Floats2 * gl_TessCoord.y);
}
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
set_position(out.gl_Position, patchIn.gl_in, gl_TessCoord);
return out;
}

View File

@@ -0,0 +1,90 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct Block
{
float4 a;
float4 b;
};
struct PatchBlock
{
float4 a;
float4 b;
};
struct Foo
{
float4 a;
float4 b;
};
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_in
{
float4 vColor [[attribute(0)]];
float4 Block_a [[attribute(4)]];
float4 Block_b [[attribute(5)]];
float4 Foo_a [[attribute(14)]];
float4 Foo_b [[attribute(15)]];
};
struct main0_patchIn
{
float4 vColors [[attribute(1)]];
float4 PatchBlock_a [[attribute(6)]];
float4 PatchBlock_b [[attribute(7)]];
float4 Foo_a [[attribute(8)]];
float4 Foo_b [[attribute(9)]];
patch_control_point<main0_in> gl_in;
};
void set_from_function(thread float4& gl_Position, thread patch_control_point<main0_in>& gl_in, thread PatchBlock& patch_block, thread float4& vColors, thread Foo& vFoo)
{
gl_Position = gl_in[0].Block_a;
gl_Position += gl_in[0].Block_b;
gl_Position += gl_in[1].Block_a;
gl_Position += gl_in[1].Block_b;
gl_Position += patch_block.a;
gl_Position += patch_block.b;
gl_Position += gl_in[0].vColor;
gl_Position += gl_in[1].vColor;
gl_Position += vColors;
Foo foo = vFoo;
gl_Position += foo.a;
gl_Position += foo.b;
Foo vFoos_105;
vFoos_105.a = gl_in[0].Foo_a;
vFoos_105.b = gl_in[0].Foo_b;
foo = vFoos_105;
gl_Position += foo.a;
gl_Position += foo.b;
Foo vFoos_119;
vFoos_119.a = gl_in[1].Foo_a;
vFoos_119.b = gl_in[1].Foo_b;
foo = vFoos_119;
gl_Position += foo.a;
gl_Position += foo.b;
}
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
{
main0_out out = {};
PatchBlock patch_block = {};
Foo vFoo = {};
patch_block.a = patchIn.PatchBlock_a;
patch_block.b = patchIn.PatchBlock_b;
vFoo.a = patchIn.Foo_a;
vFoo.b = patchIn.Foo_b;
set_from_function(out.gl_Position, patchIn.gl_in, patch_block, patchIn.vColors, vFoo);
return out;
}

View File

@@ -0,0 +1,36 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_patchIn
{
float gl_TessLevelInner_0 [[attribute(0)]];
float gl_TessLevelInner_1 [[attribute(1)]];
float gl_TessLevelOuter_0 [[attribute(2)]];
float gl_TessLevelOuter_1 [[attribute(3)]];
float gl_TessLevelOuter_2 [[attribute(4)]];
float gl_TessLevelOuter_3 [[attribute(5)]];
};
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
float gl_TessLevelInner[2] = {};
float gl_TessLevelOuter[4] = {};
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0;
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1;
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0;
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1;
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2;
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3;
gl_TessCoord.y = 1.0 - gl_TessCoord.y;
out.gl_Position = float4(((gl_TessCoord.x * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[3])) + (((1.0 - gl_TessCoord.y) * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[1])), 0.0, 1.0);
return out;
}

View File

@@ -0,0 +1,35 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_patchIn
{
float gl_TessLevelInner_0 [[attribute(0)]];
float gl_TessLevelInner_1 [[attribute(1)]];
float gl_TessLevelOuter_0 [[attribute(2)]];
float gl_TessLevelOuter_1 [[attribute(3)]];
float gl_TessLevelOuter_2 [[attribute(4)]];
float gl_TessLevelOuter_3 [[attribute(5)]];
};
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], float2 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
float gl_TessLevelInner[2] = {};
float gl_TessLevelOuter[4] = {};
gl_TessLevelInner[0] = patchIn.gl_TessLevelInner_0;
gl_TessLevelInner[1] = patchIn.gl_TessLevelInner_1;
gl_TessLevelOuter[0] = patchIn.gl_TessLevelOuter_0;
gl_TessLevelOuter[1] = patchIn.gl_TessLevelOuter_1;
gl_TessLevelOuter[2] = patchIn.gl_TessLevelOuter_2;
gl_TessLevelOuter[3] = patchIn.gl_TessLevelOuter_3;
out.gl_Position = float4(((gl_TessCoord.x * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[0])) + (((1.0 - gl_TessCoord.x) * as_type<float>(gl_TessLevelInner[0])) * as_type<float>(gl_TessLevelOuter[2])), ((gl_TessCoord.y * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[1])) + (((1.0 - gl_TessCoord.y) * as_type<float>(gl_TessLevelInner[1])) * as_type<float>(gl_TessLevelOuter[3])), 0.0, 1.0);
return out;
}

View File

@@ -0,0 +1,62 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct Block
{
float4 a;
float4 b;
};
struct Foo
{
float4 a;
float4 b;
};
struct main0_out
{
float4 gl_Position [[position]];
};
struct main0_in
{
float4 vColor [[attribute(0)]];
float4 Block_a [[attribute(2)]];
float4 Block_b [[attribute(3)]];
};
struct main0_patchIn
{
float4 vColors [[attribute(1)]];
float4 Foo_a [[attribute(4)]];
float4 Foo_b [[attribute(5)]];
patch_control_point<main0_in> gl_in;
};
void set_from_function(thread float4& gl_Position, thread patch_control_point<main0_in>& gl_in, thread float4& vColors, thread Foo& vFoo)
{
gl_Position = gl_in[0].Block_a;
gl_Position += gl_in[0].Block_b;
gl_Position += gl_in[1].Block_a;
gl_Position += gl_in[1].Block_b;
gl_Position += gl_in[0].vColor;
gl_Position += gl_in[1].vColor;
gl_Position += vColors;
gl_Position += vFoo.a;
gl_Position += vFoo.b;
}
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
{
main0_out out = {};
Foo vFoo = {};
vFoo.a = patchIn.Foo_a;
vFoo.b = patchIn.Foo_b;
set_from_function(out.gl_Position, patchIn.gl_in, patchIn.vColors, vFoo);
return out;
}

View File

@@ -0,0 +1,17 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
};
[[ patch(triangle, 0) ]] vertex main0_out main0()
{
main0_out out = {};
out.gl_Position = float4(1.0);
return out;
}

View File

@@ -0,0 +1,72 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct UBO
{
float4x4 uMVP;
float4 uScale;
float2 uInvScale;
float3 uCamPos;
float2 uPatchSize;
float2 uInvHeightmapSize;
};
struct main0_out
{
float3 vWorld [[user(locn0)]];
float4 vGradNormalTex [[user(locn1)]];
float4 gl_Position [[position]];
};
struct main0_patchIn
{
float2 vOutPatchPosBase [[attribute(0)]];
float4 vPatchLods [[attribute(1)]];
};
float2 lerp_vertex(thread const float2& tess_coord, thread float2& vOutPatchPosBase, constant UBO& v_31)
{
return vOutPatchPosBase + (tess_coord * v_31.uPatchSize);
}
float2 lod_factor(thread const float2& tess_coord, thread float4& vPatchLods)
{
float2 x = mix(vPatchLods.yx, vPatchLods.zw, float2(tess_coord.x));
float level = mix(x.x, x.y, tess_coord.y);
float floor_level = floor(level);
float fract_level = level - floor_level;
return float2(floor_level, fract_level);
}
float3 sample_height_displacement(thread const float2& uv, thread const float2& off, thread const float2& lod, thread texture2d<float> uHeightmapDisplacement, thread const sampler uHeightmapDisplacementSmplr)
{
return mix(uHeightmapDisplacement.sample(uHeightmapDisplacementSmplr, (uv + (off * 0.5)), level(lod.x)).xyz, uHeightmapDisplacement.sample(uHeightmapDisplacementSmplr, (uv + (off * 1.0)), level(lod.x + 1.0)).xyz, float3(lod.y));
}
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]], constant UBO& v_31 [[buffer(1)]], texture2d<float> uHeightmapDisplacement [[texture(0)]], sampler uHeightmapDisplacementSmplr [[sampler(0)]], float2 gl_TessCoord [[position_in_patch]])
{
main0_out out = {};
float2 tess_coord = float3(gl_TessCoord, 0).xy;
float2 param = tess_coord;
float2 pos = lerp_vertex(param, patchIn.vOutPatchPosBase, v_31);
float2 param_1 = tess_coord;
float2 lod = lod_factor(param_1, patchIn.vPatchLods);
float2 tex = pos * v_31.uInvHeightmapSize;
pos *= v_31.uScale.xy;
float delta_mod = exp2(lod.x);
float2 off = v_31.uInvHeightmapSize * delta_mod;
out.vGradNormalTex = float4(tex + (v_31.uInvHeightmapSize * 0.5), tex * v_31.uScale.zw);
float2 param_2 = tex;
float2 param_3 = off;
float2 param_4 = lod;
float3 height_displacement = sample_height_displacement(param_2, param_3, param_4, uHeightmapDisplacement, uHeightmapDisplacementSmplr);
pos += height_displacement.yz;
out.vWorld = float3(pos.x, height_displacement.x, pos.y);
out.gl_Position = v_31.uMVP * float4(out.vWorld, 1.0);
return out;
}

View File

@@ -0,0 +1,20 @@
#version 450
layout(binding = 0) uniform sampler2DMS uSampled;
layout(location = 0) out vec4 FragColor;
layout(location = 0) in vec2 vUV;
void main()
{
FragColor = vec4(0.0);
if (gl_FragCoord.x < 10.0)
{
FragColor += texelFetch(uSampled, ivec2(vUV), 0);
}
else
{
FragColor += texelFetch(uSampled, ivec2(vUV), 1);
}
}

View File

@@ -1,19 +1,19 @@
{
"entryPoints" : [
{
"name" : "main",
"mode" : "vert"
},
{
"name" : "main2",
"name" : "maim",
"mode" : "vert"
},
{
"name" : "main",
"mode" : "vert"
},
{
"name" : "maim",
"mode" : "frag"
},
{
"name" : "main2",
"name" : "main",
"mode" : "frag"
}
],

View File

@@ -0,0 +1,13 @@
#version 450
uniform sampler2D SPIRV_Cross_Combinedg_Textureg_Sampler;
uniform sampler2DShadow SPIRV_Cross_Combinedg_Textureg_CompareSampler;
layout(location = 0) in vec2 in_var_TEXCOORD0;
layout(location = 0) out float out_var_SV_Target;
void main()
{
out_var_SV_Target = texture(SPIRV_Cross_Combinedg_Textureg_Sampler, in_var_TEXCOORD0).x + textureLod(SPIRV_Cross_Combinedg_Textureg_CompareSampler, vec3(in_var_TEXCOORD0, 0.5), 0.0);
}

View File

@@ -0,0 +1,45 @@
#version 450
struct V2F
{
vec4 Position;
vec4 Color;
};
struct InstanceData
{
mat4 MATRIX_MVP;
vec4 Color;
};
layout(binding = 0, std430) readonly buffer gInstanceData
{
layout(row_major) InstanceData _data[];
} gInstanceData_1;
layout(location = 0) in vec3 PosL;
uniform int SPIRV_Cross_BaseInstance;
layout(location = 0) out vec4 _entryPointOutput_Color;
V2F _VS(vec3 PosL_1, uint instanceID)
{
InstanceData instData;
instData.MATRIX_MVP = gInstanceData_1._data[instanceID].MATRIX_MVP;
instData.Color = gInstanceData_1._data[instanceID].Color;
V2F v2f;
v2f.Position = instData.MATRIX_MVP * vec4(PosL_1, 1.0);
v2f.Color = instData.Color;
return v2f;
}
void main()
{
vec3 PosL_1 = PosL;
uint instanceID = uint((gl_InstanceID + SPIRV_Cross_BaseInstance));
vec3 param = PosL_1;
uint param_1 = instanceID;
V2F flattenTemp = _VS(param, param_1);
gl_Position = flattenTemp.Position;
_entryPointOutput_Color = flattenTemp.Color;
}

View File

@@ -27,7 +27,7 @@ void main()
{
uint ident = gl_GlobalInvocationID.x;
f16vec2 a = int16BitsToFloat16(_25.inputs[ident].xy);
_39.outputs[ident].x = int(packFloat2x16(a + f16vec2(1.0hf)));
_39.outputs[ident].x = int(packFloat2x16(a + f16vec2(float16_t(1.0))));
_39.outputs[ident].y = packInt2x16(_25.inputs[ident].zw);
_39.outputs[ident].z = int(packUint2x16(u16vec2(_25.inputs[ident].xy)));
}

View File

@@ -30,19 +30,19 @@ f16mat3 test_mat3(f16vec3 a, f16vec3 b, f16vec3 c, f16vec3 d, f16vec3 e, f16vec3
void test_constants()
{
float16_t a = 1.0hf;
float16_t b = 1.5hf;
float16_t c = -1.5hf;
float16_t d = (0.0hf / 0.0hf);
float16_t e = (1.0hf / 0.0hf);
float16_t f = (-1.0hf / 0.0hf);
float16_t g = 1014.0hf;
float16_t h = 9.5367431640625e-07hf;
float16_t a = float16_t(1.0);
float16_t b = float16_t(1.5);
float16_t c = float16_t(-1.5);
float16_t d = float16_t(0.0 / 0.0);
float16_t e = float16_t(1.0 / 0.0);
float16_t f = float16_t(-1.0 / 0.0);
float16_t g = float16_t(1014.0);
float16_t h = float16_t(9.5367431640625e-07);
}
float16_t test_result()
{
return 1.0hf;
return float16_t(1.0);
}
void test_conversions()
@@ -50,7 +50,7 @@ void test_conversions()
float16_t one = test_result();
int a = int(one);
uint b = uint(one);
bool c = one != 0.0hf;
bool c = one != float16_t(0.0);
float d = float(one);
double e = double(one);
float16_t a2 = float16_t(a);

View File

@@ -18,7 +18,7 @@ layout(location = 2) out uint16_t baz;
void main()
{
foo = 1.0hf;
foo = float16_t(1.0);
bar = 2s;
baz = 3us;
}

View File

@@ -0,0 +1,61 @@
; SPIR-V
; Version: 1.0
; Generator: Google spiregg; 0
; Bound: 32
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %in_var_TEXCOORD0 %out_var_SV_Target
OpExecutionMode %main OriginUpperLeft
OpSource HLSL 600
OpName %type_2d_image "type.2d.image"
OpName %g_Texture "g_Texture"
OpName %type_sampler "type.sampler"
OpName %g_Sampler "g_Sampler"
OpName %g_CompareSampler "g_CompareSampler"
OpName %in_var_TEXCOORD0 "in.var.TEXCOORD0"
OpName %out_var_SV_Target "out.var.SV_Target"
OpName %main "main"
OpName %type_sampled_image "type.sampled.image"
OpDecorate %in_var_TEXCOORD0 Location 0
OpDecorate %out_var_SV_Target Location 0
OpDecorate %g_Texture DescriptorSet 0
OpDecorate %g_Texture Binding 0
OpDecorate %g_Sampler DescriptorSet 0
OpDecorate %g_Sampler Binding 0
OpDecorate %g_CompareSampler DescriptorSet 0
OpDecorate %g_CompareSampler Binding 1
%float = OpTypeFloat 32
%float_0_5 = OpConstant %float 0.5
%float_0 = OpConstant %float 0
%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
%type_sampler = OpTypeSampler
%_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
%v2float = OpTypeVector %float 2
%_ptr_Input_v2float = OpTypePointer Input %v2float
%_ptr_Output_float = OpTypePointer Output %float
%void = OpTypeVoid
%19 = OpTypeFunction %void
%type_sampled_image = OpTypeSampledImage %type_2d_image
%v4float = OpTypeVector %float 4
%g_Texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
%g_Sampler = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
%g_CompareSampler = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
%in_var_TEXCOORD0 = OpVariable %_ptr_Input_v2float Input
%out_var_SV_Target = OpVariable %_ptr_Output_float Output
%main = OpFunction %void None %19
%21 = OpLabel
%22 = OpLoad %v2float %in_var_TEXCOORD0
%23 = OpLoad %type_2d_image %g_Texture
%24 = OpLoad %type_sampler %g_Sampler
%25 = OpSampledImage %type_sampled_image %23 %24
%26 = OpImageSampleImplicitLod %v4float %25 %22 None
%27 = OpCompositeExtract %float %26 0
%28 = OpLoad %type_sampler %g_CompareSampler
%29 = OpSampledImage %type_sampled_image %23 %28
%30 = OpImageSampleDrefExplicitLod %float %29 %22 %float_0_5 Lod %float_0
%31 = OpFAdd %float %27 %30
OpStore %out_var_SV_Target %31
OpReturn
OpFunctionEnd

View File

@@ -0,0 +1,141 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 79
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %VS "main" %PosL_1 %instanceID_1 %_entryPointOutput_Position %_entryPointOutput_Color
OpSource HLSL 500
OpName %VS "VS"
OpName %V2F "V2F"
OpMemberName %V2F 0 "Position"
OpMemberName %V2F 1 "Color"
OpName %_VS_vf3_u1_ "@VS(vf3;u1;"
OpName %PosL "PosL"
OpName %instanceID "instanceID"
OpName %InstanceData "InstanceData"
OpMemberName %InstanceData 0 "MATRIX_MVP"
OpMemberName %InstanceData 1 "Color"
OpName %instData "instData"
OpName %InstanceData_0 "InstanceData"
OpMemberName %InstanceData_0 0 "MATRIX_MVP"
OpMemberName %InstanceData_0 1 "Color"
OpName %gInstanceData "gInstanceData"
OpMemberName %gInstanceData 0 "@data"
OpName %gInstanceData_0 "gInstanceData"
OpName %v2f "v2f"
OpName %PosL_0 "PosL"
OpName %PosL_1 "PosL"
OpName %instanceID_0 "instanceID"
OpName %instanceID_1 "instanceID"
OpName %flattenTemp "flattenTemp"
OpName %param "param"
OpName %param_0 "param"
OpName %_entryPointOutput_Position "@entryPointOutput.Position"
OpName %_entryPointOutput_Color "@entryPointOutput.Color"
OpMemberDecorate %InstanceData_0 0 RowMajor
OpMemberDecorate %InstanceData_0 0 Offset 0
OpMemberDecorate %InstanceData_0 0 MatrixStride 16
OpMemberDecorate %InstanceData_0 1 Offset 64
OpDecorate %_runtimearr_InstanceData_0 ArrayStride 80
OpMemberDecorate %gInstanceData 0 Offset 0
OpDecorate %gInstanceData Block
OpDecorate %gInstanceData_0 DescriptorSet 1
OpDecorate %gInstanceData_0 Binding 0
OpDecorate %PosL_1 Location 0
OpDecorate %instanceID_1 BuiltIn InstanceIndex
OpDecorate %_entryPointOutput_Position BuiltIn Position
OpDecorate %_entryPointOutput_Color Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v3float = OpTypeVector %float 3
%_ptr_Function_v3float = OpTypePointer Function %v3float
%uint = OpTypeInt 32 0
%int_32 = OpConstant %uint 32
%_ptr_Function_uint = OpTypePointer Function %uint
%v4float = OpTypeVector %float 4
%V2F = OpTypeStruct %v4float %v4float
%13 = OpTypeFunction %V2F %_ptr_Function_v3float %_ptr_Function_uint
%mat4v4float = OpTypeMatrix %v4float 4
%InstanceData = OpTypeStruct %mat4v4float %v4float
%_ptr_Function_InstanceData = OpTypePointer Function %InstanceData
%InstanceData_0 = OpTypeStruct %mat4v4float %v4float
%_runtimearr_InstanceData_0 = OpTypeArray %InstanceData_0 %int_32
%gInstanceData = OpTypeStruct %_runtimearr_InstanceData_0
%_ptr_Uniform_gInstanceData = OpTypePointer Uniform %gInstanceData
%gInstanceData_0 = OpVariable %_ptr_Uniform_gInstanceData Uniform
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%_ptr_Uniform_InstanceData_0 = OpTypePointer Uniform %InstanceData_0
%_ptr_Function_mat4v4float = OpTypePointer Function %mat4v4float
%int_1 = OpConstant %int 1
%_ptr_Function_v4float = OpTypePointer Function %v4float
%_ptr_Function_V2F = OpTypePointer Function %V2F
%float_1 = OpConstant %float 1
%_ptr_Input_v3float = OpTypePointer Input %v3float
%PosL_1 = OpVariable %_ptr_Input_v3float Input
%_ptr_Input_uint = OpTypePointer Input %uint
%instanceID_1 = OpVariable %_ptr_Input_uint Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_Position = OpVariable %_ptr_Output_v4float Output
%_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
%VS = OpFunction %void None %3
%5 = OpLabel
%PosL_0 = OpVariable %_ptr_Function_v3float Function
%instanceID_0 = OpVariable %_ptr_Function_uint Function
%flattenTemp = OpVariable %_ptr_Function_V2F Function
%param = OpVariable %_ptr_Function_v3float Function
%param_0 = OpVariable %_ptr_Function_uint Function
%61 = OpLoad %v3float %PosL_1
OpStore %PosL_0 %61
%65 = OpLoad %uint %instanceID_1
OpStore %instanceID_0 %65
%68 = OpLoad %v3float %PosL_0
OpStore %param %68
%70 = OpLoad %uint %instanceID_0
OpStore %param_0 %70
%71 = OpFunctionCall %V2F %_VS_vf3_u1_ %param %param_0
OpStore %flattenTemp %71
%74 = OpAccessChain %_ptr_Function_v4float %flattenTemp %int_0
%75 = OpLoad %v4float %74
OpStore %_entryPointOutput_Position %75
%77 = OpAccessChain %_ptr_Function_v4float %flattenTemp %int_1
%78 = OpLoad %v4float %77
OpStore %_entryPointOutput_Color %78
OpReturn
OpFunctionEnd
%_VS_vf3_u1_ = OpFunction %V2F None %13
%PosL = OpFunctionParameter %_ptr_Function_v3float
%instanceID = OpFunctionParameter %_ptr_Function_uint
%17 = OpLabel
%instData = OpVariable %_ptr_Function_InstanceData Function
%v2f = OpVariable %_ptr_Function_V2F Function
%29 = OpLoad %uint %instanceID
%31 = OpAccessChain %_ptr_Uniform_InstanceData_0 %gInstanceData_0 %int_0 %29
%32 = OpLoad %InstanceData_0 %31
%33 = OpCompositeExtract %mat4v4float %32 0
%35 = OpAccessChain %_ptr_Function_mat4v4float %instData %int_0
OpStore %35 %33
%36 = OpCompositeExtract %v4float %32 1
%39 = OpAccessChain %_ptr_Function_v4float %instData %int_1
OpStore %39 %36
%42 = OpAccessChain %_ptr_Function_mat4v4float %instData %int_0
%43 = OpLoad %mat4v4float %42
%44 = OpLoad %v3float %PosL
%46 = OpCompositeExtract %float %44 0
%47 = OpCompositeExtract %float %44 1
%48 = OpCompositeExtract %float %44 2
%49 = OpCompositeConstruct %v4float %46 %47 %48 %float_1
%50 = OpMatrixTimesVector %v4float %43 %49
%51 = OpAccessChain %_ptr_Function_v4float %v2f %int_0
OpStore %51 %50
%52 = OpAccessChain %_ptr_Function_v4float %instData %int_1
%53 = OpLoad %v4float %52
%54 = OpAccessChain %_ptr_Function_v4float %v2f %int_1
OpStore %54 %53
%55 = OpLoad %V2F %v2f
OpReturnValue %55
OpFunctionEnd

View File

@@ -0,0 +1,61 @@
; SPIR-V
; Version: 1.0
; Generator: Google spiregg; 0
; Bound: 32
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %in_var_TEXCOORD0 %out_var_SV_Target
OpExecutionMode %main OriginUpperLeft
OpSource HLSL 600
OpName %type_2d_image "type.2d.image"
OpName %g_Texture "g_Texture"
OpName %type_sampler "type.sampler"
OpName %g_Sampler "g_Sampler"
OpName %g_CompareSampler "g_CompareSampler"
OpName %in_var_TEXCOORD0 "in.var.TEXCOORD0"
OpName %out_var_SV_Target "out.var.SV_Target"
OpName %main "main"
OpName %type_sampled_image "type.sampled.image"
OpDecorate %in_var_TEXCOORD0 Location 0
OpDecorate %out_var_SV_Target Location 0
OpDecorate %g_Texture DescriptorSet 0
OpDecorate %g_Texture Binding 0
OpDecorate %g_Sampler DescriptorSet 0
OpDecorate %g_Sampler Binding 0
OpDecorate %g_CompareSampler DescriptorSet 0
OpDecorate %g_CompareSampler Binding 1
%float = OpTypeFloat 32
%float_0_5 = OpConstant %float 0.5
%float_0 = OpConstant %float 0
%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
%type_sampler = OpTypeSampler
%_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
%v2float = OpTypeVector %float 2
%_ptr_Input_v2float = OpTypePointer Input %v2float
%_ptr_Output_float = OpTypePointer Output %float
%void = OpTypeVoid
%19 = OpTypeFunction %void
%type_sampled_image = OpTypeSampledImage %type_2d_image
%v4float = OpTypeVector %float 4
%g_Texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
%g_Sampler = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
%g_CompareSampler = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
%in_var_TEXCOORD0 = OpVariable %_ptr_Input_v2float Input
%out_var_SV_Target = OpVariable %_ptr_Output_float Output
%main = OpFunction %void None %19
%21 = OpLabel
%22 = OpLoad %v2float %in_var_TEXCOORD0
%23 = OpLoad %type_2d_image %g_Texture
%24 = OpLoad %type_sampler %g_Sampler
%25 = OpSampledImage %type_sampled_image %23 %24
%26 = OpImageSampleImplicitLod %v4float %25 %22 None
%27 = OpCompositeExtract %float %26 0
%28 = OpLoad %type_sampler %g_CompareSampler
%29 = OpSampledImage %type_sampled_image %23 %28
%30 = OpImageSampleDrefExplicitLod %float %29 %22 %float_0_5 Lod %float_0
%31 = OpFAdd %float %27 %30
OpStore %out_var_SV_Target %31
OpReturn
OpFunctionEnd

View File

@@ -0,0 +1,102 @@
; SPIR-V
; Version: 1.3
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 46
; Schema: 0
OpCapability Tessellation
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint TessellationControl %main "main" %gl_TessLevelInner %gl_TessLevelOuter
OpExecutionMode %main OutputVertices 1
OpExecutionMode %main Triangles
OpSource ESSL 310
OpSourceExtension "GL_EXT_shader_io_blocks"
OpSourceExtension "GL_EXT_tessellation_shader"
OpName %main "main"
OpName %gl_TessLevelInner "gl_TessLevelInner"
OpName %TessLevels "TessLevels"
OpMemberName %TessLevels 0 "inner0"
OpMemberName %TessLevels 1 "inner1"
OpMemberName %TessLevels 2 "outer0"
OpMemberName %TessLevels 3 "outer1"
OpMemberName %TessLevels 4 "outer2"
OpMemberName %TessLevels 5 "outer3"
OpName %sb_levels "sb_levels"
OpName %gl_TessLevelOuter "gl_TessLevelOuter"
OpDecorate %gl_TessLevelInner Patch
OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
OpMemberDecorate %TessLevels 0 Restrict
OpMemberDecorate %TessLevels 0 NonWritable
OpMemberDecorate %TessLevels 0 Offset 0
OpMemberDecorate %TessLevels 1 Restrict
OpMemberDecorate %TessLevels 1 NonWritable
OpMemberDecorate %TessLevels 1 Offset 4
OpMemberDecorate %TessLevels 2 Restrict
OpMemberDecorate %TessLevels 2 NonWritable
OpMemberDecorate %TessLevels 2 Offset 8
OpMemberDecorate %TessLevels 3 Restrict
OpMemberDecorate %TessLevels 3 NonWritable
OpMemberDecorate %TessLevels 3 Offset 12
OpMemberDecorate %TessLevels 4 Restrict
OpMemberDecorate %TessLevels 4 NonWritable
OpMemberDecorate %TessLevels 4 Offset 16
OpMemberDecorate %TessLevels 5 Restrict
OpMemberDecorate %TessLevels 5 NonWritable
OpMemberDecorate %TessLevels 5 Offset 20
OpDecorate %TessLevels Block
OpDecorate %sb_levels DescriptorSet 0
OpDecorate %sb_levels Binding 0
OpDecorate %gl_TessLevelOuter Patch
OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%uint = OpTypeInt 32 0
%uint_2 = OpConstant %uint 2
%_arr_float_uint_2 = OpTypeArray %float %uint_2
%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2
%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%TessLevels = OpTypeStruct %float %float %float %float %float %float
%_ptr_StorageBuffer_TessLevels = OpTypePointer StorageBuffer %TessLevels
%sb_levels = OpVariable %_ptr_StorageBuffer_TessLevels StorageBuffer
%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
%_ptr_Output_float = OpTypePointer Output %float
%int_1 = OpConstant %int 1
%uint_4 = OpConstant %uint 4
%_arr_float_uint_4 = OpTypeArray %float %uint_4
%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output
%int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3
%int_4 = OpConstant %int 4
%int_5 = OpConstant %int 5
%main = OpFunction %void None %3
%5 = OpLabel
%18 = OpAccessChain %_ptr_StorageBuffer_float %sb_levels %int_0
%19 = OpLoad %float %18
%21 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0
OpStore %21 %19
%23 = OpAccessChain %_ptr_StorageBuffer_float %sb_levels %int_1
%24 = OpLoad %float %23
%25 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1
OpStore %25 %24
%31 = OpAccessChain %_ptr_StorageBuffer_float %sb_levels %int_2
%32 = OpLoad %float %31
%33 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0
OpStore %33 %32
%35 = OpAccessChain %_ptr_StorageBuffer_float %sb_levels %int_3
%36 = OpLoad %float %35
%37 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1
OpStore %37 %36
%39 = OpAccessChain %_ptr_StorageBuffer_float %sb_levels %int_4
%40 = OpLoad %float %39
%41 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2
OpStore %41 %40
%43 = OpAccessChain %_ptr_StorageBuffer_float %sb_levels %int_5
%44 = OpLoad %float %43
%45 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3
OpStore %45 %44
OpReturn
OpFunctionEnd

View File

@@ -0,0 +1,96 @@
; SPIR-V
; Version: 1.3
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 72
; Schema: 0
OpCapability Tessellation
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint TessellationEvaluation %main "main" %_ %gl_TessCoord %gl_TessLevelInner %gl_TessLevelOuter
OpExecutionMode %main Quads
OpExecutionMode %main SpacingFractionalEven
OpExecutionMode %main VertexOrderCw
OpSource ESSL 310
OpSourceExtension "GL_EXT_shader_io_blocks"
OpSourceExtension "GL_EXT_tessellation_shader"
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
OpDecorate %gl_PerVertex Block
OpDecorate %gl_TessCoord BuiltIn TessCoord
OpDecorate %gl_TessLevelInner Patch
OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
OpDecorate %gl_TessLevelOuter Patch
OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%gl_PerVertex = OpTypeStruct %v4float %float
%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
%_ = OpVariable %_ptr_Output_gl_PerVertex Output
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%v3float = OpTypeVector %float 3
%_ptr_Input_v3float = OpTypePointer Input %v3float
%gl_TessCoord = OpVariable %_ptr_Input_v3float Input
%uint = OpTypeInt 32 0
%uint_0 = OpConstant %uint 0
%_ptr_Input_float = OpTypePointer Input %float
%uint_2 = OpConstant %uint 2
%_arr_float_uint_2 = OpTypeArray %float %uint_2
%_ptr_Input__arr_float_uint_2 = OpTypePointer Input %_arr_float_uint_2
%gl_TessLevelInner = OpVariable %_ptr_Input__arr_float_uint_2 Input
%uint_4 = OpConstant %uint 4
%_arr_float_uint_4 = OpTypeArray %float %uint_4
%_ptr_Input__arr_float_uint_4 = OpTypePointer Input %_arr_float_uint_4
%gl_TessLevelOuter = OpVariable %_ptr_Input__arr_float_uint_4 Input
%float_1 = OpConstant %float 1
%int_2 = OpConstant %int 2
%uint_1 = OpConstant %uint 1
%int_1 = OpConstant %int 1
%int_3 = OpConstant %int 3
%float_0 = OpConstant %float 0
%_ptr_Output_v4float = OpTypePointer Output %v4float
%main = OpFunction %void None %3
%5 = OpLabel
%19 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_0
%20 = OpLoad %float %19
%25 = OpAccessChain %_ptr_Input_float %gl_TessLevelInner %int_0
%26 = OpLoad %float %25
%27 = OpFMul %float %20 %26
%32 = OpAccessChain %_ptr_Input_float %gl_TessLevelOuter %int_0
%33 = OpLoad %float %32
%34 = OpFMul %float %27 %33
%36 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_0
%37 = OpLoad %float %36
%38 = OpFSub %float %float_1 %37
%39 = OpAccessChain %_ptr_Input_float %gl_TessLevelInner %int_0
%40 = OpLoad %float %39
%41 = OpFMul %float %38 %40
%43 = OpAccessChain %_ptr_Input_float %gl_TessLevelOuter %int_2
%44 = OpLoad %float %43
%45 = OpFMul %float %41 %44
%46 = OpFAdd %float %34 %45
%48 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_1
%49 = OpLoad %float %48
%51 = OpAccessChain %_ptr_Input_float %gl_TessLevelInner %int_1
%52 = OpLoad %float %51
%53 = OpFMul %float %49 %52
%54 = OpAccessChain %_ptr_Input_float %gl_TessLevelOuter %int_1
%55 = OpLoad %float %54
%56 = OpFMul %float %53 %55
%57 = OpAccessChain %_ptr_Input_float %gl_TessCoord %uint_1
%58 = OpLoad %float %57
%59 = OpFSub %float %float_1 %58
%60 = OpAccessChain %_ptr_Input_float %gl_TessLevelInner %int_1
%61 = OpLoad %float %60
%62 = OpFMul %float %59 %61
%64 = OpAccessChain %_ptr_Input_float %gl_TessLevelOuter %int_3
%65 = OpLoad %float %64
%66 = OpFMul %float %62 %65
%67 = OpFAdd %float %56 %66
%69 = OpCompositeConstruct %v4float %46 %67 %float_0 %float_1
%71 = OpAccessChain %_ptr_Output_v4float %_ %int_0
OpStore %71 %69
OpReturn
OpFunctionEnd

View File

@@ -0,0 +1,141 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 79
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %VS "main" %PosL_1 %instanceID_1 %_entryPointOutput_Position %_entryPointOutput_Color
OpSource HLSL 500
OpName %VS "VS"
OpName %V2F "V2F"
OpMemberName %V2F 0 "Position"
OpMemberName %V2F 1 "Color"
OpName %_VS_vf3_u1_ "@VS(vf3;u1;"
OpName %PosL "PosL"
OpName %instanceID "instanceID"
OpName %InstanceData "InstanceData"
OpMemberName %InstanceData 0 "MATRIX_MVP"
OpMemberName %InstanceData 1 "Color"
OpName %instData "instData"
OpName %InstanceData_0 "InstanceData"
OpMemberName %InstanceData_0 0 "MATRIX_MVP"
OpMemberName %InstanceData_0 1 "Color"
OpName %gInstanceData "gInstanceData"
OpMemberName %gInstanceData 0 "@data"
OpName %gInstanceData_0 "gInstanceData"
OpName %v2f "v2f"
OpName %PosL_0 "PosL"
OpName %PosL_1 "PosL"
OpName %instanceID_0 "instanceID"
OpName %instanceID_1 "instanceID"
OpName %flattenTemp "flattenTemp"
OpName %param "param"
OpName %param_0 "param"
OpName %_entryPointOutput_Position "@entryPointOutput.Position"
OpName %_entryPointOutput_Color "@entryPointOutput.Color"
OpMemberDecorate %InstanceData_0 0 RowMajor
OpMemberDecorate %InstanceData_0 0 Offset 0
OpMemberDecorate %InstanceData_0 0 MatrixStride 16
OpMemberDecorate %InstanceData_0 1 Offset 64
OpDecorate %_runtimearr_InstanceData_0 ArrayStride 80
OpMemberDecorate %gInstanceData 0 NonWritable
OpMemberDecorate %gInstanceData 0 Offset 0
OpDecorate %gInstanceData BufferBlock
OpDecorate %gInstanceData_0 DescriptorSet 1
OpDecorate %gInstanceData_0 Binding 0
OpDecorate %PosL_1 Location 0
OpDecorate %instanceID_1 BuiltIn InstanceIndex
OpDecorate %_entryPointOutput_Position BuiltIn Position
OpDecorate %_entryPointOutput_Color Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v3float = OpTypeVector %float 3
%_ptr_Function_v3float = OpTypePointer Function %v3float
%uint = OpTypeInt 32 0
%_ptr_Function_uint = OpTypePointer Function %uint
%v4float = OpTypeVector %float 4
%V2F = OpTypeStruct %v4float %v4float
%13 = OpTypeFunction %V2F %_ptr_Function_v3float %_ptr_Function_uint
%mat4v4float = OpTypeMatrix %v4float 4
%InstanceData = OpTypeStruct %mat4v4float %v4float
%_ptr_Function_InstanceData = OpTypePointer Function %InstanceData
%InstanceData_0 = OpTypeStruct %mat4v4float %v4float
%_runtimearr_InstanceData_0 = OpTypeRuntimeArray %InstanceData_0
%gInstanceData = OpTypeStruct %_runtimearr_InstanceData_0
%_ptr_Uniform_gInstanceData = OpTypePointer Uniform %gInstanceData
%gInstanceData_0 = OpVariable %_ptr_Uniform_gInstanceData Uniform
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%_ptr_Uniform_InstanceData_0 = OpTypePointer Uniform %InstanceData_0
%_ptr_Function_mat4v4float = OpTypePointer Function %mat4v4float
%int_1 = OpConstant %int 1
%_ptr_Function_v4float = OpTypePointer Function %v4float
%_ptr_Function_V2F = OpTypePointer Function %V2F
%float_1 = OpConstant %float 1
%_ptr_Input_v3float = OpTypePointer Input %v3float
%PosL_1 = OpVariable %_ptr_Input_v3float Input
%_ptr_Input_uint = OpTypePointer Input %uint
%instanceID_1 = OpVariable %_ptr_Input_uint Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_Position = OpVariable %_ptr_Output_v4float Output
%_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
%VS = OpFunction %void None %3
%5 = OpLabel
%PosL_0 = OpVariable %_ptr_Function_v3float Function
%instanceID_0 = OpVariable %_ptr_Function_uint Function
%flattenTemp = OpVariable %_ptr_Function_V2F Function
%param = OpVariable %_ptr_Function_v3float Function
%param_0 = OpVariable %_ptr_Function_uint Function
%61 = OpLoad %v3float %PosL_1
OpStore %PosL_0 %61
%65 = OpLoad %uint %instanceID_1
OpStore %instanceID_0 %65
%68 = OpLoad %v3float %PosL_0
OpStore %param %68
%70 = OpLoad %uint %instanceID_0
OpStore %param_0 %70
%71 = OpFunctionCall %V2F %_VS_vf3_u1_ %param %param_0
OpStore %flattenTemp %71
%74 = OpAccessChain %_ptr_Function_v4float %flattenTemp %int_0
%75 = OpLoad %v4float %74
OpStore %_entryPointOutput_Position %75
%77 = OpAccessChain %_ptr_Function_v4float %flattenTemp %int_1
%78 = OpLoad %v4float %77
OpStore %_entryPointOutput_Color %78
OpReturn
OpFunctionEnd
%_VS_vf3_u1_ = OpFunction %V2F None %13
%PosL = OpFunctionParameter %_ptr_Function_v3float
%instanceID = OpFunctionParameter %_ptr_Function_uint
%17 = OpLabel
%instData = OpVariable %_ptr_Function_InstanceData Function
%v2f = OpVariable %_ptr_Function_V2F Function
%29 = OpLoad %uint %instanceID
%31 = OpAccessChain %_ptr_Uniform_InstanceData_0 %gInstanceData_0 %int_0 %29
%32 = OpLoad %InstanceData_0 %31
%33 = OpCompositeExtract %mat4v4float %32 0
%35 = OpAccessChain %_ptr_Function_mat4v4float %instData %int_0
OpStore %35 %33
%36 = OpCompositeExtract %v4float %32 1
%39 = OpAccessChain %_ptr_Function_v4float %instData %int_1
OpStore %39 %36
%42 = OpAccessChain %_ptr_Function_mat4v4float %instData %int_0
%43 = OpLoad %mat4v4float %42
%44 = OpLoad %v3float %PosL
%46 = OpCompositeExtract %float %44 0
%47 = OpCompositeExtract %float %44 1
%48 = OpCompositeExtract %float %44 2
%49 = OpCompositeConstruct %v4float %46 %47 %48 %float_1
%50 = OpMatrixTimesVector %v4float %43 %49
%51 = OpAccessChain %_ptr_Function_v4float %v2f %int_0
OpStore %51 %50
%52 = OpAccessChain %_ptr_Function_v4float %instData %int_1
%53 = OpLoad %v4float %52
%54 = OpAccessChain %_ptr_Function_v4float %v2f %int_1
OpStore %54 %53
%55 = OpLoad %V2F %v2f
OpReturnValue %55
OpFunctionEnd

View File

@@ -0,0 +1,22 @@
#version 450
layout(cw, triangles, fractional_even_spacing) in;
in gl_PerVertex
{
vec4 gl_Position;
} gl_in[gl_MaxPatchVertices];
out gl_PerVertex
{
vec4 gl_Position;
};
void main()
{
gl_Position =
gl_in[0].gl_Position * gl_TessCoord.x +
gl_in[1].gl_Position * gl_TessCoord.y +
gl_in[2].gl_Position * gl_TessCoord.z;
}

View File

@@ -0,0 +1,15 @@
#version 450
layout(ccw, quads, fractional_odd_spacing) in;
layout(location = 0) in vec4 Floats[];
layout(location = 2) in vec4 Floats2[gl_MaxPatchVertices];
void set_position()
{
gl_Position = Floats[0] * gl_TessCoord.x + Floats2[1] * gl_TessCoord.y;
}
void main()
{
set_position();
}

View File

@@ -0,0 +1,75 @@
#version 450
layout(ccw, quads, fractional_even_spacing) in;
// Try to use the whole taxonomy of input methods.
// Per-vertex vector.
layout(location = 0) in vec4 vColor[];
// Per-patch vector.
layout(location = 1) patch in vec4 vColors;
// Per-patch vector array.
layout(location = 2) patch in vec4 vColorsArray[2];
// I/O blocks, per patch and per control point.
layout(location = 4) in Block
{
vec4 a;
vec4 b;
} blocks[];
layout(location = 6) patch in PatchBlock
{
vec4 a;
vec4 b;
} patch_block;
// Composites.
struct Foo
{
vec4 a;
vec4 b;
};
layout(location = 8) patch in Foo vFoo;
//layout(location = 10) patch in Foo vFooArray[2]; // FIXME: Handling of array-of-struct input is broken!
// Per-control point struct.
layout(location = 14) in Foo vFoos[];
void set_from_function()
{
gl_Position = blocks[0].a;
gl_Position += blocks[0].b;
gl_Position += blocks[1].a;
gl_Position += blocks[1].b;
gl_Position += patch_block.a;
gl_Position += patch_block.b;
gl_Position += vColor[0];
gl_Position += vColor[1];
gl_Position += vColors;
Foo foo = vFoo;
gl_Position += foo.a;
gl_Position += foo.b;
/*foo = vFooArray[0];
gl_Position += foo.a;
gl_Position += foo.b;
foo = vFooArray[1];
gl_Position += foo.a;
gl_Position += foo.b;*/
foo = vFoos[0];
gl_Position += foo.a;
gl_Position += foo.b;
foo = vFoos[1];
gl_Position += foo.a;
gl_Position += foo.b;
}
void main()
{
set_from_function();
}

View File

@@ -0,0 +1,12 @@
#version 310 es
#extension GL_EXT_tessellation_shader : require
layout(cw, quads, fractional_even_spacing) in;
void main()
{
gl_Position = vec4(gl_TessCoord.x * gl_TessLevelInner[0] * gl_TessLevelOuter[0] + (1.0 - gl_TessCoord.x) * gl_TessLevelInner[0] * gl_TessLevelOuter[2],
gl_TessCoord.y * gl_TessLevelInner[1] * gl_TessLevelOuter[3] + (1.0 - gl_TessCoord.y) * gl_TessLevelInner[1] * gl_TessLevelOuter[1],
0, 1);
}

View File

@@ -0,0 +1,12 @@
#version 310 es
#extension GL_EXT_tessellation_shader : require
layout(cw, quads, fractional_even_spacing) in;
void main()
{
gl_Position = vec4(gl_TessCoord.x * gl_TessLevelInner[0] * gl_TessLevelOuter[0] + (1.0 - gl_TessCoord.x) * gl_TessLevelInner[0] * gl_TessLevelOuter[2],
gl_TessCoord.y * gl_TessLevelInner[1] * gl_TessLevelOuter[1] + (1.0 - gl_TessCoord.y) * gl_TessLevelInner[1] * gl_TessLevelOuter[3],
0, 1);
}

View File

@@ -0,0 +1,36 @@
#version 450
layout(ccw, quads, fractional_even_spacing) in;
layout(location = 0) in vec4 vColor[];
layout(location = 1) patch in vec4 vColors;
layout(location = 2) in Block
{
vec4 a;
vec4 b;
} blocks[];
struct Foo
{
vec4 a;
vec4 b;
};
layout(location = 4) patch in Foo vFoo;
void set_from_function()
{
gl_Position = blocks[0].a;
gl_Position += blocks[0].b;
gl_Position += blocks[1].a;
gl_Position += blocks[1].b;
gl_Position += vColor[0];
gl_Position += vColor[1];
gl_Position += vColors;
gl_Position += vFoo.a;
gl_Position += vFoo.b;
}
void main()
{
set_from_function();
}

View File

@@ -0,0 +1,10 @@
#version 310 es
#extension GL_EXT_tessellation_shader : require
layout(cw, triangles, fractional_even_spacing) in;
void main()
{
gl_Position = vec4(1.0);
}

View File

@@ -0,0 +1,65 @@
#version 310 es
#extension GL_EXT_tessellation_shader : require
precision highp int;
layout(cw, quads, fractional_even_spacing) in;
layout(location = 0) patch in vec2 vOutPatchPosBase;
layout(location = 1) patch in vec4 vPatchLods;
layout(binding = 1, std140) uniform UBO
{
mat4 uMVP;
vec4 uScale;
vec2 uInvScale;
vec3 uCamPos;
vec2 uPatchSize;
vec2 uInvHeightmapSize;
};
layout(binding = 0) uniform mediump sampler2D uHeightmapDisplacement;
layout(location = 0) highp out vec3 vWorld;
layout(location = 1) highp out vec4 vGradNormalTex;
vec2 lerp_vertex(vec2 tess_coord)
{
return vOutPatchPosBase + tess_coord * uPatchSize;
}
mediump vec2 lod_factor(vec2 tess_coord)
{
mediump vec2 x = mix(vPatchLods.yx, vPatchLods.zw, tess_coord.x);
mediump float level = mix(x.x, x.y, tess_coord.y);
mediump float floor_level = floor(level);
mediump float fract_level = level - floor_level;
return vec2(floor_level, fract_level);
}
mediump vec3 sample_height_displacement(vec2 uv, vec2 off, mediump vec2 lod)
{
return mix(
textureLod(uHeightmapDisplacement, uv + 0.5 * off, lod.x).xyz,
textureLod(uHeightmapDisplacement, uv + 1.0 * off, lod.x + 1.0).xyz,
lod.y);
}
void main()
{
vec2 tess_coord = gl_TessCoord.xy;
vec2 pos = lerp_vertex(tess_coord);
mediump vec2 lod = lod_factor(tess_coord);
vec2 tex = pos * uInvHeightmapSize.xy;
pos *= uScale.xy;
mediump float delta_mod = exp2(lod.x);
vec2 off = uInvHeightmapSize.xy * delta_mod;
vGradNormalTex = vec4(tex + 0.5 * uInvHeightmapSize.xy, tex * uScale.zw);
vec3 height_displacement = sample_height_displacement(tex, off, lod);
pos += height_displacement.yz;
vWorld = vec3(pos.x, height_displacement.x, pos.y);
gl_Position = uMVP * vec4(vWorld, 1.0);
}

View File

@@ -0,0 +1,78 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 50
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %FragColor %gl_FragCoord %vUV
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpName %main "main"
OpName %FragColor "FragColor"
OpName %gl_FragCoord "gl_FragCoord"
OpName %uSampled "uSampled"
OpName %vUV "vUV"
OpDecorate %FragColor Location 0
OpDecorate %gl_FragCoord BuiltIn FragCoord
OpDecorate %uSampled DescriptorSet 0
OpDecorate %uSampled Binding 0
OpDecorate %vUV Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
%FragColor = OpVariable %_ptr_Output_v4float Output
%float_0 = OpConstant %float 0
%11 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
%_ptr_Input_v4float = OpTypePointer Input %v4float
%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
%uint = OpTypeInt 32 0
%uint_0 = OpConstant %uint 0
%_ptr_Input_float = OpTypePointer Input %float
%float_10 = OpConstant %float 10
%bool = OpTypeBool
%24 = OpTypeImage %float 2D 0 0 1 1 Unknown
%25 = OpTypeSampledImage %24
%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25
%uSampled = OpVariable %_ptr_UniformConstant_25 UniformConstant
%v2float = OpTypeVector %float 2
%_ptr_Input_v2float = OpTypePointer Input %v2float
%vUV = OpVariable %_ptr_Input_v2float Input
%int = OpTypeInt 32 1
%v2int = OpTypeVector %int 2
%int_0 = OpConstant %int 0
%int_1 = OpConstant %int 1
%main = OpFunction %void None %3
%5 = OpLabel
OpStore %FragColor %11
%17 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_0
%18 = OpLoad %float %17
%21 = OpFOrdLessThan %bool %18 %float_10
OpSelectionMerge %23 None
OpBranchConditional %21 %22 %41
%22 = OpLabel
%28 = OpLoad %25 %uSampled
%32 = OpLoad %v2float %vUV
%35 = OpConvertFToS %v2int %32
%64 = OpImage %24 %28
%38 = OpImageFetch %v4float %64 %35 Sample %int_0
%39 = OpLoad %v4float %FragColor
%40 = OpFAdd %v4float %39 %38
OpStore %FragColor %40
OpBranch %23
%41 = OpLabel
%42 = OpLoad %25 %uSampled
%43 = OpLoad %v2float %vUV
%44 = OpConvertFToS %v2int %43
%46 = OpImage %24 %42
%47 = OpImageFetch %v4float %46 %44 Sample %int_1
%48 = OpLoad %v4float %FragColor
%49 = OpFAdd %v4float %48 %47
OpStore %FragColor %49
OpBranch %23
%23 = OpLabel
OpReturn
OpFunctionEnd

View File

@@ -7,9 +7,9 @@
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %_
OpEntryPoint Vertex %main2 "main2" %_
OpEntryPoint Vertex %main2 "maim" %_
OpEntryPoint Fragment %main3 "main" %FragColor
OpEntryPoint Fragment %main4 "main2" %FragColor
OpEntryPoint Fragment %main4 "maim" %FragColor
OpSource GLSL 450
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize

View File

@@ -0,0 +1,61 @@
; SPIR-V
; Version: 1.0
; Generator: Google spiregg; 0
; Bound: 32
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %in_var_TEXCOORD0 %out_var_SV_Target
OpExecutionMode %main OriginUpperLeft
OpSource HLSL 600
OpName %type_2d_image "type.2d.image"
OpName %g_Texture "g_Texture"
OpName %type_sampler "type.sampler"
OpName %g_Sampler "g_Sampler"
OpName %g_CompareSampler "g_CompareSampler"
OpName %in_var_TEXCOORD0 "in.var.TEXCOORD0"
OpName %out_var_SV_Target "out.var.SV_Target"
OpName %main "main"
OpName %type_sampled_image "type.sampled.image"
OpDecorate %in_var_TEXCOORD0 Location 0
OpDecorate %out_var_SV_Target Location 0
OpDecorate %g_Texture DescriptorSet 0
OpDecorate %g_Texture Binding 0
OpDecorate %g_Sampler DescriptorSet 0
OpDecorate %g_Sampler Binding 0
OpDecorate %g_CompareSampler DescriptorSet 0
OpDecorate %g_CompareSampler Binding 1
%float = OpTypeFloat 32
%float_0_5 = OpConstant %float 0.5
%float_0 = OpConstant %float 0
%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
%type_sampler = OpTypeSampler
%_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
%v2float = OpTypeVector %float 2
%_ptr_Input_v2float = OpTypePointer Input %v2float
%_ptr_Output_float = OpTypePointer Output %float
%void = OpTypeVoid
%19 = OpTypeFunction %void
%type_sampled_image = OpTypeSampledImage %type_2d_image
%v4float = OpTypeVector %float 4
%g_Texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
%g_Sampler = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
%g_CompareSampler = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
%in_var_TEXCOORD0 = OpVariable %_ptr_Input_v2float Input
%out_var_SV_Target = OpVariable %_ptr_Output_float Output
%main = OpFunction %void None %19
%21 = OpLabel
%22 = OpLoad %v2float %in_var_TEXCOORD0
%23 = OpLoad %type_2d_image %g_Texture
%24 = OpLoad %type_sampler %g_Sampler
%25 = OpSampledImage %type_sampled_image %23 %24
%26 = OpImageSampleImplicitLod %v4float %25 %22 None
%27 = OpCompositeExtract %float %26 0
%28 = OpLoad %type_sampler %g_CompareSampler
%29 = OpSampledImage %type_sampled_image %23 %28
%30 = OpImageSampleDrefExplicitLod %float %29 %22 %float_0_5 Lod %float_0
%31 = OpFAdd %float %27 %30
OpStore %out_var_SV_Target %31
OpReturn
OpFunctionEnd

View File

@@ -0,0 +1,141 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 79
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %VS "main" %PosL_1 %instanceID_1 %_entryPointOutput_Position %_entryPointOutput_Color
OpSource HLSL 500
OpName %VS "VS"
OpName %V2F "V2F"
OpMemberName %V2F 0 "Position"
OpMemberName %V2F 1 "Color"
OpName %_VS_vf3_u1_ "@VS(vf3;u1;"
OpName %PosL "PosL"
OpName %instanceID "instanceID"
OpName %InstanceData "InstanceData"
OpMemberName %InstanceData 0 "MATRIX_MVP"
OpMemberName %InstanceData 1 "Color"
OpName %instData "instData"
OpName %InstanceData_0 "InstanceData"
OpMemberName %InstanceData_0 0 "MATRIX_MVP"
OpMemberName %InstanceData_0 1 "Color"
OpName %gInstanceData "gInstanceData"
OpMemberName %gInstanceData 0 "@data"
OpName %gInstanceData_0 "gInstanceData"
OpName %v2f "v2f"
OpName %PosL_0 "PosL"
OpName %PosL_1 "PosL"
OpName %instanceID_0 "instanceID"
OpName %instanceID_1 "instanceID"
OpName %flattenTemp "flattenTemp"
OpName %param "param"
OpName %param_0 "param"
OpName %_entryPointOutput_Position "@entryPointOutput.Position"
OpName %_entryPointOutput_Color "@entryPointOutput.Color"
OpMemberDecorate %InstanceData_0 0 RowMajor
OpMemberDecorate %InstanceData_0 0 Offset 0
OpMemberDecorate %InstanceData_0 0 MatrixStride 16
OpMemberDecorate %InstanceData_0 1 Offset 64
OpDecorate %_runtimearr_InstanceData_0 ArrayStride 80
OpMemberDecorate %gInstanceData 0 NonWritable
OpMemberDecorate %gInstanceData 0 Offset 0
OpDecorate %gInstanceData BufferBlock
OpDecorate %gInstanceData_0 DescriptorSet 1
OpDecorate %gInstanceData_0 Binding 0
OpDecorate %PosL_1 Location 0
OpDecorate %instanceID_1 BuiltIn InstanceIndex
OpDecorate %_entryPointOutput_Position BuiltIn Position
OpDecorate %_entryPointOutput_Color Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v3float = OpTypeVector %float 3
%_ptr_Function_v3float = OpTypePointer Function %v3float
%uint = OpTypeInt 32 0
%_ptr_Function_uint = OpTypePointer Function %uint
%v4float = OpTypeVector %float 4
%V2F = OpTypeStruct %v4float %v4float
%13 = OpTypeFunction %V2F %_ptr_Function_v3float %_ptr_Function_uint
%mat4v4float = OpTypeMatrix %v4float 4
%InstanceData = OpTypeStruct %mat4v4float %v4float
%_ptr_Function_InstanceData = OpTypePointer Function %InstanceData
%InstanceData_0 = OpTypeStruct %mat4v4float %v4float
%_runtimearr_InstanceData_0 = OpTypeRuntimeArray %InstanceData_0
%gInstanceData = OpTypeStruct %_runtimearr_InstanceData_0
%_ptr_Uniform_gInstanceData = OpTypePointer Uniform %gInstanceData
%gInstanceData_0 = OpVariable %_ptr_Uniform_gInstanceData Uniform
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%_ptr_Uniform_InstanceData_0 = OpTypePointer Uniform %InstanceData_0
%_ptr_Function_mat4v4float = OpTypePointer Function %mat4v4float
%int_1 = OpConstant %int 1
%_ptr_Function_v4float = OpTypePointer Function %v4float
%_ptr_Function_V2F = OpTypePointer Function %V2F
%float_1 = OpConstant %float 1
%_ptr_Input_v3float = OpTypePointer Input %v3float
%PosL_1 = OpVariable %_ptr_Input_v3float Input
%_ptr_Input_uint = OpTypePointer Input %uint
%instanceID_1 = OpVariable %_ptr_Input_uint Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_Position = OpVariable %_ptr_Output_v4float Output
%_entryPointOutput_Color = OpVariable %_ptr_Output_v4float Output
%VS = OpFunction %void None %3
%5 = OpLabel
%PosL_0 = OpVariable %_ptr_Function_v3float Function
%instanceID_0 = OpVariable %_ptr_Function_uint Function
%flattenTemp = OpVariable %_ptr_Function_V2F Function
%param = OpVariable %_ptr_Function_v3float Function
%param_0 = OpVariable %_ptr_Function_uint Function
%61 = OpLoad %v3float %PosL_1
OpStore %PosL_0 %61
%65 = OpLoad %uint %instanceID_1
OpStore %instanceID_0 %65
%68 = OpLoad %v3float %PosL_0
OpStore %param %68
%70 = OpLoad %uint %instanceID_0
OpStore %param_0 %70
%71 = OpFunctionCall %V2F %_VS_vf3_u1_ %param %param_0
OpStore %flattenTemp %71
%74 = OpAccessChain %_ptr_Function_v4float %flattenTemp %int_0
%75 = OpLoad %v4float %74
OpStore %_entryPointOutput_Position %75
%77 = OpAccessChain %_ptr_Function_v4float %flattenTemp %int_1
%78 = OpLoad %v4float %77
OpStore %_entryPointOutput_Color %78
OpReturn
OpFunctionEnd
%_VS_vf3_u1_ = OpFunction %V2F None %13
%PosL = OpFunctionParameter %_ptr_Function_v3float
%instanceID = OpFunctionParameter %_ptr_Function_uint
%17 = OpLabel
%instData = OpVariable %_ptr_Function_InstanceData Function
%v2f = OpVariable %_ptr_Function_V2F Function
%29 = OpLoad %uint %instanceID
%31 = OpAccessChain %_ptr_Uniform_InstanceData_0 %gInstanceData_0 %int_0 %29
%32 = OpLoad %InstanceData_0 %31
%33 = OpCompositeExtract %mat4v4float %32 0
%35 = OpAccessChain %_ptr_Function_mat4v4float %instData %int_0
OpStore %35 %33
%36 = OpCompositeExtract %v4float %32 1
%39 = OpAccessChain %_ptr_Function_v4float %instData %int_1
OpStore %39 %36
%42 = OpAccessChain %_ptr_Function_mat4v4float %instData %int_0
%43 = OpLoad %mat4v4float %42
%44 = OpLoad %v3float %PosL
%46 = OpCompositeExtract %float %44 0
%47 = OpCompositeExtract %float %44 1
%48 = OpCompositeExtract %float %44 2
%49 = OpCompositeConstruct %v4float %46 %47 %48 %float_1
%50 = OpMatrixTimesVector %v4float %43 %49
%51 = OpAccessChain %_ptr_Function_v4float %v2f %int_0
OpStore %51 %50
%52 = OpAccessChain %_ptr_Function_v4float %instData %int_1
%53 = OpLoad %v4float %52
%54 = OpAccessChain %_ptr_Function_v4float %v2f %int_1
OpStore %54 %53
%55 = OpLoad %V2F %v2f
OpReturnValue %55
OpFunctionEnd

View File

@@ -417,7 +417,8 @@ struct SPIRType : IVariant
Struct,
Image,
SampledImage,
Sampler
Sampler,
ControlPointArray
};
// Scalar/vector/matrix support.
@@ -1381,7 +1382,7 @@ struct Meta
{
uint32_t packed_type = 0;
bool packed = false;
uint32_t ib_member_index = -1;
uint32_t ib_member_index = static_cast<uint32_t>(-1);
uint32_t ib_orig_id = 0;
} extended;
};

View File

@@ -2017,6 +2017,16 @@ ExecutionModel Compiler::get_execution_model() const
return execution.model;
}
bool Compiler::is_tessellation_shader(ExecutionModel model)
{
return model == ExecutionModelTessellationControl || model == ExecutionModelTessellationEvaluation;
}
bool Compiler::is_tessellation_shader() const
{
return is_tessellation_shader(get_execution_model());
}
void Compiler::set_remapped_variable_state(uint32_t id, bool remap_enable)
{
get<SPIRVariable>(id).remapped_variable = remap_enable;
@@ -3043,7 +3053,7 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
}
case OpArrayLength:
// Uses literals, but cannot be a phi variable, so ignore.
// Uses literals, but cannot be a phi variable or temporary, so ignore.
break;
// Atomics shouldn't be able to access function-local variables.
@@ -3062,6 +3072,55 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
notify_variable_access(args[i], current_block->self);
break;
case OpImageWrite:
for (uint32_t i = 0; i < length; i++)
{
// Argument 3 is a literal.
if (i != 3)
notify_variable_access(args[i], current_block->self);
}
break;
case OpImageSampleImplicitLod:
case OpImageSampleExplicitLod:
case OpImageSparseSampleImplicitLod:
case OpImageSparseSampleExplicitLod:
case OpImageSampleProjImplicitLod:
case OpImageSampleProjExplicitLod:
case OpImageSparseSampleProjImplicitLod:
case OpImageSparseSampleProjExplicitLod:
case OpImageFetch:
case OpImageSparseFetch:
case OpImageRead:
case OpImageSparseRead:
for (uint32_t i = 1; i < length; i++)
{
// Argument 4 is a literal.
if (i != 4)
notify_variable_access(args[i], current_block->self);
}
break;
case OpImageSampleDrefImplicitLod:
case OpImageSampleDrefExplicitLod:
case OpImageSparseSampleDrefImplicitLod:
case OpImageSparseSampleDrefExplicitLod:
case OpImageSampleProjDrefImplicitLod:
case OpImageSampleProjDrefExplicitLod:
case OpImageSparseSampleProjDrefImplicitLod:
case OpImageSparseSampleProjDrefExplicitLod:
case OpImageGather:
case OpImageSparseGather:
case OpImageDrefGather:
case OpImageSparseDrefGather:
for (uint32_t i = 1; i < length; i++)
{
// Argument 5 is a literal.
if (i != 5)
notify_variable_access(args[i], current_block->self);
}
break;
default:
{
// Rather dirty way of figuring out where Phi variables are used.
@@ -3300,6 +3359,11 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA
continue;
}
// There is no point in doing domination analysis for opaque types.
auto &type = get<SPIRType>(itr->second);
if (type_is_opaque_value(type))
continue;
DominatorBuilder builder(cfg);
bool force_temporary = false;
@@ -3986,7 +4050,7 @@ bool Compiler::instruction_to_result_type(uint32_t &result_type, uint32_t &resul
return false;
default:
if (length > 1)
if (length > 1 && maybe_get<SPIRType>(args[0]) != nullptr)
{
result_type = args[0];
result_id = args[1];
@@ -4055,3 +4119,9 @@ bool Compiler::image_is_comparison(const spirv_cross::SPIRType &type, uint32_t i
{
return type.image.depth || (comparison_ids.count(id) != 0);
}
bool Compiler::type_is_opaque_value(const spirv_cross::SPIRType &type) const
{
return !type.pointer && (type.basetype == SPIRType::SampledImage || type.basetype == SPIRType::Image ||
type.basetype == SPIRType::Sampler);
}

View File

@@ -360,6 +360,8 @@ public:
uint32_t get_execution_mode_argument(spv::ExecutionMode mode, uint32_t index = 0) const;
spv::ExecutionModel get_execution_model() const;
bool is_tessellation_shader() const;
// In SPIR-V, the compute work group size can be represented by a constant vector, in which case
// the LocalSize execution mode is ignored.
//
@@ -563,7 +565,9 @@ protected:
template <typename T>
T *maybe_get(uint32_t id)
{
if (ir.ids[id].get_type() == static_cast<Types>(T::type))
if (id >= ir.ids.size())
return nullptr;
else if (ir.ids[id].get_type() == static_cast<Types>(T::type))
return &get<T>(id);
else
return nullptr;
@@ -613,6 +617,7 @@ protected:
const SPIREntryPoint &get_entry_point() const;
SPIREntryPoint &get_entry_point();
static bool is_tessellation_shader(spv::ExecutionModel model);
virtual std::string to_name(uint32_t id, bool allow_alias = true) const;
bool is_builtin_variable(const SPIRVariable &var) const;
@@ -979,6 +984,7 @@ private:
void fixup_type_alias();
bool type_is_block_like(const SPIRType &type) const;
bool type_is_opaque_value(const SPIRType &type) const;
};
} // namespace spirv_cross

View File

@@ -2961,51 +2961,31 @@ string CompilerGLSL::convert_half_to_string(const SPIRConstant &c, uint32_t col,
string res;
float float_value = c.scalar_f16(col, row);
// There is no literal "hf" in GL_NV_gpu_shader5, so to avoid lots
// of complicated workarounds, just value-cast to the half type always.
if (std::isnan(float_value) || std::isinf(float_value))
{
if (backend.half_literal_suffix)
{
// There is no uintBitsToFloat for 16-bit, so have to rely on legacy fallback here.
if (float_value == numeric_limits<float>::infinity())
res = join("(1.0", backend.half_literal_suffix, " / 0.0", backend.half_literal_suffix, ")");
else if (float_value == -numeric_limits<float>::infinity())
res = join("(-1.0", backend.half_literal_suffix, " / 0.0", backend.half_literal_suffix, ")");
else if (std::isnan(float_value))
res = join("(0.0", backend.half_literal_suffix, " / 0.0", backend.half_literal_suffix, ")");
else
SPIRV_CROSS_THROW("Cannot represent non-finite floating point constant.");
}
else
{
SPIRType type;
type.basetype = SPIRType::Half;
type.vecsize = 1;
type.columns = 1;
SPIRType type;
type.basetype = SPIRType::Half;
type.vecsize = 1;
type.columns = 1;
if (float_value == numeric_limits<float>::infinity())
res = join(type_to_glsl(type), "(1.0 / 0.0)");
else if (float_value == -numeric_limits<float>::infinity())
res = join(type_to_glsl(type), "(-1.0 / 0.0)");
else if (std::isnan(float_value))
res = join(type_to_glsl(type), "(0.0 / 0.0)");
else
SPIRV_CROSS_THROW("Cannot represent non-finite floating point constant.");
}
if (float_value == numeric_limits<float>::infinity())
res = join(type_to_glsl(type), "(1.0 / 0.0)");
else if (float_value == -numeric_limits<float>::infinity())
res = join(type_to_glsl(type), "(-1.0 / 0.0)");
else if (std::isnan(float_value))
res = join(type_to_glsl(type), "(0.0 / 0.0)");
else
SPIRV_CROSS_THROW("Cannot represent non-finite floating point constant.");
}
else
{
if (backend.half_literal_suffix)
res = convert_to_string(float_value) + backend.half_literal_suffix;
else
{
// In HLSL (FXC), it's important to cast the literals to half precision right away.
// There is no literal for it.
SPIRType type;
type.basetype = SPIRType::Half;
type.vecsize = 1;
type.columns = 1;
res = join(type_to_glsl(type), "(", convert_to_string(float_value), ")");
}
SPIRType type;
type.basetype = SPIRType::Half;
type.vecsize = 1;
type.columns = 1;
res = join(type_to_glsl(type), "(", convert_to_string(float_value), ")");
}
return res;
@@ -4150,6 +4130,29 @@ void CompilerGLSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_i
}
}
static inline bool image_opcode_is_sample_no_dref(Op op)
{
switch (op)
{
case OpImageSampleExplicitLod:
case OpImageSampleImplicitLod:
case OpImageSampleProjExplicitLod:
case OpImageSampleProjImplicitLod:
case OpImageFetch:
case OpImageRead:
case OpImageSparseSampleExplicitLod:
case OpImageSparseSampleImplicitLod:
case OpImageSparseSampleProjExplicitLod:
case OpImageSparseSampleProjImplicitLod:
case OpImageSparseFetch:
case OpImageSparseRead:
return true;
default:
return false;
}
}
void CompilerGLSL::emit_texture_op(const Instruction &i)
{
auto *ops = stream(i);
@@ -4304,6 +4307,20 @@ void CompilerGLSL::emit_texture_op(const Instruction &i)
if (is_legacy() && image_is_comparison(imgtype, img))
expr += ".r";
// Sampling from a texture which was deduced to be a depth image, might actually return 1 component here.
// Remap back to 4 components as sampling opcodes expect.
bool image_is_depth;
const auto *combined = maybe_get<SPIRCombinedImageSampler>(img);
if (combined)
image_is_depth = image_is_comparison(imgtype, combined->image);
else
image_is_depth = image_is_comparison(imgtype, img);
if (image_is_depth && backend.comparison_image_samples_scalar && image_opcode_is_sample_no_dref(op))
{
expr = remap_swizzle(get<SPIRType>(result_type), 1, expr);
}
// Deals with reads from MSL. We might need to downconvert to fewer components.
if (op == OpImageRead)
expr = remap_swizzle(get<SPIRType>(result_type), 4, expr);
@@ -5671,6 +5688,12 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
append_index();
}
if (type->basetype == SPIRType::ControlPointArray)
{
type_id = type->parent_type;
type = &get<SPIRType>(type_id);
}
access_chain_is_arrayed = true;
}
// Arrays
@@ -8934,7 +8957,7 @@ bool CompilerGLSL::is_non_native_row_major_matrix(uint32_t id)
return false;
// Non-matrix or column-major matrix types do not need to be converted.
if (!ir.meta[id].decoration.decoration_flags.get(DecorationRowMajor))
if (!has_decoration(id, DecorationRowMajor))
return false;
// Only square row-major matrices can be converted at this time.
@@ -8955,7 +8978,7 @@ bool CompilerGLSL::member_is_non_native_row_major_matrix(const SPIRType &type, u
return false;
// Non-matrix or column-major matrix types do not need to be converted.
if (!combined_decoration_for_member(type, index).get(DecorationRowMajor))
if (!has_member_decoration(type.self, index, DecorationRowMajor))
return false;
// Only square row-major matrices can be converted at this time.

View File

@@ -380,7 +380,6 @@ protected:
const char *basic_uint8_type = "uint8_t";
const char *basic_int16_type = "int16_t";
const char *basic_uint16_type = "uint16_t";
const char *half_literal_suffix = "hf";
const char *int16_t_literal_suffix = "s";
const char *uint16_t_literal_suffix = "us";
bool swizzle_is_function = false;
@@ -402,6 +401,7 @@ protected:
bool supports_extensions = false;
bool supports_empty_struct = false;
bool array_is_value_type = true;
bool comparison_image_samples_scalar = false;
} backend;
void emit_struct(SPIRType &type);

View File

@@ -4618,7 +4618,6 @@ string CompilerHLSL::compile()
options.vulkan_semantics = true;
backend.float_literal_suffix = true;
backend.double_literal_suffix = false;
backend.half_literal_suffix = nullptr;
backend.long_long_literal_suffix = true;
backend.uint32_t_literal_suffix = true;
backend.int16_t_literal_suffix = nullptr;

View File

@@ -36,7 +36,11 @@ CompilerMSL::CompilerMSL(vector<uint32_t> spirv_, vector<MSLVertexAttr> *p_vtx_a
{
if (p_vtx_attrs)
for (auto &va : *p_vtx_attrs)
{
vtx_attrs_by_location[va.location] = &va;
if (va.builtin != BuiltInMax && !vtx_attrs_by_builtin.count(va.builtin))
vtx_attrs_by_builtin[va.builtin] = &va;
}
if (p_res_bindings)
for (auto &rb : *p_res_bindings)
@@ -49,7 +53,12 @@ CompilerMSL::CompilerMSL(const uint32_t *ir_, size_t word_count, MSLVertexAttr *
{
if (p_vtx_attrs)
for (size_t i = 0; i < vtx_attrs_count; i++)
vtx_attrs_by_location[p_vtx_attrs[i].location] = &p_vtx_attrs[i];
{
auto &va = p_vtx_attrs[i];
vtx_attrs_by_location[va.location] = &va;
if (va.builtin != BuiltInMax && !vtx_attrs_by_builtin.count(va.builtin))
vtx_attrs_by_builtin[va.builtin] = &va;
}
if (p_res_bindings)
for (size_t i = 0; i < res_bindings_count; i++)
@@ -62,7 +71,12 @@ CompilerMSL::CompilerMSL(const ParsedIR &ir_, MSLVertexAttr *p_vtx_attrs, size_t
{
if (p_vtx_attrs)
for (size_t i = 0; i < vtx_attrs_count; i++)
vtx_attrs_by_location[p_vtx_attrs[i].location] = &p_vtx_attrs[i];
{
auto &va = p_vtx_attrs[i];
vtx_attrs_by_location[va.location] = &va;
if (va.builtin != BuiltInMax && !vtx_attrs_by_builtin.count(va.builtin))
vtx_attrs_by_builtin[va.builtin] = &va;
}
if (p_res_bindings)
for (size_t i = 0; i < res_bindings_count; i++)
@@ -75,7 +89,12 @@ CompilerMSL::CompilerMSL(ParsedIR &&ir_, MSLVertexAttr *p_vtx_attrs, size_t vtx_
{
if (p_vtx_attrs)
for (size_t i = 0; i < vtx_attrs_count; i++)
vtx_attrs_by_location[p_vtx_attrs[i].location] = &p_vtx_attrs[i];
{
auto &va = p_vtx_attrs[i];
vtx_attrs_by_location[va.location] = &va;
if (va.builtin != BuiltInMax && !vtx_attrs_by_builtin.count(va.builtin))
vtx_attrs_by_builtin[va.builtin] = &va;
}
if (p_res_bindings)
for (size_t i = 0; i < res_bindings_count; i++)
@@ -391,6 +410,12 @@ SPIRType &CompilerMSL::get_stage_out_struct_type()
return get_variable_data_type(so_var);
}
SPIRType &CompilerMSL::get_patch_stage_in_struct_type()
{
auto &si_var = get<SPIRVariable>(patch_stage_in_var_id);
return get_variable_data_type(si_var);
}
SPIRType &CompilerMSL::get_patch_stage_out_struct_type()
{
auto &so_var = get<SPIRVariable>(patch_stage_out_var_id);
@@ -558,7 +583,6 @@ string CompilerMSL::compile()
options.version = 450;
backend.null_pointer_literal = "nullptr";
backend.float_literal_suffix = false;
backend.half_literal_suffix = "h";
backend.uint32_t_literal_suffix = true;
backend.int16_t_literal_suffix = nullptr;
backend.uint16_t_literal_suffix = "u";
@@ -580,6 +604,7 @@ string CompilerMSL::compile()
backend.boolean_mix_support = false;
backend.allow_truncated_access_chain = true;
backend.array_is_value_type = false;
backend.comparison_image_samples_scalar = true;
capture_output_to_buffer = msl_options.capture_output_to_buffer;
is_rasterization_disabled = msl_options.disable_rasterization || capture_output_to_buffer;
@@ -609,12 +634,13 @@ string CompilerMSL::compile()
stage_out_var_id = add_interface_block(StorageClassOutput);
patch_stage_out_var_id = add_interface_block(StorageClassOutput, true);
stage_in_var_id = add_interface_block(StorageClassInput);
if (get_execution_model() == ExecutionModelTessellationEvaluation)
patch_stage_in_var_id = add_interface_block(StorageClassInput, true);
if (get_execution_model() == ExecutionModelTessellationControl)
{
stage_out_ptr_var_id = add_interface_block_pointer(stage_out_var_id, StorageClassOutput);
if (is_tessellation_shader())
stage_in_ptr_var_id = add_interface_block_pointer(stage_in_var_id, StorageClassInput);
}
// Metal vertex functions that define no output must disable rasterization and return void.
if (!stage_out_var_id)
@@ -662,7 +688,11 @@ string CompilerMSL::compile(vector<MSLVertexAttr> *p_vtx_attrs, vector<MSLResour
{
vtx_attrs_by_location.clear();
for (auto &va : *p_vtx_attrs)
{
vtx_attrs_by_location[va.location] = &va;
if (va.builtin != BuiltInMax && !vtx_attrs_by_builtin.count(va.builtin))
vtx_attrs_by_builtin[va.builtin] = &va;
}
}
if (p_res_bindings)
@@ -869,14 +899,15 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std::
auto *p_type = &get<SPIRType>(type_id);
BuiltIn bi_type = BuiltIn(get_decoration(arg_id, DecorationBuiltIn));
if (get_execution_model() == ExecutionModelTessellationControl &&
(var.storage == StorageClassInput || var.storage == StorageClassOutput) &&
!has_decoration(arg_id, DecorationPatch) &&
if (((is_tessellation_shader() && var.storage == StorageClassInput) ||
(get_execution_model() == ExecutionModelTessellationControl && var.storage == StorageClassOutput)) &&
!(has_decoration(arg_id, DecorationPatch) || is_patch_block(*p_type)) &&
(!is_builtin_variable(var) || bi_type == BuiltInPosition || bi_type == BuiltInPointSize ||
bi_type == BuiltInClipDistance || bi_type == BuiltInCullDistance ||
p_type->basetype == SPIRType::Struct))
{
// Tessellation control shaders see inputs and per-vertex outputs as arrays.
// Similarly, tessellation evaluation shaders see per-vertex inputs as arrays.
// We collected them into a structure; we must pass the array of this
// structure to the function.
std::string name;
@@ -1003,8 +1034,8 @@ void CompilerMSL::mark_as_packable(SPIRType &type)
void CompilerMSL::mark_location_as_used_by_shader(uint32_t location, StorageClass storage)
{
MSLVertexAttr *p_va;
if ((get_execution_model() == ExecutionModelVertex || get_execution_model() == ExecutionModelTessellationControl) &&
(storage == StorageClassInput) && (p_va = vtx_attrs_by_location[location]))
if ((get_execution_model() == ExecutionModelVertex || is_tessellation_shader()) && (storage == StorageClassInput) &&
(p_va = vtx_attrs_by_location[location]))
p_va->used_by_shader = true;
}
@@ -1086,7 +1117,7 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co
statement(qual_var_name, " = ", remap_swizzle(padded_type, type_components, to_name(var.self)), ";");
});
}
else
else if (!strip_array)
ir.meta[var.self].decoration.qualified_alias = qual_var_name;
if (var.storage == StorageClassOutput && var.initializer != 0)
@@ -1099,8 +1130,7 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co
if (get_decoration_bitset(var.self).get(DecorationLocation))
{
uint32_t locn = get_decoration(var.self, DecorationLocation);
if (storage == StorageClassInput && (get_execution_model() == ExecutionModelVertex ||
get_execution_model() == ExecutionModelTessellationControl))
if (storage == StorageClassInput && (get_execution_model() == ExecutionModelVertex || is_tessellation_shader()))
{
type_id = ensure_correct_attribute_type(var.basetype, locn);
var.basetype = type_id;
@@ -1112,6 +1142,12 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
mark_location_as_used_by_shader(locn, storage);
}
else if (is_builtin && is_tessellation_shader() && vtx_attrs_by_builtin.count(builtin))
{
uint32_t locn = vtx_attrs_by_builtin[builtin]->location;
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
mark_location_as_used_by_shader(locn, storage);
}
if (get_decoration_bitset(var.self).get(DecorationComponent))
{
@@ -1168,6 +1204,8 @@ void CompilerMSL::add_composite_variable_to_interface_block(StorageClass storage
elem_cnt = to_array_size_literal(var_type);
}
bool is_builtin = is_builtin_variable(var);
BuiltIn builtin = BuiltIn(get_decoration(var.self, DecorationBuiltIn));
bool is_flat = has_decoration(var.self, DecorationFlat);
bool is_noperspective = has_decoration(var.self, DecorationNoPerspective);
bool is_centroid = has_decoration(var.self, DecorationCentroid);
@@ -1179,6 +1217,10 @@ void CompilerMSL::add_composite_variable_to_interface_block(StorageClass storage
while (is_array(*usable_type) || is_matrix(*usable_type))
usable_type = &get<SPIRType>(usable_type->parent_type);
// If a builtin, force it to have the proper name.
if (is_builtin)
set_name(var.self, builtin_to_glsl(builtin, StorageClassFunction));
entry_func.add_local_variable(var.self);
// We need to declare the variable early and at entry-point scope.
@@ -1217,8 +1259,8 @@ void CompilerMSL::add_composite_variable_to_interface_block(StorageClass storage
if (get_decoration_bitset(var.self).get(DecorationLocation))
{
uint32_t locn = get_decoration(var.self, DecorationLocation) + i;
if (storage == StorageClassInput && (get_execution_model() == ExecutionModelVertex ||
get_execution_model() == ExecutionModelTessellationControl))
if (storage == StorageClassInput &&
(get_execution_model() == ExecutionModelVertex || is_tessellation_shader()))
{
var.basetype = ensure_correct_attribute_type(var.basetype, locn);
uint32_t mbr_type_id = ensure_correct_attribute_type(usable_type->self, locn);
@@ -1227,6 +1269,12 @@ void CompilerMSL::add_composite_variable_to_interface_block(StorageClass storage
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
mark_location_as_used_by_shader(locn, storage);
}
else if (is_builtin && is_tessellation_shader() && vtx_attrs_by_builtin.count(builtin))
{
uint32_t locn = vtx_attrs_by_builtin[builtin]->location + i;
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
mark_location_as_used_by_shader(locn, storage);
}
if (get_decoration_bitset(var.self).get(DecorationIndex))
{
@@ -1246,29 +1294,33 @@ void CompilerMSL::add_composite_variable_to_interface_block(StorageClass storage
set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceOrigID, var.self);
switch (storage)
if (!strip_array)
{
case StorageClassInput:
entry_func.fixup_hooks_in.push_back(
[=, &var]() { statement(to_name(var.self), "[", i, "] = ", ib_var_ref, ".", mbr_name, ";"); });
break;
switch (storage)
{
case StorageClassInput:
entry_func.fixup_hooks_in.push_back(
[=, &var]() { statement(to_name(var.self), "[", i, "] = ", ib_var_ref, ".", mbr_name, ";"); });
break;
case StorageClassOutput:
entry_func.fixup_hooks_out.push_back([=, &var]() {
if (padded_output)
{
auto &padded_type = this->get<SPIRType>(type_id);
statement(ib_var_ref, ".", mbr_name, " = ",
remap_swizzle(padded_type, usable_type->vecsize, join(to_name(var.self), "[", i, "]")),
";");
}
else
statement(ib_var_ref, ".", mbr_name, " = ", to_name(var.self), "[", i, "];");
});
break;
case StorageClassOutput:
entry_func.fixup_hooks_out.push_back([=, &var]() {
if (padded_output)
{
auto &padded_type = this->get<SPIRType>(type_id);
statement(
ib_var_ref, ".", mbr_name, " = ",
remap_swizzle(padded_type, usable_type->vecsize, join(to_name(var.self), "[", i, "]")),
";");
}
else
statement(ib_var_ref, ".", mbr_name, " = ", to_name(var.self), "[", i, "];");
});
break;
default:
break;
default:
break;
}
}
}
}
@@ -1308,6 +1360,8 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass
auto &entry_func = get<SPIRFunction>(ir.default_entry_point);
auto &var_type = strip_array ? get_variable_element_type(var) : get_variable_data_type(var);
BuiltIn builtin;
bool is_builtin = is_member_builtin(var_type, mbr_idx, &builtin);
bool is_flat =
has_member_decoration(var_type.self, mbr_idx, DecorationFlat) || has_decoration(var.self, DecorationFlat);
bool is_noperspective = has_member_decoration(var_type.self, mbr_idx, DecorationNoPerspective) ||
@@ -1364,6 +1418,12 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
mark_location_as_used_by_shader(locn, storage);
}
else if (is_builtin && is_tessellation_shader() && vtx_attrs_by_builtin.count(builtin))
{
uint32_t locn = vtx_attrs_by_builtin[builtin]->location + i;
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
mark_location_as_used_by_shader(locn, storage);
}
if (has_member_decoration(var_type.self, mbr_idx, DecorationComponent))
SPIRV_CROSS_THROW("DecorationComponent on matrices and arrays make little sense.");
@@ -1382,24 +1442,27 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass
set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceMemberIndex, mbr_idx);
// Unflatten or flatten from [[stage_in]] or [[stage_out]] as appropriate.
switch (storage)
if (!strip_array)
{
case StorageClassInput:
entry_func.fixup_hooks_in.push_back([=, &var, &var_type]() {
statement(to_name(var.self), ".", to_member_name(var_type, mbr_idx), "[", i, "] = ", ib_var_ref, ".",
mbr_name, ";");
});
break;
switch (storage)
{
case StorageClassInput:
entry_func.fixup_hooks_in.push_back([=, &var, &var_type]() {
statement(to_name(var.self), ".", to_member_name(var_type, mbr_idx), "[", i, "] = ", ib_var_ref,
".", mbr_name, ";");
});
break;
case StorageClassOutput:
entry_func.fixup_hooks_out.push_back([=, &var, &var_type]() {
statement(ib_var_ref, ".", mbr_name, " = ", to_name(var.self), ".", to_member_name(var_type, mbr_idx),
"[", i, "];");
});
break;
case StorageClassOutput:
entry_func.fixup_hooks_out.push_back([=, &var, &var_type]() {
statement(ib_var_ref, ".", mbr_name, " = ", to_name(var.self), ".",
to_member_name(var_type, mbr_idx), "[", i, "];");
});
break;
default:
break;
default:
break;
}
}
}
}
@@ -1436,13 +1499,13 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor
// Update the original variable reference to include the structure reference
string qual_var_name = ib_var_ref + "." + mbr_name;
if (is_builtin || get_execution_model() == ExecutionModelTessellationControl)
if (is_builtin && !strip_array)
{
// For the builtin gl_PerVertex, we cannot treat it as a block anyways,
// so redirect to qualified name.
set_member_qualified_name(var_type.self, mbr_idx, qual_var_name);
}
else
else if (!strip_array)
{
// Unflatten or flatten from [[stage_in]] or [[stage_out]] as appropriate.
switch (storage)
@@ -1468,8 +1531,7 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor
if (has_member_decoration(var_type.self, mbr_idx, DecorationLocation))
{
uint32_t locn = get_member_decoration(var_type.self, mbr_idx, DecorationLocation);
if (storage == StorageClassInput && (get_execution_model() == ExecutionModelVertex ||
get_execution_model() == ExecutionModelTessellationControl))
if (storage == StorageClassInput && (get_execution_model() == ExecutionModelVertex || is_tessellation_shader()))
{
mbr_type_id = ensure_correct_attribute_type(mbr_type_id, locn);
var_type.member_types[mbr_idx] = mbr_type_id;
@@ -1483,8 +1545,7 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor
// The block itself might have a location and in this case, all members of the block
// receive incrementing locations.
uint32_t locn = get_accumulated_member_location(var, mbr_idx, strip_array);
if (storage == StorageClassInput && (get_execution_model() == ExecutionModelVertex ||
get_execution_model() == ExecutionModelTessellationControl))
if (storage == StorageClassInput && (get_execution_model() == ExecutionModelVertex || is_tessellation_shader()))
{
mbr_type_id = ensure_correct_attribute_type(mbr_type_id, locn);
var_type.member_types[mbr_idx] = mbr_type_id;
@@ -1493,6 +1554,12 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
mark_location_as_used_by_shader(locn, storage);
}
else if (is_builtin && is_tessellation_shader() && vtx_attrs_by_builtin.count(builtin))
{
uint32_t locn = vtx_attrs_by_builtin[builtin]->location;
set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn);
mark_location_as_used_by_shader(locn, storage);
}
// Copy the component location, if present.
if (has_member_decoration(var_type.self, mbr_idx, DecorationComponent))
@@ -1566,7 +1633,9 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st
if (!is_builtin || has_active_builtin(builtin, storage))
{
if (!is_builtin && (storage == StorageClassInput || storage == StorageClassOutput) &&
if ((!is_builtin ||
(storage == StorageClassInput && get_execution_model() != ExecutionModelFragment)) &&
(storage == StorageClassInput || storage == StorageClassOutput) &&
(is_matrix(mbr_type) || is_array(mbr_type)))
{
add_composite_member_variable_to_interface_block(storage, ib_var_ref, ib_type, var, mbr_idx,
@@ -1590,7 +1659,7 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st
if (!is_builtin || has_active_builtin(builtin, storage))
{
// MSL does not allow matrices or arrays in input or output variables, so need to handle it specially.
if (!is_builtin &&
if ((!is_builtin || (storage == StorageClassInput && get_execution_model() != ExecutionModelFragment)) &&
(storage == StorageClassInput || (storage == StorageClassOutput && !capture_output_to_buffer)) &&
(is_matrix(var_type) || is_array(var_type)))
{
@@ -1608,8 +1677,9 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st
// for per-vertex variables in a tessellation control shader.
void CompilerMSL::fix_up_interface_member_indices(StorageClass storage, uint32_t ib_type_id)
{
// Only needed for tessellation control shaders.
if (get_execution_model() != ExecutionModelTessellationControl)
// Only needed for tessellation shaders.
if (get_execution_model() != ExecutionModelTessellationControl &&
!(get_execution_model() == ExecutionModelTessellationEvaluation && storage == StorageClassInput))
return;
bool in_array = false;
@@ -1672,24 +1742,28 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
{
// Accumulate the variables that should appear in the interface struct
vector<SPIRVariable *> vars;
bool incl_builtins = (storage == StorageClassOutput || get_execution_model() == ExecutionModelTessellationControl);
bool incl_builtins = (storage == StorageClassOutput || is_tessellation_shader());
ir.for_each_typed_id<SPIRVariable>([&](uint32_t var_id, SPIRVariable &var) {
auto &type = this->get<SPIRType>(var.basetype);
BuiltIn bi_type = BuiltIn(get_decoration(var_id, DecorationBuiltIn));
if (var.storage == storage && interface_variable_exists_in_entry_point(var.self) &&
!is_hidden_variable(var, incl_builtins) && type.pointer &&
has_decoration(var_id, DecorationPatch) == patch &&
(has_decoration(var_id, DecorationPatch) || is_patch_block(type)) == patch &&
(!is_builtin_variable(var) || bi_type == BuiltInPosition || bi_type == BuiltInPointSize ||
bi_type == BuiltInClipDistance || bi_type == BuiltInCullDistance || bi_type == BuiltInLayer ||
bi_type == BuiltInViewportIndex || bi_type == BuiltInFragDepth || bi_type == BuiltInSampleMask))
bi_type == BuiltInViewportIndex || bi_type == BuiltInFragDepth || bi_type == BuiltInSampleMask ||
(get_execution_model() == ExecutionModelTessellationEvaluation &&
(bi_type == BuiltInTessLevelOuter || bi_type == BuiltInTessLevelInner))))
{
vars.push_back(&var);
}
});
// If no variables qualify, leave
if (vars.empty())
// If no variables qualify, leave.
// For patch input in a tessellation evaluation shader, the per-vertex stage inputs
// are included in a special patch control point array.
if (vars.empty() && !(storage == StorageClassInput && patch && stage_in_var_id))
return 0;
// Add a new typed variable for this interface structure.
@@ -1711,7 +1785,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
switch (storage)
{
case StorageClassInput:
ib_var_ref = stage_in_var_name;
ib_var_ref = patch ? patch_stage_in_var_name : stage_in_var_name;
if (get_execution_model() == ExecutionModelTessellationControl)
{
// Add a hook to populate the shared workgroup memory containing
@@ -1752,6 +1826,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
switch (get_execution_model())
{
case ExecutionModelVertex:
case ExecutionModelTessellationEvaluation:
// 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
@@ -1798,7 +1873,10 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
for (auto p_var : vars)
{
bool strip_array = get_execution_model() == ExecutionModelTessellationControl && !patch;
bool strip_array =
(get_execution_model() == ExecutionModelTessellationControl ||
(get_execution_model() == ExecutionModelTessellationEvaluation && storage == StorageClassInput)) &&
!patch;
add_variable_to_interface_block(storage, ib_var_ref, ib_type, *p_var, strip_array);
}
@@ -1811,6 +1889,21 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
if (!patch)
fix_up_interface_member_indices(storage, ib_type_id);
// For patch inputs, add one more member, holding the array of control point data.
if (get_execution_model() == ExecutionModelTessellationEvaluation && storage == StorageClassInput && patch &&
stage_in_var_id)
{
uint32_t pcp_type_id = ir.increase_bound_by(1);
auto &pcp_type = set<SPIRType>(pcp_type_id, ib_type);
pcp_type.basetype = SPIRType::ControlPointArray;
pcp_type.parent_type = pcp_type.type_alias = get_stage_in_struct_type().self;
pcp_type.storage = storage;
ir.meta[pcp_type_id] = ir.meta[ib_type.self];
uint32_t mbr_idx = uint32_t(ib_type.member_types.size());
ib_type.member_types.push_back(pcp_type_id);
set_member_name(ib_type.self, mbr_idx, "gl_in");
}
return ib_var_id;
}
@@ -1819,28 +1912,52 @@ uint32_t CompilerMSL::add_interface_block_pointer(uint32_t ib_var_id, StorageCla
if (!ib_var_id)
return 0;
// Tessellation control per-vertex I/O is presented as an array, so we must
// do the same with our struct here.
uint32_t ib_ptr_var_id;
uint32_t next_id = ir.increase_bound_by(3);
uint32_t ib_ptr_type_id = next_id++;
auto &ib_type = expression_type(ib_var_id);
auto &ib_ptr_type = set<SPIRType>(ib_ptr_type_id, ib_type);
ib_ptr_type.parent_type = ib_ptr_type.type_alias = ib_type.self;
ib_ptr_type.pointer = true;
ib_ptr_type.storage = storage == StorageClassInput ? StorageClassWorkgroup : StorageClassStorageBuffer;
ir.meta[ib_ptr_type_id] = ir.meta[ib_type.self];
// To ensure that get_variable_data_type() doesn't strip off the pointer,
// which we need, use another pointer.
uint32_t ib_ptr_ptr_type_id = next_id++;
auto &ib_ptr_ptr_type = set<SPIRType>(ib_ptr_ptr_type_id, ib_ptr_type);
ib_ptr_ptr_type.parent_type = ib_ptr_type_id;
ib_ptr_ptr_type.type_alias = ib_type.self;
ib_ptr_ptr_type.storage = StorageClassFunction;
ir.meta[ib_ptr_ptr_type_id] = ir.meta[ib_type.self];
if (get_execution_model() == ExecutionModelTessellationControl)
{
// Tessellation control per-vertex I/O is presented as an array, so we must
// do the same with our struct here.
uint32_t ib_ptr_type_id = next_id++;
auto &ib_ptr_type = set<SPIRType>(ib_ptr_type_id, ib_type);
ib_ptr_type.parent_type = ib_ptr_type.type_alias = ib_type.self;
ib_ptr_type.pointer = true;
ib_ptr_type.storage = storage == StorageClassInput ? StorageClassWorkgroup : StorageClassStorageBuffer;
ir.meta[ib_ptr_type_id] = ir.meta[ib_type.self];
// To ensure that get_variable_data_type() doesn't strip off the pointer,
// which we need, use another pointer.
uint32_t ib_ptr_ptr_type_id = next_id++;
auto &ib_ptr_ptr_type = set<SPIRType>(ib_ptr_ptr_type_id, ib_ptr_type);
ib_ptr_ptr_type.parent_type = ib_ptr_type_id;
ib_ptr_ptr_type.type_alias = ib_type.self;
ib_ptr_ptr_type.storage = StorageClassFunction;
ir.meta[ib_ptr_ptr_type_id] = ir.meta[ib_type.self];
uint32_t ib_ptr_var_id = next_id;
set<SPIRVariable>(ib_ptr_var_id, ib_ptr_ptr_type_id, StorageClassFunction, 0);
set_name(ib_ptr_var_id, storage == StorageClassInput ? input_wg_var_name : "gl_out");
ib_ptr_var_id = next_id;
set<SPIRVariable>(ib_ptr_var_id, ib_ptr_ptr_type_id, StorageClassFunction, 0);
set_name(ib_ptr_var_id, storage == StorageClassInput ? input_wg_var_name : "gl_out");
}
else
{
// Tessellation evaluation per-vertex inputs are also presented as arrays.
// But, in Metal, this array uses a very special type, 'patch_control_point<T>',
// which is a container that can be used to access the control point data.
// To represent this, a special 'ControlPointArray' type has been added to the
// SPIRV-Cross type system. It should only be generated by and seen in the MSL
// backend (i.e. this one).
uint32_t pcp_type_id = next_id++;
auto &pcp_type = set<SPIRType>(pcp_type_id, ib_type);
pcp_type.basetype = SPIRType::ControlPointArray;
pcp_type.parent_type = pcp_type.type_alias = ib_type.self;
pcp_type.storage = storage;
ir.meta[pcp_type_id] = ir.meta[ib_type.self];
ib_ptr_var_id = next_id;
set<SPIRVariable>(ib_ptr_var_id, pcp_type_id, storage, 0);
set_name(ib_ptr_var_id, "gl_in");
ir.meta[ib_ptr_var_id].decoration.qualified_alias = join(patch_stage_in_var_name, ".gl_in");
}
return ib_ptr_var_id;
}
@@ -2723,6 +2840,7 @@ void CompilerMSL::emit_resources()
emit_interface_block(stage_out_var_id);
emit_interface_block(patch_stage_out_var_id);
emit_interface_block(stage_in_var_id);
emit_interface_block(patch_stage_in_var_id);
}
// Emit declarations for the specialization Metal function constants
@@ -2822,6 +2940,8 @@ void CompilerMSL::emit_specialization_constants_and_structs()
is_declarable_struct = false;
if (stage_in_var_id && get_stage_in_struct_type().self == type_id)
is_declarable_struct = false;
if (patch_stage_in_var_id && get_patch_stage_in_struct_type().self == type_id)
is_declarable_struct = false;
// Align and emit declarable structs...but avoid declaring each more than once.
if (is_declarable_struct && declared_structs.count(type_id) == 0)
@@ -2859,13 +2979,15 @@ void CompilerMSL::emit_binary_unord_op(uint32_t result_type, uint32_t result_id,
inherit_expression_dependencies(result_id, op1);
}
bool CompilerMSL::emit_tessellation_control_access_chain(const uint32_t *ops, uint32_t length)
bool CompilerMSL::emit_tessellation_access_chain(const uint32_t *ops, uint32_t length)
{
// If this is a per-vertex output, remap it to the I/O array buffer.
auto *var = maybe_get<SPIRVariable>(ops[2]);
BuiltIn bi_type = BuiltIn(get_decoration(ops[2], DecorationBuiltIn));
if (var && (var->storage == StorageClassInput || var->storage == StorageClassOutput) &&
!has_decoration(ops[2], DecorationPatch) &&
if (var &&
(var->storage == StorageClassInput ||
(get_execution_model() == ExecutionModelTessellationControl && var->storage == StorageClassOutput)) &&
!(has_decoration(ops[2], DecorationPatch) || is_patch_block(get_variable_data_type(*var))) &&
(!is_builtin_variable(*var) || bi_type == BuiltInPosition || bi_type == BuiltInPointSize ||
bi_type == BuiltInClipDistance || bi_type == BuiltInCullDistance ||
get_variable_data_type(*var).basetype == SPIRType::Struct))
@@ -2934,7 +3056,8 @@ bool CompilerMSL::emit_tessellation_control_access_chain(const uint32_t *ops, ui
for (uint32_t k = 0; k < mbr_type.columns; k++, index++)
{
set<SPIRConstant>(const_mbr_id, type_id, index, false);
auto e = access_chain(ptr, indices.data(), indices.size(), mbr_type, nullptr, true);
auto e = access_chain(ptr, indices.data(), uint32_t(indices.size()), mbr_type, nullptr,
true);
statement(temp_name, ".", to_member_name(*type, j), "[", k, "] = ", e, ";");
}
}
@@ -2943,14 +3066,16 @@ bool CompilerMSL::emit_tessellation_control_access_chain(const uint32_t *ops, ui
for (uint32_t k = 0; k < mbr_type.array[0]; k++, index++)
{
set<SPIRConstant>(const_mbr_id, type_id, index, false);
auto e = access_chain(ptr, indices.data(), indices.size(), mbr_type, nullptr, true);
auto e = access_chain(ptr, indices.data(), uint32_t(indices.size()), mbr_type, nullptr,
true);
statement(temp_name, ".", to_member_name(*type, j), "[", k, "] = ", e, ";");
}
}
else
{
set<SPIRConstant>(const_mbr_id, type_id, index, false);
auto e = access_chain(ptr, indices.data(), indices.size(), mbr_type, nullptr, true);
auto e =
access_chain(ptr, indices.data(), uint32_t(indices.size()), mbr_type, nullptr, true);
statement(temp_name, ".", to_member_name(*type, j), " = ", e, ";");
}
}
@@ -2960,7 +3085,7 @@ bool CompilerMSL::emit_tessellation_control_access_chain(const uint32_t *ops, ui
for (uint32_t j = 0; j < type->columns; j++, index++)
{
set<SPIRConstant>(const_mbr_id, type_id, index, false);
auto e = access_chain(ptr, indices.data(), indices.size(), *type, nullptr, true);
auto e = access_chain(ptr, indices.data(), uint32_t(indices.size()), *type, nullptr, true);
statement(temp_name, "[", j, "] = ", e, ";");
}
}
@@ -2970,7 +3095,7 @@ bool CompilerMSL::emit_tessellation_control_access_chain(const uint32_t *ops, ui
for (uint32_t j = 0; j < type->array[0]; j++, index++)
{
set<SPIRConstant>(const_mbr_id, type_id, index, false);
auto e = access_chain(ptr, indices.data(), indices.size(), *type, nullptr, true);
auto e = access_chain(ptr, indices.data(), uint32_t(indices.size()), *type, nullptr, true);
statement(temp_name, "[", j, "] = ", e, ";");
}
}
@@ -3006,7 +3131,7 @@ bool CompilerMSL::emit_tessellation_control_access_chain(const uint32_t *ops, ui
// We use the pointer to the base of the input/output array here,
// so this is always a pointer chain.
auto e = access_chain(ptr, indices.data(), indices.size(), get<SPIRType>(ops[0]), &meta, true);
auto e = access_chain(ptr, indices.data(), uint32_t(indices.size()), get<SPIRType>(ops[0]), &meta, true);
auto &expr = set<SPIRExpression>(ops[1], move(e), ops[0], should_forward(ops[2]));
expr.loaded_from = var->self;
expr.need_transpose = meta.need_transpose;
@@ -3033,10 +3158,15 @@ bool CompilerMSL::emit_tessellation_control_access_chain(const uint32_t *ops, ui
// drop the last index. It isn't an array in this case, so we can't have an
// array reference here. We need to make this ID a variable instead of an
// expression so we don't try to dereference it as a variable pointer.
// Don't do this if the index is a constant 1, though. We need to drop stores
// to that one.
auto *m = ir.find_meta(var ? var->self : 0);
if (var && m && m->decoration.builtin_type == BuiltInTessLevelInner &&
get_entry_point().flags.get(ExecutionModeTriangles))
if (get_execution_model() == ExecutionModelTessellationControl && var && m &&
m->decoration.builtin_type == BuiltInTessLevelInner && get_entry_point().flags.get(ExecutionModeTriangles))
{
auto *c = maybe_get<SPIRConstant>(ops[3]);
if (c && c->scalar() == 1)
return false;
auto &dest_var = set<SPIRVariable>(ops[1], *var);
dest_var.basetype = ops[0];
ir.meta[ops[1]] = ir.meta[ops[2]];
@@ -3047,6 +3177,33 @@ bool CompilerMSL::emit_tessellation_control_access_chain(const uint32_t *ops, ui
return false;
}
bool CompilerMSL::is_out_of_bounds_tessellation_level(uint32_t id_lhs)
{
if (!get_entry_point().flags.get(ExecutionModeTriangles))
return false;
// In SPIR-V, TessLevelInner always has two elements and TessLevelOuter always has
// four. This is true even if we are tessellating triangles. This allows clients
// to use a single tessellation control shader with multiple tessellation evaluation
// shaders.
// In Metal, however, only the first element of TessLevelInner and the first three
// of TessLevelOuter are accessible. This stems from how in Metal, the tessellation
// levels must be stored to a dedicated buffer in a particular format that depends
// on the patch type. Therefore, in Triangles mode, any access to the second
// inner level or the fourth outer level must be dropped.
const auto *e = maybe_get<SPIRExpression>(id_lhs);
if (!e || !e->access_chain)
return false;
BuiltIn builtin = BuiltIn(get_decoration(e->loaded_from, DecorationBuiltIn));
if (builtin != BuiltInTessLevelInner && builtin != BuiltInTessLevelOuter)
return false;
auto *c = maybe_get<SPIRConstant>(e->implied_read_expressions[1]);
if (!c)
return false;
return (builtin == BuiltInTessLevelInner && c->scalar() == 1) ||
(builtin == BuiltInTessLevelOuter && c->scalar() == 3);
}
// Override for MSL-specific syntax instructions
void CompilerMSL::emit_instruction(const Instruction &instruction)
{
@@ -3518,9 +3675,9 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
case OpInBoundsAccessChain:
case OpAccessChain:
case OpPtrAccessChain:
if (get_execution_model() == ExecutionModelTessellationControl)
if (is_tessellation_shader())
{
if (!emit_tessellation_control_access_chain(ops, instruction.length))
if (!emit_tessellation_access_chain(ops, instruction.length))
CompilerGLSL::emit_instruction(instruction);
}
else
@@ -3528,6 +3685,9 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
break;
case OpStore:
if (is_out_of_bounds_tessellation_level(ops[0]))
break;
if (maybe_emit_array_assignment(ops[0], ops[1]))
break;
@@ -4592,6 +4752,21 @@ string CompilerMSL::to_swizzle_expression(uint32_t id)
}
}
// Checks whether the type is a Block all of whose members have DecorationPatch.
bool CompilerMSL::is_patch_block(const SPIRType &type)
{
if (!has_decoration(type.self, DecorationBlock))
return false;
for (uint32_t i = 0; i < type.member_types.size(); i++)
{
if (!has_member_decoration(type.self, i, DecorationPatch))
return false;
}
return true;
}
// Checks whether the ID is a row_major matrix that requires conversion before use
bool CompilerMSL::is_non_native_row_major_matrix(uint32_t id)
{
@@ -4600,7 +4775,7 @@ bool CompilerMSL::is_non_native_row_major_matrix(uint32_t id)
return false;
// Non-matrix or column-major matrix types do not need to be converted.
if (!ir.meta[id].decoration.decoration_flags.get(DecorationRowMajor))
if (!has_decoration(id, DecorationRowMajor))
return false;
// Generate a function that will swap matrix elements from row-major to column-major.
@@ -4622,7 +4797,7 @@ bool CompilerMSL::member_is_non_native_row_major_matrix(const SPIRType &type, ui
return false;
// Non-matrix or column-major matrix types do not need to be converted.
if (!combined_decoration_for_member(type, index).get(DecorationRowMajor))
if (!has_member_decoration(type.self, index, DecorationRowMajor))
return false;
// Generate a function that will swap matrix elements from row-major to column-major.
@@ -4685,7 +4860,9 @@ string CompilerMSL::convert_row_major_matrix(string exp_str, const SPIRType &exp
// Called automatically at the end of the entry point function
void CompilerMSL::emit_fixup()
{
if ((get_entry_point().model == ExecutionModelVertex) && stage_out_var_id && !qual_pos_var_name.empty())
if ((get_execution_model() == ExecutionModelVertex ||
get_execution_model() == ExecutionModelTessellationEvaluation) &&
stage_out_var_id && !qual_pos_var_name.empty() && !capture_output_to_buffer)
{
if (options.vertex.fixup_clipspace)
statement(qual_pos_var_name, ".z = (", qual_pos_var_name, ".z + ", qual_pos_var_name,
@@ -4792,8 +4969,9 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
return string(" [[attribute(") + convert_to_string(locn) + ")]]";
}
// Vertex function outputs
if (execution.model == ExecutionModelVertex && type.storage == StorageClassOutput)
// Vertex and tessellation evaluation function outputs
if ((execution.model == ExecutionModelVertex || execution.model == ExecutionModelTessellationEvaluation) &&
type.storage == StorageClassOutput)
{
if (is_builtin)
{
@@ -4860,6 +5038,33 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
return "";
}
// Tessellation evaluation function inputs
if (execution.model == ExecutionModelTessellationEvaluation && type.storage == StorageClassInput)
{
if (is_builtin)
{
switch (builtin)
{
case BuiltInPrimitiveId:
case BuiltInTessCoord:
return string(" [[") + builtin_qualifier(builtin) + "]]";
case BuiltInPatchVertices:
return "";
// Others come from stage input.
default:
break;
}
}
// The special control point array must not be marked with an attribute.
if (get_type(type.member_types[index]).basetype == SPIRType::ControlPointArray)
return "";
uint32_t locn = get_ordered_member_location(type.self, index);
if (locn != k_unknown_location)
return string(" [[attribute(") + convert_to_string(locn) + ")]]";
}
// Tessellation evaluation function outputs were handled above.
// Fragment function inputs
if (execution.model == ExecutionModelFragment && type.storage == StorageClassInput)
{
@@ -5028,6 +5233,18 @@ string CompilerMSL::func_type_decl(SPIRType &type)
case ExecutionModelVertex:
entry_type = "vertex";
break;
case ExecutionModelTessellationEvaluation:
if (!msl_options.supports_msl_version(1, 2))
SPIRV_CROSS_THROW("Tessellation requires Metal 1.2.");
if (execution.flags.get(ExecutionModeIsolines))
SPIRV_CROSS_THROW("Metal does not support isoline tessellation.");
if (msl_options.is_ios())
entry_type =
join("[[ patch(", execution.flags.get(ExecutionModeTriangles) ? "triangle" : "quad", ") ]] vertex");
else
entry_type = join("[[ patch(", execution.flags.get(ExecutionModeTriangles) ? "triangle" : "quad", ", ",
execution.output_vertices, ") ]] vertex");
break;
case ExecutionModelFragment:
entry_type =
execution.flags.get(ExecutionModeEarlyFragmentTests) ? "[[ early_fragment_tests ]] fragment" : "fragment";
@@ -5152,9 +5369,15 @@ string CompilerMSL::entry_point_args(bool append_comma)
string ep_args;
// Stage-in structure
if (stage_in_var_id)
uint32_t stage_in_id;
if (get_execution_model() == ExecutionModelTessellationEvaluation)
stage_in_id = patch_stage_in_var_id;
else
stage_in_id = stage_in_var_id;
if (stage_in_id)
{
auto &var = get<SPIRVariable>(stage_in_var_id);
auto &var = get<SPIRVariable>(stage_in_id);
auto &type = get_variable_data_type(var);
if (!ep_args.empty())
@@ -5284,7 +5507,8 @@ string CompilerMSL::entry_point_args(bool append_comma)
// Don't emit SamplePosition as a separate parameter. In the entry
// point, we get that by calling get_sample_position() on the sample ID.
if (var.storage == StorageClassInput && is_builtin_variable(var) &&
get_variable_data_type(var).basetype != SPIRType::Struct)
get_variable_data_type(var).basetype != SPIRType::Struct &&
get_variable_data_type(var).basetype != SPIRType::ControlPointArray)
{
if (bi_type != BuiltInSamplePosition && bi_type != BuiltInHelperInvocation &&
bi_type != BuiltInPatchVertices && bi_type != BuiltInTessLevelInner &&
@@ -5413,9 +5637,24 @@ void CompilerMSL::fix_up_shader_inputs_outputs()
});
break;
case BuiltInPatchVertices:
entry_func.fixup_hooks_in.push_back([=]() {
statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = spvIndirectParams[0];");
});
if (get_execution_model() == ExecutionModelTessellationEvaluation)
entry_func.fixup_hooks_in.push_back([=]() {
statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = ",
to_expression(patch_stage_in_var_id), ".gl_in.size();");
});
else
entry_func.fixup_hooks_in.push_back([=]() {
statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = spvIndirectParams[0];");
});
break;
case BuiltInTessCoord:
// Emit a fixup to account for the shifted domain. Don't do this for triangles;
// MoltenVK will just reverse the winding order instead.
if (msl_options.tess_domain_origin_lower_left && !get_entry_point().flags.get(ExecutionModeTriangles))
{
string tc = to_expression(var_id);
entry_func.fixup_hooks_in.push_back([=]() { statement(tc, ".y = 1.0 - ", tc, ".y;"); });
}
break;
default:
break;
@@ -5982,6 +6221,9 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
case SPIRType::AtomicCounter:
return "atomic_uint";
case SPIRType::ControlPointArray:
return join("patch_control_point<", type_to_glsl(get<SPIRType>(type.parent_type), id), ">");
// Scalars
case SPIRType::Boolean:
type_name = "bool";
@@ -6263,7 +6505,7 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
// When used in the entry function, output builtins are qualified with output struct name.
// Test storage class as NOT Input, as output builtins might be part of generic type.
// Also don't do this for tessellation shaders.
// Also don't do this for tessellation control shaders.
case BuiltInViewportIndex:
if (!msl_options.supports_msl_version(2, 0))
SPIRV_CROSS_THROW("ViewportIndex requires Metal 2.0.");
@@ -6283,12 +6525,16 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
break;
case BuiltInTessLevelOuter:
if (get_execution_model() == ExecutionModelTessellationEvaluation)
break;
if (storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point))
return join(tess_factor_buffer_var_name, "[", to_expression(builtin_primitive_id_id),
"].edgeTessellationFactor");
break;
case BuiltInTessLevelInner:
if (get_execution_model() == ExecutionModelTessellationEvaluation)
break;
if (storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point))
return join(tess_factor_buffer_var_name, "[", to_expression(builtin_primitive_id_id),
"].insideTessellationFactor");
@@ -6345,7 +6591,15 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
// Shouldn't be reached.
SPIRV_CROSS_THROW("PatchVertices is derived from the auxiliary buffer in MSL.");
case BuiltInPrimitiveId:
return "threadgroup_position_in_grid";
switch (execution.model)
{
case ExecutionModelTessellationControl:
return "threadgroup_position_in_grid";
case ExecutionModelTessellationEvaluation:
return "patch_id";
default:
SPIRV_CROSS_THROW("PrimitiveId is not supported in this execution model.");
}
// Tess. control function out
case BuiltInTessLevelOuter:
@@ -6353,6 +6607,10 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
// Shouldn't be reached.
SPIRV_CROSS_THROW("Tessellation levels are handled specially in MSL.");
// Tess. evaluation function in
case BuiltInTessCoord:
return "position_in_patch";
// Fragment function in
case BuiltInFrontFacing:
return "front_facing";
@@ -6447,6 +6705,10 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin)
case BuiltInTessLevelOuter:
return "half";
// Tess. evaluation function in
case BuiltInTessCoord:
return get_entry_point().flags.get(ExecutionModeTriangles) ? "float3" : "float2";
// Fragment function in
case BuiltInFrontFacing:
return "bool";
@@ -6973,6 +7235,13 @@ void CompilerMSL::bitcast_from_builtin_load(uint32_t source_id, std::string &exp
if (expected_type != expr_type.basetype)
expr = bitcast_expression(expr_type, expected_type, expr);
if (builtin == BuiltInTessCoord && get_entry_point().flags.get(ExecutionModeQuads) && expr_type.vecsize == 3)
{
// In SPIR-V, this is always a vec3, even for quads. In Metal, though, it's a float2 for quads.
// The code is expecting a float3, so we need to widen this.
expr = join("float3(", expr, ", 0)");
}
}
void CompilerMSL::bitcast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type)

View File

@@ -48,6 +48,7 @@ struct MSLVertexAttr
uint32_t msl_stride = 0;
bool per_instance = false;
MSLVertexFormat format = MSL_VERTEX_FORMAT_OTHER;
spv::BuiltIn builtin = spv::BuiltInMax;
bool used_by_shader = false;
};
@@ -177,6 +178,7 @@ public:
bool disable_rasterization = false;
bool capture_output_to_buffer = false;
bool swizzle_texture_samples = false;
bool tess_domain_origin_lower_left = false;
// Fragment output in MSL must have at least as many components as the render pass.
// Add support to explicit pad out components.
@@ -235,7 +237,8 @@ public:
bool get_is_rasterization_disabled() const
{
return is_rasterization_disabled && (get_entry_point().model == spv::ExecutionModelVertex ||
get_entry_point().model == spv::ExecutionModelTessellationControl);
get_entry_point().model == spv::ExecutionModelTessellationControl ||
get_entry_point().model == spv::ExecutionModelTessellationEvaluation);
}
// Provide feedback to calling API to allow it to pass an auxiliary
@@ -388,6 +391,7 @@ protected:
void replace_illegal_names() override;
void declare_undefined_values() override;
void declare_constant_arrays();
bool is_patch_block(const SPIRType &type);
bool is_non_native_row_major_matrix(uint32_t id) override;
bool member_is_non_native_row_major_matrix(const SPIRType &type, uint32_t index) override;
std::string convert_row_major_matrix(std::string exp_str, const SPIRType &exp_type, bool is_packed) override;
@@ -456,6 +460,7 @@ protected:
std::string get_type_address_space(const SPIRType &type);
SPIRType &get_stage_in_struct_type();
SPIRType &get_stage_out_struct_type();
SPIRType &get_patch_stage_in_struct_type();
SPIRType &get_patch_stage_out_struct_type();
std::string get_tess_factor_struct_name();
void emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, uint32_t mem_order_1,
@@ -484,11 +489,13 @@ protected:
void analyze_sampled_image_usage();
bool emit_tessellation_control_access_chain(const uint32_t *ops, uint32_t length);
bool emit_tessellation_access_chain(const uint32_t *ops, uint32_t length);
bool is_out_of_bounds_tessellation_level(uint32_t id_lhs);
Options msl_options;
std::set<SPVFuncImpl> spv_function_implementations;
std::unordered_map<uint32_t, MSLVertexAttr *> vtx_attrs_by_location;
std::unordered_map<uint32_t, MSLVertexAttr *> vtx_attrs_by_builtin;
std::unordered_map<uint32_t, uint32_t> fragment_output_components;
std::unordered_map<MSLStructMemberKey, uint32_t> struct_member_padding;
std::set<std::string> pragma_lines;
@@ -498,6 +505,7 @@ protected:
MSLResourceBinding next_metal_resource_index;
uint32_t stage_in_var_id = 0;
uint32_t stage_out_var_id = 0;
uint32_t patch_stage_in_var_id = 0;
uint32_t patch_stage_out_var_id = 0;
uint32_t stage_in_ptr_var_id = 0;
uint32_t stage_out_ptr_var_id = 0;
@@ -511,6 +519,7 @@ protected:
std::string qual_pos_var_name;
std::string stage_in_var_name = "in";
std::string stage_out_var_name = "out";
std::string patch_stage_in_var_name = "patchIn";
std::string patch_stage_out_var_name = "patchOut";
std::string sampler_name_suffix = "Smplr";
std::string swizzle_name_suffix = "Swzl";

View File

@@ -391,6 +391,16 @@ void CompilerReflection::emit_entry_points()
auto entries = get_entry_points_and_stages();
if (!entries.empty())
{
// Needed to make output deterministic.
sort(begin(entries), end(entries), [](const EntryPoint &a, const EntryPoint &b) -> bool {
if (a.execution_model < b.execution_model)
return true;
else if (a.execution_model > b.execution_model)
return false;
else
return a.name < b.name;
});
json_stream->emit_json_key_array("entryPoints");
for (auto &e : entries)
{

View File

@@ -135,8 +135,12 @@ def cross_compile_msl(shader, spirv, opt):
spirv_path = create_temporary()
msl_path = create_temporary(os.path.basename(shader))
spirv_cmd = ['spirv-as', '-o', spirv_path, shader]
if '.preserve.' in shader:
spirv_cmd.append('--preserve-numeric-ids')
if spirv:
subprocess.check_call(['spirv-as', '-o', spirv_path, shader])
subprocess.check_call(spirv_cmd)
else:
subprocess.check_call(['glslangValidator', '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
@@ -156,6 +160,8 @@ def cross_compile_msl(shader, spirv, opt):
msl_args.append('--msl-pad-fragment-output')
if '.capture.' in shader:
msl_args.append('--msl-capture-output')
if '.domain.' in shader:
msl_args.append('--msl-domain-lower-left')
subprocess.check_call(msl_args)
@@ -229,8 +235,12 @@ def cross_compile_hlsl(shader, spirv, opt, force_no_external_validation):
spirv_path = create_temporary()
hlsl_path = create_temporary(os.path.basename(shader))
spirv_cmd = ['spirv-as', '-o', spirv_path, shader]
if '.preserve.' in shader:
spirv_cmd.append('--preserve-numeric-ids')
if spirv:
subprocess.check_call(['spirv-as', '-o', spirv_path, shader])
subprocess.check_call(spirv_cmd)
else:
subprocess.check_call(['glslangValidator', '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
@@ -253,8 +263,12 @@ def cross_compile_reflect(shader, spirv, opt):
spirv_path = create_temporary()
reflect_path = create_temporary(os.path.basename(shader))
spirv_cmd = ['spirv-as', '-o', spirv_path, shader]
if '.preserve.' in shader:
spirv_cmd.append('--preserve-numeric-ids')
if spirv:
subprocess.check_call(['spirv-as', '-o', spirv_path, shader])
subprocess.check_call(spirv_cmd)
else:
subprocess.check_call(['glslangValidator', '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
@@ -280,8 +294,12 @@ def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, fl
if vulkan or spirv:
vulkan_glsl_path = create_temporary('vk' + os.path.basename(shader))
spirv_cmd = ['spirv-as', '-o', spirv_path, shader]
if '.preserve.' in shader:
spirv_cmd.append('--preserve-numeric-ids')
if spirv:
subprocess.check_call(['spirv-as', '-o', spirv_path, shader])
subprocess.check_call(spirv_cmd)
else:
subprocess.check_call(['glslangValidator', '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])