1e5c31af7Sopenharmony_ci#!amber
2e5c31af7Sopenharmony_ci
3e5c31af7Sopenharmony_ci# Copyright 2019 Google LLC
4e5c31af7Sopenharmony_ci#
5e5c31af7Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
6e5c31af7Sopenharmony_ci# you may not use this file except in compliance with the License.
7e5c31af7Sopenharmony_ci# You may obtain a copy of the License at
8e5c31af7Sopenharmony_ci#
9e5c31af7Sopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
10e5c31af7Sopenharmony_ci#
11e5c31af7Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software
12e5c31af7Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
13e5c31af7Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14e5c31af7Sopenharmony_ci# See the License for the specific language governing permissions and
15e5c31af7Sopenharmony_ci# limitations under the License.
16e5c31af7Sopenharmony_ci
17e5c31af7Sopenharmony_ci
18e5c31af7Sopenharmony_ci# A test for a bug found by GraphicsFuzz.
19e5c31af7Sopenharmony_ci
20e5c31af7Sopenharmony_ci# Short description: A fragment shader with complex nested loops, breaks, etc.
21e5c31af7Sopenharmony_ci
22e5c31af7Sopenharmony_ci# The test passes because the shader always outputs the color red.
23e5c31af7Sopenharmony_ci# pickColor(i) returns red (because i is always 1).
24e5c31af7Sopenharmony_ci# mand() returns red because it sets iteration to 1, breaks from the first loop,
25e5c31af7Sopenharmony_ci# does not enter the if, and returns pickColor(iteration).
26e5c31af7Sopenharmony_ci# main() writes red because it sets data[0] to mand() and then writes
27e5c31af7Sopenharmony_ci# vec4(data[0], 1.0) to the color output variable.
28e5c31af7Sopenharmony_ci
29e5c31af7Sopenharmony_ci# Optimized using spirv-opt with the following arguments:
30e5c31af7Sopenharmony_ci# '-O'
31e5c31af7Sopenharmony_ci# spirv-opt commit hash: 06407250a169c6a03b3765e86619075af1a8c187
32e5c31af7Sopenharmony_ci
33e5c31af7Sopenharmony_ci
34e5c31af7Sopenharmony_ci
35e5c31af7Sopenharmony_ciSHADER vertex variant_vertex_shader PASSTHROUGH
36e5c31af7Sopenharmony_ci
37e5c31af7Sopenharmony_ci# variant_fragment_shader is derived from the following GLSL:
38e5c31af7Sopenharmony_ci# #version 310 es
39e5c31af7Sopenharmony_ci# precision highp float;
40e5c31af7Sopenharmony_ci#
41e5c31af7Sopenharmony_ci# precision highp int;
42e5c31af7Sopenharmony_ci#
43e5c31af7Sopenharmony_ci# layout(set = 0, binding = 0) uniform buf0
44e5c31af7Sopenharmony_ci# {
45e5c31af7Sopenharmony_ci#     vec2 injectionSwitch;
46e5c31af7Sopenharmony_ci# };
47e5c31af7Sopenharmony_ci# layout(location = 0) out vec4 _GLF_color;
48e5c31af7Sopenharmony_ci#
49e5c31af7Sopenharmony_ci# vec3 pickColor(int i)
50e5c31af7Sopenharmony_ci# {
51e5c31af7Sopenharmony_ci#     return vec3(float(i), 0.0, 0.0); // i is always 1
52e5c31af7Sopenharmony_ci# }
53e5c31af7Sopenharmony_ci#
54e5c31af7Sopenharmony_ci# // Returns vec3(1.0, 0.0, 0.0)
55e5c31af7Sopenharmony_ci# vec3 mand()
56e5c31af7Sopenharmony_ci# {
57e5c31af7Sopenharmony_ci#     float x = 0.0, y = 0.0;
58e5c31af7Sopenharmony_ci#     int iteration = 1;
59e5c31af7Sopenharmony_ci#     int k = 1;
60e5c31af7Sopenharmony_ci#     int iterationCap = 17;
61e5c31af7Sopenharmony_ci#     do
62e5c31af7Sopenharmony_ci#     {
63e5c31af7Sopenharmony_ci#         if (injectionSwitch.x < 10.0) // always true
64e5c31af7Sopenharmony_ci#         {
65e5c31af7Sopenharmony_ci#             break;
66e5c31af7Sopenharmony_ci#         }
67e5c31af7Sopenharmony_ci#         if (injectionSwitch.x < 20.0)
68e5c31af7Sopenharmony_ci#         {
69e5c31af7Sopenharmony_ci#             discard;
70e5c31af7Sopenharmony_ci#         }
71e5c31af7Sopenharmony_ci#         iteration++;
72e5c31af7Sopenharmony_ci#         if (injectionSwitch.x < 30.0)
73e5c31af7Sopenharmony_ci#         {
74e5c31af7Sopenharmony_ci#             return vec3(1.0);
75e5c31af7Sopenharmony_ci#         }
76e5c31af7Sopenharmony_ci#     } while (k < iterationCap);
77e5c31af7Sopenharmony_ci#
78e5c31af7Sopenharmony_ci#     if (injectionSwitch.x > 10.0) // always false
79e5c31af7Sopenharmony_ci#     {
80e5c31af7Sopenharmony_ci#         if (gl_FragCoord.x < 0.0)
81e5c31af7Sopenharmony_ci#         {
82e5c31af7Sopenharmony_ci#             do
83e5c31af7Sopenharmony_ci#             {
84e5c31af7Sopenharmony_ci#                 _GLF_color = vec4(1.0);
85e5c31af7Sopenharmony_ci#             } while (gl_FragCoord.y < 0.0);
86e5c31af7Sopenharmony_ci#         }
87e5c31af7Sopenharmony_ci#         do
88e5c31af7Sopenharmony_ci#         {
89e5c31af7Sopenharmony_ci#             _GLF_color = vec4(1.0);
90e5c31af7Sopenharmony_ci#         } while (gl_FragCoord.x < 0.0);
91e5c31af7Sopenharmony_ci#         return vec3(1.0);
92e5c31af7Sopenharmony_ci#     }
93e5c31af7Sopenharmony_ci#     return pickColor(iteration); // pickColor(1)
94e5c31af7Sopenharmony_ci# }
95e5c31af7Sopenharmony_ci# void main()
96e5c31af7Sopenharmony_ci# {
97e5c31af7Sopenharmony_ci#     vec3 data[16];
98e5c31af7Sopenharmony_ci#     for (
99e5c31af7Sopenharmony_ci#         int i = 0;
100e5c31af7Sopenharmony_ci#         i < int(injectionSwitch.y); // i < 1
101e5c31af7Sopenharmony_ci#         i++)
102e5c31af7Sopenharmony_ci#     {
103e5c31af7Sopenharmony_ci#         for (
104e5c31af7Sopenharmony_ci#             int j = 0;
105e5c31af7Sopenharmony_ci#             j < 2;
106e5c31af7Sopenharmony_ci#             j++)
107e5c31af7Sopenharmony_ci#         {
108e5c31af7Sopenharmony_ci#             data[int(injectionSwitch.x)] = mand(); // data[0] = vec3(1.0, 0.0, 0.0);
109e5c31af7Sopenharmony_ci#         }
110e5c31af7Sopenharmony_ci#     }
111e5c31af7Sopenharmony_ci#     _GLF_color = vec4(data[0], 1.0);
112e5c31af7Sopenharmony_ci# }
113e5c31af7Sopenharmony_ciSHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
114e5c31af7Sopenharmony_ci; SPIR-V
115e5c31af7Sopenharmony_ci; Version: 1.0
116e5c31af7Sopenharmony_ci; Generator: Khronos Glslang Reference Front End; 7
117e5c31af7Sopenharmony_ci; Bound: 255
118e5c31af7Sopenharmony_ci; Schema: 0
119e5c31af7Sopenharmony_ci               OpCapability Shader
120e5c31af7Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
121e5c31af7Sopenharmony_ci               OpMemoryModel Logical GLSL450
122e5c31af7Sopenharmony_ci               OpEntryPoint Fragment %4 "main" %79 %91
123e5c31af7Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
124e5c31af7Sopenharmony_ci               OpSource ESSL 310
125e5c31af7Sopenharmony_ci               OpName %4 "main"
126e5c31af7Sopenharmony_ci               OpName %36 "buf0"
127e5c31af7Sopenharmony_ci               OpMemberName %36 0 "injectionSwitch"
128e5c31af7Sopenharmony_ci               OpName %38 ""
129e5c31af7Sopenharmony_ci               OpName %79 "gl_FragCoord"
130e5c31af7Sopenharmony_ci               OpName %91 "_GLF_color"
131e5c31af7Sopenharmony_ci               OpName %133 "data"
132e5c31af7Sopenharmony_ci               OpMemberDecorate %36 0 Offset 0
133e5c31af7Sopenharmony_ci               OpDecorate %36 Block
134e5c31af7Sopenharmony_ci               OpDecorate %38 DescriptorSet 0
135e5c31af7Sopenharmony_ci               OpDecorate %38 Binding 0
136e5c31af7Sopenharmony_ci               OpDecorate %79 BuiltIn FragCoord
137e5c31af7Sopenharmony_ci               OpDecorate %91 Location 0
138e5c31af7Sopenharmony_ci          %2 = OpTypeVoid
139e5c31af7Sopenharmony_ci          %3 = OpTypeFunction %2
140e5c31af7Sopenharmony_ci          %6 = OpTypeInt 32 1
141e5c31af7Sopenharmony_ci          %8 = OpTypeFloat 32
142e5c31af7Sopenharmony_ci          %9 = OpTypeVector %8 3
143e5c31af7Sopenharmony_ci         %19 = OpConstant %8 0
144e5c31af7Sopenharmony_ci         %27 = OpConstant %6 1
145e5c31af7Sopenharmony_ci         %35 = OpTypeVector %8 2
146e5c31af7Sopenharmony_ci         %36 = OpTypeStruct %35
147e5c31af7Sopenharmony_ci         %37 = OpTypePointer Uniform %36
148e5c31af7Sopenharmony_ci         %38 = OpVariable %37 Uniform
149e5c31af7Sopenharmony_ci         %39 = OpConstant %6 0
150e5c31af7Sopenharmony_ci         %40 = OpTypeInt 32 0
151e5c31af7Sopenharmony_ci         %41 = OpConstant %40 0
152e5c31af7Sopenharmony_ci         %42 = OpTypePointer Uniform %8
153e5c31af7Sopenharmony_ci         %45 = OpConstant %8 10
154e5c31af7Sopenharmony_ci         %46 = OpTypeBool
155e5c31af7Sopenharmony_ci         %53 = OpConstant %8 20
156e5c31af7Sopenharmony_ci         %62 = OpConstant %8 30
157e5c31af7Sopenharmony_ci         %66 = OpConstant %8 1
158e5c31af7Sopenharmony_ci         %67 = OpConstantComposite %9 %66 %66 %66
159e5c31af7Sopenharmony_ci         %77 = OpTypeVector %8 4
160e5c31af7Sopenharmony_ci         %78 = OpTypePointer Input %77
161e5c31af7Sopenharmony_ci         %79 = OpVariable %78 Input
162e5c31af7Sopenharmony_ci         %80 = OpTypePointer Input %8
163e5c31af7Sopenharmony_ci         %90 = OpTypePointer Output %77
164e5c31af7Sopenharmony_ci         %91 = OpVariable %90 Output
165e5c31af7Sopenharmony_ci         %92 = OpConstantComposite %77 %66 %66 %66 %66
166e5c31af7Sopenharmony_ci         %93 = OpConstant %40 1
167e5c31af7Sopenharmony_ci        %128 = OpConstant %6 2
168e5c31af7Sopenharmony_ci        %130 = OpConstant %40 16
169e5c31af7Sopenharmony_ci        %131 = OpTypeArray %9 %130
170e5c31af7Sopenharmony_ci        %132 = OpTypePointer Function %131
171e5c31af7Sopenharmony_ci        %138 = OpTypePointer Function %9
172e5c31af7Sopenharmony_ci        %159 = OpConstantFalse %46
173e5c31af7Sopenharmony_ci        %162 = OpConstantTrue %46
174e5c31af7Sopenharmony_ci        %251 = OpUndef %9
175e5c31af7Sopenharmony_ci          %4 = OpFunction %2 None %3
176e5c31af7Sopenharmony_ci          %5 = OpLabel
177e5c31af7Sopenharmony_ci        %133 = OpVariable %132 Function
178e5c31af7Sopenharmony_ci               OpBranch %111
179e5c31af7Sopenharmony_ci        %111 = OpLabel
180e5c31af7Sopenharmony_ci        %237 = OpPhi %6 %39 %5 %143 %124
181e5c31af7Sopenharmony_ci        %250 = OpPhi %9 %251 %5 %249 %124
182e5c31af7Sopenharmony_ci        %117 = OpAccessChain %42 %38 %39 %93
183e5c31af7Sopenharmony_ci        %118 = OpLoad %8 %117
184e5c31af7Sopenharmony_ci        %119 = OpConvertFToS %6 %118
185e5c31af7Sopenharmony_ci        %120 = OpSLessThan %46 %237 %119
186e5c31af7Sopenharmony_ci               OpLoopMerge %113 %124 None
187e5c31af7Sopenharmony_ci               OpBranchConditional %120 %112 %113
188e5c31af7Sopenharmony_ci        %112 = OpLabel
189e5c31af7Sopenharmony_ci               OpBranch %122
190e5c31af7Sopenharmony_ci        %122 = OpLabel
191e5c31af7Sopenharmony_ci        %249 = OpPhi %9 %250 %112 %245 %175
192e5c31af7Sopenharmony_ci        %238 = OpPhi %6 %39 %112 %141 %175
193e5c31af7Sopenharmony_ci        %129 = OpSLessThan %46 %238 %128
194e5c31af7Sopenharmony_ci               OpLoopMerge %252 %175 None
195e5c31af7Sopenharmony_ci               OpBranchConditional %129 %123 %252
196e5c31af7Sopenharmony_ci        %123 = OpLabel
197e5c31af7Sopenharmony_ci        %134 = OpAccessChain %42 %38 %39 %41
198e5c31af7Sopenharmony_ci        %135 = OpLoad %8 %134
199e5c31af7Sopenharmony_ci        %136 = OpConvertFToS %6 %135
200e5c31af7Sopenharmony_ci               OpBranch %174
201e5c31af7Sopenharmony_ci        %174 = OpLabel
202e5c31af7Sopenharmony_ci               OpLoopMerge %254 %176 None
203e5c31af7Sopenharmony_ci               OpBranch %178
204e5c31af7Sopenharmony_ci        %178 = OpLabel
205e5c31af7Sopenharmony_ci        %240 = OpPhi %6 %27 %174 %194 %198
206e5c31af7Sopenharmony_ci               OpLoopMerge %179 %198 None
207e5c31af7Sopenharmony_ci               OpBranch %181
208e5c31af7Sopenharmony_ci        %181 = OpLabel
209e5c31af7Sopenharmony_ci        %184 = OpFOrdLessThan %46 %135 %45
210e5c31af7Sopenharmony_ci               OpSelectionMerge %185 None
211e5c31af7Sopenharmony_ci               OpBranchConditional %184 %186 %185
212e5c31af7Sopenharmony_ci        %186 = OpLabel
213e5c31af7Sopenharmony_ci               OpBranch %179
214e5c31af7Sopenharmony_ci        %185 = OpLabel
215e5c31af7Sopenharmony_ci        %189 = OpFOrdLessThan %46 %135 %53
216e5c31af7Sopenharmony_ci               OpSelectionMerge %190 None
217e5c31af7Sopenharmony_ci               OpBranchConditional %189 %191 %190
218e5c31af7Sopenharmony_ci        %191 = OpLabel
219e5c31af7Sopenharmony_ci               OpKill
220e5c31af7Sopenharmony_ci        %190 = OpLabel
221e5c31af7Sopenharmony_ci        %194 = OpIAdd %6 %240 %27
222e5c31af7Sopenharmony_ci        %197 = OpFOrdLessThan %46 %135 %62
223e5c31af7Sopenharmony_ci               OpSelectionMerge %253 None
224e5c31af7Sopenharmony_ci               OpBranchConditional %197 %199 %198
225e5c31af7Sopenharmony_ci        %199 = OpLabel
226e5c31af7Sopenharmony_ci               OpBranch %179
227e5c31af7Sopenharmony_ci        %253 = OpLabel
228e5c31af7Sopenharmony_ci               OpBranch %198
229e5c31af7Sopenharmony_ci        %198 = OpLabel
230e5c31af7Sopenharmony_ci               OpBranch %178
231e5c31af7Sopenharmony_ci        %179 = OpLabel
232e5c31af7Sopenharmony_ci        %246 = OpPhi %9 %249 %186 %67 %199
233e5c31af7Sopenharmony_ci        %244 = OpPhi %6 %240 %186 %194 %199
234e5c31af7Sopenharmony_ci        %241 = OpPhi %46 %159 %186 %162 %199
235e5c31af7Sopenharmony_ci               OpSelectionMerge %204 None
236e5c31af7Sopenharmony_ci               OpBranchConditional %241 %254 %204
237e5c31af7Sopenharmony_ci        %204 = OpLabel
238e5c31af7Sopenharmony_ci        %207 = OpFOrdGreaterThan %46 %135 %45
239e5c31af7Sopenharmony_ci               OpSelectionMerge %208 None
240e5c31af7Sopenharmony_ci               OpBranchConditional %207 %209 %208
241e5c31af7Sopenharmony_ci        %209 = OpLabel
242e5c31af7Sopenharmony_ci        %210 = OpAccessChain %80 %79 %41
243e5c31af7Sopenharmony_ci        %211 = OpLoad %8 %210
244e5c31af7Sopenharmony_ci        %212 = OpFOrdLessThan %46 %211 %19
245e5c31af7Sopenharmony_ci               OpSelectionMerge %213 None
246e5c31af7Sopenharmony_ci               OpBranchConditional %212 %214 %213
247e5c31af7Sopenharmony_ci        %214 = OpLabel
248e5c31af7Sopenharmony_ci               OpBranch %215
249e5c31af7Sopenharmony_ci        %215 = OpLabel
250e5c31af7Sopenharmony_ci               OpStore %91 %92
251e5c31af7Sopenharmony_ci        %219 = OpAccessChain %80 %79 %93
252e5c31af7Sopenharmony_ci        %220 = OpLoad %8 %219
253e5c31af7Sopenharmony_ci        %221 = OpFOrdLessThan %46 %220 %19
254e5c31af7Sopenharmony_ci               OpLoopMerge %216 %215 None
255e5c31af7Sopenharmony_ci               OpBranchConditional %221 %215 %216
256e5c31af7Sopenharmony_ci        %216 = OpLabel
257e5c31af7Sopenharmony_ci               OpBranch %213
258e5c31af7Sopenharmony_ci        %213 = OpLabel
259e5c31af7Sopenharmony_ci               OpBranch %222
260e5c31af7Sopenharmony_ci        %222 = OpLabel
261e5c31af7Sopenharmony_ci               OpStore %91 %92
262e5c31af7Sopenharmony_ci               OpLoopMerge %223 %222 None
263e5c31af7Sopenharmony_ci               OpBranchConditional %212 %222 %223
264e5c31af7Sopenharmony_ci        %223 = OpLabel
265e5c31af7Sopenharmony_ci               OpBranch %254
266e5c31af7Sopenharmony_ci        %208 = OpLabel
267e5c31af7Sopenharmony_ci        %235 = OpConvertSToF %8 %244
268e5c31af7Sopenharmony_ci        %236 = OpCompositeConstruct %9 %235 %19 %19
269e5c31af7Sopenharmony_ci               OpBranch %254
270e5c31af7Sopenharmony_ci        %176 = OpLabel
271e5c31af7Sopenharmony_ci               OpBranch %174
272e5c31af7Sopenharmony_ci        %254 = OpLabel
273e5c31af7Sopenharmony_ci        %245 = OpPhi %9 %246 %179 %67 %223 %236 %208
274e5c31af7Sopenharmony_ci               OpBranch %175
275e5c31af7Sopenharmony_ci        %175 = OpLabel
276e5c31af7Sopenharmony_ci        %139 = OpAccessChain %138 %133 %136
277e5c31af7Sopenharmony_ci               OpStore %139 %245
278e5c31af7Sopenharmony_ci        %141 = OpIAdd %6 %238 %27
279e5c31af7Sopenharmony_ci               OpBranch %122
280e5c31af7Sopenharmony_ci        %252 = OpLabel
281e5c31af7Sopenharmony_ci	       OpBranch %124
282e5c31af7Sopenharmony_ci        %124 = OpLabel
283e5c31af7Sopenharmony_ci        %143 = OpIAdd %6 %237 %27
284e5c31af7Sopenharmony_ci               OpBranch %111
285e5c31af7Sopenharmony_ci        %113 = OpLabel
286e5c31af7Sopenharmony_ci        %144 = OpAccessChain %138 %133 %39
287e5c31af7Sopenharmony_ci        %145 = OpLoad %9 %144
288e5c31af7Sopenharmony_ci        %146 = OpCompositeExtract %8 %145 0
289e5c31af7Sopenharmony_ci        %147 = OpCompositeExtract %8 %145 1
290e5c31af7Sopenharmony_ci        %148 = OpCompositeExtract %8 %145 2
291e5c31af7Sopenharmony_ci        %149 = OpCompositeConstruct %77 %146 %147 %148 %66
292e5c31af7Sopenharmony_ci               OpStore %91 %149
293e5c31af7Sopenharmony_ci               OpReturn
294e5c31af7Sopenharmony_ci               OpFunctionEnd
295e5c31af7Sopenharmony_ciEND
296e5c31af7Sopenharmony_ci
297e5c31af7Sopenharmony_ci# uniforms for variant
298e5c31af7Sopenharmony_ci
299e5c31af7Sopenharmony_ci# injectionSwitch
300e5c31af7Sopenharmony_ciBUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
301e5c31af7Sopenharmony_ci 0.0 1.0
302e5c31af7Sopenharmony_ciEND
303e5c31af7Sopenharmony_ci
304e5c31af7Sopenharmony_ciBUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
305e5c31af7Sopenharmony_ci
306e5c31af7Sopenharmony_ciPIPELINE graphics variant_pipeline
307e5c31af7Sopenharmony_ci  ATTACH variant_vertex_shader
308e5c31af7Sopenharmony_ci  ATTACH variant_fragment_shader
309e5c31af7Sopenharmony_ci  FRAMEBUFFER_SIZE 256 256
310e5c31af7Sopenharmony_ci  BIND BUFFER variant_framebuffer AS color LOCATION 0
311e5c31af7Sopenharmony_ci  BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
312e5c31af7Sopenharmony_ciEND
313e5c31af7Sopenharmony_ciCLEAR_COLOR variant_pipeline 0 0 0 255
314e5c31af7Sopenharmony_ci
315e5c31af7Sopenharmony_ciCLEAR variant_pipeline
316e5c31af7Sopenharmony_ciRUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
317e5c31af7Sopenharmony_ci
318e5c31af7Sopenharmony_ciEXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
319