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