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 many uses of gl_FragCoord 21 22# The test passes because the shader always write red. 23 24# Optimized using spirv-opt with the following arguments: 25# '--scalar-replacement=100' 26# '--vector-dce' 27# '--combine-access-chains' 28# '--convert-local-access-chains' 29# '--eliminate-dead-code-aggressive' 30# '--private-to-local' 31# '--combine-access-chains' 32# '--reduce-load-size' 33# '--eliminate-dead-inserts' 34# '--combine-access-chains' 35# '--eliminate-local-single-store' 36# '--eliminate-local-single-block' 37# '--inline-entry-points-exhaustive' 38# '--combine-access-chains' 39# spirv-opt commit hash: e95fbfb1f509ad7a7fdfb72ac35fe412d72fc4a4 40 41 42 43SHADER vertex variant_vertex_shader PASSTHROUGH 44 45# variant_fragment_shader is derived from the following GLSL: 46# #version 310 es 47# 48# precision highp float; 49# precision highp int; 50# 51# layout(location = 0) out vec4 _GLF_color; 52# 53# layout(set = 0, binding = 0) uniform buf0 { 54# // Always (0.0, 1.0). 55# vec2 injectionSwitch; 56# }; 57# 58# // coord is gl_FragCoord.xy. 59# // Always returns 0. 60# int alwaysZero(vec2 coord) 61# { 62# // injectionSwitch.y is 1.0. 63# float a = coord.y < 50.0 ? injectionSwitch.y : 0.0; 64# float b = gl_FragCoord.y < 50.0 ? 1.0 : 0.0; 65# 66# // a == b. Thus, the condition is always true. 67# if (a - b < 1.0) 68# { 69# return 0; 70# } 71# return 1; 72# } 73# 74# void main() 75# { 76# int zero = alwaysZero(gl_FragCoord.xy); 77# 78# // Always false. 79# if (zero == 1) 80# { 81# return; 82# } 83# 84# // All conditions below are true. 85# // So _GLF_color will end up as red: (1.0, 0.0, 0.0, 1.0). 86# _GLF_color = vec4(0.0, 1.0, 1.0, 1.0); 87# 88# // Always true. 89# if (gl_FragCoord.x >= injectionSwitch.x) 90# { 91# // Always true. 92# if (gl_FragCoord.y >= 0.0) 93# { 94# // _GLF_color.x = 1.0; 95# _GLF_color.x = injectionSwitch.y; 96# } 97# } 98# 99# // Always true. 100# if (gl_FragCoord.y >= 0.0) 101# { 102# // _GLF_color.y = 0.0; 103# _GLF_color.y = injectionSwitch.x; 104# } 105# 106# vec2 temp = vec2(gl_FragCoord.xy); 107# 108# // Always true. 109# if (temp.y >= 0.0) 110# { 111# // _GLF_color.z = 0.0; 112# _GLF_color.z = injectionSwitch.x; 113# } 114# } 115SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0 116; SPIR-V 117; Version: 1.0 118; Generator: Khronos Glslang Reference Front End; 8 119; Bound: 137 120; Schema: 0 121 OpCapability Shader 122 %1 = OpExtInstImport "GLSL.std.450" 123 OpMemoryModel Logical GLSL450 124 OpEntryPoint Fragment %4 "main" %39 %68 125 OpExecutionMode %4 OriginUpperLeft 126 OpSource ESSL 310 127 OpName %4 "main" 128 OpName %12 "alwaysZero(vf2;" 129 OpName %11 "coord" 130 OpName %15 "a" 131 OpName %26 "buf0" 132 OpMemberName %26 0 "injectionSwitch" 133 OpName %28 "" 134 OpName %36 "b" 135 OpName %39 "gl_FragCoord" 136 OpName %57 "zero" 137 OpName %58 "param" 138 OpName %68 "_GLF_color" 139 OpName %95 "temp" 140 OpMemberDecorate %26 0 Offset 0 141 OpDecorate %26 Block 142 OpDecorate %28 DescriptorSet 0 143 OpDecorate %28 Binding 0 144 OpDecorate %39 BuiltIn FragCoord 145 OpDecorate %68 Location 0 146 %2 = OpTypeVoid 147 %3 = OpTypeFunction %2 148 %6 = OpTypeFloat 32 149 %7 = OpTypeVector %6 2 150 %8 = OpTypePointer Function %7 151 %9 = OpTypeInt 32 1 152 %10 = OpTypeFunction %9 %8 153 %14 = OpTypePointer Function %6 154 %16 = OpTypeInt 32 0 155 %17 = OpConstant %16 1 156 %20 = OpConstant %6 50 157 %21 = OpTypeBool 158 %26 = OpTypeStruct %7 159 %27 = OpTypePointer Uniform %26 160 %28 = OpVariable %27 Uniform 161 %29 = OpConstant %9 0 162 %30 = OpTypePointer Uniform %6 163 %34 = OpConstant %6 0 164 %37 = OpTypeVector %6 4 165 %38 = OpTypePointer Input %37 166 %39 = OpVariable %38 Input 167 %40 = OpTypePointer Input %6 168 %44 = OpConstant %6 1 169 %53 = OpConstant %9 1 170 %56 = OpTypePointer Function %9 171 %67 = OpTypePointer Output %37 172 %68 = OpVariable %67 Output 173 %69 = OpConstantComposite %37 %34 %44 %44 %44 174 %70 = OpConstant %16 0 175 %85 = OpTypePointer Output %6 176 %108 = OpConstant %16 2 177 %136 = OpConstantFalse %21 178 %4 = OpFunction %2 None %3 179 %5 = OpLabel 180 %111 = OpVariable %14 Function 181 %112 = OpVariable %14 Function 182 %113 = OpVariable %14 Function 183 %114 = OpVariable %56 Function 184 %57 = OpVariable %56 Function 185 %58 = OpVariable %8 Function 186 %95 = OpVariable %8 Function 187 %59 = OpLoad %37 %39 188 %60 = OpVectorShuffle %7 %59 %59 0 1 189 OpStore %58 %60 190 OpBranch %115 191 %115 = OpLabel 192 OpLoopMerge %116 %117 None 193 OpBranch %118 194 %118 = OpLabel 195 %119 = OpAccessChain %14 %58 %17 196 %120 = OpLoad %6 %119 197 %121 = OpFOrdLessThan %21 %120 %20 198 OpSelectionMerge %122 None 199 OpBranchConditional %121 %123 %124 200 %123 = OpLabel 201 %125 = OpAccessChain %30 %28 %29 %17 202 %126 = OpLoad %6 %125 203 OpStore %112 %126 204 OpBranch %122 205 %124 = OpLabel 206 OpStore %112 %34 207 OpBranch %122 208 %122 = OpLabel 209 %127 = OpLoad %6 %112 210 OpStore %111 %127 211 %128 = OpAccessChain %40 %39 %17 212 %129 = OpLoad %6 %128 213 %130 = OpFOrdLessThan %21 %129 %20 214 %131 = OpSelect %6 %130 %44 %34 215 OpStore %113 %131 216 %132 = OpFSub %6 %127 %131 217 %133 = OpFOrdLessThan %21 %132 %44 218 OpSelectionMerge %134 None 219 OpBranchConditional %133 %135 %134 220 %135 = OpLabel 221 OpStore %114 %29 222 OpBranch %116 223 %134 = OpLabel 224 OpStore %114 %53 225 OpBranch %116 226 %117 = OpLabel 227 OpBranchConditional %136 %115 %116 228 %116 = OpLabel 229 %61 = OpLoad %9 %114 230 OpStore %57 %61 231 %63 = OpIEqual %21 %61 %53 232 OpSelectionMerge %65 None 233 OpBranchConditional %63 %64 %65 234 %64 = OpLabel 235 OpReturn 236 %65 = OpLabel 237 OpStore %68 %69 238 %71 = OpAccessChain %40 %39 %70 239 %72 = OpLoad %6 %71 240 %73 = OpAccessChain %30 %28 %29 %70 241 %74 = OpLoad %6 %73 242 %75 = OpFOrdGreaterThanEqual %21 %72 %74 243 OpSelectionMerge %77 None 244 OpBranchConditional %75 %76 %77 245 %76 = OpLabel 246 %78 = OpAccessChain %40 %39 %17 247 %79 = OpLoad %6 %78 248 %80 = OpFOrdGreaterThanEqual %21 %79 %34 249 OpSelectionMerge %82 None 250 OpBranchConditional %80 %81 %82 251 %81 = OpLabel 252 %83 = OpAccessChain %30 %28 %29 %17 253 %84 = OpLoad %6 %83 254 %86 = OpAccessChain %85 %68 %70 255 OpStore %86 %84 256 OpBranch %82 257 %82 = OpLabel 258 OpBranch %77 259 %77 = OpLabel 260 %87 = OpAccessChain %40 %39 %17 261 %88 = OpLoad %6 %87 262 %89 = OpFOrdGreaterThanEqual %21 %88 %34 263 OpSelectionMerge %91 None 264 OpBranchConditional %89 %90 %91 265 %90 = OpLabel 266 %92 = OpAccessChain %30 %28 %29 %70 267 %93 = OpLoad %6 %92 268 %94 = OpAccessChain %85 %68 %17 269 OpStore %94 %93 270 OpBranch %91 271 %91 = OpLabel 272 %96 = OpLoad %37 %39 273 %97 = OpVectorShuffle %7 %96 %96 0 1 274 %98 = OpCompositeExtract %6 %97 0 275 %99 = OpCompositeExtract %6 %97 1 276 %100 = OpCompositeConstruct %7 %98 %99 277 OpStore %95 %100 278 %102 = OpCompositeExtract %6 %100 1 279 %103 = OpFOrdGreaterThanEqual %21 %102 %34 280 OpSelectionMerge %105 None 281 OpBranchConditional %103 %104 %105 282 %104 = OpLabel 283 %106 = OpAccessChain %30 %28 %29 %70 284 %107 = OpLoad %6 %106 285 %109 = OpAccessChain %85 %68 %108 286 OpStore %109 %107 287 OpBranch %105 288 %105 = OpLabel 289 OpReturn 290 OpFunctionEnd 291 %12 = OpFunction %9 None %10 292 %11 = OpFunctionParameter %8 293 %13 = OpLabel 294 %15 = OpVariable %14 Function 295 %23 = OpVariable %14 Function 296 %36 = OpVariable %14 Function 297 %18 = OpAccessChain %14 %11 %17 298 %19 = OpLoad %6 %18 299 %22 = OpFOrdLessThan %21 %19 %20 300 OpSelectionMerge %25 None 301 OpBranchConditional %22 %24 %33 302 %24 = OpLabel 303 %31 = OpAccessChain %30 %28 %29 %17 304 %32 = OpLoad %6 %31 305 OpStore %23 %32 306 OpBranch %25 307 %33 = OpLabel 308 OpStore %23 %34 309 OpBranch %25 310 %25 = OpLabel 311 %35 = OpLoad %6 %23 312 OpStore %15 %35 313 %41 = OpAccessChain %40 %39 %17 314 %42 = OpLoad %6 %41 315 %43 = OpFOrdLessThan %21 %42 %20 316 %45 = OpSelect %6 %43 %44 %34 317 OpStore %36 %45 318 %48 = OpFSub %6 %35 %45 319 %49 = OpFOrdLessThan %21 %48 %44 320 OpSelectionMerge %51 None 321 OpBranchConditional %49 %50 %51 322 %50 = OpLabel 323 OpReturnValue %29 324 %51 = OpLabel 325 OpReturnValue %53 326 OpFunctionEnd 327END 328 329# uniforms for variant 330 331# injectionSwitch 332BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA 333 0.0 1.0 334END 335 336BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM 337 338PIPELINE graphics variant_pipeline 339 ATTACH variant_vertex_shader 340 ATTACH variant_fragment_shader 341 FRAMEBUFFER_SIZE 256 256 342 BIND BUFFER variant_framebuffer AS color LOCATION 0 343 BIND BUFFER variant_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0 344END 345CLEAR_COLOR variant_pipeline 0 0 0 255 346 347CLEAR variant_pipeline 348RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256 349 350EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255 351