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