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 push constant and nested min max 21 22# The test passes because both shaders render the same image. 23 24SHADER vertex reference_vertex_shader PASSTHROUGH 25 26# reference_fragment_shader is derived from the following GLSL: 27# #version 320 es 28# precision highp float; 29# 30# precision highp int; 31# 32# layout(location = 0) out vec4 _GLF_color; 33# 34# layout(set = 0, binding = 0) uniform buf0 { 35# vec2 resolution; 36# }; 37# const vec4 pal[16] = vec4[16](vec4(0.0, 0.0, 0.0, 1.0), vec4(0.5, 0.0, 0.0, 1.0), vec4(0.0, 0.5, 0.0, 1.0), vec4(0.5, 0.5, 0.0, 1.0), vec4(0.0, 0.0, 0.5, 1.0), vec4(0.5, 0.0, 0.5, 1.0), vec4(0.0, 0.5, 0.5, 1.0), vec4(0.5, 0.5, 0.5, 1.0), vec4(0.0, 0.0, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), vec4(1.0, 1.0, 0.0, 1.0), vec4(0.0, 0.0, 1.0, 1.0), vec4(1.0, 0.0, 1.0, 1.0), vec4(0.0, 1.0, 1.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0)); 38# 39# int collatz(int v) 40# { 41# int count = 0; 42# while(v > 1) 43# { 44# if((v & 1) == 1) 45# { 46# v = 3 * v + 1; 47# } 48# else 49# { 50# v /= 2; 51# } 52# count ++; 53# } 54# return count; 55# } 56# void main() 57# { 58# vec2 lin = gl_FragCoord.xy / resolution; 59# lin = floor(lin * 8.0); 60# int v = int(lin.x) * 8 + int(lin.y); 61# _GLF_color = pal[collatz(v) % 16]; 62# } 63SHADER fragment reference_fragment_shader SPIRV-ASM TARGET_ENV spv1.0 64; SPIR-V 65; Version: 1.0 66; Generator: Khronos Glslang Reference Front End; 10 67; Bound: 108 68; Schema: 0 69 OpCapability Shader 70 %1 = OpExtInstImport "GLSL.std.450" 71 OpMemoryModel Logical GLSL450 72 OpEntryPoint Fragment %4 "main" %47 %76 73 OpExecutionMode %4 OriginUpperLeft 74 OpSource ESSL 320 75 OpName %4 "main" 76 OpName %10 "collatz(i1;" 77 OpName %9 "v" 78 OpName %12 "count" 79 OpName %44 "lin" 80 OpName %47 "gl_FragCoord" 81 OpName %50 "buf0" 82 OpMemberName %50 0 "resolution" 83 OpName %52 "" 84 OpName %61 "v" 85 OpName %76 "_GLF_color" 86 OpName %98 "param" 87 OpName %104 "indexable" 88 OpDecorate %47 BuiltIn FragCoord 89 OpMemberDecorate %50 0 Offset 0 90 OpDecorate %50 Block 91 OpDecorate %52 DescriptorSet 0 92 OpDecorate %52 Binding 0 93 OpDecorate %76 Location 0 94 %2 = OpTypeVoid 95 %3 = OpTypeFunction %2 96 %6 = OpTypeInt 32 1 97 %7 = OpTypePointer Function %6 98 %8 = OpTypeFunction %6 %7 99 %13 = OpConstant %6 0 100 %20 = OpConstant %6 1 101 %21 = OpTypeBool 102 %28 = OpConstant %6 3 103 %33 = OpConstant %6 2 104 %41 = OpTypeFloat 32 105 %42 = OpTypeVector %41 2 106 %43 = OpTypePointer Function %42 107 %45 = OpTypeVector %41 4 108 %46 = OpTypePointer Input %45 109 %47 = OpVariable %46 Input 110 %50 = OpTypeStruct %42 111 %51 = OpTypePointer Uniform %50 112 %52 = OpVariable %51 Uniform 113 %53 = OpTypePointer Uniform %42 114 %58 = OpConstant %41 8 115 %62 = OpTypeInt 32 0 116 %63 = OpConstant %62 0 117 %64 = OpTypePointer Function %41 118 %68 = OpConstant %6 8 119 %70 = OpConstant %62 1 120 %75 = OpTypePointer Output %45 121 %76 = OpVariable %75 Output 122 %77 = OpConstant %62 16 123 %78 = OpTypeArray %45 %77 124 %79 = OpConstant %41 0 125 %80 = OpConstant %41 1 126 %81 = OpConstantComposite %45 %79 %79 %79 %80 127 %82 = OpConstant %41 0.5 128 %83 = OpConstantComposite %45 %82 %79 %79 %80 129 %84 = OpConstantComposite %45 %79 %82 %79 %80 130 %85 = OpConstantComposite %45 %82 %82 %79 %80 131 %86 = OpConstantComposite %45 %79 %79 %82 %80 132 %87 = OpConstantComposite %45 %82 %79 %82 %80 133 %88 = OpConstantComposite %45 %79 %82 %82 %80 134 %89 = OpConstantComposite %45 %82 %82 %82 %80 135 %90 = OpConstantComposite %45 %80 %79 %79 %80 136 %91 = OpConstantComposite %45 %79 %80 %79 %80 137 %92 = OpConstantComposite %45 %80 %80 %79 %80 138 %93 = OpConstantComposite %45 %79 %79 %80 %80 139 %94 = OpConstantComposite %45 %80 %79 %80 %80 140 %95 = OpConstantComposite %45 %79 %80 %80 %80 141 %96 = OpConstantComposite %45 %80 %80 %80 %80 142 %97 = OpConstantComposite %78 %81 %83 %84 %85 %86 %87 %88 %89 %81 %90 %91 %92 %93 %94 %95 %96 143 %101 = OpConstant %6 16 144 %103 = OpTypePointer Function %78 145 %105 = OpTypePointer Function %45 146 %4 = OpFunction %2 None %3 147 %5 = OpLabel 148 %44 = OpVariable %43 Function 149 %61 = OpVariable %7 Function 150 %98 = OpVariable %7 Function 151 %104 = OpVariable %103 Function 152 %48 = OpLoad %45 %47 153 %49 = OpVectorShuffle %42 %48 %48 0 1 154 %54 = OpAccessChain %53 %52 %13 155 %55 = OpLoad %42 %54 156 %56 = OpFDiv %42 %49 %55 157 OpStore %44 %56 158 %57 = OpLoad %42 %44 159 %59 = OpVectorTimesScalar %42 %57 %58 160 %60 = OpExtInst %42 %1 Floor %59 161 OpStore %44 %60 162 %65 = OpAccessChain %64 %44 %63 163 %66 = OpLoad %41 %65 164 %67 = OpConvertFToS %6 %66 165 %69 = OpIMul %6 %67 %68 166 %71 = OpAccessChain %64 %44 %70 167 %72 = OpLoad %41 %71 168 %73 = OpConvertFToS %6 %72 169 %74 = OpIAdd %6 %69 %73 170 OpStore %61 %74 171 %99 = OpLoad %6 %61 172 OpStore %98 %99 173 %100 = OpFunctionCall %6 %10 %98 174 %102 = OpSMod %6 %100 %101 175 OpStore %104 %97 176 %106 = OpAccessChain %105 %104 %102 177 %107 = OpLoad %45 %106 178 OpStore %76 %107 179 OpReturn 180 OpFunctionEnd 181 %10 = OpFunction %6 None %8 182 %9 = OpFunctionParameter %7 183 %11 = OpLabel 184 %12 = OpVariable %7 Function 185 OpStore %12 %13 186 OpBranch %14 187 %14 = OpLabel 188 OpLoopMerge %16 %17 None 189 OpBranch %18 190 %18 = OpLabel 191 %19 = OpLoad %6 %9 192 %22 = OpSGreaterThan %21 %19 %20 193 OpBranchConditional %22 %15 %16 194 %15 = OpLabel 195 %23 = OpLoad %6 %9 196 %24 = OpBitwiseAnd %6 %23 %20 197 %25 = OpIEqual %21 %24 %20 198 OpSelectionMerge %27 None 199 OpBranchConditional %25 %26 %32 200 %26 = OpLabel 201 %29 = OpLoad %6 %9 202 %30 = OpIMul %6 %28 %29 203 %31 = OpIAdd %6 %30 %20 204 OpStore %9 %31 205 OpBranch %27 206 %32 = OpLabel 207 %34 = OpLoad %6 %9 208 %35 = OpSDiv %6 %34 %33 209 OpStore %9 %35 210 OpBranch %27 211 %27 = OpLabel 212 %36 = OpLoad %6 %12 213 %37 = OpIAdd %6 %36 %20 214 OpStore %12 %37 215 OpBranch %17 216 %17 = OpLabel 217 OpBranch %14 218 %16 = OpLabel 219 %38 = OpLoad %6 %12 220 OpReturnValue %38 221 OpFunctionEnd 222END 223 224# uniforms for reference 225 226# resolution 227BUFFER reference_resolution DATA_TYPE vec2<float> DATA 228 256.0 256.0 229END 230 231BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM 232 233PIPELINE graphics reference_pipeline 234 ATTACH reference_vertex_shader 235 ATTACH reference_fragment_shader 236 FRAMEBUFFER_SIZE 256 256 237 BIND BUFFER reference_framebuffer AS color LOCATION 0 238 BIND BUFFER reference_resolution AS uniform DESCRIPTOR_SET 0 BINDING 0 239END 240CLEAR_COLOR reference_pipeline 0 0 0 255 241 242CLEAR reference_pipeline 243RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256 244 245 246SHADER vertex variant_vertex_shader PASSTHROUGH 247 248# variant_fragment_shader is derived from the following GLSL: 249# #version 320 es 250# precision highp float; 251# 252# precision highp int; 253# 254# layout(location = 0) out vec4 _GLF_color; 255# 256# layout(push_constant) uniform buf_push { 257# vec2 resolution; 258# }; 259# const vec4 pal[16] = vec4[16](vec4(0.0, 0.0, 0.0, 1.0), vec4(0.5, 0.0, 0.0, 1.0), vec4(0.0, 0.5, 0.0, 1.0), vec4(0.5, 0.5, 0.0, 1.0), vec4(0.0, 0.0, 0.5, 1.0), vec4(0.5, 0.0, 0.5, 1.0), vec4(0.0, 0.5, 0.5, 1.0), vec4(0.5, 0.5, 0.5, 1.0), vec4(0.0, 0.0, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), vec4(1.0, 1.0, 0.0, 1.0), vec4(0.0, 0.0, 1.0, 1.0), vec4(1.0, 0.0, 1.0, 1.0), vec4(0.0, 1.0, 1.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0)); 260# 261# int collatz(int v) 262# { 263# int count = 0; 264# while(v > 1) 265# { 266# if((v & 1) == 1) 267# { 268# v = 3 * v + 1; 269# } 270# else 271# { 272# v /= 2; 273# } 274# count ++; 275# } 276# return count; 277# } 278# void main() 279# { 280# // vec2 max_c == (gl_FragCoord.xy / resolution). 281# vec2 max_c = max( // This should return the same result. 282# gl_FragCoord.xy / resolution, 283# gl_FragCoord.xy / (vec2(resolution.x, resolution.y)) 284# ); 285# // vec2 max_a == (gl_FragCoord.xy / resolution) 286# vec2 max_a = max( 287# // gl_FragCoord.y < 0 is always false. 288# // mix operation returns vec2(0.0 , 0.0). 289# // cosine of 0 is 1. 290# // anything divided by 1 stays the same. 291# max_c / cos(mix(vec2(1.0, 0.0), vec2(0.0, 218.851), bvec2(true, (gl_FragCoord.y < 0.0)))), 292# gl_FragCoord.xy / resolution 293# ); 294# // vec2 max_d == vec2(1.0, 1.0) 295# vec2 max_d = max( 296# // Same cosine fucntion as in max_a. 297# 1.0 / cos(mix(vec2(1.0, 0.0), vec2(0.0, 218.851), bvec2(true, (gl_FragCoord.y < 0.0)))), 298# vec2(1.0, 1.0) 299# ); 300# // vec2 max_b == vec2(1.0, 1.0) 301# vec2 max_b = max( 302# vec2(1.0, 1.0), 303# max_d // max_d == vec2(1.0, 1.0) 304# ); 305# // vec2 lin == (gl_FragCoord.xy / resolution) 306# vec2 lin = min( 307# max_a, // max_a == gl_FragCoord.xy / resolution 308# max_b // max_b == vec2(1.0, 1.0) 309# ); 310# lin = floor(lin * 8.0); 311# int v = int(lin.x) * 8 + int(lin.y); 312# _GLF_color = pal[collatz(v) % 16]; 313# } 314SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0 315; SPIR-V 316; Version: 1.0 317; Generator: Khronos Glslang Reference Front End; 10 318; Bound: 157 319; Schema: 0 320 OpCapability Shader 321 %1 = OpExtInstImport "GLSL.std.450" 322 OpMemoryModel Logical GLSL450 323 OpEntryPoint Fragment %4 "main" %47 %127 324 OpExecutionMode %4 OriginUpperLeft 325 OpSource ESSL 320 326 OpName %4 "main" 327 OpName %10 "collatz(i1;" 328 OpName %9 "v" 329 OpName %12 "count" 330 OpName %44 "max_c" 331 OpName %47 "gl_FragCoord" 332 OpName %50 "buf_push" 333 OpMemberName %50 0 "resolution" 334 OpName %52 "" 335 OpName %70 "max_a" 336 OpName %93 "max_d" 337 OpName %104 "max_b" 338 OpName %107 "lin" 339 OpName %115 "v" 340 OpName %127 "_GLF_color" 341 OpName %147 "param" 342 OpName %153 "indexable" 343 OpDecorate %47 BuiltIn FragCoord 344 OpMemberDecorate %50 0 Offset 0 345 OpDecorate %50 Block 346 OpDecorate %127 Location 0 347 %2 = OpTypeVoid 348 %3 = OpTypeFunction %2 349 %6 = OpTypeInt 32 1 350 %7 = OpTypePointer Function %6 351 %8 = OpTypeFunction %6 %7 352 %13 = OpConstant %6 0 353 %20 = OpConstant %6 1 354 %21 = OpTypeBool 355 %28 = OpConstant %6 3 356 %33 = OpConstant %6 2 357 %41 = OpTypeFloat 32 358 %42 = OpTypeVector %41 2 359 %43 = OpTypePointer Function %42 360 %45 = OpTypeVector %41 4 361 %46 = OpTypePointer Input %45 362 %47 = OpVariable %46 Input 363 %50 = OpTypeStruct %42 364 %51 = OpTypePointer PushConstant %50 365 %52 = OpVariable %51 PushConstant 366 %53 = OpTypePointer PushConstant %42 367 %59 = OpTypeInt 32 0 368 %60 = OpConstant %59 0 369 %61 = OpTypePointer PushConstant %41 370 %64 = OpConstant %59 1 371 %72 = OpConstant %41 1 372 %73 = OpConstant %41 0 373 %74 = OpConstantComposite %42 %72 %73 374 %75 = OpConstant %41 218.850998 375 %76 = OpConstantComposite %42 %73 %75 376 %77 = OpConstantTrue %21 377 %78 = OpTypePointer Input %41 378 %82 = OpTypeVector %21 2 379 %102 = OpConstantComposite %42 %72 %72 380 %112 = OpConstant %41 8 381 %116 = OpTypePointer Function %41 382 %120 = OpConstant %6 8 383 %126 = OpTypePointer Output %45 384 %127 = OpVariable %126 Output 385 %128 = OpConstant %59 16 386 %129 = OpTypeArray %45 %128 387 %130 = OpConstantComposite %45 %73 %73 %73 %72 388 %131 = OpConstant %41 0.5 389 %132 = OpConstantComposite %45 %131 %73 %73 %72 390 %133 = OpConstantComposite %45 %73 %131 %73 %72 391 %134 = OpConstantComposite %45 %131 %131 %73 %72 392 %135 = OpConstantComposite %45 %73 %73 %131 %72 393 %136 = OpConstantComposite %45 %131 %73 %131 %72 394 %137 = OpConstantComposite %45 %73 %131 %131 %72 395 %138 = OpConstantComposite %45 %131 %131 %131 %72 396 %139 = OpConstantComposite %45 %72 %73 %73 %72 397 %140 = OpConstantComposite %45 %73 %72 %73 %72 398 %141 = OpConstantComposite %45 %72 %72 %73 %72 399 %142 = OpConstantComposite %45 %73 %73 %72 %72 400 %143 = OpConstantComposite %45 %72 %73 %72 %72 401 %144 = OpConstantComposite %45 %73 %72 %72 %72 402 %145 = OpConstantComposite %45 %72 %72 %72 %72 403 %146 = OpConstantComposite %129 %130 %132 %133 %134 %135 %136 %137 %138 %130 %139 %140 %141 %142 %143 %144 %145 404 %150 = OpConstant %6 16 405 %152 = OpTypePointer Function %129 406 %154 = OpTypePointer Function %45 407 %4 = OpFunction %2 None %3 408 %5 = OpLabel 409 %44 = OpVariable %43 Function 410 %70 = OpVariable %43 Function 411 %93 = OpVariable %43 Function 412 %104 = OpVariable %43 Function 413 %107 = OpVariable %43 Function 414 %115 = OpVariable %7 Function 415 %147 = OpVariable %7 Function 416 %153 = OpVariable %152 Function 417 %48 = OpLoad %45 %47 418 %49 = OpVectorShuffle %42 %48 %48 0 1 419 %54 = OpAccessChain %53 %52 %13 420 %55 = OpLoad %42 %54 421 %56 = OpFDiv %42 %49 %55 422 %57 = OpLoad %45 %47 423 %58 = OpVectorShuffle %42 %57 %57 0 1 424 %62 = OpAccessChain %61 %52 %13 %60 425 %63 = OpLoad %41 %62 426 %65 = OpAccessChain %61 %52 %13 %64 427 %66 = OpLoad %41 %65 428 %67 = OpCompositeConstruct %42 %63 %66 429 %68 = OpFDiv %42 %58 %67 430 %69 = OpExtInst %42 %1 FMax %56 %68 431 OpStore %44 %69 432 %71 = OpLoad %42 %44 433 %79 = OpAccessChain %78 %47 %64 434 %80 = OpLoad %41 %79 435 %81 = OpFOrdLessThan %21 %80 %73 436 %83 = OpCompositeConstruct %82 %77 %81 437 %84 = OpSelect %42 %83 %76 %74 438 %85 = OpExtInst %42 %1 Cos %84 439 %86 = OpFDiv %42 %71 %85 440 %87 = OpLoad %45 %47 441 %88 = OpVectorShuffle %42 %87 %87 0 1 442 %89 = OpAccessChain %53 %52 %13 443 %90 = OpLoad %42 %89 444 %91 = OpFDiv %42 %88 %90 445 %92 = OpExtInst %42 %1 FMax %86 %91 446 OpStore %70 %92 447 %94 = OpAccessChain %78 %47 %64 448 %95 = OpLoad %41 %94 449 %96 = OpFOrdLessThan %21 %95 %73 450 %97 = OpCompositeConstruct %82 %77 %96 451 %98 = OpSelect %42 %97 %76 %74 452 %99 = OpExtInst %42 %1 Cos %98 453 %100 = OpCompositeConstruct %42 %72 %72 454 %101 = OpFDiv %42 %100 %99 455 %103 = OpExtInst %42 %1 FMax %101 %102 456 OpStore %93 %103 457 %105 = OpLoad %42 %93 458 %106 = OpExtInst %42 %1 FMax %102 %105 459 OpStore %104 %106 460 %108 = OpLoad %42 %70 461 %109 = OpLoad %42 %104 462 %110 = OpExtInst %42 %1 FMin %108 %109 463 OpStore %107 %110 464 %111 = OpLoad %42 %107 465 %113 = OpVectorTimesScalar %42 %111 %112 466 %114 = OpExtInst %42 %1 Floor %113 467 OpStore %107 %114 468 %117 = OpAccessChain %116 %107 %60 469 %118 = OpLoad %41 %117 470 %119 = OpConvertFToS %6 %118 471 %121 = OpIMul %6 %119 %120 472 %122 = OpAccessChain %116 %107 %64 473 %123 = OpLoad %41 %122 474 %124 = OpConvertFToS %6 %123 475 %125 = OpIAdd %6 %121 %124 476 OpStore %115 %125 477 %148 = OpLoad %6 %115 478 OpStore %147 %148 479 %149 = OpFunctionCall %6 %10 %147 480 %151 = OpSMod %6 %149 %150 481 OpStore %153 %146 482 %155 = OpAccessChain %154 %153 %151 483 %156 = OpLoad %45 %155 484 OpStore %127 %156 485 OpReturn 486 OpFunctionEnd 487 %10 = OpFunction %6 None %8 488 %9 = OpFunctionParameter %7 489 %11 = OpLabel 490 %12 = OpVariable %7 Function 491 OpStore %12 %13 492 OpBranch %14 493 %14 = OpLabel 494 OpLoopMerge %16 %17 None 495 OpBranch %18 496 %18 = OpLabel 497 %19 = OpLoad %6 %9 498 %22 = OpSGreaterThan %21 %19 %20 499 OpBranchConditional %22 %15 %16 500 %15 = OpLabel 501 %23 = OpLoad %6 %9 502 %24 = OpBitwiseAnd %6 %23 %20 503 %25 = OpIEqual %21 %24 %20 504 OpSelectionMerge %27 None 505 OpBranchConditional %25 %26 %32 506 %26 = OpLabel 507 %29 = OpLoad %6 %9 508 %30 = OpIMul %6 %28 %29 509 %31 = OpIAdd %6 %30 %20 510 OpStore %9 %31 511 OpBranch %27 512 %32 = OpLabel 513 %34 = OpLoad %6 %9 514 %35 = OpSDiv %6 %34 %33 515 OpStore %9 %35 516 OpBranch %27 517 %27 = OpLabel 518 %36 = OpLoad %6 %12 519 %37 = OpIAdd %6 %36 %20 520 OpStore %12 %37 521 OpBranch %17 522 %17 = OpLabel 523 OpBranch %14 524 %16 = OpLabel 525 %38 = OpLoad %6 %12 526 OpReturnValue %38 527 OpFunctionEnd 528END 529 530# uniforms for variant 531 532# resolution 533BUFFER variant_resolution DATA_TYPE vec2<float> DATA 534 256.0 256.0 535END 536 537BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM 538 539PIPELINE graphics variant_pipeline 540 ATTACH variant_vertex_shader 541 ATTACH variant_fragment_shader 542 FRAMEBUFFER_SIZE 256 256 543 BIND BUFFER variant_framebuffer AS color LOCATION 0 544 BIND BUFFER variant_resolution AS push_constant 545END 546CLEAR_COLOR variant_pipeline 0 0 0 255 547 548CLEAR variant_pipeline 549RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256 550 551EXPECT reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005 552