blob: 6f4ea281f84ce82dabd9db7a6f46bec1c5a2cef4 [file] [log] [blame]
#!amber
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# A test for a bug found by GraphicsFuzz.
# Short description: A fragment shader with few nested loops with fallthrough
# A fragment shader with several nested loops depending on each other and switch case with fallthrough.
# The test passes because shader always writes red.
# Optimized using spirv-opt with the following arguments:
# '-O'
# spirv-opt commit hash: ab7ac60f14ae66006bed5c989a2cfd4c4881704c
SHADER vertex variant_vertex_shader PASSTHROUGH
# variant_fragment_shader is derived from the following GLSL:
# #version 310 es
# precision highp float;
# precision highp int;
#
# layout(set = 0, binding = 0) uniform buf0
# {
# float zero;
# };
# layout(location = 0) out vec4 _GLF_color;
#
# void main()
# {
# float sums[9];
# int sum_index = 0;
#
# _GLF_color = vec4(0, 0, 0, 1);
#
# sums[0] = 0.0;
#
# // sum_index is modified in loops A and B like this:
# // A: 0 -> 1, 1 -> 2
# // B: 2 -> 3
# // A: 3 -> 4, 4 -> 5
# // B: 5 -> 6. At this point we set red channel to 1.
# // A: 6: return from main.
# for(int i0 = 2; i0 < 5; i0++)
# {
# // Loop A: After this loop sum_index = sum_index + 2.
# for(int i1 = 2; i1 < 4; i1++)
# {
# for(int i2 = 0; i2 < i0; i2++)
# {
# for(int i3 = 0; i3 < i1; i3++)
# {
# switch(sum_index)
# {
# case 0:
# sums[sum_index]++;
# break;
# case 1:
# sums[sum_index]++;
# break;
# case 2:
# sums[sum_index]++;
# case 3:
# sums[sum_index]++;
# case 4:
# sums[sum_index]++;
# case 5:
# sums[sum_index]++;
# break;
# case 6:
# // This is hit eventually.
# return;
# case 7:
# sums[sum_index]++;
# break;
# case 8:
# sums[sum_index]++;
# }
# }
# }
#
# if(clamp(1.0, gl_FragCoord.y, gl_FragCoord.y) < 0.0) // Always false.
# continue;
#
# if(zero < 0.0) // Always false.
# sums[sum_index]++;
#
# if(gl_FragCoord.y < 0.0) // Always false.
# discard;
#
# sum_index++;
# }
#
# // Loop B: After this loop sum_index = sum_index + 1.
# //
# // Cases that are not supposed to be hit set the green channel
# // to one to mark an error.
# for(int i4 = 4; i4 < 5; i4++)
# {
# for(int i5 = 0; i5 < i0; i5++)
# {
# for(int i6 = 0; i6 < i4; i6++)
# {
# switch(sum_index)
# {
# case 0:
# sums[sum_index]++;
# _GLF_color.g = 1.0;
# case 1:
# sums[sum_index]++;
# _GLF_color.g = 1.0;
# case 2:
# sums[sum_index]++;
# break;
# case 3:
# sums[sum_index]++;
# _GLF_color.g = 1.0;
# case 4:
# sums[sum_index]++;
# _GLF_color.g = 1.0;
# break;
# case 5:
# sums[sum_index]++;
# if (sums[0] != 0.0) // Always true.
# _GLF_color.r = 1.0;
# break;
# case 6:
# sums[sum_index]++;
# _GLF_color.g = 1.0;
# case 7:
# sums[sum_index]++;
# _GLF_color.g = 1.0;
# case 8:
# sums[sum_index]++;
# _GLF_color.g = 1.0;
# }
# }
# }
#
# sum_index++;
#
# if (zero < 1.0) // Always true, but we run the loop only once anyway.
# break;
# }
# }
#
# // We never reach here. Both branches write incorrect color.
# if (sums[0] == 0.0)
# _GLF_color = vec4(0);
# else
# _GLF_color = vec4(1);
# }
SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 8
; Bound: 358
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main" %13 %117
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %13 "_GLF_color"
OpName %21 "sums"
OpName %117 "gl_FragCoord"
OpName %129 "buf0"
OpMemberName %129 0 "zero"
OpName %131 ""
OpDecorate %13 Location 0
OpDecorate %117 BuiltIn FragCoord
OpMemberDecorate %129 0 Offset 0
OpDecorate %129 Block
OpDecorate %131 DescriptorSet 0
OpDecorate %131 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 1
%9 = OpConstant %6 0
%10 = OpTypeFloat 32
%11 = OpTypeVector %10 4
%12 = OpTypePointer Output %11
%13 = OpVariable %12 Output
%14 = OpConstant %10 0
%15 = OpConstant %10 1
%16 = OpConstantComposite %11 %14 %14 %14 %15
%17 = OpTypeInt 32 0
%18 = OpConstant %17 9
%19 = OpTypeArray %10 %18
%20 = OpTypePointer Function %19
%22 = OpTypePointer Function %10
%25 = OpConstant %6 2
%32 = OpConstant %6 5
%33 = OpTypeBool
%42 = OpConstant %6 4
%112 = OpConstant %6 1
%116 = OpTypePointer Input %11
%117 = OpVariable %116 Input
%118 = OpConstant %17 1
%119 = OpTypePointer Input %10
%129 = OpTypeStruct %10
%130 = OpTypePointer Uniform %129
%131 = OpVariable %130 Uniform
%132 = OpTypePointer Uniform %10
%193 = OpTypePointer Output %10
%225 = OpConstant %17 0
%265 = OpConstantComposite %11 %14 %14 %14 %14
%267 = OpConstantComposite %11 %15 %15 %15 %15
%272 = OpConstantFalse %33
%275 = OpConstantTrue %33
%4 = OpFunction %2 None %3
%5 = OpLabel
%21 = OpVariable %20 Function
OpBranch %269
%269 = OpLabel
OpStore %13 %16
%23 = OpAccessChain %22 %21 %9
OpStore %23 %14
OpLoopMerge %268 %271 None
OpBranch %26
%26 = OpLabel
%300 = OpPhi %33 %272 %269 %312 %29
%295 = OpPhi %6 %9 %269 %356 %29
%284 = OpPhi %6 %25 %269 %259 %29
%34 = OpSLessThan %33 %284 %32
OpLoopMerge %28 %29 None
OpBranchConditional %34 %27 %28
%27 = OpLabel
OpBranch %36
%36 = OpLabel
%299 = OpPhi %33 %300 %27 %304 %39
%294 = OpPhi %6 %295 %27 %357 %39
%285 = OpPhi %6 %25 %27 %151 %39
%43 = OpSLessThan %33 %285 %42
OpLoopMerge %38 %39 None
OpBranchConditional %43 %37 %38
%37 = OpLabel
OpBranch %45
%45 = OpLabel
%298 = OpPhi %33 %299 %37 %296 %48
%286 = OpPhi %6 %9 %37 %115 %48
%52 = OpSLessThan %33 %286 %284
OpLoopMerge %47 %48 None
OpBranchConditional %52 %46 %47
%46 = OpLabel
OpBranch %54
%54 = OpLabel
%289 = OpPhi %6 %9 %46 %113 %57
%61 = OpSLessThan %33 %289 %285
OpLoopMerge %56 %57 None
OpBranchConditional %61 %55 %56
%55 = OpLabel
OpSelectionMerge %72 None
OpSwitch %294 %72 0 %63 1 %64 2 %65 3 %66 4 %67 5 %68 6 %69 7 %70 8 %71
%63 = OpLabel
%74 = OpAccessChain %22 %21 %294
%75 = OpLoad %10 %74
%76 = OpFAdd %10 %75 %15
OpStore %74 %76
OpBranch %72
%64 = OpLabel
%79 = OpAccessChain %22 %21 %294
%80 = OpLoad %10 %79
%81 = OpFAdd %10 %80 %15
OpStore %79 %81
OpBranch %72
%65 = OpLabel
%84 = OpAccessChain %22 %21 %294
%85 = OpLoad %10 %84
%86 = OpFAdd %10 %85 %15
OpStore %84 %86
OpBranch %66
%66 = OpLabel
%88 = OpAccessChain %22 %21 %294
%89 = OpLoad %10 %88
%90 = OpFAdd %10 %89 %15
OpStore %88 %90
OpBranch %67
%67 = OpLabel
%92 = OpAccessChain %22 %21 %294
%93 = OpLoad %10 %92
%94 = OpFAdd %10 %93 %15
OpStore %92 %94
OpBranch %68
%68 = OpLabel
%96 = OpAccessChain %22 %21 %294
%97 = OpLoad %10 %96
%98 = OpFAdd %10 %97 %15
OpStore %96 %98
OpBranch %72
%69 = OpLabel
OpBranch %56
%70 = OpLabel
%102 = OpAccessChain %22 %21 %294
%103 = OpLoad %10 %102
%104 = OpFAdd %10 %103 %15
OpStore %102 %104
OpBranch %72
%71 = OpLabel
%107 = OpAccessChain %22 %21 %294
%108 = OpLoad %10 %107
%109 = OpFAdd %10 %108 %15
OpStore %107 %109
OpBranch %72
%72 = OpLabel
OpBranch %57
%57 = OpLabel
%113 = OpIAdd %6 %289 %112
OpBranch %54
%56 = OpLabel
%296 = OpPhi %33 %298 %54 %275 %69
OpSelectionMerge %276 None
OpBranchConditional %296 %47 %276
%276 = OpLabel
OpBranch %48
%48 = OpLabel
%115 = OpIAdd %6 %286 %112
OpBranch %45
%47 = OpLabel
%304 = OpPhi %33 %298 %45 %296 %56
OpSelectionMerge %278 None
OpBranchConditional %304 %38 %278
%278 = OpLabel
%120 = OpAccessChain %119 %117 %118
%121 = OpLoad %10 %120
%124 = OpExtInst %10 %1 FClamp %15 %121 %121
%125 = OpFOrdLessThan %33 %124 %14
OpSelectionMerge %127 None
OpBranchConditional %125 %126 %127
%126 = OpLabel
OpBranch %39
%127 = OpLabel
%133 = OpAccessChain %132 %131 %9
%134 = OpLoad %10 %133
%135 = OpFOrdLessThan %33 %134 %14
OpSelectionMerge %137 None
OpBranchConditional %135 %136 %137
%136 = OpLabel
%139 = OpAccessChain %22 %21 %294
%140 = OpLoad %10 %139
%141 = OpFAdd %10 %140 %15
OpStore %139 %141
OpBranch %137
%137 = OpLabel
%144 = OpFOrdLessThan %33 %121 %14
OpSelectionMerge %146 None
OpBranchConditional %144 %145 %146
%145 = OpLabel
OpKill
%146 = OpLabel
%149 = OpIAdd %6 %294 %112
OpBranch %39
%39 = OpLabel
%357 = OpPhi %6 %294 %126 %149 %146
%151 = OpIAdd %6 %285 %112
OpBranch %36
%38 = OpLabel
%312 = OpPhi %33 %299 %36 %304 %47
OpSelectionMerge %280 None
OpBranchConditional %312 %28 %280
%280 = OpLabel
OpBranch %153
%153 = OpLabel
%322 = OpPhi %6 %294 %280 %249 %156
%313 = OpPhi %6 %42 %280 %257 %156
%159 = OpSLessThan %33 %313 %32
OpLoopMerge %155 %156 None
OpBranchConditional %159 %154 %155
%154 = OpLabel
OpBranch %161
%161 = OpLabel
%314 = OpPhi %6 %9 %154 %247 %164
%168 = OpSLessThan %33 %314 %284
OpLoopMerge %163 %164 None
OpBranchConditional %168 %162 %163
%162 = OpLabel
OpBranch %170
%170 = OpLabel
%326 = OpPhi %6 %9 %162 %245 %173
%177 = OpSLessThan %33 %326 %313
OpLoopMerge %172 %173 None
OpBranchConditional %177 %171 %172
%171 = OpLabel
OpSelectionMerge %188 None
OpSwitch %322 %188 0 %179 1 %180 2 %181 3 %182 4 %183 5 %184 6 %185 7 %186 8 %187
%179 = OpLabel
%190 = OpAccessChain %22 %21 %322
%191 = OpLoad %10 %190
%192 = OpFAdd %10 %191 %15
OpStore %190 %192
%194 = OpAccessChain %193 %13 %118
OpStore %194 %15
OpBranch %180
%180 = OpLabel
%196 = OpAccessChain %22 %21 %322
%197 = OpLoad %10 %196
%198 = OpFAdd %10 %197 %15
OpStore %196 %198
%199 = OpAccessChain %193 %13 %118
OpStore %199 %15
OpBranch %181
%181 = OpLabel
%201 = OpAccessChain %22 %21 %322
%202 = OpLoad %10 %201
%203 = OpFAdd %10 %202 %15
OpStore %201 %203
OpBranch %188
%182 = OpLabel
%206 = OpAccessChain %22 %21 %322
%207 = OpLoad %10 %206
%208 = OpFAdd %10 %207 %15
OpStore %206 %208
%209 = OpAccessChain %193 %13 %118
OpStore %209 %15
OpBranch %183
%183 = OpLabel
%211 = OpAccessChain %22 %21 %322
%212 = OpLoad %10 %211
%213 = OpFAdd %10 %212 %15
OpStore %211 %213
%214 = OpAccessChain %193 %13 %118
OpStore %214 %15
OpBranch %188
%184 = OpLabel
%217 = OpAccessChain %22 %21 %322
%218 = OpLoad %10 %217
%219 = OpFAdd %10 %218 %15
OpStore %217 %219
%221 = OpLoad %10 %23
%222 = OpFOrdNotEqual %33 %221 %14
OpSelectionMerge %224 None
OpBranchConditional %222 %223 %224
%223 = OpLabel
%226 = OpAccessChain %193 %13 %225
OpStore %226 %15
OpBranch %224
%224 = OpLabel
OpBranch %188
%185 = OpLabel
%229 = OpAccessChain %22 %21 %322
%230 = OpLoad %10 %229
%231 = OpFAdd %10 %230 %15
OpStore %229 %231
%232 = OpAccessChain %193 %13 %118
OpStore %232 %15
OpBranch %186
%186 = OpLabel
%234 = OpAccessChain %22 %21 %322
%235 = OpLoad %10 %234
%236 = OpFAdd %10 %235 %15
OpStore %234 %236
%237 = OpAccessChain %193 %13 %118
OpStore %237 %15
OpBranch %187
%187 = OpLabel
%239 = OpAccessChain %22 %21 %322
%240 = OpLoad %10 %239
%241 = OpFAdd %10 %240 %15
OpStore %239 %241
%242 = OpAccessChain %193 %13 %118
OpStore %242 %15
OpBranch %188
%188 = OpLabel
OpBranch %173
%173 = OpLabel
%245 = OpIAdd %6 %326 %112
OpBranch %170
%172 = OpLabel
OpBranch %164
%164 = OpLabel
%247 = OpIAdd %6 %314 %112
OpBranch %161
%163 = OpLabel
%249 = OpIAdd %6 %322 %112
%250 = OpAccessChain %132 %131 %9
%251 = OpLoad %10 %250
%252 = OpFOrdLessThan %33 %251 %15
OpSelectionMerge %254 None
OpBranchConditional %252 %253 %254
%253 = OpLabel
OpBranch %155
%254 = OpLabel
OpBranch %156
%156 = OpLabel
%257 = OpIAdd %6 %313 %112
OpBranch %153
%155 = OpLabel
%356 = OpPhi %6 %322 %153 %249 %253
OpBranch %29
%29 = OpLabel
%259 = OpIAdd %6 %284 %112
OpBranch %26
%28 = OpLabel
%342 = OpPhi %33 %300 %26 %312 %38
OpSelectionMerge %282 None
OpBranchConditional %342 %268 %282
%282 = OpLabel
%261 = OpLoad %10 %23
%262 = OpFOrdEqual %33 %261 %14
OpSelectionMerge %264 None
OpBranchConditional %262 %263 %266
%263 = OpLabel
OpStore %13 %265
OpBranch %264
%266 = OpLabel
OpStore %13 %267
OpBranch %264
%264 = OpLabel
OpBranch %268
%271 = OpLabel
OpBranch %269
%268 = OpLabel
OpReturn
OpFunctionEnd
END
# uniforms for variant
# zero
BUFFER variant_zero DATA_TYPE float DATA
0.0
END
BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
PIPELINE graphics variant_pipeline
ATTACH variant_vertex_shader
ATTACH variant_fragment_shader
FRAMEBUFFER_SIZE 64 64
BIND BUFFER variant_framebuffer AS color LOCATION 0
BIND BUFFER variant_zero AS uniform DESCRIPTOR_SET 0 BINDING 0
END
CLEAR_COLOR variant_pipeline 0 0 0 255
CLEAR variant_pipeline
RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 64 64
EXPECT variant_framebuffer IDX 0 0 SIZE 64 64 EQ_RGBA 255 0 0 255