1#!amber 2 3# Copyright 2019 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 nested loops and a function call 21 22# The test passes because the fragment shader enters the first loop, immediately breaks, and then 23# writes the color red. 24 25# Optimized using spirv-opt with the following arguments: 26# '-O' 27# spirv-opt commit hash: 06407250a169c6a03b3765e86619075af1a8c187 28 29 30 31SHADER vertex variant_vertex_shader PASSTHROUGH 32 33# variant_fragment_shader is derived from the following GLSL: 34# #version 310 es 35# precision highp float; 36# 37# layout(set = 0, binding = 0) uniform buf0 38# { 39# vec2 injectionSwitch; 40# }; 41# layout(location = 0) out vec4 _GLF_color; 42# 43# vec3 mand() 44# { 45# float x, y; 46# int iteration; 47# iteration = 0; 48# if (gl_FragCoord.y < 0.0) 49# { 50# return vec3(1.0); 51# } 52# for ( 53# int k = 0; 54# k < 50; 55# k++) 56# { 57# if (x * x + y * y > 4.0) 58# { 59# if (injectionSwitch.x > injectionSwitch.y) 60# { 61# discard; 62# } 63# break; 64# } 65# float x_new; 66# x_new = 1.0 - y; 67# if (gl_FragCoord.x < 0.0) 68# { 69# discard; 70# } 71# y = 2.0 * y + 1.0; 72# x = x_new; 73# iteration++; 74# } 75# vec3 pickColor_inline_return_value_0; 76# int i; 77# i = iteration; 78# pickColor_inline_return_value_0 = vec3(1.0, 1.0, float(i)); 79# return pickColor_inline_return_value_0; 80# } 81# 82# void main() 83# { 84# vec3 data[16]; 85# data[1] = vec3(0.0); 86# for ( 87# int i = 0; 88# i < 4; 89# i++) 90# { 91# if (injectionSwitch.x < 1.0) // always true 92# { 93# break; 94# } 95# for ( 96# int j = 0; 97# j < 4; 98# j++) 99# { 100# data[4 * j + i] = mand(); 101# if (injectionSwitch.x > injectionSwitch.y) 102# { 103# discard; 104# } 105# } 106# } 107# vec4 sum; 108# sum = vec4(1.0, 0.0, 0.0, 1.0); // red 109# sum += data[1].xxyz; // sum is unchanged 110# _GLF_color = sum; // red 111# } 112SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0 113; SPIR-V 114; Version: 1.0 115; Generator: Khronos Glslang Reference Front End; 7 116; Bound: 270 117; Schema: 0 118 OpCapability Shader 119 %1 = OpExtInstImport "GLSL.std.450" 120 OpMemoryModel Logical GLSL450 121 OpEntryPoint Fragment %4 "main" %17 %154 122 OpExecutionMode %4 OriginUpperLeft 123 OpSource ESSL 310 124 OpName %4 "main" 125 OpName %17 "gl_FragCoord" 126 OpName %55 "buf0" 127 OpMemberName %55 0 "injectionSwitch" 128 OpName %57 "" 129 OpName %101 "data" 130 OpName %154 "_GLF_color" 131 OpDecorate %17 BuiltIn FragCoord 132 OpMemberDecorate %55 0 Offset 0 133 OpDecorate %55 Block 134 OpDecorate %57 DescriptorSet 0 135 OpDecorate %57 Binding 0 136 OpDecorate %128 RelaxedPrecision 137 OpDecorate %130 RelaxedPrecision 138 OpDecorate %142 RelaxedPrecision 139 OpDecorate %144 RelaxedPrecision 140 OpDecorate %154 Location 0 141 OpDecorate %228 RelaxedPrecision 142 OpDecorate %230 RelaxedPrecision 143 OpDecorate %240 RelaxedPrecision 144 OpDecorate %241 RelaxedPrecision 145 OpDecorate %243 RelaxedPrecision 146 OpDecorate %253 RelaxedPrecision 147 OpDecorate %241 RelaxedPrecision 148 %2 = OpTypeVoid 149 %3 = OpTypeFunction %2 150 %6 = OpTypeFloat 32 151 %7 = OpTypeVector %6 3 152 %11 = OpTypeInt 32 1 153 %14 = OpConstant %11 0 154 %15 = OpTypeVector %6 4 155 %16 = OpTypePointer Input %15 156 %17 = OpVariable %16 Input 157 %18 = OpTypeInt 32 0 158 %19 = OpConstant %18 1 159 %20 = OpTypePointer Input %6 160 %23 = OpConstant %6 0 161 %24 = OpTypeBool 162 %28 = OpConstant %6 1 163 %29 = OpConstantComposite %7 %28 %28 %28 164 %38 = OpConstant %11 50 165 %50 = OpConstant %6 4 166 %54 = OpTypeVector %6 2 167 %55 = OpTypeStruct %54 168 %56 = OpTypePointer Uniform %55 169 %57 = OpVariable %56 Uniform 170 %58 = OpConstant %18 0 171 %59 = OpTypePointer Uniform %6 172 %78 = OpConstant %6 2 173 %84 = OpConstant %11 1 174 %90 = OpTypePointer Function %7 175 %98 = OpConstant %18 16 176 %99 = OpTypeArray %7 %98 177 %100 = OpTypePointer Function %99 178 %102 = OpConstantComposite %7 %23 %23 %23 179 %111 = OpConstant %11 4 180 %147 = OpConstantComposite %15 %28 %23 %23 %28 181 %153 = OpTypePointer Output %15 182 %154 = OpVariable %153 Output 183 %248 = OpUndef %6 184 %4 = OpFunction %2 None %3 185 %5 = OpLabel 186 %101 = OpVariable %100 Function 187 %103 = OpAccessChain %90 %101 %84 188 OpStore %103 %102 189 OpBranch %105 190 %105 = OpLabel 191 %240 = OpPhi %11 %14 %5 %144 %122 192 %252 = OpPhi %6 %248 %5 %251 %122 193 %247 = OpPhi %6 %248 %5 %246 %122 194 %112 = OpSLessThan %24 %240 %111 195 OpLoopMerge %107 %122 None 196 OpBranchConditional %112 %106 %107 197 %106 = OpLabel 198 %113 = OpAccessChain %59 %57 %14 %58 199 %114 = OpLoad %6 %113 200 %115 = OpFOrdLessThan %24 %114 %28 201 OpSelectionMerge %117 None 202 OpBranchConditional %115 %116 %117 203 %116 = OpLabel 204 OpBranch %107 205 %117 = OpLabel 206 OpBranch %120 207 %120 = OpLabel 208 %251 = OpPhi %6 %252 %117 %266 %139 209 %246 = OpPhi %6 %247 %117 %264 %139 210 %241 = OpPhi %11 %14 %117 %142 %139 211 %126 = OpSLessThan %24 %241 %111 212 OpLoopMerge %267 %139 None 213 OpBranchConditional %126 %121 %267 214 %121 = OpLabel 215 %128 = OpIMul %11 %111 %241 216 %130 = OpIAdd %11 %128 %240 217 OpBranch %181 218 %181 = OpLabel 219 OpLoopMerge %182 %183 None 220 OpBranch %184 221 %184 = OpLabel 222 %185 = OpAccessChain %20 %17 %19 223 %186 = OpLoad %6 %185 224 %187 = OpFOrdLessThan %24 %186 %23 225 OpSelectionMerge %188 None 226 OpBranchConditional %187 %189 %188 227 %189 = OpLabel 228 OpBranch %182 229 %188 = OpLabel 230 OpBranch %190 231 %190 = OpLabel 232 %253 = OpPhi %11 %14 %188 %228 %220 233 %249 = OpPhi %6 %251 %188 %225 %220 234 %244 = OpPhi %6 %246 %188 %216 %220 235 %243 = OpPhi %11 %14 %188 %230 %220 236 %195 = OpSLessThan %24 %243 %38 237 OpLoopMerge %191 %220 None 238 OpBranchConditional %195 %196 %191 239 %196 = OpLabel 240 %199 = OpFMul %6 %244 %244 241 %202 = OpFMul %6 %249 %249 242 %203 = OpFAdd %6 %199 %202 243 %204 = OpFOrdGreaterThan %24 %203 %50 244 OpSelectionMerge %205 None 245 OpBranchConditional %204 %206 %205 246 %206 = OpLabel 247 %209 = OpAccessChain %59 %57 %14 %19 248 %210 = OpLoad %6 %209 249 %211 = OpFOrdGreaterThan %24 %114 %210 250 OpSelectionMerge %212 None 251 OpBranchConditional %211 %213 %212 252 %213 = OpLabel 253 OpKill 254 %212 = OpLabel 255 OpBranch %191 256 %205 = OpLabel 257 %216 = OpFSub %6 %28 %249 258 %217 = OpAccessChain %20 %17 %58 259 %218 = OpLoad %6 %217 260 %219 = OpFOrdLessThan %24 %218 %23 261 OpSelectionMerge %269 None 262 OpBranchConditional %219 %221 %220 263 %221 = OpLabel 264 OpKill 265 %269 = OpLabel 266 OpBranch %220 267 %220 = OpLabel 268 %224 = OpFMul %6 %78 %249 269 %225 = OpFAdd %6 %224 %28 270 %228 = OpIAdd %11 %253 %84 271 %230 = OpIAdd %11 %243 %84 272 OpBranch %190 273 %191 = OpLabel 274 %233 = OpConvertSToF %6 %253 275 %234 = OpCompositeConstruct %7 %28 %28 %233 276 OpBranch %182 277 %183 = OpLabel 278 OpBranch %181 279 %182 = OpLabel 280 %266 = OpPhi %6 %251 %189 %249 %191 281 %264 = OpPhi %6 %246 %189 %244 %191 282 %255 = OpPhi %7 %29 %189 %234 %191 283 %132 = OpAccessChain %90 %101 %130 284 OpStore %132 %255 285 %135 = OpAccessChain %59 %57 %14 %19 286 %136 = OpLoad %6 %135 287 %137 = OpFOrdGreaterThan %24 %114 %136 288 OpSelectionMerge %268 None 289 OpBranchConditional %137 %138 %139 290 %138 = OpLabel 291 OpKill 292 %268 = OpLabel 293 OpBranch %139 294 %139 = OpLabel 295 %142 = OpIAdd %11 %241 %84 296 OpBranch %120 297 %267 = OpLabel 298 OpBranch %122 299 %122 = OpLabel 300 %144 = OpIAdd %11 %240 %84 301 OpBranch %105 302 %107 = OpLabel 303 %149 = OpLoad %7 %103 304 %150 = OpVectorShuffle %15 %149 %149 0 0 1 2 305 %152 = OpFAdd %15 %147 %150 306 OpStore %154 %152 307 OpReturn 308 OpFunctionEnd 309END 310 311# uniforms for variant 312 313# injectionSwitch 314BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA 315 0.0 1.0 316END 317 318BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM 319 320PIPELINE graphics variant_pipeline 321 ATTACH variant_vertex_shader 322 ATTACH variant_fragment_shader 323 FRAMEBUFFER_SIZE 256 256 324 BIND BUFFER variant_framebuffer AS color LOCATION 0 325 BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0 326END 327CLEAR_COLOR variant_pipeline 0 0 0 255 328 329CLEAR variant_pipeline 330RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256 331 332EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255 333