Skip to content

Commit 0286442

Browse files
Add test case for interlocks in control flow.
1 parent 1dc7e93 commit 0286442

6 files changed

Lines changed: 507 additions & 0 deletions

File tree

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
RasterizerOrderedByteAddressBuffer _7 : register(u1, space0);
2+
RWByteAddressBuffer _13 : register(u2, space0);
3+
RasterizerOrderedByteAddressBuffer _9 : register(u0, space0);
4+
5+
static float4 gl_FragCoord;
6+
struct SPIRV_Cross_Input
7+
{
8+
float4 gl_FragCoord : SV_Position;
9+
};
10+
11+
void callee2()
12+
{
13+
int _44 = int(gl_FragCoord.x);
14+
_7.Store(_44 * 4 + 0, _7.Load(_44 * 4 + 0) + 1u);
15+
}
16+
17+
void callee()
18+
{
19+
int _52 = int(gl_FragCoord.x);
20+
_9.Store(_52 * 4 + 0, _9.Load(_52 * 4 + 0) + 1u);
21+
callee2();
22+
if (true)
23+
{
24+
}
25+
}
26+
27+
void _35()
28+
{
29+
_13.Store(int(gl_FragCoord.x) * 4 + 0, 4u);
30+
}
31+
32+
void frag_main()
33+
{
34+
callee();
35+
_35();
36+
}
37+
38+
void main(SPIRV_Cross_Input stage_input)
39+
{
40+
gl_FragCoord = stage_input.gl_FragCoord;
41+
frag_main();
42+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma clang diagnostic ignored "-Wmissing-prototypes"
2+
3+
#include <metal_stdlib>
4+
#include <simd/simd.h>
5+
6+
using namespace metal;
7+
8+
struct SSBO1
9+
{
10+
uint values1[1];
11+
};
12+
13+
struct _12
14+
{
15+
uint _m0[1];
16+
};
17+
18+
struct SSBO0
19+
{
20+
uint values0[1];
21+
};
22+
23+
inline void callee2(thread float4& gl_FragCoord, device SSBO1& v_7)
24+
{
25+
int _44 = int(gl_FragCoord.x);
26+
v_7.values1[_44]++;
27+
}
28+
29+
inline void callee(thread float4& gl_FragCoord, device SSBO1& v_7, device SSBO0& v_9)
30+
{
31+
int _52 = int(gl_FragCoord.x);
32+
v_9.values0[_52]++;
33+
callee2(gl_FragCoord, v_7);
34+
if (true)
35+
{
36+
}
37+
}
38+
39+
inline void _35(thread float4& gl_FragCoord, device _12& v_13)
40+
{
41+
v_13._m0[int(gl_FragCoord.x)] = 4u;
42+
}
43+
44+
fragment void main0(device SSBO1& v_7 [[buffer(0), raster_order_group(0)]], device _12& v_13 [[buffer(1)]], device SSBO0& v_9 [[buffer(2), raster_order_group(0)]], float4 gl_FragCoord [[position]])
45+
{
46+
callee(gl_FragCoord, v_7, v_9);
47+
_35(gl_FragCoord, v_13);
48+
}
49+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#version 450
2+
#extension GL_ARB_fragment_shader_interlock : require
3+
layout(pixel_interlock_ordered) in;
4+
5+
layout(binding = 1, std430) buffer SSBO1
6+
{
7+
uint values1[];
8+
} _7;
9+
10+
layout(binding = 2, std430) buffer _12_13
11+
{
12+
uint _m0[];
13+
} _13;
14+
15+
layout(binding = 0, std430) buffer SSBO0
16+
{
17+
uint values0[];
18+
} _9;
19+
20+
void callee2()
21+
{
22+
int _44 = int(gl_FragCoord.x);
23+
_7.values1[_44]++;
24+
}
25+
26+
void callee()
27+
{
28+
int _52 = int(gl_FragCoord.x);
29+
_9.values0[_52]++;
30+
callee2();
31+
if (true)
32+
{
33+
}
34+
}
35+
36+
void _35()
37+
{
38+
_13._m0[int(gl_FragCoord.x)] = 4u;
39+
}
40+
41+
void spvMainInterlockedBody()
42+
{
43+
callee();
44+
_35();
45+
}
46+
47+
void main()
48+
{
49+
// Interlocks were used in a way not compatible with GLSL, this is very slow.
50+
beginInvocationInterlockARB();
51+
spvMainInterlockedBody();
52+
endInvocationInterlockARB();
53+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
; SPIR-V
2+
; Version: 1.0
3+
; Generator: Khronos Glslang Reference Front End; 7
4+
; Bound: 45
5+
; Schema: 0
6+
OpCapability Shader
7+
OpCapability FragmentShaderPixelInterlockEXT
8+
OpExtension "SPV_EXT_fragment_shader_interlock"
9+
%1 = OpExtInstImport "GLSL.std.450"
10+
OpMemoryModel Logical GLSL450
11+
OpEntryPoint Fragment %main "main" %gl_FragCoord
12+
OpExecutionMode %main OriginUpperLeft
13+
OpExecutionMode %main PixelInterlockOrderedEXT
14+
OpSource GLSL 450
15+
OpSourceExtension "GL_ARB_fragment_shader_interlock"
16+
OpName %main "main"
17+
OpName %callee2_ "callee2("
18+
OpName %callee_ "callee("
19+
OpName %SSBO1 "SSBO1"
20+
OpMemberName %SSBO1 0 "values1"
21+
OpName %_ ""
22+
OpName %gl_FragCoord "gl_FragCoord"
23+
OpName %SSBO0 "SSBO0"
24+
OpMemberName %SSBO0 0 "values0"
25+
OpName %__0 ""
26+
OpDecorate %_runtimearr_uint ArrayStride 4
27+
OpMemberDecorate %SSBO1 0 Offset 0
28+
OpDecorate %SSBO1 BufferBlock
29+
OpDecorate %_ DescriptorSet 0
30+
OpDecorate %_ Binding 1
31+
OpDecorate %gl_FragCoord BuiltIn FragCoord
32+
OpDecorate %_runtimearr_uint_0 ArrayStride 4
33+
OpMemberDecorate %SSBO0 0 Offset 0
34+
OpDecorate %SSBO0 BufferBlock
35+
OpDecorate %__0 DescriptorSet 0
36+
OpDecorate %__0 Binding 0
37+
38+
OpMemberDecorate %SSBO2 0 Offset 0
39+
OpDecorate %SSBO2 BufferBlock
40+
OpDecorate %ssbo2 DescriptorSet 0
41+
OpDecorate %ssbo2 Binding 2
42+
43+
%void = OpTypeVoid
44+
%3 = OpTypeFunction %void
45+
%uint = OpTypeInt 32 0
46+
%_runtimearr_uint = OpTypeRuntimeArray %uint
47+
%SSBO1 = OpTypeStruct %_runtimearr_uint
48+
%SSBO2 = OpTypeStruct %_runtimearr_uint
49+
%_ptr_Uniform_SSBO1 = OpTypePointer Uniform %SSBO1
50+
%_ptr_Uniform_SSBO2 = OpTypePointer Uniform %SSBO2
51+
%_ = OpVariable %_ptr_Uniform_SSBO1 Uniform
52+
%ssbo2 = OpVariable %_ptr_Uniform_SSBO2 Uniform
53+
%int = OpTypeInt 32 1
54+
%int_0 = OpConstant %int 0
55+
%uint_4 = OpConstant %uint 4
56+
%float = OpTypeFloat 32
57+
%v4float = OpTypeVector %float 4
58+
%bool = OpTypeBool
59+
%true = OpConstantTrue %bool
60+
%_ptr_Input_v4float = OpTypePointer Input %v4float
61+
%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
62+
%uint_0 = OpConstant %uint 0
63+
%_ptr_Input_float = OpTypePointer Input %float
64+
%uint_1 = OpConstant %uint 1
65+
%_ptr_Uniform_uint = OpTypePointer Uniform %uint
66+
%_runtimearr_uint_0 = OpTypeRuntimeArray %uint
67+
%SSBO0 = OpTypeStruct %_runtimearr_uint_0
68+
%_ptr_Uniform_SSBO0 = OpTypePointer Uniform %SSBO0
69+
%__0 = OpVariable %_ptr_Uniform_SSBO0 Uniform
70+
%main = OpFunction %void None %3
71+
%5 = OpLabel
72+
%44 = OpFunctionCall %void %callee_
73+
%callee3_res = OpFunctionCall %void %callee3_
74+
OpReturn
75+
OpFunctionEnd
76+
77+
%callee3_ = OpFunction %void None %3
78+
%calle3_block = OpLabel
79+
%frag_coord_x_ptr = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_0
80+
%frag_coord_x = OpLoad %float %frag_coord_x_ptr
81+
%frag_coord_int = OpConvertFToS %int %frag_coord_x
82+
%ssbo_ptr = OpAccessChain %_ptr_Uniform_uint %ssbo2 %int_0 %frag_coord_int
83+
OpStore %ssbo_ptr %uint_4
84+
OpReturn
85+
OpFunctionEnd
86+
87+
%callee2_ = OpFunction %void None %3
88+
%7 = OpLabel
89+
%23 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_0
90+
%24 = OpLoad %float %23
91+
%25 = OpConvertFToS %int %24
92+
%28 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 %25
93+
%29 = OpLoad %uint %28
94+
%30 = OpIAdd %uint %29 %uint_1
95+
%31 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 %25
96+
OpStore %31 %30
97+
OpReturn
98+
OpFunctionEnd
99+
%callee_ = OpFunction %void None %3
100+
%9 = OpLabel
101+
%36 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_0
102+
%37 = OpLoad %float %36
103+
%38 = OpConvertFToS %int %37
104+
%39 = OpAccessChain %_ptr_Uniform_uint %__0 %int_0 %38
105+
%40 = OpLoad %uint %39
106+
%41 = OpIAdd %uint %40 %uint_1
107+
%42 = OpAccessChain %_ptr_Uniform_uint %__0 %int_0 %38
108+
OpStore %42 %41
109+
%43 = OpFunctionCall %void %callee2_
110+
111+
OpSelectionMerge %merged_block None
112+
OpBranchConditional %true %dummy_block %merged_block
113+
%dummy_block = OpLabel
114+
OpBeginInvocationInterlockEXT
115+
OpEndInvocationInterlockEXT
116+
OpBranch %merged_block
117+
118+
%merged_block = OpLabel
119+
OpReturn
120+
121+
OpFunctionEnd
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
; SPIR-V
2+
; Version: 1.0
3+
; Generator: Khronos Glslang Reference Front End; 7
4+
; Bound: 45
5+
; Schema: 0
6+
OpCapability Shader
7+
OpCapability FragmentShaderPixelInterlockEXT
8+
OpExtension "SPV_EXT_fragment_shader_interlock"
9+
%1 = OpExtInstImport "GLSL.std.450"
10+
OpMemoryModel Logical GLSL450
11+
OpEntryPoint Fragment %main "main" %gl_FragCoord
12+
OpExecutionMode %main OriginUpperLeft
13+
OpExecutionMode %main PixelInterlockOrderedEXT
14+
OpSource GLSL 450
15+
OpSourceExtension "GL_ARB_fragment_shader_interlock"
16+
OpName %main "main"
17+
OpName %callee2_ "callee2("
18+
OpName %callee_ "callee("
19+
OpName %SSBO1 "SSBO1"
20+
OpMemberName %SSBO1 0 "values1"
21+
OpName %_ ""
22+
OpName %gl_FragCoord "gl_FragCoord"
23+
OpName %SSBO0 "SSBO0"
24+
OpMemberName %SSBO0 0 "values0"
25+
OpName %__0 ""
26+
OpDecorate %_runtimearr_uint ArrayStride 4
27+
OpMemberDecorate %SSBO1 0 Offset 0
28+
OpDecorate %SSBO1 BufferBlock
29+
OpDecorate %_ DescriptorSet 0
30+
OpDecorate %_ Binding 1
31+
OpDecorate %gl_FragCoord BuiltIn FragCoord
32+
OpDecorate %_runtimearr_uint_0 ArrayStride 4
33+
OpMemberDecorate %SSBO0 0 Offset 0
34+
OpDecorate %SSBO0 BufferBlock
35+
OpDecorate %__0 DescriptorSet 0
36+
OpDecorate %__0 Binding 0
37+
38+
OpMemberDecorate %SSBO2 0 Offset 0
39+
OpDecorate %SSBO2 BufferBlock
40+
OpDecorate %ssbo2 DescriptorSet 0
41+
OpDecorate %ssbo2 Binding 2
42+
43+
%void = OpTypeVoid
44+
%3 = OpTypeFunction %void
45+
%uint = OpTypeInt 32 0
46+
%_runtimearr_uint = OpTypeRuntimeArray %uint
47+
%SSBO1 = OpTypeStruct %_runtimearr_uint
48+
%SSBO2 = OpTypeStruct %_runtimearr_uint
49+
%_ptr_Uniform_SSBO1 = OpTypePointer Uniform %SSBO1
50+
%_ptr_Uniform_SSBO2 = OpTypePointer Uniform %SSBO2
51+
%_ = OpVariable %_ptr_Uniform_SSBO1 Uniform
52+
%ssbo2 = OpVariable %_ptr_Uniform_SSBO2 Uniform
53+
%int = OpTypeInt 32 1
54+
%int_0 = OpConstant %int 0
55+
%uint_4 = OpConstant %uint 4
56+
%float = OpTypeFloat 32
57+
%v4float = OpTypeVector %float 4
58+
%bool = OpTypeBool
59+
%true = OpConstantTrue %bool
60+
%_ptr_Input_v4float = OpTypePointer Input %v4float
61+
%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
62+
%uint_0 = OpConstant %uint 0
63+
%_ptr_Input_float = OpTypePointer Input %float
64+
%uint_1 = OpConstant %uint 1
65+
%_ptr_Uniform_uint = OpTypePointer Uniform %uint
66+
%_runtimearr_uint_0 = OpTypeRuntimeArray %uint
67+
%SSBO0 = OpTypeStruct %_runtimearr_uint_0
68+
%_ptr_Uniform_SSBO0 = OpTypePointer Uniform %SSBO0
69+
%__0 = OpVariable %_ptr_Uniform_SSBO0 Uniform
70+
%main = OpFunction %void None %3
71+
%5 = OpLabel
72+
%44 = OpFunctionCall %void %callee_
73+
%callee3_res = OpFunctionCall %void %callee3_
74+
OpReturn
75+
OpFunctionEnd
76+
77+
%callee3_ = OpFunction %void None %3
78+
%calle3_block = OpLabel
79+
%frag_coord_x_ptr = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_0
80+
%frag_coord_x = OpLoad %float %frag_coord_x_ptr
81+
%frag_coord_int = OpConvertFToS %int %frag_coord_x
82+
%ssbo_ptr = OpAccessChain %_ptr_Uniform_uint %ssbo2 %int_0 %frag_coord_int
83+
OpStore %ssbo_ptr %uint_4
84+
OpReturn
85+
OpFunctionEnd
86+
87+
%callee2_ = OpFunction %void None %3
88+
%7 = OpLabel
89+
%23 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_0
90+
%24 = OpLoad %float %23
91+
%25 = OpConvertFToS %int %24
92+
%28 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 %25
93+
%29 = OpLoad %uint %28
94+
%30 = OpIAdd %uint %29 %uint_1
95+
%31 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 %25
96+
OpStore %31 %30
97+
OpReturn
98+
OpFunctionEnd
99+
%callee_ = OpFunction %void None %3
100+
%9 = OpLabel
101+
%36 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_0
102+
%37 = OpLoad %float %36
103+
%38 = OpConvertFToS %int %37
104+
%39 = OpAccessChain %_ptr_Uniform_uint %__0 %int_0 %38
105+
%40 = OpLoad %uint %39
106+
%41 = OpIAdd %uint %40 %uint_1
107+
%42 = OpAccessChain %_ptr_Uniform_uint %__0 %int_0 %38
108+
OpStore %42 %41
109+
%43 = OpFunctionCall %void %callee2_
110+
111+
OpSelectionMerge %merged_block None
112+
OpBranchConditional %true %dummy_block %merged_block
113+
%dummy_block = OpLabel
114+
OpBeginInvocationInterlockEXT
115+
OpEndInvocationInterlockEXT
116+
OpBranch %merged_block
117+
118+
%merged_block = OpLabel
119+
OpReturn
120+
121+
OpFunctionEnd

0 commit comments

Comments
 (0)