Merge pull request #1587 from KhronosGroup/refactor-active-variable-consideration
Refactor active variable consideration
diff --git a/reference/opt/shaders-msl/asm/vert/fake-builtin-input.asm.vert b/reference/opt/shaders-msl/asm/vert/fake-builtin-input.asm.vert
index f9fcbc8..3079ae9 100644
--- a/reference/opt/shaders-msl/asm/vert/fake-builtin-input.asm.vert
+++ b/reference/opt/shaders-msl/asm/vert/fake-builtin-input.asm.vert
@@ -5,6 +5,7 @@
struct main0_out
{
+ half4 out_var_SV_Target [[user(locn0)]];
float4 gl_Position [[position]];
};
diff --git a/reference/opt/shaders/asm/vert/empty-io.asm.vert b/reference/opt/shaders/asm/vert/empty-io.asm.vert
index 3819a71..52fd706 100644
--- a/reference/opt/shaders/asm/vert/empty-io.asm.vert
+++ b/reference/opt/shaders/asm/vert/empty-io.asm.vert
@@ -6,6 +6,7 @@
};
layout(location = 0) in vec4 position;
+layout(location = 0) out VSOutput _entryPointOutput;
void main()
{
diff --git a/reference/shaders-hlsl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag b/reference/shaders-hlsl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
new file mode 100644
index 0000000..dcbe5d1
--- /dev/null
+++ b/reference/shaders-hlsl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
@@ -0,0 +1,17 @@
+static float gl_FragDepth = 0.5f;
+struct SPIRV_Cross_Output
+{
+ float gl_FragDepth : SV_Depth;
+};
+
+void frag_main()
+{
+}
+
+SPIRV_Cross_Output main()
+{
+ frag_main();
+ SPIRV_Cross_Output stage_output;
+ stage_output.gl_FragDepth = gl_FragDepth;
+ return stage_output;
+}
diff --git a/reference/shaders-hlsl-no-opt/asm/vert/builtin-output-initializer.asm.vert b/reference/shaders-hlsl-no-opt/asm/vert/builtin-output-initializer.asm.vert
index cf3e916..ee30c17 100644
--- a/reference/shaders-hlsl-no-opt/asm/vert/builtin-output-initializer.asm.vert
+++ b/reference/shaders-hlsl-no-opt/asm/vert/builtin-output-initializer.asm.vert
@@ -2,9 +2,14 @@
static const float _24[1] = { 0.0f };
static float4 gl_Position = 0.0f.xxxx;
+static float gl_PointSize = 0.0f;
+static float gl_ClipDistance[1] = _23;
+static float gl_CullDistance[1] = _24;
struct SPIRV_Cross_Output
{
float4 gl_Position : SV_Position;
+ float gl_ClipDistance0 : SV_ClipDistance0;
+ float gl_CullDistance0 : SV_CullDistance0;
};
void vert_main()
@@ -17,5 +22,7 @@
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
+ stage_output.gl_ClipDistance0.x = gl_ClipDistance[0];
+ stage_output.gl_CullDistance0.x = gl_CullDistance[0];
return stage_output;
}
diff --git a/reference/shaders-msl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag b/reference/shaders-msl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
new file mode 100644
index 0000000..3f552eb
--- /dev/null
+++ b/reference/shaders-msl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
@@ -0,0 +1,17 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+ float gl_FragDepth [[depth(any)]];
+};
+
+fragment main0_out main0()
+{
+ main0_out out = {};
+ out.gl_FragDepth = 0.5;
+ return out;
+}
+
diff --git a/reference/shaders-msl-no-opt/asm/tesc/builtin-control-point-initializer.asm.tesc b/reference/shaders-msl-no-opt/asm/tesc/builtin-control-point-initializer.asm.tesc
index 4d6e757..8777212 100644
--- a/reference/shaders-msl-no-opt/asm/tesc/builtin-control-point-initializer.asm.tesc
+++ b/reference/shaders-msl-no-opt/asm/tesc/builtin-control-point-initializer.asm.tesc
@@ -48,8 +48,6 @@
{
float4 _RESERVED_IDENTIFIER_FIXUP_gl_Position;
float _RESERVED_IDENTIFIER_FIXUP_gl_PointSize;
- spvUnsafeArray<float, 1> _RESERVED_IDENTIFIER_FIXUP_gl_ClipDistance;
- spvUnsafeArray<float, 1> _RESERVED_IDENTIFIER_FIXUP_gl_CullDistance;
};
struct Verts
@@ -58,25 +56,24 @@
float2 b;
};
-constant spvUnsafeArray<float, 1> _40 = spvUnsafeArray<float, 1>({ 0.0 });
-constant spvUnsafeArray<float, 1> _41 = spvUnsafeArray<float, 1>({ 0.0 });
-
struct main0_out
{
float Verts_a;
float2 Verts_b;
float4 gl_Position;
+ float gl_PointSize;
};
kernel void main0(uint gl_InvocationID [[thread_index_in_threadgroup]], uint gl_PrimitiveID [[threadgroup_position_in_grid]], device main0_out* spvOut [[buffer(28)]], constant uint* spvIndirectParams [[buffer(29)]], device MTLQuadTessellationFactorsHalf* spvTessLevel [[buffer(26)]])
{
- spvUnsafeArray<_RESERVED_IDENTIFIER_FIXUP_gl_PerVertex, 4> _18 = spvUnsafeArray<_RESERVED_IDENTIFIER_FIXUP_gl_PerVertex, 4>({ _RESERVED_IDENTIFIER_FIXUP_gl_PerVertex{ float4(0.0), 0.0, spvUnsafeArray<float, 1>({ 0.0 }), spvUnsafeArray<float, 1>({ 0.0 }) }, _RESERVED_IDENTIFIER_FIXUP_gl_PerVertex{ float4(0.0), 0.0, spvUnsafeArray<float, 1>({ 0.0 }), spvUnsafeArray<float, 1>({ 0.0 }) }, _RESERVED_IDENTIFIER_FIXUP_gl_PerVertex{ float4(0.0), 0.0, spvUnsafeArray<float, 1>({ 0.0 }), spvUnsafeArray<float, 1>({ 0.0 }) }, _RESERVED_IDENTIFIER_FIXUP_gl_PerVertex{ float4(0.0), 0.0, spvUnsafeArray<float, 1>({ 0.0 }), spvUnsafeArray<float, 1>({ 0.0 }) } });
- spvUnsafeArray<Verts, 4> _28 = spvUnsafeArray<Verts, 4>({ Verts{ 0.0, float2(0.0) }, Verts{ 0.0, float2(0.0) }, Verts{ 0.0, float2(0.0) }, Verts{ 0.0, float2(0.0) } });
+ spvUnsafeArray<_RESERVED_IDENTIFIER_FIXUP_gl_PerVertex, 4> _17 = spvUnsafeArray<_RESERVED_IDENTIFIER_FIXUP_gl_PerVertex, 4>({ _RESERVED_IDENTIFIER_FIXUP_gl_PerVertex{ float4(0.0), 0.0 }, _RESERVED_IDENTIFIER_FIXUP_gl_PerVertex{ float4(0.0), 0.0 }, _RESERVED_IDENTIFIER_FIXUP_gl_PerVertex{ float4(0.0), 0.0 }, _RESERVED_IDENTIFIER_FIXUP_gl_PerVertex{ float4(0.0), 0.0 } });
+ spvUnsafeArray<Verts, 4> _27 = spvUnsafeArray<Verts, 4>({ Verts{ 0.0, float2(0.0) }, Verts{ 0.0, float2(0.0) }, Verts{ 0.0, float2(0.0) }, Verts{ 0.0, float2(0.0) } });
device main0_out* gl_out = &spvOut[gl_PrimitiveID * 4];
- gl_out[gl_InvocationID].gl_Position = _18[gl_InvocationID]._RESERVED_IDENTIFIER_FIXUP_gl_Position;
- gl_out[gl_InvocationID].Verts_a = _28[gl_InvocationID].a;
- gl_out[gl_InvocationID].Verts_b = _28[gl_InvocationID].b;
+ gl_out[gl_InvocationID].gl_Position = _17[gl_InvocationID]._RESERVED_IDENTIFIER_FIXUP_gl_Position;
+ gl_out[gl_InvocationID].gl_PointSize = _17[gl_InvocationID]._RESERVED_IDENTIFIER_FIXUP_gl_PointSize;
+ gl_out[gl_InvocationID].Verts_a = _27[gl_InvocationID].a;
+ gl_out[gl_InvocationID].Verts_b = _27[gl_InvocationID].b;
gl_out[gl_InvocationID].gl_Position = float4(1.0);
gl_out[gl_InvocationID].Verts_a = float(gl_InvocationID);
}
diff --git a/reference/shaders-msl-no-opt/asm/vert/builtin-output-initializer.asm.vert b/reference/shaders-msl-no-opt/asm/vert/builtin-output-initializer.asm.vert
index 3736533..54b88ba 100644
--- a/reference/shaders-msl-no-opt/asm/vert/builtin-output-initializer.asm.vert
+++ b/reference/shaders-msl-no-opt/asm/vert/builtin-output-initializer.asm.vert
@@ -1,61 +1,19 @@
-#pragma clang diagnostic ignored "-Wmissing-prototypes"
-#pragma clang diagnostic ignored "-Wmissing-braces"
-
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
-template<typename T, size_t Num>
-struct spvUnsafeArray
-{
- T elements[Num ? Num : 1];
-
- thread T& operator [] (size_t pos) thread
- {
- return elements[pos];
- }
- constexpr const thread T& operator [] (size_t pos) const thread
- {
- return elements[pos];
- }
-
- device T& operator [] (size_t pos) device
- {
- return elements[pos];
- }
- constexpr const device T& operator [] (size_t pos) const device
- {
- return elements[pos];
- }
-
- constexpr const constant T& operator [] (size_t pos) const constant
- {
- return elements[pos];
- }
-
- threadgroup T& operator [] (size_t pos) threadgroup
- {
- return elements[pos];
- }
- constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
- {
- return elements[pos];
- }
-};
-
-constant spvUnsafeArray<float, 1> _23 = spvUnsafeArray<float, 1>({ 0.0 });
-constant spvUnsafeArray<float, 1> _24 = spvUnsafeArray<float, 1>({ 0.0 });
-
struct main0_out
{
float4 gl_Position [[position]];
+ float gl_PointSize [[point_size]];
};
vertex main0_out main0()
{
main0_out out = {};
out.gl_Position = float4(0.0);
+ out.gl_PointSize = 0.0;
out.gl_Position = float4(1.0);
return out;
}
diff --git a/reference/shaders-msl-no-opt/asm/vert/duplicate-view-index.asm.vert b/reference/shaders-msl-no-opt/asm/vert/duplicate-view-index.asm.vert
new file mode 100644
index 0000000..f007a67
--- /dev/null
+++ b/reference/shaders-msl-no-opt/asm/vert/duplicate-view-index.asm.vert
@@ -0,0 +1,19 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+ float4 gl_Position [[position]];
+ uint gl_Layer [[render_target_array_index]];
+};
+
+vertex main0_out main0(uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]])
+{
+ main0_out out = {};
+ const uint gl_ViewIndex = 0;
+ out.gl_Position = float4(float(int(gl_ViewIndex)));
+ return out;
+}
+
diff --git a/reference/shaders-msl-no-opt/vert/uninitialized-vertex-output.vert b/reference/shaders-msl-no-opt/vert/uninitialized-vertex-output.vert
new file mode 100644
index 0000000..f8209ae
--- /dev/null
+++ b/reference/shaders-msl-no-opt/vert/uninitialized-vertex-output.vert
@@ -0,0 +1,18 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+ float4 Pos [[user(locn0)]];
+ float4 gl_Position [[position]];
+};
+
+vertex main0_out main0()
+{
+ main0_out out = {};
+ out.gl_Position = float4(1.0);
+ return out;
+}
+
diff --git a/reference/shaders-msl/asm/vert/fake-builtin-input.asm.vert b/reference/shaders-msl/asm/vert/fake-builtin-input.asm.vert
index f9fcbc8..3079ae9 100644
--- a/reference/shaders-msl/asm/vert/fake-builtin-input.asm.vert
+++ b/reference/shaders-msl/asm/vert/fake-builtin-input.asm.vert
@@ -5,6 +5,7 @@
struct main0_out
{
+ half4 out_var_SV_Target [[user(locn0)]];
float4 gl_Position [[position]];
};
diff --git a/reference/shaders-no-opt/asm/frag/only-initializer-frag-depth.asm.frag b/reference/shaders-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
new file mode 100644
index 0000000..1041f71
--- /dev/null
+++ b/reference/shaders-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
@@ -0,0 +1,8 @@
+#version 450
+
+const float _3_init = 0.5;
+void main()
+{
+ gl_FragDepth = _3_init;
+}
+
diff --git a/reference/shaders-no-opt/asm/tesc/array-of-block-output-initializer.asm.tesc b/reference/shaders-no-opt/asm/tesc/array-of-block-output-initializer.asm.tesc
index 83e2651..13e1d32 100644
--- a/reference/shaders-no-opt/asm/tesc/array-of-block-output-initializer.asm.tesc
+++ b/reference/shaders-no-opt/asm/tesc/array-of-block-output-initializer.asm.tesc
@@ -1,6 +1,14 @@
#version 450
layout(vertices = 4) out;
+out gl_PerVertex
+{
+ vec4 gl_Position;
+ float gl_PointSize;
+ float gl_ClipDistance[1];
+ float gl_CullDistance[1];
+} gl_out[4];
+
layout(location = 0) patch out vert
{
float v0;
@@ -23,6 +31,8 @@
const vec4 _3_0_init[4] = vec4[](vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0));
const float _3_1_init[4] = float[](0.0, 0.0, 0.0, 0.0);
+const float _3_2_init[4][1] = float[][](float[](0.0), float[](0.0), float[](0.0), float[](0.0));
+const float _3_3_init[4][1] = float[][](float[](0.0), float[](0.0), float[](0.0), float[](0.0));
const float _6_0_init[2] = float[](0.0, 0.0);
const float _6_1_init[2] = float[](0.0, 0.0);
const float _7_init = 0.0;
@@ -34,6 +44,8 @@
{
gl_out[gl_InvocationID].gl_Position = _3_0_init[gl_InvocationID];
gl_out[gl_InvocationID].gl_PointSize = _3_1_init[gl_InvocationID];
+ gl_out[gl_InvocationID].gl_ClipDistance = _3_2_init[gl_InvocationID];
+ gl_out[gl_InvocationID].gl_CullDistance = _3_3_init[gl_InvocationID];
if (gl_InvocationID == 0)
{
_5.v0 = 0.0;
diff --git a/reference/shaders-no-opt/asm/vert/builtin-output-initializer.asm.vert b/reference/shaders-no-opt/asm/vert/builtin-output-initializer.asm.vert
index 4b77870..b449f08 100644
--- a/reference/shaders-no-opt/asm/vert/builtin-output-initializer.asm.vert
+++ b/reference/shaders-no-opt/asm/vert/builtin-output-initializer.asm.vert
@@ -1,9 +1,14 @@
#version 450
+out float gl_ClipDistance[1];
+out float gl_CullDistance[1];
+
void main()
{
gl_Position = vec4(0.0);
gl_PointSize = 0.0;
+ gl_ClipDistance = float[](0.0);
+ gl_CullDistance = float[](0.0);
gl_Position = vec4(1.0);
}
diff --git a/reference/shaders/asm/vert/empty-io.asm.vert b/reference/shaders/asm/vert/empty-io.asm.vert
index cc432cb..91e65d6 100644
--- a/reference/shaders/asm/vert/empty-io.asm.vert
+++ b/reference/shaders/asm/vert/empty-io.asm.vert
@@ -16,6 +16,7 @@
};
layout(location = 0) in vec4 position;
+layout(location = 0) out VSOutput_1 _entryPointOutput;
VSOutput _main(VSInput _input)
{
diff --git a/shaders-hlsl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag b/shaders-hlsl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
new file mode 100644
index 0000000..17aab1d
--- /dev/null
+++ b/shaders-hlsl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
@@ -0,0 +1,25 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 10
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %gl_FragDepth
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main DepthReplacing
+ OpSource GLSL 450
+ OpName %main "main"
+ OpName %gl_FragDepth "gl_FragDepth"
+ OpDecorate %gl_FragDepth BuiltIn FragDepth
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+%_ptr_Output_float = OpTypePointer Output %float
+ %float_0_5 = OpConstant %float 0.5
+%gl_FragDepth = OpVariable %_ptr_Output_float Output %float_0_5
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/shaders-msl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag b/shaders-msl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
new file mode 100644
index 0000000..17aab1d
--- /dev/null
+++ b/shaders-msl-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
@@ -0,0 +1,25 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 10
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %gl_FragDepth
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main DepthReplacing
+ OpSource GLSL 450
+ OpName %main "main"
+ OpName %gl_FragDepth "gl_FragDepth"
+ OpDecorate %gl_FragDepth BuiltIn FragDepth
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+%_ptr_Output_float = OpTypePointer Output %float
+ %float_0_5 = OpConstant %float 0.5
+%gl_FragDepth = OpVariable %_ptr_Output_float Output %float_0_5
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/shaders-msl-no-opt/asm/tesc/builtin-control-point-initializer.asm.tesc b/shaders-msl-no-opt/asm/tesc/builtin-control-point-initializer.asm.tesc
index a04e0dd..1219183 100644
--- a/shaders-msl-no-opt/asm/tesc/builtin-control-point-initializer.asm.tesc
+++ b/shaders-msl-no-opt/asm/tesc/builtin-control-point-initializer.asm.tesc
@@ -13,8 +13,6 @@
OpName %gl_PerVertex "gl_PerVertex"
OpMemberName %gl_PerVertex 0 "gl_Position"
OpMemberName %gl_PerVertex 1 "gl_PointSize"
- OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
- OpMemberName %gl_PerVertex 3 "gl_CullDistance"
OpName %gl_out "gl_out"
OpName %gl_InvocationID "gl_InvocationID"
OpName %Verts "Verts"
@@ -23,8 +21,6 @@
OpName %verts "verts"
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
- OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
- OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
OpDecorate %gl_PerVertex Block
OpDecorate %gl_InvocationID BuiltIn InvocationId
OpDecorate %Verts Block
@@ -35,8 +31,7 @@
%v4float = OpTypeVector %float 4
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1
-%_arr_float_uint_1 = OpTypeArray %float %uint_1
-%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float
%uint_4 = OpConstant %uint 4
%_arr_gl_PerVertex_uint_4 = OpTypeArray %gl_PerVertex %uint_4
%_ptr_Output__arr_gl_PerVertex_uint_4 = OpTypePointer Output %_arr_gl_PerVertex_uint_4
diff --git a/shaders-msl-no-opt/asm/vert/builtin-output-initializer.asm.vert b/shaders-msl-no-opt/asm/vert/builtin-output-initializer.asm.vert
index aaa6866..a00d4b7 100644
--- a/shaders-msl-no-opt/asm/vert/builtin-output-initializer.asm.vert
+++ b/shaders-msl-no-opt/asm/vert/builtin-output-initializer.asm.vert
@@ -12,13 +12,9 @@
OpName %gl_PerVertex "gl_PerVertex"
OpMemberName %gl_PerVertex 0 "gl_Position"
OpMemberName %gl_PerVertex 1 "gl_PointSize"
- OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
- OpMemberName %gl_PerVertex 3 "gl_CullDistance"
OpName %_ ""
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
- OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
- OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
OpDecorate %gl_PerVertex Block
%void = OpTypeVoid
%3 = OpTypeFunction %void
@@ -26,8 +22,7 @@
%v4float = OpTypeVector %float 4
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1
-%_arr_float_uint_1 = OpTypeArray %float %uint_1
-%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float
%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
%zero = OpConstantNull %gl_PerVertex
%_ = OpVariable %_ptr_Output_gl_PerVertex Output %zero
diff --git a/shaders-msl-no-opt/asm/vert/duplicate-view-index.asm.vert b/shaders-msl-no-opt/asm/vert/duplicate-view-index.asm.vert
new file mode 100644
index 0000000..00ad1ee
--- /dev/null
+++ b/shaders-msl-no-opt/asm/vert/duplicate-view-index.asm.vert
@@ -0,0 +1,66 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 23
+; Schema: 0
+ OpCapability Shader
+ OpCapability MultiView
+ OpExtension "SPV_KHR_multiview"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %_ %gl_ViewIndex
+ OpEntryPoint Vertex %main2 "main2" %_ %gl_ViewIndex2
+ OpSource GLSL 450
+ OpSourceExtension "GL_EXT_multiview"
+ OpName %main "main"
+ OpName %gl_PerVertex "gl_PerVertex"
+ OpMemberName %gl_PerVertex 0 "gl_Position"
+ OpMemberName %gl_PerVertex 1 "gl_PointSize"
+ OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
+ OpMemberName %gl_PerVertex 3 "gl_CullDistance"
+ OpName %_ ""
+ OpName %gl_ViewIndex "gl_ViewIndex"
+ OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+ OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+ OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+ OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
+ OpDecorate %gl_PerVertex Block
+ OpDecorate %gl_ViewIndex BuiltIn ViewIndex
+ OpDecorate %gl_ViewIndex2 BuiltIn ViewIndex
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+ %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_ViewIndex = OpVariable %_ptr_Input_int Input
+%gl_ViewIndex2 = OpVariable %_ptr_Input_int Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %18 = OpLoad %int %gl_ViewIndex
+ %19 = OpConvertSToF %float %18
+ %20 = OpCompositeConstruct %v4float %19 %19 %19 %19
+ %22 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %22 %20
+ OpReturn
+ OpFunctionEnd
+
+ %main2 = OpFunction %void None %3
+ %100 = OpLabel
+ %101 = OpLoad %int %gl_ViewIndex2
+ %102 = OpConvertSToF %float %101
+ %103 = OpCompositeConstruct %v4float %102 %102 %102 %102
+ %104 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+ OpStore %104 %103
+
+ OpReturn
+ OpFunctionEnd
diff --git a/shaders-msl-no-opt/vert/uninitialized-vertex-output.vert b/shaders-msl-no-opt/vert/uninitialized-vertex-output.vert
new file mode 100644
index 0000000..54c7afd
--- /dev/null
+++ b/shaders-msl-no-opt/vert/uninitialized-vertex-output.vert
@@ -0,0 +1,8 @@
+#version 450
+
+layout(location = 0) out vec4 Pos;
+
+void main()
+{
+ gl_Position = vec4(1.0);
+}
diff --git a/shaders-no-opt/asm/frag/only-initializer-frag-depth.asm.frag b/shaders-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
new file mode 100644
index 0000000..17aab1d
--- /dev/null
+++ b/shaders-no-opt/asm/frag/only-initializer-frag-depth.asm.frag
@@ -0,0 +1,25 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 10
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %gl_FragDepth
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main DepthReplacing
+ OpSource GLSL 450
+ OpName %main "main"
+ OpName %gl_FragDepth "gl_FragDepth"
+ OpDecorate %gl_FragDepth BuiltIn FragDepth
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+%_ptr_Output_float = OpTypePointer Output %float
+ %float_0_5 = OpConstant %float 0.5
+%gl_FragDepth = OpVariable %_ptr_Output_float Output %float_0_5
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/spirv_cross.cpp b/spirv_cross.cpp
index 5c1b3eb..5fd7876 100644
--- a/spirv_cross.cpp
+++ b/spirv_cross.cpp
@@ -805,9 +805,17 @@
InterfaceVariableAccessHandler handler(*this, variables);
traverse_all_reachable_opcodes(get<SPIRFunction>(ir.default_entry_point), handler);
- // Make sure we preserve output variables which are only initialized, but never accessed by any code.
ir.for_each_typed_id<SPIRVariable>([&](uint32_t, const SPIRVariable &var) {
- if (var.storage == StorageClassOutput && var.initializer != ID(0))
+ if (var.storage != StorageClassOutput)
+ return;
+ if (!interface_variable_exists_in_entry_point(var.self))
+ return;
+
+ // An output variable which is just declared (but uninitialized) might be read by subsequent stages
+ // so we should force-enable these outputs,
+ // since compilation will fail if a subsequent stage attempts to read from the variable in question.
+ // Also, make sure we preserve output variables which are only initialized, but never accessed by any code.
+ if (var.initializer != ID(0) || get_execution_model() != ExecutionModelFragment)
variables.insert(var.self);
});
@@ -3839,23 +3847,55 @@
}
}
-bool Compiler::ActiveBuiltinHandler::handle(spv::Op opcode, const uint32_t *args, uint32_t length)
+void Compiler::ActiveBuiltinHandler::add_if_builtin(uint32_t id, bool allow_blocks)
{
- const auto add_if_builtin = [&](uint32_t id) {
- // Only handles variables here.
- // Builtins which are part of a block are handled in AccessChain.
- auto *var = compiler.maybe_get<SPIRVariable>(id);
- auto &decorations = compiler.ir.meta[id].decoration;
- if (var && decorations.builtin)
+ // Only handle plain variables here.
+ // Builtins which are part of a block are handled in AccessChain.
+ // If allow_blocks is used however, this is to handle initializers of blocks,
+ // which implies that all members are written to.
+
+ auto *var = compiler.maybe_get<SPIRVariable>(id);
+ auto *m = compiler.ir.find_meta(id);
+ if (var && m)
+ {
+ auto &type = compiler.get<SPIRType>(var->basetype);
+ auto &decorations = m->decoration;
+ auto &flags = type.storage == StorageClassInput ?
+ compiler.active_input_builtins : compiler.active_output_builtins;
+ if (decorations.builtin)
{
- auto &type = compiler.get<SPIRType>(var->basetype);
- auto &flags =
- type.storage == StorageClassInput ? compiler.active_input_builtins : compiler.active_output_builtins;
flags.set(decorations.builtin_type);
handle_builtin(type, decorations.builtin_type, decorations.decoration_flags);
}
- };
+ else if (allow_blocks && compiler.has_decoration(type.self, DecorationBlock))
+ {
+ uint32_t member_count = uint32_t(type.member_types.size());
+ for (uint32_t i = 0; i < member_count; i++)
+ {
+ if (compiler.has_member_decoration(type.self, i, DecorationBuiltIn))
+ {
+ auto &member_type = compiler.get<SPIRType>(type.member_types[i]);
+ BuiltIn builtin = BuiltIn(compiler.get_member_decoration(type.self, i, DecorationBuiltIn));
+ flags.set(builtin);
+ handle_builtin(member_type, builtin, compiler.get_member_decoration_bitset(type.self, i));
+ }
+ }
+ }
+ }
+}
+void Compiler::ActiveBuiltinHandler::add_if_builtin(uint32_t id)
+{
+ add_if_builtin(id, false);
+}
+
+void Compiler::ActiveBuiltinHandler::add_if_builtin_or_block(uint32_t id)
+{
+ add_if_builtin(id, true);
+}
+
+bool Compiler::ActiveBuiltinHandler::handle(spv::Op opcode, const uint32_t *args, uint32_t length)
+{
switch (opcode)
{
case OpStore:
@@ -3993,6 +4033,17 @@
clip_distance_count = 0;
ActiveBuiltinHandler handler(*this);
traverse_all_reachable_opcodes(get<SPIRFunction>(ir.default_entry_point), handler);
+
+ ir.for_each_typed_id<SPIRVariable>([&](uint32_t, const SPIRVariable &var) {
+ if (var.storage != StorageClassOutput)
+ return;
+ if (!interface_variable_exists_in_entry_point(var.self))
+ return;
+
+ // Also, make sure we preserve output variables which are only initialized, but never accessed by any code.
+ if (var.initializer != ID(0))
+ handler.add_if_builtin_or_block(var.self);
+ });
}
// Returns whether this shader uses a builtin of the storage class
diff --git a/spirv_cross.hpp b/spirv_cross.hpp
index 47f1d79..016d13e 100644
--- a/spirv_cross.hpp
+++ b/spirv_cross.hpp
@@ -833,6 +833,9 @@
Compiler &compiler;
void handle_builtin(const SPIRType &type, spv::BuiltIn builtin, const Bitset &decoration_flags);
+ void add_if_builtin(uint32_t id);
+ void add_if_builtin_or_block(uint32_t id);
+ void add_if_builtin(uint32_t id, bool allow_blocks);
};
bool traverse_all_reachable_opcodes(const SPIRBlock &block, OpcodeHandler &handler) const;
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp
index 3b5bd8e..ab47941 100644
--- a/spirv_glsl.cpp
+++ b/spirv_glsl.cpp
@@ -2801,6 +2801,13 @@
}
});
+ // If we're declaring clip/cull planes with control points we need to force block declaration.
+ if (get_execution_model() == ExecutionModelTessellationControl &&
+ (clip_distance_count || cull_distance_count))
+ {
+ should_force = true;
+ }
+
return should_force;
}
diff --git a/spirv_msl.cpp b/spirv_msl.cpp
index 688da23..daca7c7 100644
--- a/spirv_msl.cpp
+++ b/spirv_msl.cpp
@@ -198,9 +198,12 @@
bool has_workgroup_size = false;
uint32_t workgroup_id_type = 0;
- // FIXME: Investigate the fact that there are no checks for the entry point interface variables.
ir.for_each_typed_id<SPIRVariable>([&](uint32_t, SPIRVariable &var) {
- if (!ir.meta[var.self].decoration.builtin)
+ if (var.storage != StorageClassInput && var.storage != StorageClassOutput)
+ return;
+ if (!interface_variable_exists_in_entry_point(var.self))
+ return;
+ if (!has_decoration(var.self, DecorationBuiltIn))
return;
BuiltIn builtin = ir.meta[var.self].decoration.builtin_type;
@@ -10586,11 +10589,14 @@
// Builtin variables
SmallVector<pair<SPIRVariable *, BuiltIn>, 8> active_builtins;
ir.for_each_typed_id<SPIRVariable>([&](uint32_t var_id, SPIRVariable &var) {
+ if (var.storage != StorageClassInput)
+ return;
+
auto bi_type = BuiltIn(get_decoration(var_id, DecorationBuiltIn));
// 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) &&
+ if (is_builtin_variable(var) &&
get_variable_data_type(var).basetype != SPIRType::Struct &&
get_variable_data_type(var).basetype != SPIRType::ControlPointArray)
{
@@ -10624,8 +10630,7 @@
}
}
- if (var.storage == StorageClassInput &&
- has_extended_decoration(var_id, SPIRVCrossDecorationBuiltInDispatchBase))
+ if (has_extended_decoration(var_id, SPIRVCrossDecorationBuiltInDispatchBase))
{
// This is a special implicit builtin, not corresponding to any SPIR-V builtin,
// which holds the base that was passed to vkCmdDispatchBase() or vkCmdDrawIndexed(). If it's present,
@@ -10637,8 +10642,7 @@
ep_args += type_to_glsl(get_variable_data_type(var)) + " " + to_expression(var_id) + " [[grid_origin]]";
}
- if (var.storage == StorageClassInput &&
- has_extended_decoration(var_id, SPIRVCrossDecorationBuiltInStageInputSize))
+ if (has_extended_decoration(var_id, SPIRVCrossDecorationBuiltInStageInputSize))
{
// This is another special implicit builtin, not corresponding to any SPIR-V builtin,
// which holds the number of vertices and instances to draw. If it's present,
@@ -11175,6 +11179,11 @@
uint32_t var_id = var.self;
BuiltIn bi_type = ir.meta[var_id].decoration.builtin_type;
+ if (var.storage != StorageClassInput && var.storage != StorageClassOutput)
+ return;
+ if (!interface_variable_exists_in_entry_point(var.self))
+ return;
+
if (var.storage == StorageClassInput && is_builtin_variable(var) && active_input_builtins.get(bi_type))
{
switch (bi_type)