Add a batch of GraphicsFuzz tests
authorToni Salmivalli <toni.salmivalli@siru.fi>
Thu, 26 Nov 2020 13:45:43 +0000 (15:45 +0200)
committerAlexander Galazin <alexander.galazin@arm.com>
Wed, 14 Apr 2021 11:36:11 +0000 (14:36 +0300)
Components: Vulkan

New Tests:

dEQP-VK.graphicsfuzz.do-while-false-if
dEQP-VK.graphicsfuzz.struct-array-index
dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-float-mat-determinant-clamp
dEQP-VK.graphicsfuzz.stable-mergesort-clamped-conditional-bit-shift
dEQP-VK.graphicsfuzz.stable-quicksort-conditional-bitwise-or-clamp
dEQP-VK.graphicsfuzz.stable-triangle-clamp-conditional-mix
dEQP-VK.graphicsfuzz.stable-triangle-nested-conditional-clamped-float

Change-Id: I211d897d64f7c41b844cd0ab2bbb154b555e1496

android/cts/master/vk-master-2021-03-01.txt
android/cts/master/vk-master.txt
external/vulkancts/data/vulkan/amber/graphicsfuzz/do-while-false-if.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/index.txt
external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-colorgrid-modulo-float-mat-determinant-clamp.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-mergesort-clamped-conditional-bit-shift.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-quicksort-conditional-bitwise-or-clamp.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-clamp-conditional-mix.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-nested-conditional-clamped-float.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/graphicsfuzz/struct-array-index.amber [new file with mode: 0644]
external/vulkancts/mustpass/master/vk-default.txt

index 65e28df..825ef56 100644 (file)
@@ -260693,6 +260693,7 @@ dEQP-VK.graphicsfuzz.cov-x86-isel-lowering-selection-dag-struct-array-clamp-inde
 dEQP-VK.graphicsfuzz.cov-x86-isel-lowering-apfloat-nan-cos-cos
 dEQP-VK.graphicsfuzz.cov-x86-isel-lowering-negative-left-shift
 dEQP-VK.graphicsfuzz.create-color-in-do-while-for-loop
+dEQP-VK.graphicsfuzz.do-while-false-if
 dEQP-VK.graphicsfuzz.do-while-false-loops
 dEQP-VK.graphicsfuzz.do-while-if-return
 dEQP-VK.graphicsfuzz.do-while-with-if-condition
@@ -260747,18 +260748,24 @@ dEQP-VK.graphicsfuzz.stable-binarysearch-tree-nested-if-and-conditional
 dEQP-VK.graphicsfuzz.stable-binarysearch-tree-with-loop-read-write-global
 dEQP-VK.graphicsfuzz.stable-collatz-push-constant-with-nested-min-max
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-double-always-false-discard
+dEQP-VK.graphicsfuzz.stable-mergesort-for-always-false-if-discard
+dEQP-VK.graphicsfuzz.stable-mergesort-reversed-for-loop
+dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-float-mat-determinant-clamp
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-injected-conditional-true
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-true-conditional-simple-loop
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-vec3-values-from-matrix
-dEQP-VK.graphicsfuzz.stable-mergesort-for-always-false-if-discard
-dEQP-VK.graphicsfuzz.stable-mergesort-reversed-for-loop
+dEQP-VK.graphicsfuzz.stable-mergesort-clamped-conditional-bit-shift
+dEQP-VK.graphicsfuzz.stable-quicksort-conditional-bitwise-or-clamp
 dEQP-VK.graphicsfuzz.stable-quicksort-for-loop-with-injection
 dEQP-VK.graphicsfuzz.stable-quicksort-if-false-else-return
 dEQP-VK.graphicsfuzz.stable-quicksort-max-value-as-index
 dEQP-VK.graphicsfuzz.stable-rects-vec4-clamp-conditional-min-mix
 dEQP-VK.graphicsfuzz.stable-triangle-array-nested-loop
 dEQP-VK.graphicsfuzz.stable-triangle-nested-for-loop-and-true-if
+dEQP-VK.graphicsfuzz.stable-triangle-clamp-conditional-mix
+dEQP-VK.graphicsfuzz.stable-triangle-nested-conditional-clamped-float
 dEQP-VK.graphicsfuzz.struct-array-data-as-loop-iterator
+dEQP-VK.graphicsfuzz.struct-array-index
 dEQP-VK.graphicsfuzz.switch-case-with-undefined-expression
 dEQP-VK.graphicsfuzz.switch-inside-while-always-return
 dEQP-VK.graphicsfuzz.switch-loop-switch-if
index 37bfbee..c94b113 100644 (file)
@@ -833160,6 +833160,7 @@ dEQP-VK.graphicsfuzz.discard-in-array-manipulating-loop
 dEQP-VK.graphicsfuzz.discard-in-loop
 dEQP-VK.graphicsfuzz.discard-in-loop-in-function
 dEQP-VK.graphicsfuzz.discards-in-control-flow
+dEQP-VK.graphicsfuzz.do-while-false-if
 dEQP-VK.graphicsfuzz.do-while-false-loops
 dEQP-VK.graphicsfuzz.do-while-if-return
 dEQP-VK.graphicsfuzz.do-while-loop-in-conditionals
@@ -833247,19 +833248,25 @@ dEQP-VK.graphicsfuzz.stable-binarysearch-tree-nested-if-and-conditional
 dEQP-VK.graphicsfuzz.stable-binarysearch-tree-with-loop-read-write-global
 dEQP-VK.graphicsfuzz.stable-collatz-push-constant-with-nested-min-max
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-double-always-false-discard
+dEQP-VK.graphicsfuzz.stable-mergesort-for-always-false-if-discard
+dEQP-VK.graphicsfuzz.stable-mergesort-reversed-for-loop
+dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-float-mat-determinant-clamp
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-injected-conditional-true
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-true-conditional-simple-loop
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-vec3-values-from-matrix
-dEQP-VK.graphicsfuzz.stable-mergesort-for-always-false-if-discard
-dEQP-VK.graphicsfuzz.stable-mergesort-reversed-for-loop
+dEQP-VK.graphicsfuzz.stable-mergesort-clamped-conditional-bit-shift
+dEQP-VK.graphicsfuzz.stable-quicksort-conditional-bitwise-or-clamp
 dEQP-VK.graphicsfuzz.stable-quicksort-for-loop-with-injection
 dEQP-VK.graphicsfuzz.stable-quicksort-if-false-else-return
 dEQP-VK.graphicsfuzz.stable-quicksort-max-value-as-index
 dEQP-VK.graphicsfuzz.stable-rects-vec4-clamp-conditional-min-mix
 dEQP-VK.graphicsfuzz.stable-triangle-array-nested-loop
 dEQP-VK.graphicsfuzz.stable-triangle-nested-for-loop-and-true-if
+dEQP-VK.graphicsfuzz.stable-triangle-clamp-conditional-mix
+dEQP-VK.graphicsfuzz.stable-triangle-nested-conditional-clamped-float
 dEQP-VK.graphicsfuzz.struct-and-unreachable-infinite-loop
 dEQP-VK.graphicsfuzz.struct-array-data-as-loop-iterator
+dEQP-VK.graphicsfuzz.struct-array-index
 dEQP-VK.graphicsfuzz.struct-controlled-loop
 dEQP-VK.graphicsfuzz.struct-used-as-temporary
 dEQP-VK.graphicsfuzz.switch-case-with-undefined-expression
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/do-while-false-if.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/do-while-false-if.amber
new file mode 100644 (file)
index 0000000..ed31004
--- /dev/null
@@ -0,0 +1,221 @@
+#!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 the GraphicsFuzz project.
+
+# Short description: A fragment shader with false if return in do while loop
+
+# The test passes because the shader always writes color red.
+
+# Optimized using spirv-opt with the following arguments:
+# '--inline-entry-points-exhaustive'
+# '--ccp'
+# '--eliminate-local-single-block'
+# '--eliminate-dead-inserts'
+# '--eliminate-dead-inserts'
+# '--combine-access-chains'
+# '--eliminate-local-single-block'
+# '--reduce-load-size'
+# '--eliminate-local-single-store'
+# '--eliminate-dead-branches'
+# '--reduce-load-size'
+# '--eliminate-dead-code-aggressive'
+# '--eliminate-local-multi-store'
+# '--redundancy-elimination'
+# spirv-opt commit hash: e28436f2b8a2f0705a07de908178d2ea2682c6d3
+
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+#
+# precision highp float;
+# precision highp int;
+#
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;   //x == 0.0, y == 1.0
+# };
+#
+# struct struct_base
+# {
+#     float count;
+# };
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# void main()
+# {    // loop_limit == 100
+#     int loop_limit = (injectionSwitch.y > 0.0 ? 100 : 1);
+#     int loop_count = 0;
+#
+#     bool bool_a = true;
+#
+#     struct_base struct_a = struct_base(1.0);
+#     do
+#     {
+#         loop_count++;
+#         // Always false.
+#         if (injectionSwitch.x > injectionSwitch.y)
+#         {
+#             return ;
+#         }
+#     }
+#     // Always false.
+#     while ((struct_a.count != injectionSwitch.y) && (loop_count < loop_limit));
+#     bool_a = struct_a.count < 1.0;
+#     // bool_a == false
+#     if (bool_a == false)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(1.0);
+#     };
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 75
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %70
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %11 "buf0"
+               OpMemberName %11 0 "injectionSwitch"
+               OpName %13 ""
+               OpName %26 "loop_count"
+               OpName %30 "struct_base"
+               OpMemberName %30 0 "count"
+               OpName %32 "struct_a"
+               OpName %70 "_GLF_color"
+               OpMemberDecorate %11 0 Offset 0
+               OpDecorate %11 Block
+               OpDecorate %13 DescriptorSet 0
+               OpDecorate %13 Binding 0
+               OpDecorate %70 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %9 = OpTypeFloat 32
+         %10 = OpTypeVector %9 2
+         %11 = OpTypeStruct %10
+         %12 = OpTypePointer Uniform %11
+         %13 = OpVariable %12 Uniform
+         %14 = OpConstant %6 0
+         %15 = OpTypeInt 32 0
+         %16 = OpConstant %15 1
+         %17 = OpTypePointer Uniform %9
+         %20 = OpConstant %9 0
+         %21 = OpTypeBool
+         %23 = OpConstant %6 100
+         %24 = OpConstant %6 1
+         %30 = OpTypeStruct %9
+         %31 = OpTypePointer Function %30
+         %33 = OpConstant %9 1
+         %34 = OpConstantComposite %30 %33
+         %41 = OpConstant %15 0
+         %50 = OpTypePointer Function %9
+         %64 = OpConstantFalse %21
+         %68 = OpTypeVector %9 4
+         %69 = OpTypePointer Output %68
+         %70 = OpVariable %69 Output
+         %71 = OpConstantComposite %68 %33 %20 %20 %33
+         %73 = OpConstantComposite %68 %33 %33 %33 %33
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %26 = OpVariable %7 Function
+         %32 = OpVariable %31 Function
+         %18 = OpAccessChain %17 %13 %14 %16
+         %19 = OpLoad %9 %18
+         %22 = OpFOrdGreaterThan %21 %19 %20
+         %25 = OpSelect %6 %22 %23 %24
+               OpStore %26 %14
+               OpStore %32 %34
+               OpBranch %35
+         %35 = OpLabel
+         %74 = OpPhi %6 %14 %5 %40 %38
+               OpLoopMerge %37 %38 None
+               OpBranch %36
+         %36 = OpLabel
+         %40 = OpIAdd %6 %74 %24
+               OpStore %26 %40
+         %42 = OpAccessChain %17 %13 %14 %41
+         %43 = OpLoad %9 %42
+         %46 = OpFOrdGreaterThan %21 %43 %19
+               OpSelectionMerge %48 None
+               OpBranchConditional %46 %47 %48
+         %47 = OpLabel
+               OpReturn
+         %48 = OpLabel
+               OpBranch %38
+         %38 = OpLabel
+         %51 = OpAccessChain %50 %32 %14
+         %52 = OpLoad %9 %51
+         %55 = OpFUnordNotEqual %21 %52 %19
+         %58 = OpSLessThan %21 %40 %25
+         %59 = OpLogicalAnd %21 %55 %58
+               OpBranchConditional %59 %35 %37
+         %37 = OpLabel
+         %61 = OpLoad %9 %51
+         %62 = OpFOrdLessThan %21 %61 %33
+         %65 = OpLogicalEqual %21 %62 %64
+               OpSelectionMerge %67 None
+               OpBranchConditional %65 %66 %72
+         %66 = OpLabel
+               OpStore %70 %71
+               OpBranch %67
+         %72 = OpLabel
+               OpStore %70 %73
+               OpBranch %67
+         %67 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> STD140 DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch 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 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
index 9c04c30..e4d1dc1 100644 (file)
 {      "discard-in-loop.amber",                                                                                                                                        "discard-in-loop",                                                                                                                                      "A shader with a discard in a loop"                                                                                                     },
 {      "discard-in-loop-in-function.amber",                                                                                                            "discard-in-loop-in-function",                                                                                                          "A shader with a discard nested in a loop in a function"                                                        },
 {      "discards-in-control-flow.amber",                                                                                                                       "discards-in-control-flow",                                                                                                                     "A fragment shader with discards in loops and conditionals"                                                     },
+{      "do-while-false-if.amber",                                                                                                                                      "do-while-false-if",                                                                                                                            "A fragment shader with false if return in do while loop"                                                       },
 {      "do-while-false-loops.amber",                                                                                                                           "do-while-false-loops",                                                                                                                         "Code wrapped in nested single iteration loops"                                                                         },
 {      "do-while-if-return.amber",                                                                                                                                     "do-while-if-return",                                                                                                                           "A fragment shader with true if in a nested do while loop"                                                      },
 {      "do-while-loop-in-conditionals.amber",                                                                                                          "do-while-loop-in-conditionals",                                                                                                        "A fragment shader with do-while loop in conditional nest"                                                      },
 {      "stable-binarysearch-tree-with-loop-read-write-global.amber",                                                           "stable-binarysearch-tree-with-loop-read-write-global",                                                         "A pair of fragment shaders that both render red"                                                                       },
 {      "stable-collatz-push-constant-with-nested-min-max.amber",                                                                       "stable-collatz-push-constant-with-nested-min-max",                                                                     "A fragment shader with push constant and nested min max"                                                       },
 {      "stable-colorgrid-modulo-double-always-false-discard.amber",                                                            "stable-colorgrid-modulo-double-always-false-discard",                                                          "A fragment shader with two always false discards"                                                                      },
+{      "stable-mergesort-for-always-false-if-discard.amber",                                                                           "stable-mergesort-for-always-false-if-discard",                                                                         "A fragment shader with for loop and always false if"                                                           },
+{      "stable-mergesort-reversed-for-loop.amber",                                                                                                     "stable-mergesort-reversed-for-loop",                                                                                           "A fragment shader with once iterated reversed for loop"                                                        },
+{      "stable-colorgrid-modulo-float-mat-determinant-clamp.amber",                                                            "stable-colorgrid-modulo-float-mat-determinant-clamp",                                                          "A fragment shader with clamped float in determinant matrix"                                            },
 {      "stable-colorgrid-modulo-injected-conditional-true.amber",                                                                      "stable-colorgrid-modulo-injected-conditional-true",                                                            "A fragment shader with an always true conditional"                                                                     },
 {      "stable-colorgrid-modulo-true-conditional-simple-loop.amber",                                                           "stable-colorgrid-modulo-true-conditional-simple-loop",                                                         "A fragment shader with conditional and simple loop"                                                            },
 {      "stable-colorgrid-modulo-vec3-values-from-matrix.amber",                                                                        "stable-colorgrid-modulo-vec3-values-from-matrix",                                                                      "A fragment shader with vec3 values set from matrix4x2"                                                         },
-{      "stable-mergesort-for-always-false-if-discard.amber",                                                                           "stable-mergesort-for-always-false-if-discard",                                                                         "A fragment shader with for loop and always false if"                                                           },
-{      "stable-mergesort-reversed-for-loop.amber",                                                                                                     "stable-mergesort-reversed-for-loop",                                                                                           "A fragment shader with once iterated reversed for loop"                                                        },
+{      "stable-mergesort-clamped-conditional-bit-shift.amber",                                                                         "stable-mergesort-clamped-conditional-bit-shift",                                                                       "Two shaders with diff: conditional bit shift in a clamp"                                                       },
+{      "stable-quicksort-conditional-bitwise-or-clamp.amber",                                                                          "stable-quicksort-conditional-bitwise-or-clamp",                                                                        "A fragment shader with conditional bitwise or clamped"                                                         },
 {      "stable-quicksort-for-loop-with-injection.amber",                                                                                       "stable-quicksort-for-loop-with-injection",                                                                                     "A fragment shader with a for loop containing injection"                                                        },
 {      "stable-quicksort-if-false-else-return.amber",                                                                                          "stable-quicksort-if-false-else-return",                                                                                        "A fragment shader with an always false if statement"                                                           },
 {      "stable-quicksort-max-value-as-index.amber",                                                                                            "stable-quicksort-max-value-as-index",                                                                                          "A fragment shader with greater of two values as index"                                                         },
 {      "stable-rects-vec4-clamp-conditional-min-mix.amber",                                                                            "stable-rects-vec4-clamp-conditional-min-mix",                                                                          "A fragment shader with min-mix in always false conditional"                                            },
 {      "stable-triangle-array-nested-loop.amber",                                                                                                      "stable-triangle-array-nested-loop",                                                                                            "A fragment shader with array and nested loops"                                                                         },
 {      "stable-triangle-nested-for-loop-and-true-if.amber",                                                                            "stable-triangle-nested-for-loop-and-true-if",                                                                          "A fragment shader with nested for loop and always true if"                                                     },
+{      "stable-triangle-clamp-conditional-mix.amber",                                                                                          "stable-triangle-clamp-conditional-mix",                                                                                        "A fragment shader with mix conditional in a clamp"                                                                     },
+{      "stable-triangle-nested-conditional-clamped-float.amber",                                                                       "stable-triangle-nested-conditional-clamped-float",                                                                     "A fragment shader with nested conditional float in clamp"                                                      },
 {      "struct-and-unreachable-infinite-loop.amber",                                                                                           "struct-and-unreachable-infinite-loop",                                                                                         "Fragment shader with struct and unreachable infinite loop"                                                     },
 {      "struct-array-data-as-loop-iterator.amber",                                                                                                     "struct-array-data-as-loop-iterator",                                                                                           "A fragment shader that uses struct array data for loop iterator value"                         },
+{      "struct-array-index.amber",                                                                                                                                     "struct-array-index",                                                                                                                           "A fragment shader with struct array and always true if"                                                        },
 {      "struct-controlled-loop.amber",                                                                                                                         "struct-controlled-loop",                                                                                                                       "Shader with loop controlled by struct"                                                                                         },
 {      "struct-used-as-temporary.amber",                                                                                                                       "struct-used-as-temporary",                                                                                                                     "A fragment shader that uses a temporary struct variable"                                                       },
 {      "switch-case-with-undefined-expression.amber",                                                                                          "switch-case-with-undefined-expression",                                                                                        "A fragment shader with undefined expression"                                                                           },
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-colorgrid-modulo-float-mat-determinant-clamp.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-colorgrid-modulo-float-mat-determinant-clamp.amber
new file mode 100644 (file)
index 0000000..827edc8
--- /dev/null
@@ -0,0 +1,689 @@
+#!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 the GraphicsFuzz project.
+
+# Short description: A fragment shader with clamped float in determinant matrix
+
+# The test passes because both shaders render the same image.
+
+SHADER vertex reference_vertex_shader PASSTHROUGH
+
+# reference_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#  vec2 resolution;
+# };
+# float compute_value(float limit, float thirty_two)
+# {
+#  float result = -0.5;
+#  for (int i = 1; i < 800; i++)
+#  {
+#    if ((i % 32) == 0)
+#    {
+#      result += 0.4;
+#    }
+#    else
+#    {
+#      if (mod(float(i), round(thirty_two)) <= 0.01)
+#      {
+#        result += 100.0;
+#      }
+#    }
+#    if (float(i) >= limit)
+#    {
+#      return result;
+#    }
+#  }
+#  return result;
+# }
+# void main()
+# {
+#  vec3 c = vec3(7.0, 8.0, 9.0);
+#  float thirty_two = round(resolution.x / 8.0);
+#  c.x = compute_value(gl_FragCoord.x, thirty_two);
+#  c.y = compute_value(gl_FragCoord.y, thirty_two);
+#  c.z = c.x + c.y;
+#  for (int i = 0; i < 3; i++)
+#  {
+#    if (c[i] >= 1.0)
+#    {
+#      c[i] = c[i] * c[i];
+#    }
+#  }
+#  _GLF_color = vec4(normalize(abs(c)), 1.0);
+# }
+SHADER fragment reference_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 145
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %85 %137
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %11 "compute_value(f1;f1;"
+               OpName %9 "limit"
+               OpName %10 "thirty_two"
+               OpName %13 "result"
+               OpName %17 "i"
+               OpName %66 "c"
+               OpName %71 "thirty_two"
+               OpName %73 "buf0"
+               OpMemberName %73 0 "resolution"
+               OpName %75 ""
+               OpName %85 "gl_FragCoord"
+               OpName %86 "param"
+               OpName %90 "param"
+               OpName %94 "param"
+               OpName %98 "param"
+               OpName %109 "i"
+               OpName %137 "_GLF_color"
+               OpMemberDecorate %73 0 Offset 0
+               OpDecorate %73 Block
+               OpDecorate %75 DescriptorSet 0
+               OpDecorate %75 Binding 0
+               OpDecorate %85 BuiltIn FragCoord
+               OpDecorate %137 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypePointer Function %6
+          %8 = OpTypeFunction %6 %7 %7
+         %14 = OpConstant %6 -0.5
+         %15 = OpTypeInt 32 1
+         %16 = OpTypePointer Function %15
+         %18 = OpConstant %15 1
+         %25 = OpConstant %15 800
+         %26 = OpTypeBool
+         %29 = OpConstant %15 32
+         %31 = OpConstant %15 0
+         %35 = OpConstant %6 0.400000006
+         %44 = OpConstant %6 0.00999999978
+         %48 = OpConstant %6 100
+         %64 = OpTypeVector %6 3
+         %65 = OpTypePointer Function %64
+         %67 = OpConstant %6 7
+         %68 = OpConstant %6 8
+         %69 = OpConstant %6 9
+         %70 = OpConstantComposite %64 %67 %68 %69
+         %72 = OpTypeVector %6 2
+         %73 = OpTypeStruct %72
+         %74 = OpTypePointer Uniform %73
+         %75 = OpVariable %74 Uniform
+         %76 = OpTypeInt 32 0
+         %77 = OpConstant %76 0
+         %78 = OpTypePointer Uniform %6
+         %83 = OpTypeVector %6 4
+         %84 = OpTypePointer Input %83
+         %85 = OpVariable %84 Input
+         %87 = OpTypePointer Input %6
+         %95 = OpConstant %76 1
+        %107 = OpConstant %76 2
+        %116 = OpConstant %15 3
+        %121 = OpConstant %6 1
+        %136 = OpTypePointer Output %83
+        %137 = OpVariable %136 Output
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %66 = OpVariable %65 Function
+         %71 = OpVariable %7 Function
+         %86 = OpVariable %7 Function
+         %90 = OpVariable %7 Function
+         %94 = OpVariable %7 Function
+         %98 = OpVariable %7 Function
+        %109 = OpVariable %16 Function
+               OpStore %66 %70
+         %79 = OpAccessChain %78 %75 %31 %77
+         %80 = OpLoad %6 %79
+         %81 = OpFDiv %6 %80 %68
+         %82 = OpExtInst %6 %1 Round %81
+               OpStore %71 %82
+         %88 = OpAccessChain %87 %85 %77
+         %89 = OpLoad %6 %88
+               OpStore %86 %89
+         %91 = OpLoad %6 %71
+               OpStore %90 %91
+         %92 = OpFunctionCall %6 %11 %86 %90
+         %93 = OpAccessChain %7 %66 %77
+               OpStore %93 %92
+         %96 = OpAccessChain %87 %85 %95
+         %97 = OpLoad %6 %96
+               OpStore %94 %97
+         %99 = OpLoad %6 %71
+               OpStore %98 %99
+        %100 = OpFunctionCall %6 %11 %94 %98
+        %101 = OpAccessChain %7 %66 %95
+               OpStore %101 %100
+        %102 = OpAccessChain %7 %66 %77
+        %103 = OpLoad %6 %102
+        %104 = OpAccessChain %7 %66 %95
+        %105 = OpLoad %6 %104
+        %106 = OpFAdd %6 %103 %105
+        %108 = OpAccessChain %7 %66 %107
+               OpStore %108 %106
+               OpStore %109 %31
+               OpBranch %110
+        %110 = OpLabel
+               OpLoopMerge %112 %113 None
+               OpBranch %114
+        %114 = OpLabel
+        %115 = OpLoad %15 %109
+        %117 = OpSLessThan %26 %115 %116
+               OpBranchConditional %117 %111 %112
+        %111 = OpLabel
+        %118 = OpLoad %15 %109
+        %119 = OpAccessChain %7 %66 %118
+        %120 = OpLoad %6 %119
+        %122 = OpFOrdGreaterThanEqual %26 %120 %121
+               OpSelectionMerge %124 None
+               OpBranchConditional %122 %123 %124
+        %123 = OpLabel
+        %125 = OpLoad %15 %109
+        %126 = OpLoad %15 %109
+        %127 = OpAccessChain %7 %66 %126
+        %128 = OpLoad %6 %127
+        %129 = OpLoad %15 %109
+        %130 = OpAccessChain %7 %66 %129
+        %131 = OpLoad %6 %130
+        %132 = OpFMul %6 %128 %131
+        %133 = OpAccessChain %7 %66 %125
+               OpStore %133 %132
+               OpBranch %124
+        %124 = OpLabel
+               OpBranch %113
+        %113 = OpLabel
+        %134 = OpLoad %15 %109
+        %135 = OpIAdd %15 %134 %18
+               OpStore %109 %135
+               OpBranch %110
+        %112 = OpLabel
+        %138 = OpLoad %64 %66
+        %139 = OpExtInst %64 %1 FAbs %138
+        %140 = OpExtInst %64 %1 Normalize %139
+        %141 = OpCompositeExtract %6 %140 0
+        %142 = OpCompositeExtract %6 %140 1
+        %143 = OpCompositeExtract %6 %140 2
+        %144 = OpCompositeConstruct %83 %141 %142 %143 %121
+               OpStore %137 %144
+               OpReturn
+               OpFunctionEnd
+         %11 = OpFunction %6 None %8
+          %9 = OpFunctionParameter %7
+         %10 = OpFunctionParameter %7
+         %12 = OpLabel
+         %13 = OpVariable %7 Function
+         %17 = OpVariable %16 Function
+               OpStore %13 %14
+               OpStore %17 %18
+               OpBranch %19
+         %19 = OpLabel
+               OpLoopMerge %21 %22 None
+               OpBranch %23
+         %23 = OpLabel
+         %24 = OpLoad %15 %17
+         %27 = OpSLessThan %26 %24 %25
+               OpBranchConditional %27 %20 %21
+         %20 = OpLabel
+         %28 = OpLoad %15 %17
+         %30 = OpSMod %15 %28 %29
+         %32 = OpIEqual %26 %30 %31
+               OpSelectionMerge %34 None
+               OpBranchConditional %32 %33 %38
+         %33 = OpLabel
+         %36 = OpLoad %6 %13
+         %37 = OpFAdd %6 %36 %35
+               OpStore %13 %37
+               OpBranch %34
+         %38 = OpLabel
+         %39 = OpLoad %15 %17
+         %40 = OpConvertSToF %6 %39
+         %41 = OpLoad %6 %10
+         %42 = OpExtInst %6 %1 Round %41
+         %43 = OpFMod %6 %40 %42
+         %45 = OpFOrdLessThanEqual %26 %43 %44
+               OpSelectionMerge %47 None
+               OpBranchConditional %45 %46 %47
+         %46 = OpLabel
+         %49 = OpLoad %6 %13
+         %50 = OpFAdd %6 %49 %48
+               OpStore %13 %50
+               OpBranch %47
+         %47 = OpLabel
+               OpBranch %34
+         %34 = OpLabel
+         %51 = OpLoad %15 %17
+         %52 = OpConvertSToF %6 %51
+         %53 = OpLoad %6 %9
+         %54 = OpFOrdGreaterThanEqual %26 %52 %53
+               OpSelectionMerge %56 None
+               OpBranchConditional %54 %55 %56
+         %55 = OpLabel
+         %57 = OpLoad %6 %13
+               OpReturnValue %57
+         %56 = OpLabel
+               OpBranch %22
+         %22 = OpLabel
+         %59 = OpLoad %15 %17
+         %60 = OpIAdd %15 %59 %18
+               OpStore %17 %60
+               OpBranch %19
+         %21 = OpLabel
+         %61 = OpLoad %6 %13
+               OpReturnValue %61
+               OpFunctionEnd
+END
+
+# uniforms for reference
+
+# resolution
+BUFFER reference_resolution DATA_TYPE vec2<float> STD140 DATA
+ 256.0 256.0
+END
+
+BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics reference_pipeline
+  ATTACH reference_vertex_shader
+  ATTACH reference_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER reference_framebuffer AS color LOCATION 0
+  BIND BUFFER reference_resolution AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR reference_pipeline 0 0 0 255
+
+CLEAR reference_pipeline
+RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#   vec2 resolution;
+# };
+# float compute_value(float limit, float thirty_two)
+# {
+#  float result = -0.5;
+#  for (int i = 1; i < 800; i++)
+#  {
+#    if ((i % 32) == 0)
+#    {
+#      result += 0.4;
+#    }
+#    else
+#    {
+#      if (mod(float(i), round(thirty_two)) <= 0.01)
+#      {
+#        result += 100.0;
+#      }
+#    }
+#    if (float(i) >= limit)
+#    {
+#      // clamp_a == 1.0
+#      float clamp_a = clamp((1.0), (1.0), ((gl_FragCoord.y < 0.0) ? (-1.0) : (false ? exp(result) : 1.0)));
+#      // det_a == 1.0
+#      float det_a = determinant(mat4(1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, clamp_a));
+#      // Type casting matrix to float takes the first value in matrix.
+#      // float_a == result
+#      float float_a = float(mat4x3(((result) / det_a), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0));
+#      // Returns result.
+#      return float_a;
+#    }
+#  }
+#  return result;
+# }
+# void main()
+# {
+#  vec3 c = vec3(7.0, 8.0, 9.0);
+#  float thirty_two = round(resolution.x / 8.0);
+#  c.x = compute_value(gl_FragCoord.x, thirty_two);
+#  c.y = compute_value(gl_FragCoord.y, thirty_two);
+#  c.z = c.x + c.y;
+#  for (int i = 0; i < 3; i++)
+#  {
+#    if (c[i] >= 1.0)
+#    {
+#      c[i] = c[i] * c[i];
+#    }
+#  }
+#  _GLF_color = vec4(normalize(abs(c)), 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 185
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %61 %177
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %11 "compute_value(f1;f1;"
+               OpName %9 "limit"
+               OpName %10 "thirty_two"
+               OpName %13 "result"
+               OpName %17 "i"
+               OpName %57 "clamp_a"
+               OpName %61 "gl_FragCoord"
+               OpName %84 "det_a"
+               OpName %93 "float_a"
+               OpName %113 "c"
+               OpName %118 "thirty_two"
+               OpName %120 "buf0"
+               OpMemberName %120 0 "resolution"
+               OpName %122 ""
+               OpName %129 "param"
+               OpName %132 "param"
+               OpName %136 "param"
+               OpName %139 "param"
+               OpName %150 "i"
+               OpName %177 "_GLF_color"
+               OpDecorate %61 BuiltIn FragCoord
+               OpMemberDecorate %120 0 Offset 0
+               OpDecorate %120 Block
+               OpDecorate %122 DescriptorSet 0
+               OpDecorate %122 Binding 0
+               OpDecorate %177 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypePointer Function %6
+          %8 = OpTypeFunction %6 %7 %7
+         %14 = OpConstant %6 -0.5
+         %15 = OpTypeInt 32 1
+         %16 = OpTypePointer Function %15
+         %18 = OpConstant %15 1
+         %25 = OpConstant %15 800
+         %26 = OpTypeBool
+         %29 = OpConstant %15 32
+         %31 = OpConstant %15 0
+         %35 = OpConstant %6 0.400000006
+         %44 = OpConstant %6 0.00999999978
+         %48 = OpConstant %6 100
+         %58 = OpConstant %6 1
+         %59 = OpTypeVector %6 4
+         %60 = OpTypePointer Input %59
+         %61 = OpVariable %60 Input
+         %62 = OpTypeInt 32 0
+         %63 = OpConstant %62 1
+         %64 = OpTypePointer Input %6
+         %67 = OpConstant %6 0
+         %72 = OpConstant %6 -1
+         %74 = OpConstantFalse %26
+         %86 = OpTypeMatrix %59 4
+         %97 = OpTypeVector %6 3
+         %98 = OpTypeMatrix %97 4
+        %112 = OpTypePointer Function %97
+        %114 = OpConstant %6 7
+        %115 = OpConstant %6 8
+        %116 = OpConstant %6 9
+        %117 = OpConstantComposite %97 %114 %115 %116
+        %119 = OpTypeVector %6 2
+        %120 = OpTypeStruct %119
+        %121 = OpTypePointer Uniform %120
+        %122 = OpVariable %121 Uniform
+        %123 = OpConstant %62 0
+        %124 = OpTypePointer Uniform %6
+        %148 = OpConstant %62 2
+        %157 = OpConstant %15 3
+        %176 = OpTypePointer Output %59
+        %177 = OpVariable %176 Output
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %113 = OpVariable %112 Function
+        %118 = OpVariable %7 Function
+        %129 = OpVariable %7 Function
+        %132 = OpVariable %7 Function
+        %136 = OpVariable %7 Function
+        %139 = OpVariable %7 Function
+        %150 = OpVariable %16 Function
+               OpStore %113 %117
+        %125 = OpAccessChain %124 %122 %31 %123
+        %126 = OpLoad %6 %125
+        %127 = OpFDiv %6 %126 %115
+        %128 = OpExtInst %6 %1 Round %127
+               OpStore %118 %128
+        %130 = OpAccessChain %64 %61 %123
+        %131 = OpLoad %6 %130
+               OpStore %129 %131
+        %133 = OpLoad %6 %118
+               OpStore %132 %133
+        %134 = OpFunctionCall %6 %11 %129 %132
+        %135 = OpAccessChain %7 %113 %123
+               OpStore %135 %134
+        %137 = OpAccessChain %64 %61 %63
+        %138 = OpLoad %6 %137
+               OpStore %136 %138
+        %140 = OpLoad %6 %118
+               OpStore %139 %140
+        %141 = OpFunctionCall %6 %11 %136 %139
+        %142 = OpAccessChain %7 %113 %63
+               OpStore %142 %141
+        %143 = OpAccessChain %7 %113 %123
+        %144 = OpLoad %6 %143
+        %145 = OpAccessChain %7 %113 %63
+        %146 = OpLoad %6 %145
+        %147 = OpFAdd %6 %144 %146
+        %149 = OpAccessChain %7 %113 %148
+               OpStore %149 %147
+               OpStore %150 %31
+               OpBranch %151
+        %151 = OpLabel
+               OpLoopMerge %153 %154 None
+               OpBranch %155
+        %155 = OpLabel
+        %156 = OpLoad %15 %150
+        %158 = OpSLessThan %26 %156 %157
+               OpBranchConditional %158 %152 %153
+        %152 = OpLabel
+        %159 = OpLoad %15 %150
+        %160 = OpAccessChain %7 %113 %159
+        %161 = OpLoad %6 %160
+        %162 = OpFOrdGreaterThanEqual %26 %161 %58
+               OpSelectionMerge %164 None
+               OpBranchConditional %162 %163 %164
+        %163 = OpLabel
+        %165 = OpLoad %15 %150
+        %166 = OpLoad %15 %150
+        %167 = OpAccessChain %7 %113 %166
+        %168 = OpLoad %6 %167
+        %169 = OpLoad %15 %150
+        %170 = OpAccessChain %7 %113 %169
+        %171 = OpLoad %6 %170
+        %172 = OpFMul %6 %168 %171
+        %173 = OpAccessChain %7 %113 %165
+               OpStore %173 %172
+               OpBranch %164
+        %164 = OpLabel
+               OpBranch %154
+        %154 = OpLabel
+        %174 = OpLoad %15 %150
+        %175 = OpIAdd %15 %174 %18
+               OpStore %150 %175
+               OpBranch %151
+        %153 = OpLabel
+        %178 = OpLoad %97 %113
+        %179 = OpExtInst %97 %1 FAbs %178
+        %180 = OpExtInst %97 %1 Normalize %179
+        %181 = OpCompositeExtract %6 %180 0
+        %182 = OpCompositeExtract %6 %180 1
+        %183 = OpCompositeExtract %6 %180 2
+        %184 = OpCompositeConstruct %59 %181 %182 %183 %58
+               OpStore %177 %184
+               OpReturn
+               OpFunctionEnd
+         %11 = OpFunction %6 None %8
+          %9 = OpFunctionParameter %7
+         %10 = OpFunctionParameter %7
+         %12 = OpLabel
+         %13 = OpVariable %7 Function
+         %17 = OpVariable %16 Function
+         %57 = OpVariable %7 Function
+         %69 = OpVariable %7 Function
+         %75 = OpVariable %7 Function
+         %84 = OpVariable %7 Function
+         %93 = OpVariable %7 Function
+               OpStore %13 %14
+               OpStore %17 %18
+               OpBranch %19
+         %19 = OpLabel
+               OpLoopMerge %21 %22 None
+               OpBranch %23
+         %23 = OpLabel
+         %24 = OpLoad %15 %17
+         %27 = OpSLessThan %26 %24 %25
+               OpBranchConditional %27 %20 %21
+         %20 = OpLabel
+         %28 = OpLoad %15 %17
+         %30 = OpSMod %15 %28 %29
+         %32 = OpIEqual %26 %30 %31
+               OpSelectionMerge %34 None
+               OpBranchConditional %32 %33 %38
+         %33 = OpLabel
+         %36 = OpLoad %6 %13
+         %37 = OpFAdd %6 %36 %35
+               OpStore %13 %37
+               OpBranch %34
+         %38 = OpLabel
+         %39 = OpLoad %15 %17
+         %40 = OpConvertSToF %6 %39
+         %41 = OpLoad %6 %10
+         %42 = OpExtInst %6 %1 Round %41
+         %43 = OpFMod %6 %40 %42
+         %45 = OpFOrdLessThanEqual %26 %43 %44
+               OpSelectionMerge %47 None
+               OpBranchConditional %45 %46 %47
+         %46 = OpLabel
+         %49 = OpLoad %6 %13
+         %50 = OpFAdd %6 %49 %48
+               OpStore %13 %50
+               OpBranch %47
+         %47 = OpLabel
+               OpBranch %34
+         %34 = OpLabel
+         %51 = OpLoad %15 %17
+         %52 = OpConvertSToF %6 %51
+         %53 = OpLoad %6 %9
+         %54 = OpFOrdGreaterThanEqual %26 %52 %53
+               OpSelectionMerge %56 None
+               OpBranchConditional %54 %55 %56
+         %55 = OpLabel
+         %65 = OpAccessChain %64 %61 %63
+         %66 = OpLoad %6 %65
+         %68 = OpFOrdLessThan %26 %66 %67
+               OpSelectionMerge %71 None
+               OpBranchConditional %68 %70 %73
+         %70 = OpLabel
+               OpStore %69 %72
+               OpBranch %71
+         %73 = OpLabel
+               OpSelectionMerge %77 None
+               OpBranchConditional %74 %76 %80
+         %76 = OpLabel
+         %78 = OpLoad %6 %13
+         %79 = OpExtInst %6 %1 Exp %78
+               OpStore %75 %79
+               OpBranch %77
+         %80 = OpLabel
+               OpStore %75 %58
+               OpBranch %77
+         %77 = OpLabel
+         %81 = OpLoad %6 %75
+               OpStore %69 %81
+               OpBranch %71
+         %71 = OpLabel
+         %82 = OpLoad %6 %69
+         %83 = OpExtInst %6 %1 FClamp %58 %58 %82
+               OpStore %57 %83
+         %85 = OpLoad %6 %57
+         %87 = OpCompositeConstruct %59 %58 %58 %58 %58
+         %88 = OpCompositeConstruct %59 %67 %58 %58 %67
+         %89 = OpCompositeConstruct %59 %67 %67 %58 %67
+         %90 = OpCompositeConstruct %59 %67 %67 %67 %85
+         %91 = OpCompositeConstruct %86 %87 %88 %89 %90
+         %92 = OpExtInst %6 %1 Determinant %91
+               OpStore %84 %92
+         %94 = OpLoad %6 %13
+         %95 = OpLoad %6 %84
+         %96 = OpFDiv %6 %94 %95
+         %99 = OpCompositeConstruct %97 %96 %67 %67
+        %100 = OpCompositeConstruct %97 %67 %67 %67
+        %101 = OpCompositeConstruct %97 %67 %58 %58
+        %102 = OpCompositeConstruct %97 %58 %67 %58
+        %103 = OpCompositeConstruct %98 %99 %100 %101 %102
+        %104 = OpCompositeExtract %6 %103 0 0
+               OpStore %93 %104
+        %105 = OpLoad %6 %93
+               OpReturnValue %105
+         %56 = OpLabel
+               OpBranch %22
+         %22 = OpLabel
+        %107 = OpLoad %15 %17
+        %108 = OpIAdd %15 %107 %18
+               OpStore %17 %108
+               OpBranch %19
+         %21 = OpLabel
+        %109 = OpLoad %6 %13
+               OpReturnValue %109
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# resolution
+BUFFER variant_resolution DATA_TYPE vec2<float> STD140 DATA
+ 256.0 256.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_resolution 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 256 256
+
+EXPECT reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-mergesort-clamped-conditional-bit-shift.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-mergesort-clamped-conditional-bit-shift.amber
new file mode 100644 (file)
index 0000000..b947f49
--- /dev/null
@@ -0,0 +1,1603 @@
+#!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 the GraphicsFuzz project.
+
+# Short description: Two shaders with diff: conditional bit shift in a clamp
+
+# The test renders two images using semantically equivalent shaders, and then
+# checks that the images are similar.
+# The test passes because the shaders have the same semantics and so the images
+# should be the same.
+
+SHADER vertex reference_vertex_shader PASSTHROUGH
+
+# reference_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+#  vec2 injectionSwitch;
+# };
+# const int N = 10;
+#
+# int data[10], temp[10];
+#
+# void merge(int from, int mid, int to)
+# {
+#  int k = from, i = from, j = mid + 1;
+#  while(i <= mid && j <= to)
+#   {
+#    if(data[i] < data[j])
+#     {
+#      temp[k ++] = data[i ++];
+#     }
+#    else
+#     {
+#      temp[k ++] = data[j ++];
+#     }
+#   }
+#  while(i < N && i <= mid)
+#   {
+#    temp[k ++] = data[i ++];
+#   }
+#  for(int i = from; i <= to; i ++)
+#   {
+#    data[i] = temp[i];
+#   }
+# }
+# void mergeSort()
+# {
+#  int low = 0;
+#  int high = N - 1;
+#  for(int m = 1; m <= high; m = 2 * m)
+#   {
+#    for(int i = low; i < high; i += 2 * m)
+#     {
+#      int from = i;
+#      int mid = i + m - 1;
+#      int to = min(i + 2 * m - 1, high);
+#      merge(from, mid, to);
+#     }
+#   }
+# }
+# void main()
+# {
+#  int i = int(injectionSwitch.x);
+#  do
+#   {
+#    switch(i)
+#     {
+#      case 0:
+#      data[i] = 4;
+#      break;
+#      case 1:
+#      data[i] = 3;
+#      break;
+#      case 2:
+#      data[i] = 2;
+#      break;
+#      case 3:
+#      data[i] = 1;
+#      break;
+#      case 4:
+#      data[i] = 0;
+#      break;
+#      case 5:
+#      data[i] = - 1;
+#      break;
+#      case 6:
+#      data[i] = - 2;
+#      break;
+#      case 7:
+#      data[i] = - 3;
+#      break;
+#      case 8:
+#      data[i] = - 4;
+#      break;
+#      case 9:
+#      data[i] = - 5;
+#      break;
+#     }
+#    i ++;
+#   }
+#  while(i < 10);
+#  for(int j = 0; j < 10; j ++)
+#   {
+#    temp[j] = data[j];
+#   }
+#  mergeSort();
+#  float grey;
+#  if(int(gl_FragCoord[1]) < 30)
+#   {
+#    grey = 0.5 + float(data[0]) / 10.0;
+#   }
+#  else
+#   {
+#    if(int(gl_FragCoord[1]) < 60)
+#     {
+#      grey = 0.5 + float(data[1]) / 10.0;
+#     }
+#    else
+#     {
+#      if(int(gl_FragCoord[1]) < 90)
+#       {
+#        grey = 0.5 + float(data[2]) / 10.0;
+#       }
+#      else
+#       {
+#        if(int(gl_FragCoord[1]) < 120)
+#         {
+#          grey = 0.5 + float(data[3]) / 10.0;
+#         }
+#        else
+#         {
+#          if(int(gl_FragCoord[1]) < 150)
+#           {
+#            discard;
+#           }
+#          else
+#           {
+#            if(int(gl_FragCoord[1]) < 180)
+#             {
+#              grey = 0.5 + float(data[5]) / 10.0;
+#             }
+#            else
+#             {
+#              if(int(gl_FragCoord[1]) < 210)
+#               {
+#                grey = 0.5 + float(data[6]) / 10.0;
+#               }
+#              else
+#               {
+#                if(int(gl_FragCoord[1]) < 240)
+#                 {
+#                  grey = 0.5 + float(data[7]) / 10.0;
+#                 }
+#                else
+#                 {
+#                  if(int(gl_FragCoord[1]) < 270)
+#                   {
+#                    grey = 0.5 + float(data[8]) / 10.0;
+#                   }
+#                  else
+#                   {
+#                    discard;
+#                   }
+#                 }
+#               }
+#             }
+#           }
+#         }
+#       }
+#     }
+#   }
+#  _GLF_color = vec4(vec3(grey), 1.0);
+# }
+SHADER fragment reference_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 378
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %243 %369
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %12 "merge(i1;i1;i1;"
+               OpName %9 "from"
+               OpName %10 "mid"
+               OpName %11 "to"
+               OpName %14 "mergeSort("
+               OpName %16 "k"
+               OpName %18 "i"
+               OpName %20 "j"
+               OpName %41 "data"
+               OpName %52 "temp"
+               OpName %87 "i"
+               OpName %104 "low"
+               OpName %106 "high"
+               OpName %108 "m"
+               OpName %117 "i"
+               OpName %127 "from"
+               OpName %129 "mid"
+               OpName %134 "to"
+               OpName %143 "param"
+               OpName %145 "param"
+               OpName %147 "param"
+               OpName %156 "i"
+               OpName %159 "buf0"
+               OpMemberName %159 0 "injectionSwitch"
+               OpName %161 ""
+               OpName %225 "j"
+               OpName %243 "gl_FragCoord"
+               OpName %254 "grey"
+               OpName %369 "_GLF_color"
+               OpMemberDecorate %159 0 Offset 0
+               OpDecorate %159 Block
+               OpDecorate %161 DescriptorSet 0
+               OpDecorate %161 Binding 0
+               OpDecorate %243 BuiltIn FragCoord
+               OpDecorate %369 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %8 = OpTypeFunction %2 %7 %7 %7
+         %22 = OpConstant %6 1
+         %31 = OpTypeBool
+         %37 = OpTypeInt 32 0
+         %38 = OpConstant %37 10
+         %39 = OpTypeArray %6 %38
+         %40 = OpTypePointer Private %39
+         %41 = OpVariable %40 Private
+         %43 = OpTypePointer Private %6
+         %52 = OpVariable %40 Private
+         %74 = OpConstant %6 10
+        %105 = OpConstant %6 0
+        %107 = OpConstant %6 9
+        %136 = OpConstant %6 2
+        %157 = OpTypeFloat 32
+        %158 = OpTypeVector %157 2
+        %159 = OpTypeStruct %158
+        %160 = OpTypePointer Uniform %159
+        %161 = OpVariable %160 Uniform
+        %162 = OpConstant %37 0
+        %163 = OpTypePointer Uniform %157
+        %184 = OpConstant %6 4
+        %188 = OpConstant %6 3
+        %201 = OpConstant %6 -1
+        %205 = OpConstant %6 -2
+        %209 = OpConstant %6 -3
+        %213 = OpConstant %6 -4
+        %217 = OpConstant %6 -5
+        %241 = OpTypeVector %157 4
+        %242 = OpTypePointer Input %241
+        %243 = OpVariable %242 Input
+        %244 = OpConstant %37 1
+        %245 = OpTypePointer Input %157
+        %249 = OpConstant %6 30
+        %253 = OpTypePointer Function %157
+        %255 = OpConstant %157 0.5
+        %259 = OpConstant %157 10
+        %266 = OpConstant %6 60
+        %279 = OpConstant %6 90
+        %292 = OpConstant %6 120
+        %305 = OpConstant %6 150
+        %314 = OpConstant %6 180
+        %318 = OpConstant %6 5
+        %328 = OpConstant %6 210
+        %332 = OpConstant %6 6
+        %342 = OpConstant %6 240
+        %346 = OpConstant %6 7
+        %356 = OpConstant %6 270
+        %360 = OpConstant %6 8
+        %368 = OpTypePointer Output %241
+        %369 = OpVariable %368 Output
+        %371 = OpTypeVector %157 3
+        %373 = OpConstant %157 1
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %156 = OpVariable %7 Function
+        %225 = OpVariable %7 Function
+        %254 = OpVariable %253 Function
+        %164 = OpAccessChain %163 %161 %105 %162
+        %165 = OpLoad %157 %164
+        %166 = OpConvertFToS %6 %165
+               OpStore %156 %166
+               OpBranch %167
+        %167 = OpLabel
+               OpLoopMerge %169 %170 None
+               OpBranch %168
+        %168 = OpLabel
+        %171 = OpLoad %6 %156
+               OpSelectionMerge %182 None
+               OpSwitch %171 %182 0 %172 1 %173 2 %174 3 %175 4 %176 5 %177 6 %178 7 %179 8 %180 9 %181
+        %172 = OpLabel
+        %183 = OpLoad %6 %156
+        %185 = OpAccessChain %43 %41 %183
+               OpStore %185 %184
+               OpBranch %182
+        %173 = OpLabel
+        %187 = OpLoad %6 %156
+        %189 = OpAccessChain %43 %41 %187
+               OpStore %189 %188
+               OpBranch %182
+        %174 = OpLabel
+        %191 = OpLoad %6 %156
+        %192 = OpAccessChain %43 %41 %191
+               OpStore %192 %136
+               OpBranch %182
+        %175 = OpLabel
+        %194 = OpLoad %6 %156
+        %195 = OpAccessChain %43 %41 %194
+               OpStore %195 %22
+               OpBranch %182
+        %176 = OpLabel
+        %197 = OpLoad %6 %156
+        %198 = OpAccessChain %43 %41 %197
+               OpStore %198 %105
+               OpBranch %182
+        %177 = OpLabel
+        %200 = OpLoad %6 %156
+        %202 = OpAccessChain %43 %41 %200
+               OpStore %202 %201
+               OpBranch %182
+        %178 = OpLabel
+        %204 = OpLoad %6 %156
+        %206 = OpAccessChain %43 %41 %204
+               OpStore %206 %205
+               OpBranch %182
+        %179 = OpLabel
+        %208 = OpLoad %6 %156
+        %210 = OpAccessChain %43 %41 %208
+               OpStore %210 %209
+               OpBranch %182
+        %180 = OpLabel
+        %212 = OpLoad %6 %156
+        %214 = OpAccessChain %43 %41 %212
+               OpStore %214 %213
+               OpBranch %182
+        %181 = OpLabel
+        %216 = OpLoad %6 %156
+        %218 = OpAccessChain %43 %41 %216
+               OpStore %218 %217
+               OpBranch %182
+        %182 = OpLabel
+        %221 = OpLoad %6 %156
+        %222 = OpIAdd %6 %221 %22
+               OpStore %156 %222
+               OpBranch %170
+        %170 = OpLabel
+        %223 = OpLoad %6 %156
+        %224 = OpSLessThan %31 %223 %74
+               OpBranchConditional %224 %167 %169
+        %169 = OpLabel
+               OpStore %225 %105
+               OpBranch %226
+        %226 = OpLabel
+               OpLoopMerge %228 %229 None
+               OpBranch %230
+        %230 = OpLabel
+        %231 = OpLoad %6 %225
+        %232 = OpSLessThan %31 %231 %74
+               OpBranchConditional %232 %227 %228
+        %227 = OpLabel
+        %233 = OpLoad %6 %225
+        %234 = OpLoad %6 %225
+        %235 = OpAccessChain %43 %41 %234
+        %236 = OpLoad %6 %235
+        %237 = OpAccessChain %43 %52 %233
+               OpStore %237 %236
+               OpBranch %229
+        %229 = OpLabel
+        %238 = OpLoad %6 %225
+        %239 = OpIAdd %6 %238 %22
+               OpStore %225 %239
+               OpBranch %226
+        %228 = OpLabel
+        %240 = OpFunctionCall %2 %14
+        %246 = OpAccessChain %245 %243 %244
+        %247 = OpLoad %157 %246
+        %248 = OpConvertFToS %6 %247
+        %250 = OpSLessThan %31 %248 %249
+               OpSelectionMerge %252 None
+               OpBranchConditional %250 %251 %262
+        %251 = OpLabel
+        %256 = OpAccessChain %43 %41 %105
+        %257 = OpLoad %6 %256
+        %258 = OpConvertSToF %157 %257
+        %260 = OpFDiv %157 %258 %259
+        %261 = OpFAdd %157 %255 %260
+               OpStore %254 %261
+               OpBranch %252
+        %262 = OpLabel
+        %263 = OpAccessChain %245 %243 %244
+        %264 = OpLoad %157 %263
+        %265 = OpConvertFToS %6 %264
+        %267 = OpSLessThan %31 %265 %266
+               OpSelectionMerge %269 None
+               OpBranchConditional %267 %268 %275
+        %268 = OpLabel
+        %270 = OpAccessChain %43 %41 %22
+        %271 = OpLoad %6 %270
+        %272 = OpConvertSToF %157 %271
+        %273 = OpFDiv %157 %272 %259
+        %274 = OpFAdd %157 %255 %273
+               OpStore %254 %274
+               OpBranch %269
+        %275 = OpLabel
+        %276 = OpAccessChain %245 %243 %244
+        %277 = OpLoad %157 %276
+        %278 = OpConvertFToS %6 %277
+        %280 = OpSLessThan %31 %278 %279
+               OpSelectionMerge %282 None
+               OpBranchConditional %280 %281 %288
+        %281 = OpLabel
+        %283 = OpAccessChain %43 %41 %136
+        %284 = OpLoad %6 %283
+        %285 = OpConvertSToF %157 %284
+        %286 = OpFDiv %157 %285 %259
+        %287 = OpFAdd %157 %255 %286
+               OpStore %254 %287
+               OpBranch %282
+        %288 = OpLabel
+        %289 = OpAccessChain %245 %243 %244
+        %290 = OpLoad %157 %289
+        %291 = OpConvertFToS %6 %290
+        %293 = OpSLessThan %31 %291 %292
+               OpSelectionMerge %295 None
+               OpBranchConditional %293 %294 %301
+        %294 = OpLabel
+        %296 = OpAccessChain %43 %41 %188
+        %297 = OpLoad %6 %296
+        %298 = OpConvertSToF %157 %297
+        %299 = OpFDiv %157 %298 %259
+        %300 = OpFAdd %157 %255 %299
+               OpStore %254 %300
+               OpBranch %295
+        %301 = OpLabel
+        %302 = OpAccessChain %245 %243 %244
+        %303 = OpLoad %157 %302
+        %304 = OpConvertFToS %6 %303
+        %306 = OpSLessThan %31 %304 %305
+               OpSelectionMerge %308 None
+               OpBranchConditional %306 %307 %310
+        %307 = OpLabel
+               OpKill
+        %310 = OpLabel
+        %311 = OpAccessChain %245 %243 %244
+        %312 = OpLoad %157 %311
+        %313 = OpConvertFToS %6 %312
+        %315 = OpSLessThan %31 %313 %314
+               OpSelectionMerge %317 None
+               OpBranchConditional %315 %316 %324
+        %316 = OpLabel
+        %319 = OpAccessChain %43 %41 %318
+        %320 = OpLoad %6 %319
+        %321 = OpConvertSToF %157 %320
+        %322 = OpFDiv %157 %321 %259
+        %323 = OpFAdd %157 %255 %322
+               OpStore %254 %323
+               OpBranch %317
+        %324 = OpLabel
+        %325 = OpAccessChain %245 %243 %244
+        %326 = OpLoad %157 %325
+        %327 = OpConvertFToS %6 %326
+        %329 = OpSLessThan %31 %327 %328
+               OpSelectionMerge %331 None
+               OpBranchConditional %329 %330 %338
+        %330 = OpLabel
+        %333 = OpAccessChain %43 %41 %332
+        %334 = OpLoad %6 %333
+        %335 = OpConvertSToF %157 %334
+        %336 = OpFDiv %157 %335 %259
+        %337 = OpFAdd %157 %255 %336
+               OpStore %254 %337
+               OpBranch %331
+        %338 = OpLabel
+        %339 = OpAccessChain %245 %243 %244
+        %340 = OpLoad %157 %339
+        %341 = OpConvertFToS %6 %340
+        %343 = OpSLessThan %31 %341 %342
+               OpSelectionMerge %345 None
+               OpBranchConditional %343 %344 %352
+        %344 = OpLabel
+        %347 = OpAccessChain %43 %41 %346
+        %348 = OpLoad %6 %347
+        %349 = OpConvertSToF %157 %348
+        %350 = OpFDiv %157 %349 %259
+        %351 = OpFAdd %157 %255 %350
+               OpStore %254 %351
+               OpBranch %345
+        %352 = OpLabel
+        %353 = OpAccessChain %245 %243 %244
+        %354 = OpLoad %157 %353
+        %355 = OpConvertFToS %6 %354
+        %357 = OpSLessThan %31 %355 %356
+               OpSelectionMerge %359 None
+               OpBranchConditional %357 %358 %366
+        %358 = OpLabel
+        %361 = OpAccessChain %43 %41 %360
+        %362 = OpLoad %6 %361
+        %363 = OpConvertSToF %157 %362
+        %364 = OpFDiv %157 %363 %259
+        %365 = OpFAdd %157 %255 %364
+               OpStore %254 %365
+               OpBranch %359
+        %366 = OpLabel
+               OpKill
+        %359 = OpLabel
+               OpBranch %345
+        %345 = OpLabel
+               OpBranch %331
+        %331 = OpLabel
+               OpBranch %317
+        %317 = OpLabel
+               OpBranch %308
+        %308 = OpLabel
+               OpBranch %295
+        %295 = OpLabel
+               OpBranch %282
+        %282 = OpLabel
+               OpBranch %269
+        %269 = OpLabel
+               OpBranch %252
+        %252 = OpLabel
+        %370 = OpLoad %157 %254
+        %372 = OpCompositeConstruct %371 %370 %370 %370
+        %374 = OpCompositeExtract %157 %372 0
+        %375 = OpCompositeExtract %157 %372 1
+        %376 = OpCompositeExtract %157 %372 2
+        %377 = OpCompositeConstruct %241 %374 %375 %376 %373
+               OpStore %369 %377
+               OpReturn
+               OpFunctionEnd
+         %12 = OpFunction %2 None %8
+          %9 = OpFunctionParameter %7
+         %10 = OpFunctionParameter %7
+         %11 = OpFunctionParameter %7
+         %13 = OpLabel
+         %16 = OpVariable %7 Function
+         %18 = OpVariable %7 Function
+         %20 = OpVariable %7 Function
+         %87 = OpVariable %7 Function
+         %17 = OpLoad %6 %9
+               OpStore %16 %17
+         %19 = OpLoad %6 %9
+               OpStore %18 %19
+         %21 = OpLoad %6 %10
+         %23 = OpIAdd %6 %21 %22
+               OpStore %20 %23
+               OpBranch %24
+         %24 = OpLabel
+               OpLoopMerge %26 %27 None
+               OpBranch %28
+         %28 = OpLabel
+         %29 = OpLoad %6 %18
+         %30 = OpLoad %6 %10
+         %32 = OpSLessThanEqual %31 %29 %30
+         %33 = OpLoad %6 %20
+         %34 = OpLoad %6 %11
+         %35 = OpSLessThanEqual %31 %33 %34
+         %36 = OpLogicalAnd %31 %32 %35
+               OpBranchConditional %36 %25 %26
+         %25 = OpLabel
+         %42 = OpLoad %6 %18
+         %44 = OpAccessChain %43 %41 %42
+         %45 = OpLoad %6 %44
+         %46 = OpLoad %6 %20
+         %47 = OpAccessChain %43 %41 %46
+         %48 = OpLoad %6 %47
+         %49 = OpSLessThan %31 %45 %48
+               OpSelectionMerge %51 None
+               OpBranchConditional %49 %50 %60
+         %50 = OpLabel
+         %53 = OpLoad %6 %16
+         %54 = OpIAdd %6 %53 %22
+               OpStore %16 %54
+         %55 = OpLoad %6 %18
+         %56 = OpIAdd %6 %55 %22
+               OpStore %18 %56
+         %57 = OpAccessChain %43 %41 %55
+         %58 = OpLoad %6 %57
+         %59 = OpAccessChain %43 %52 %53
+               OpStore %59 %58
+               OpBranch %51
+         %60 = OpLabel
+         %61 = OpLoad %6 %16
+         %62 = OpIAdd %6 %61 %22
+               OpStore %16 %62
+         %63 = OpLoad %6 %20
+         %64 = OpIAdd %6 %63 %22
+               OpStore %20 %64
+         %65 = OpAccessChain %43 %41 %63
+         %66 = OpLoad %6 %65
+         %67 = OpAccessChain %43 %52 %61
+               OpStore %67 %66
+               OpBranch %51
+         %51 = OpLabel
+               OpBranch %27
+         %27 = OpLabel
+               OpBranch %24
+         %26 = OpLabel
+               OpBranch %68
+         %68 = OpLabel
+               OpLoopMerge %70 %71 None
+               OpBranch %72
+         %72 = OpLabel
+         %73 = OpLoad %6 %18
+         %75 = OpSLessThan %31 %73 %74
+         %76 = OpLoad %6 %18
+         %77 = OpLoad %6 %10
+         %78 = OpSLessThanEqual %31 %76 %77
+         %79 = OpLogicalAnd %31 %75 %78
+               OpBranchConditional %79 %69 %70
+         %69 = OpLabel
+         %80 = OpLoad %6 %16
+         %81 = OpIAdd %6 %80 %22
+               OpStore %16 %81
+         %82 = OpLoad %6 %18
+         %83 = OpIAdd %6 %82 %22
+               OpStore %18 %83
+         %84 = OpAccessChain %43 %41 %82
+         %85 = OpLoad %6 %84
+         %86 = OpAccessChain %43 %52 %80
+               OpStore %86 %85
+               OpBranch %71
+         %71 = OpLabel
+               OpBranch %68
+         %70 = OpLabel
+         %88 = OpLoad %6 %9
+               OpStore %87 %88
+               OpBranch %89
+         %89 = OpLabel
+               OpLoopMerge %91 %92 None
+               OpBranch %93
+         %93 = OpLabel
+         %94 = OpLoad %6 %87
+         %95 = OpLoad %6 %11
+         %96 = OpSLessThanEqual %31 %94 %95
+               OpBranchConditional %96 %90 %91
+         %90 = OpLabel
+         %97 = OpLoad %6 %87
+         %98 = OpLoad %6 %87
+         %99 = OpAccessChain %43 %52 %98
+        %100 = OpLoad %6 %99
+        %101 = OpAccessChain %43 %41 %97
+               OpStore %101 %100
+               OpBranch %92
+         %92 = OpLabel
+        %102 = OpLoad %6 %87
+        %103 = OpIAdd %6 %102 %22
+               OpStore %87 %103
+               OpBranch %89
+         %91 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %14 = OpFunction %2 None %3
+         %15 = OpLabel
+        %104 = OpVariable %7 Function
+        %106 = OpVariable %7 Function
+        %108 = OpVariable %7 Function
+        %117 = OpVariable %7 Function
+        %127 = OpVariable %7 Function
+        %129 = OpVariable %7 Function
+        %134 = OpVariable %7 Function
+        %143 = OpVariable %7 Function
+        %145 = OpVariable %7 Function
+        %147 = OpVariable %7 Function
+               OpStore %104 %105
+               OpStore %106 %107
+               OpStore %108 %22
+               OpBranch %109
+        %109 = OpLabel
+               OpLoopMerge %111 %112 None
+               OpBranch %113
+        %113 = OpLabel
+        %114 = OpLoad %6 %108
+        %115 = OpLoad %6 %106
+        %116 = OpSLessThanEqual %31 %114 %115
+               OpBranchConditional %116 %110 %111
+        %110 = OpLabel
+        %118 = OpLoad %6 %104
+               OpStore %117 %118
+               OpBranch %119
+        %119 = OpLabel
+               OpLoopMerge %121 %122 None
+               OpBranch %123
+        %123 = OpLabel
+        %124 = OpLoad %6 %117
+        %125 = OpLoad %6 %106
+        %126 = OpSLessThan %31 %124 %125
+               OpBranchConditional %126 %120 %121
+        %120 = OpLabel
+        %128 = OpLoad %6 %117
+               OpStore %127 %128
+        %130 = OpLoad %6 %117
+        %131 = OpLoad %6 %108
+        %132 = OpIAdd %6 %130 %131
+        %133 = OpISub %6 %132 %22
+               OpStore %129 %133
+        %135 = OpLoad %6 %117
+        %137 = OpLoad %6 %108
+        %138 = OpIMul %6 %136 %137
+        %139 = OpIAdd %6 %135 %138
+        %140 = OpISub %6 %139 %22
+        %141 = OpLoad %6 %106
+        %142 = OpExtInst %6 %1 SMin %140 %141
+               OpStore %134 %142
+        %144 = OpLoad %6 %127
+               OpStore %143 %144
+        %146 = OpLoad %6 %129
+               OpStore %145 %146
+        %148 = OpLoad %6 %134
+               OpStore %147 %148
+        %149 = OpFunctionCall %2 %12 %143 %145 %147
+               OpBranch %122
+        %122 = OpLabel
+        %150 = OpLoad %6 %108
+        %151 = OpIMul %6 %136 %150
+        %152 = OpLoad %6 %117
+        %153 = OpIAdd %6 %152 %151
+               OpStore %117 %153
+               OpBranch %119
+        %121 = OpLabel
+               OpBranch %112
+        %112 = OpLabel
+        %154 = OpLoad %6 %108
+        %155 = OpIMul %6 %136 %154
+               OpStore %108 %155
+               OpBranch %109
+        %111 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for reference
+
+# injectionSwitch
+BUFFER reference_injectionSwitch DATA_TYPE vec2<float> STD140 DATA
+ 0.0 1.0
+END
+
+BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics reference_pipeline
+  ATTACH reference_vertex_shader
+  ATTACH reference_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER reference_framebuffer AS color LOCATION 0
+  BIND BUFFER reference_injectionSwitch AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR reference_pipeline 0 0 0 255
+
+CLEAR reference_pipeline
+RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0 {
+#  vec2 injectionSwitch;
+# };
+# const int N = 10;
+#
+# int data[10], temp[10];
+#
+# void merge(int from, int mid, int to)
+# {
+#  int k = from, i = from, j = mid + 1;
+#  while(i <= mid && j <= to)
+#   {
+#    if(data[i] < data[j])
+#     {
+#      temp[k ++] = data[i ++];
+#     }
+#    else
+#     {
+#      temp[k ++] = data[j ++];
+#     }
+#   }
+#  while(i < N && i <= mid)
+#   {
+#    temp[k ++] = data[i ++];
+#   }
+#  for(int i = from; i <= to; i ++)
+#   {
+#    data[i] = temp[i];
+#   }
+# }
+# int func(int m, int high)
+# {
+#   // int x == 1, bitshifted to left by 4, x == 16.
+#   int x = (gl_FragCoord.x >= 0.0) ? 1 << ((false ? ((high) << 0) : 4)) : 1;
+#   // int x == 16, bitshifted to right by 4, x == 1.
+#   x = x >> int(4);
+#   // returns 2 * m.
+#   return clamp(2 * m, 2 * m, (2 * m) / x);
+# }
+# void mergeSort()
+# {
+#  int low = 0;
+#  int high = N - 1;
+#  for(int m = 1; m <= high; m = 2 * m)
+#   {
+#    for(int i = low; i < high; i += func(m, high))
+#     {
+#      int from = i;
+#      int mid = i + m - 1;
+#      int to = min(i + 2 * m - 1, high);
+#      merge(from, mid, to);
+#     }
+#   }
+# }
+# void main()
+# {
+#  int i = int(injectionSwitch.x);
+#  do
+#   {
+#    switch(i)
+#     {
+#      case 0:
+#      data[i] = 4;
+#      break;
+#      case 1:
+#      data[i] = 3;
+#      break;
+#      case 2:
+#      data[i] = 2;
+#      break;
+#      case 3:
+#      data[i] = 1;
+#      break;
+#      case 4:
+#      data[i] = 0;
+#      break;
+#      case 5:
+#      data[i] = - 1;
+#      break;
+#      case 6:
+#      data[i] = - 2;
+#      break;
+#      case 7:
+#      data[i] = - 3;
+#      break;
+#      case 8:
+#      data[i] = - 4;
+#      break;
+#      case 9:
+#      data[i] = - 5;
+#      break;
+#     }
+#    i ++;
+#   }
+#  while(i < 10);
+#  for(int j = 0; j < 10; j ++)
+#   {
+#    temp[j] = data[j];
+#   }
+#  mergeSort();
+#  float grey;
+#  if(int(gl_FragCoord[1]) < 30)
+#   {
+#    grey = 0.5 + float(data[0]) / 10.0;
+#   }
+#  else
+#   {
+#    if(int(gl_FragCoord[1]) < 60)
+#     {
+#      grey = 0.5 + float(data[1]) / 10.0;
+#     }
+#    else
+#     {
+#      if(int(gl_FragCoord[1]) < 90)
+#       {
+#        grey = 0.5 + float(data[2]) / 10.0;
+#       }
+#      else
+#       {
+#        if(int(gl_FragCoord[1]) < 120)
+#         {
+#          grey = 0.5 + float(data[3]) / 10.0;
+#         }
+#        else
+#         {
+#          if(int(gl_FragCoord[1]) < 150)
+#           {
+#            discard;
+#           }
+#          else
+#           {
+#            if(int(gl_FragCoord[1]) < 180)
+#             {
+#              grey = 0.5 + float(data[5]) / 10.0;
+#             }
+#            else
+#             {
+#              if(int(gl_FragCoord[1]) < 210)
+#               {
+#                grey = 0.5 + float(data[6]) / 10.0;
+#               }
+#              else
+#               {
+#                if(int(gl_FragCoord[1]) < 240)
+#                 {
+#                  grey = 0.5 + float(data[7]) / 10.0;
+#                 }
+#                else
+#                 {
+#                  if(int(gl_FragCoord[1]) < 270)
+#                   {
+#                    grey = 0.5 + float(data[8]) / 10.0;
+#                   }
+#                  else
+#                   {
+#                    discard;
+#                   }
+#                 }
+#               }
+#             }
+#           }
+#         }
+#       }
+#     }
+#   }
+#  _GLF_color = vec4(vec3(grey), 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 418
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %113 %409
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %12 "merge(i1;i1;i1;"
+               OpName %9 "from"
+               OpName %10 "mid"
+               OpName %11 "to"
+               OpName %17 "func(i1;i1;"
+               OpName %15 "m"
+               OpName %16 "high"
+               OpName %19 "mergeSort("
+               OpName %21 "k"
+               OpName %23 "i"
+               OpName %25 "j"
+               OpName %46 "data"
+               OpName %57 "temp"
+               OpName %92 "i"
+               OpName %109 "x"
+               OpName %113 "gl_FragCoord"
+               OpName %150 "low"
+               OpName %151 "high"
+               OpName %153 "m"
+               OpName %162 "i"
+               OpName %172 "from"
+               OpName %174 "mid"
+               OpName %179 "to"
+               OpName %187 "param"
+               OpName %189 "param"
+               OpName %191 "param"
+               OpName %194 "param"
+               OpName %196 "param"
+               OpName %203 "i"
+               OpName %205 "buf0"
+               OpMemberName %205 0 "injectionSwitch"
+               OpName %207 ""
+               OpName %269 "j"
+               OpName %294 "grey"
+               OpName %409 "_GLF_color"
+               OpDecorate %113 BuiltIn FragCoord
+               OpMemberDecorate %205 0 Offset 0
+               OpDecorate %205 Block
+               OpDecorate %207 DescriptorSet 0
+               OpDecorate %207 Binding 0
+               OpDecorate %409 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %8 = OpTypeFunction %2 %7 %7 %7
+         %14 = OpTypeFunction %6 %7 %7
+         %27 = OpConstant %6 1
+         %36 = OpTypeBool
+         %42 = OpTypeInt 32 0
+         %43 = OpConstant %42 10
+         %44 = OpTypeArray %6 %43
+         %45 = OpTypePointer Private %44
+         %46 = OpVariable %45 Private
+         %48 = OpTypePointer Private %6
+         %57 = OpVariable %45 Private
+         %79 = OpConstant %6 10
+        %110 = OpTypeFloat 32
+        %111 = OpTypeVector %110 4
+        %112 = OpTypePointer Input %111
+        %113 = OpVariable %112 Input
+        %114 = OpConstant %42 0
+        %115 = OpTypePointer Input %110
+        %118 = OpConstant %110 0
+        %123 = OpConstantFalse %36
+        %128 = OpConstant %6 0
+        %131 = OpConstant %6 4
+        %138 = OpConstant %6 2
+        %152 = OpConstant %6 9
+        %204 = OpTypeVector %110 2
+        %205 = OpTypeStruct %204
+        %206 = OpTypePointer Uniform %205
+        %207 = OpVariable %206 Uniform
+        %208 = OpTypePointer Uniform %110
+        %232 = OpConstant %6 3
+        %245 = OpConstant %6 -1
+        %249 = OpConstant %6 -2
+        %253 = OpConstant %6 -3
+        %257 = OpConstant %6 -4
+        %261 = OpConstant %6 -5
+        %285 = OpConstant %42 1
+        %289 = OpConstant %6 30
+        %293 = OpTypePointer Function %110
+        %295 = OpConstant %110 0.5
+        %299 = OpConstant %110 10
+        %306 = OpConstant %6 60
+        %319 = OpConstant %6 90
+        %332 = OpConstant %6 120
+        %345 = OpConstant %6 150
+        %354 = OpConstant %6 180
+        %358 = OpConstant %6 5
+        %368 = OpConstant %6 210
+        %372 = OpConstant %6 6
+        %382 = OpConstant %6 240
+        %386 = OpConstant %6 7
+        %396 = OpConstant %6 270
+        %400 = OpConstant %6 8
+        %408 = OpTypePointer Output %111
+        %409 = OpVariable %408 Output
+        %411 = OpTypeVector %110 3
+        %413 = OpConstant %110 1
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %203 = OpVariable %7 Function
+        %269 = OpVariable %7 Function
+        %294 = OpVariable %293 Function
+        %209 = OpAccessChain %208 %207 %128 %114
+        %210 = OpLoad %110 %209
+        %211 = OpConvertFToS %6 %210
+               OpStore %203 %211
+               OpBranch %212
+        %212 = OpLabel
+               OpLoopMerge %214 %215 None
+               OpBranch %213
+        %213 = OpLabel
+        %216 = OpLoad %6 %203
+               OpSelectionMerge %227 None
+               OpSwitch %216 %227 0 %217 1 %218 2 %219 3 %220 4 %221 5 %222 6 %223 7 %224 8 %225 9 %226
+        %217 = OpLabel
+        %228 = OpLoad %6 %203
+        %229 = OpAccessChain %48 %46 %228
+               OpStore %229 %131
+               OpBranch %227
+        %218 = OpLabel
+        %231 = OpLoad %6 %203
+        %233 = OpAccessChain %48 %46 %231
+               OpStore %233 %232
+               OpBranch %227
+        %219 = OpLabel
+        %235 = OpLoad %6 %203
+        %236 = OpAccessChain %48 %46 %235
+               OpStore %236 %138
+               OpBranch %227
+        %220 = OpLabel
+        %238 = OpLoad %6 %203
+        %239 = OpAccessChain %48 %46 %238
+               OpStore %239 %27
+               OpBranch %227
+        %221 = OpLabel
+        %241 = OpLoad %6 %203
+        %242 = OpAccessChain %48 %46 %241
+               OpStore %242 %128
+               OpBranch %227
+        %222 = OpLabel
+        %244 = OpLoad %6 %203
+        %246 = OpAccessChain %48 %46 %244
+               OpStore %246 %245
+               OpBranch %227
+        %223 = OpLabel
+        %248 = OpLoad %6 %203
+        %250 = OpAccessChain %48 %46 %248
+               OpStore %250 %249
+               OpBranch %227
+        %224 = OpLabel
+        %252 = OpLoad %6 %203
+        %254 = OpAccessChain %48 %46 %252
+               OpStore %254 %253
+               OpBranch %227
+        %225 = OpLabel
+        %256 = OpLoad %6 %203
+        %258 = OpAccessChain %48 %46 %256
+               OpStore %258 %257
+               OpBranch %227
+        %226 = OpLabel
+        %260 = OpLoad %6 %203
+        %262 = OpAccessChain %48 %46 %260
+               OpStore %262 %261
+               OpBranch %227
+        %227 = OpLabel
+        %265 = OpLoad %6 %203
+        %266 = OpIAdd %6 %265 %27
+               OpStore %203 %266
+               OpBranch %215
+        %215 = OpLabel
+        %267 = OpLoad %6 %203
+        %268 = OpSLessThan %36 %267 %79
+               OpBranchConditional %268 %212 %214
+        %214 = OpLabel
+               OpStore %269 %128
+               OpBranch %270
+        %270 = OpLabel
+               OpLoopMerge %272 %273 None
+               OpBranch %274
+        %274 = OpLabel
+        %275 = OpLoad %6 %269
+        %276 = OpSLessThan %36 %275 %79
+               OpBranchConditional %276 %271 %272
+        %271 = OpLabel
+        %277 = OpLoad %6 %269
+        %278 = OpLoad %6 %269
+        %279 = OpAccessChain %48 %46 %278
+        %280 = OpLoad %6 %279
+        %281 = OpAccessChain %48 %57 %277
+               OpStore %281 %280
+               OpBranch %273
+        %273 = OpLabel
+        %282 = OpLoad %6 %269
+        %283 = OpIAdd %6 %282 %27
+               OpStore %269 %283
+               OpBranch %270
+        %272 = OpLabel
+        %284 = OpFunctionCall %2 %19
+        %286 = OpAccessChain %115 %113 %285
+        %287 = OpLoad %110 %286
+        %288 = OpConvertFToS %6 %287
+        %290 = OpSLessThan %36 %288 %289
+               OpSelectionMerge %292 None
+               OpBranchConditional %290 %291 %302
+        %291 = OpLabel
+        %296 = OpAccessChain %48 %46 %128
+        %297 = OpLoad %6 %296
+        %298 = OpConvertSToF %110 %297
+        %300 = OpFDiv %110 %298 %299
+        %301 = OpFAdd %110 %295 %300
+               OpStore %294 %301
+               OpBranch %292
+        %302 = OpLabel
+        %303 = OpAccessChain %115 %113 %285
+        %304 = OpLoad %110 %303
+        %305 = OpConvertFToS %6 %304
+        %307 = OpSLessThan %36 %305 %306
+               OpSelectionMerge %309 None
+               OpBranchConditional %307 %308 %315
+        %308 = OpLabel
+        %310 = OpAccessChain %48 %46 %27
+        %311 = OpLoad %6 %310
+        %312 = OpConvertSToF %110 %311
+        %313 = OpFDiv %110 %312 %299
+        %314 = OpFAdd %110 %295 %313
+               OpStore %294 %314
+               OpBranch %309
+        %315 = OpLabel
+        %316 = OpAccessChain %115 %113 %285
+        %317 = OpLoad %110 %316
+        %318 = OpConvertFToS %6 %317
+        %320 = OpSLessThan %36 %318 %319
+               OpSelectionMerge %322 None
+               OpBranchConditional %320 %321 %328
+        %321 = OpLabel
+        %323 = OpAccessChain %48 %46 %138
+        %324 = OpLoad %6 %323
+        %325 = OpConvertSToF %110 %324
+        %326 = OpFDiv %110 %325 %299
+        %327 = OpFAdd %110 %295 %326
+               OpStore %294 %327
+               OpBranch %322
+        %328 = OpLabel
+        %329 = OpAccessChain %115 %113 %285
+        %330 = OpLoad %110 %329
+        %331 = OpConvertFToS %6 %330
+        %333 = OpSLessThan %36 %331 %332
+               OpSelectionMerge %335 None
+               OpBranchConditional %333 %334 %341
+        %334 = OpLabel
+        %336 = OpAccessChain %48 %46 %232
+        %337 = OpLoad %6 %336
+        %338 = OpConvertSToF %110 %337
+        %339 = OpFDiv %110 %338 %299
+        %340 = OpFAdd %110 %295 %339
+               OpStore %294 %340
+               OpBranch %335
+        %341 = OpLabel
+        %342 = OpAccessChain %115 %113 %285
+        %343 = OpLoad %110 %342
+        %344 = OpConvertFToS %6 %343
+        %346 = OpSLessThan %36 %344 %345
+               OpSelectionMerge %348 None
+               OpBranchConditional %346 %347 %350
+        %347 = OpLabel
+               OpKill
+        %350 = OpLabel
+        %351 = OpAccessChain %115 %113 %285
+        %352 = OpLoad %110 %351
+        %353 = OpConvertFToS %6 %352
+        %355 = OpSLessThan %36 %353 %354
+               OpSelectionMerge %357 None
+               OpBranchConditional %355 %356 %364
+        %356 = OpLabel
+        %359 = OpAccessChain %48 %46 %358
+        %360 = OpLoad %6 %359
+        %361 = OpConvertSToF %110 %360
+        %362 = OpFDiv %110 %361 %299
+        %363 = OpFAdd %110 %295 %362
+               OpStore %294 %363
+               OpBranch %357
+        %364 = OpLabel
+        %365 = OpAccessChain %115 %113 %285
+        %366 = OpLoad %110 %365
+        %367 = OpConvertFToS %6 %366
+        %369 = OpSLessThan %36 %367 %368
+               OpSelectionMerge %371 None
+               OpBranchConditional %369 %370 %378
+        %370 = OpLabel
+        %373 = OpAccessChain %48 %46 %372
+        %374 = OpLoad %6 %373
+        %375 = OpConvertSToF %110 %374
+        %376 = OpFDiv %110 %375 %299
+        %377 = OpFAdd %110 %295 %376
+               OpStore %294 %377
+               OpBranch %371
+        %378 = OpLabel
+        %379 = OpAccessChain %115 %113 %285
+        %380 = OpLoad %110 %379
+        %381 = OpConvertFToS %6 %380
+        %383 = OpSLessThan %36 %381 %382
+               OpSelectionMerge %385 None
+               OpBranchConditional %383 %384 %392
+        %384 = OpLabel
+        %387 = OpAccessChain %48 %46 %386
+        %388 = OpLoad %6 %387
+        %389 = OpConvertSToF %110 %388
+        %390 = OpFDiv %110 %389 %299
+        %391 = OpFAdd %110 %295 %390
+               OpStore %294 %391
+               OpBranch %385
+        %392 = OpLabel
+        %393 = OpAccessChain %115 %113 %285
+        %394 = OpLoad %110 %393
+        %395 = OpConvertFToS %6 %394
+        %397 = OpSLessThan %36 %395 %396
+               OpSelectionMerge %399 None
+               OpBranchConditional %397 %398 %406
+        %398 = OpLabel
+        %401 = OpAccessChain %48 %46 %400
+        %402 = OpLoad %6 %401
+        %403 = OpConvertSToF %110 %402
+        %404 = OpFDiv %110 %403 %299
+        %405 = OpFAdd %110 %295 %404
+               OpStore %294 %405
+               OpBranch %399
+        %406 = OpLabel
+               OpKill
+        %399 = OpLabel
+               OpBranch %385
+        %385 = OpLabel
+               OpBranch %371
+        %371 = OpLabel
+               OpBranch %357
+        %357 = OpLabel
+               OpBranch %348
+        %348 = OpLabel
+               OpBranch %335
+        %335 = OpLabel
+               OpBranch %322
+        %322 = OpLabel
+               OpBranch %309
+        %309 = OpLabel
+               OpBranch %292
+        %292 = OpLabel
+        %410 = OpLoad %110 %294
+        %412 = OpCompositeConstruct %411 %410 %410 %410
+        %414 = OpCompositeExtract %110 %412 0
+        %415 = OpCompositeExtract %110 %412 1
+        %416 = OpCompositeExtract %110 %412 2
+        %417 = OpCompositeConstruct %111 %414 %415 %416 %413
+               OpStore %409 %417
+               OpReturn
+               OpFunctionEnd
+         %12 = OpFunction %2 None %8
+          %9 = OpFunctionParameter %7
+         %10 = OpFunctionParameter %7
+         %11 = OpFunctionParameter %7
+         %13 = OpLabel
+         %21 = OpVariable %7 Function
+         %23 = OpVariable %7 Function
+         %25 = OpVariable %7 Function
+         %92 = OpVariable %7 Function
+         %22 = OpLoad %6 %9
+               OpStore %21 %22
+         %24 = OpLoad %6 %9
+               OpStore %23 %24
+         %26 = OpLoad %6 %10
+         %28 = OpIAdd %6 %26 %27
+               OpStore %25 %28
+               OpBranch %29
+         %29 = OpLabel
+               OpLoopMerge %31 %32 None
+               OpBranch %33
+         %33 = OpLabel
+         %34 = OpLoad %6 %23
+         %35 = OpLoad %6 %10
+         %37 = OpSLessThanEqual %36 %34 %35
+         %38 = OpLoad %6 %25
+         %39 = OpLoad %6 %11
+         %40 = OpSLessThanEqual %36 %38 %39
+         %41 = OpLogicalAnd %36 %37 %40
+               OpBranchConditional %41 %30 %31
+         %30 = OpLabel
+         %47 = OpLoad %6 %23
+         %49 = OpAccessChain %48 %46 %47
+         %50 = OpLoad %6 %49
+         %51 = OpLoad %6 %25
+         %52 = OpAccessChain %48 %46 %51
+         %53 = OpLoad %6 %52
+         %54 = OpSLessThan %36 %50 %53
+               OpSelectionMerge %56 None
+               OpBranchConditional %54 %55 %65
+         %55 = OpLabel
+         %58 = OpLoad %6 %21
+         %59 = OpIAdd %6 %58 %27
+               OpStore %21 %59
+         %60 = OpLoad %6 %23
+         %61 = OpIAdd %6 %60 %27
+               OpStore %23 %61
+         %62 = OpAccessChain %48 %46 %60
+         %63 = OpLoad %6 %62
+         %64 = OpAccessChain %48 %57 %58
+               OpStore %64 %63
+               OpBranch %56
+         %65 = OpLabel
+         %66 = OpLoad %6 %21
+         %67 = OpIAdd %6 %66 %27
+               OpStore %21 %67
+         %68 = OpLoad %6 %25
+         %69 = OpIAdd %6 %68 %27
+               OpStore %25 %69
+         %70 = OpAccessChain %48 %46 %68
+         %71 = OpLoad %6 %70
+         %72 = OpAccessChain %48 %57 %66
+               OpStore %72 %71
+               OpBranch %56
+         %56 = OpLabel
+               OpBranch %32
+         %32 = OpLabel
+               OpBranch %29
+         %31 = OpLabel
+               OpBranch %73
+         %73 = OpLabel
+               OpLoopMerge %75 %76 None
+               OpBranch %77
+         %77 = OpLabel
+         %78 = OpLoad %6 %23
+         %80 = OpSLessThan %36 %78 %79
+         %81 = OpLoad %6 %23
+         %82 = OpLoad %6 %10
+         %83 = OpSLessThanEqual %36 %81 %82
+         %84 = OpLogicalAnd %36 %80 %83
+               OpBranchConditional %84 %74 %75
+         %74 = OpLabel
+         %85 = OpLoad %6 %21
+         %86 = OpIAdd %6 %85 %27
+               OpStore %21 %86
+         %87 = OpLoad %6 %23
+         %88 = OpIAdd %6 %87 %27
+               OpStore %23 %88
+         %89 = OpAccessChain %48 %46 %87
+         %90 = OpLoad %6 %89
+         %91 = OpAccessChain %48 %57 %85
+               OpStore %91 %90
+               OpBranch %76
+         %76 = OpLabel
+               OpBranch %73
+         %75 = OpLabel
+         %93 = OpLoad %6 %9
+               OpStore %92 %93
+               OpBranch %94
+         %94 = OpLabel
+               OpLoopMerge %96 %97 None
+               OpBranch %98
+         %98 = OpLabel
+         %99 = OpLoad %6 %92
+        %100 = OpLoad %6 %11
+        %101 = OpSLessThanEqual %36 %99 %100
+               OpBranchConditional %101 %95 %96
+         %95 = OpLabel
+        %102 = OpLoad %6 %92
+        %103 = OpLoad %6 %92
+        %104 = OpAccessChain %48 %57 %103
+        %105 = OpLoad %6 %104
+        %106 = OpAccessChain %48 %46 %102
+               OpStore %106 %105
+               OpBranch %97
+         %97 = OpLabel
+        %107 = OpLoad %6 %92
+        %108 = OpIAdd %6 %107 %27
+               OpStore %92 %108
+               OpBranch %94
+         %96 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %17 = OpFunction %6 None %14
+         %15 = OpFunctionParameter %7
+         %16 = OpFunctionParameter %7
+         %18 = OpLabel
+        %109 = OpVariable %7 Function
+        %120 = OpVariable %7 Function
+        %124 = OpVariable %7 Function
+        %116 = OpAccessChain %115 %113 %114
+        %117 = OpLoad %110 %116
+        %119 = OpFOrdGreaterThanEqual %36 %117 %118
+               OpSelectionMerge %122 None
+               OpBranchConditional %119 %121 %134
+        %121 = OpLabel
+               OpSelectionMerge %126 None
+               OpBranchConditional %123 %125 %130
+        %125 = OpLabel
+        %127 = OpLoad %6 %16
+        %129 = OpShiftLeftLogical %6 %127 %128
+               OpStore %124 %129
+               OpBranch %126
+        %130 = OpLabel
+               OpStore %124 %131
+               OpBranch %126
+        %126 = OpLabel
+        %132 = OpLoad %6 %124
+        %133 = OpShiftLeftLogical %6 %27 %132
+               OpStore %120 %133
+               OpBranch %122
+        %134 = OpLabel
+               OpStore %120 %27
+               OpBranch %122
+        %122 = OpLabel
+        %135 = OpLoad %6 %120
+               OpStore %109 %135
+        %136 = OpLoad %6 %109
+        %137 = OpShiftRightArithmetic %6 %136 %131
+               OpStore %109 %137
+        %139 = OpLoad %6 %15
+        %140 = OpIMul %6 %138 %139
+        %141 = OpLoad %6 %15
+        %142 = OpIMul %6 %138 %141
+        %143 = OpLoad %6 %15
+        %144 = OpIMul %6 %138 %143
+        %145 = OpLoad %6 %109
+        %146 = OpSDiv %6 %144 %145
+        %147 = OpExtInst %6 %1 SClamp %140 %142 %146
+               OpReturnValue %147
+               OpFunctionEnd
+         %19 = OpFunction %2 None %3
+         %20 = OpLabel
+        %150 = OpVariable %7 Function
+        %151 = OpVariable %7 Function
+        %153 = OpVariable %7 Function
+        %162 = OpVariable %7 Function
+        %172 = OpVariable %7 Function
+        %174 = OpVariable %7 Function
+        %179 = OpVariable %7 Function
+        %187 = OpVariable %7 Function
+        %189 = OpVariable %7 Function
+        %191 = OpVariable %7 Function
+        %194 = OpVariable %7 Function
+        %196 = OpVariable %7 Function
+               OpStore %150 %128
+               OpStore %151 %152
+               OpStore %153 %27
+               OpBranch %154
+        %154 = OpLabel
+               OpLoopMerge %156 %157 None
+               OpBranch %158
+        %158 = OpLabel
+        %159 = OpLoad %6 %153
+        %160 = OpLoad %6 %151
+        %161 = OpSLessThanEqual %36 %159 %160
+               OpBranchConditional %161 %155 %156
+        %155 = OpLabel
+        %163 = OpLoad %6 %150
+               OpStore %162 %163
+               OpBranch %164
+        %164 = OpLabel
+               OpLoopMerge %166 %167 None
+               OpBranch %168
+        %168 = OpLabel
+        %169 = OpLoad %6 %162
+        %170 = OpLoad %6 %151
+        %171 = OpSLessThan %36 %169 %170
+               OpBranchConditional %171 %165 %166
+        %165 = OpLabel
+        %173 = OpLoad %6 %162
+               OpStore %172 %173
+        %175 = OpLoad %6 %162
+        %176 = OpLoad %6 %153
+        %177 = OpIAdd %6 %175 %176
+        %178 = OpISub %6 %177 %27
+               OpStore %174 %178
+        %180 = OpLoad %6 %162
+        %181 = OpLoad %6 %153
+        %182 = OpIMul %6 %138 %181
+        %183 = OpIAdd %6 %180 %182
+        %184 = OpISub %6 %183 %27
+        %185 = OpLoad %6 %151
+        %186 = OpExtInst %6 %1 SMin %184 %185
+               OpStore %179 %186
+        %188 = OpLoad %6 %172
+               OpStore %187 %188
+        %190 = OpLoad %6 %174
+               OpStore %189 %190
+        %192 = OpLoad %6 %179
+               OpStore %191 %192
+        %193 = OpFunctionCall %2 %12 %187 %189 %191
+               OpBranch %167
+        %167 = OpLabel
+        %195 = OpLoad %6 %153
+               OpStore %194 %195
+        %197 = OpLoad %6 %151
+               OpStore %196 %197
+        %198 = OpFunctionCall %6 %17 %194 %196
+        %199 = OpLoad %6 %162
+        %200 = OpIAdd %6 %199 %198
+               OpStore %162 %200
+               OpBranch %164
+        %166 = OpLabel
+               OpBranch %157
+        %157 = OpLabel
+        %201 = OpLoad %6 %153
+        %202 = OpIMul %6 %138 %201
+               OpStore %153 %202
+               OpBranch %154
+        %156 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> STD140 DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch 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 256 256
+
+EXPECT reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-quicksort-conditional-bitwise-or-clamp.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-quicksort-conditional-bitwise-or-clamp.amber
new file mode 100644 (file)
index 0000000..1b45fef
--- /dev/null
@@ -0,0 +1,1314 @@
+#!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 conditional bitwise or clamped
+
+# The test passes because both shaders render the same image.
+
+SHADER vertex reference_vertex_shader PASSTHROUGH
+
+# reference_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 resolution;
+# };
+# struct QuicksortObject
+# {
+#     int numbers[10];
+# };
+#
+# QuicksortObject obj;
+#
+# void swap(int i, int j)
+# {
+#     int temp = obj.numbers[i];
+#     obj.numbers[i] = obj.numbers[j];
+#     obj.numbers[j] = temp;
+# }
+# int performPartition(int l, int h)
+# {
+#     int pivot = obj.numbers[h];
+#     int i = l - 1;
+#     for (int j = l; j <= h - 1; j++)
+#     {
+#         if (obj.numbers[j] <= pivot)
+#         {
+#             i++;
+#             swap(i, j);
+#         }
+#     }
+#     i++;
+#     swap(i, h);
+#     return i;
+# }
+# void quicksort()
+# {
+#     int l = 0, h = 9;
+#     int stack[10];
+#     int top = -1;
+#     stack[++top] = l;
+#     stack[++top] = h;
+#     while (top >= 0)
+#     {
+#         h = stack[top--];
+#         l = stack[top--];
+#         int p = performPartition(l, h);
+#         if (p - 1 > l)
+#         {
+#             stack[++top] = l;
+#             stack[++top] = p - 1;
+#         }
+#         if (p + 1 < h)
+#         {
+#             stack[++top] = p + 1;
+#             stack[++top] = h;
+#         }
+#     }
+# }
+# void main()
+# {
+#     for (int i = 0; i < 10; i++)
+#     {
+#         obj.numbers[i] = (10 - i);
+#         obj.numbers[i] = obj.numbers[i] * obj.numbers[i];
+#     }
+#     quicksort();
+#     vec2 uv = gl_FragCoord.xy / resolution;
+#     vec3 color = vec3(1.0, 2.0, 3.0);
+#     color.x += float(obj.numbers[0]);
+#     if (uv.x > (1.0 / 4.0))
+#     {
+#         color.x += float(obj.numbers[1]);
+#     }
+#     if (uv.x > (2.0 / 4.0))
+#     {
+#         color.y += float(obj.numbers[2]);
+#     }
+#     if (uv.x > (3.0 / 4.0))
+#     {
+#         color.z += float(obj.numbers[3]);
+#     }
+#     color.y += float(obj.numbers[4]);
+#     if (uv.y > (1.0 / 4.0))
+#     {
+#         color.x += float(obj.numbers[5]);
+#     }
+#     if (uv.y > (2.0 / 4.0))
+#     {
+#         color.y += float(obj.numbers[6]);
+#     }
+#     if (uv.y > (3.0 / 4.0))
+#     {
+#         color.z += float(obj.numbers[7]);
+#     }
+#     color.z += float(obj.numbers[8]);
+#     if (abs(uv.x - uv.y) < 0.25)
+#     {
+#         color.x += float(obj.numbers[9]);
+#     }
+#     _GLF_color = vec4(normalize(color), 1.0);
+# }
+SHADER fragment reference_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 331
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %183 %324
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %11 "swap(i1;i1;"
+               OpName %9 "i"
+               OpName %10 "j"
+               OpName %16 "performPartition(i1;i1;"
+               OpName %14 "l"
+               OpName %15 "h"
+               OpName %18 "quicksort("
+               OpName %20 "temp"
+               OpName %24 "QuicksortObject"
+               OpMemberName %24 0 "numbers"
+               OpName %26 "obj"
+               OpName %40 "pivot"
+               OpName %44 "i"
+               OpName %48 "j"
+               OpName %69 "param"
+               OpName %71 "param"
+               OpName %78 "param"
+               OpName %80 "param"
+               OpName %86 "l"
+               OpName %87 "h"
+               OpName %89 "top"
+               OpName %92 "stack"
+               OpName %116 "p"
+               OpName %117 "param"
+               OpName %119 "param"
+               OpName %152 "i"
+               OpName %180 "uv"
+               OpName %183 "gl_FragCoord"
+               OpName %186 "buf0"
+               OpMemberName %186 0 "resolution"
+               OpName %188 ""
+               OpName %195 "color"
+               OpName %324 "_GLF_color"
+               OpDecorate %183 BuiltIn FragCoord
+               OpMemberDecorate %186 0 Offset 0
+               OpDecorate %186 Block
+               OpDecorate %188 DescriptorSet 0
+               OpDecorate %188 Binding 0
+               OpDecorate %324 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %8 = OpTypeFunction %2 %7 %7
+         %13 = OpTypeFunction %6 %7 %7
+         %21 = OpTypeInt 32 0
+         %22 = OpConstant %21 10
+         %23 = OpTypeArray %6 %22
+         %24 = OpTypeStruct %23
+         %25 = OpTypePointer Private %24
+         %26 = OpVariable %25 Private
+         %27 = OpConstant %6 0
+         %29 = OpTypePointer Private %6
+         %46 = OpConstant %6 1
+         %58 = OpTypeBool
+         %88 = OpConstant %6 9
+         %90 = OpConstant %6 -1
+         %91 = OpTypePointer Function %23
+        %159 = OpConstant %6 10
+        %177 = OpTypeFloat 32
+        %178 = OpTypeVector %177 2
+        %179 = OpTypePointer Function %178
+        %181 = OpTypeVector %177 4
+        %182 = OpTypePointer Input %181
+        %183 = OpVariable %182 Input
+        %186 = OpTypeStruct %178
+        %187 = OpTypePointer Uniform %186
+        %188 = OpVariable %187 Uniform
+        %189 = OpTypePointer Uniform %178
+        %193 = OpTypeVector %177 3
+        %194 = OpTypePointer Function %193
+        %196 = OpConstant %177 1
+        %197 = OpConstant %177 2
+        %198 = OpConstant %177 3
+        %199 = OpConstantComposite %193 %196 %197 %198
+        %203 = OpConstant %21 0
+        %204 = OpTypePointer Function %177
+        %211 = OpConstant %177 0.25
+        %224 = OpConstant %177 0.5
+        %228 = OpConstant %6 2
+        %232 = OpConstant %21 1
+        %239 = OpConstant %177 0.75
+        %243 = OpConstant %6 3
+        %247 = OpConstant %21 2
+        %252 = OpConstant %6 4
+        %265 = OpConstant %6 5
+        %278 = OpConstant %6 6
+        %291 = OpConstant %6 7
+        %299 = OpConstant %6 8
+        %323 = OpTypePointer Output %181
+        %324 = OpVariable %323 Output
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %152 = OpVariable %7 Function
+        %180 = OpVariable %179 Function
+        %195 = OpVariable %194 Function
+               OpStore %152 %27
+               OpBranch %153
+        %153 = OpLabel
+               OpLoopMerge %155 %156 None
+               OpBranch %157
+        %157 = OpLabel
+        %158 = OpLoad %6 %152
+        %160 = OpSLessThan %58 %158 %159
+               OpBranchConditional %160 %154 %155
+        %154 = OpLabel
+        %161 = OpLoad %6 %152
+        %162 = OpLoad %6 %152
+        %163 = OpISub %6 %159 %162
+        %164 = OpAccessChain %29 %26 %27 %161
+               OpStore %164 %163
+        %165 = OpLoad %6 %152
+        %166 = OpLoad %6 %152
+        %167 = OpAccessChain %29 %26 %27 %166
+        %168 = OpLoad %6 %167
+        %169 = OpLoad %6 %152
+        %170 = OpAccessChain %29 %26 %27 %169
+        %171 = OpLoad %6 %170
+        %172 = OpIMul %6 %168 %171
+        %173 = OpAccessChain %29 %26 %27 %165
+               OpStore %173 %172
+               OpBranch %156
+        %156 = OpLabel
+        %174 = OpLoad %6 %152
+        %175 = OpIAdd %6 %174 %46
+               OpStore %152 %175
+               OpBranch %153
+        %155 = OpLabel
+        %176 = OpFunctionCall %2 %18
+        %184 = OpLoad %181 %183
+        %185 = OpVectorShuffle %178 %184 %184 0 1
+        %190 = OpAccessChain %189 %188 %27
+        %191 = OpLoad %178 %190
+        %192 = OpFDiv %178 %185 %191
+               OpStore %180 %192
+               OpStore %195 %199
+        %200 = OpAccessChain %29 %26 %27 %27
+        %201 = OpLoad %6 %200
+        %202 = OpConvertSToF %177 %201
+        %205 = OpAccessChain %204 %195 %203
+        %206 = OpLoad %177 %205
+        %207 = OpFAdd %177 %206 %202
+        %208 = OpAccessChain %204 %195 %203
+               OpStore %208 %207
+        %209 = OpAccessChain %204 %180 %203
+        %210 = OpLoad %177 %209
+        %212 = OpFOrdGreaterThan %58 %210 %211
+               OpSelectionMerge %214 None
+               OpBranchConditional %212 %213 %214
+        %213 = OpLabel
+        %215 = OpAccessChain %29 %26 %27 %46
+        %216 = OpLoad %6 %215
+        %217 = OpConvertSToF %177 %216
+        %218 = OpAccessChain %204 %195 %203
+        %219 = OpLoad %177 %218
+        %220 = OpFAdd %177 %219 %217
+        %221 = OpAccessChain %204 %195 %203
+               OpStore %221 %220
+               OpBranch %214
+        %214 = OpLabel
+        %222 = OpAccessChain %204 %180 %203
+        %223 = OpLoad %177 %222
+        %225 = OpFOrdGreaterThan %58 %223 %224
+               OpSelectionMerge %227 None
+               OpBranchConditional %225 %226 %227
+        %226 = OpLabel
+        %229 = OpAccessChain %29 %26 %27 %228
+        %230 = OpLoad %6 %229
+        %231 = OpConvertSToF %177 %230
+        %233 = OpAccessChain %204 %195 %232
+        %234 = OpLoad %177 %233
+        %235 = OpFAdd %177 %234 %231
+        %236 = OpAccessChain %204 %195 %232
+               OpStore %236 %235
+               OpBranch %227
+        %227 = OpLabel
+        %237 = OpAccessChain %204 %180 %203
+        %238 = OpLoad %177 %237
+        %240 = OpFOrdGreaterThan %58 %238 %239
+               OpSelectionMerge %242 None
+               OpBranchConditional %240 %241 %242
+        %241 = OpLabel
+        %244 = OpAccessChain %29 %26 %27 %243
+        %245 = OpLoad %6 %244
+        %246 = OpConvertSToF %177 %245
+        %248 = OpAccessChain %204 %195 %247
+        %249 = OpLoad %177 %248
+        %250 = OpFAdd %177 %249 %246
+        %251 = OpAccessChain %204 %195 %247
+               OpStore %251 %250
+               OpBranch %242
+        %242 = OpLabel
+        %253 = OpAccessChain %29 %26 %27 %252
+        %254 = OpLoad %6 %253
+        %255 = OpConvertSToF %177 %254
+        %256 = OpAccessChain %204 %195 %232
+        %257 = OpLoad %177 %256
+        %258 = OpFAdd %177 %257 %255
+        %259 = OpAccessChain %204 %195 %232
+               OpStore %259 %258
+        %260 = OpAccessChain %204 %180 %232
+        %261 = OpLoad %177 %260
+        %262 = OpFOrdGreaterThan %58 %261 %211
+               OpSelectionMerge %264 None
+               OpBranchConditional %262 %263 %264
+        %263 = OpLabel
+        %266 = OpAccessChain %29 %26 %27 %265
+        %267 = OpLoad %6 %266
+        %268 = OpConvertSToF %177 %267
+        %269 = OpAccessChain %204 %195 %203
+        %270 = OpLoad %177 %269
+        %271 = OpFAdd %177 %270 %268
+        %272 = OpAccessChain %204 %195 %203
+               OpStore %272 %271
+               OpBranch %264
+        %264 = OpLabel
+        %273 = OpAccessChain %204 %180 %232
+        %274 = OpLoad %177 %273
+        %275 = OpFOrdGreaterThan %58 %274 %224
+               OpSelectionMerge %277 None
+               OpBranchConditional %275 %276 %277
+        %276 = OpLabel
+        %279 = OpAccessChain %29 %26 %27 %278
+        %280 = OpLoad %6 %279
+        %281 = OpConvertSToF %177 %280
+        %282 = OpAccessChain %204 %195 %232
+        %283 = OpLoad %177 %282
+        %284 = OpFAdd %177 %283 %281
+        %285 = OpAccessChain %204 %195 %232
+               OpStore %285 %284
+               OpBranch %277
+        %277 = OpLabel
+        %286 = OpAccessChain %204 %180 %232
+        %287 = OpLoad %177 %286
+        %288 = OpFOrdGreaterThan %58 %287 %239
+               OpSelectionMerge %290 None
+               OpBranchConditional %288 %289 %290
+        %289 = OpLabel
+        %292 = OpAccessChain %29 %26 %27 %291
+        %293 = OpLoad %6 %292
+        %294 = OpConvertSToF %177 %293
+        %295 = OpAccessChain %204 %195 %247
+        %296 = OpLoad %177 %295
+        %297 = OpFAdd %177 %296 %294
+        %298 = OpAccessChain %204 %195 %247
+               OpStore %298 %297
+               OpBranch %290
+        %290 = OpLabel
+        %300 = OpAccessChain %29 %26 %27 %299
+        %301 = OpLoad %6 %300
+        %302 = OpConvertSToF %177 %301
+        %303 = OpAccessChain %204 %195 %247
+        %304 = OpLoad %177 %303
+        %305 = OpFAdd %177 %304 %302
+        %306 = OpAccessChain %204 %195 %247
+               OpStore %306 %305
+        %307 = OpAccessChain %204 %180 %203
+        %308 = OpLoad %177 %307
+        %309 = OpAccessChain %204 %180 %232
+        %310 = OpLoad %177 %309
+        %311 = OpFSub %177 %308 %310
+        %312 = OpExtInst %177 %1 FAbs %311
+        %313 = OpFOrdLessThan %58 %312 %211
+               OpSelectionMerge %315 None
+               OpBranchConditional %313 %314 %315
+        %314 = OpLabel
+        %316 = OpAccessChain %29 %26 %27 %88
+        %317 = OpLoad %6 %316
+        %318 = OpConvertSToF %177 %317
+        %319 = OpAccessChain %204 %195 %203
+        %320 = OpLoad %177 %319
+        %321 = OpFAdd %177 %320 %318
+        %322 = OpAccessChain %204 %195 %203
+               OpStore %322 %321
+               OpBranch %315
+        %315 = OpLabel
+        %325 = OpLoad %193 %195
+        %326 = OpExtInst %193 %1 Normalize %325
+        %327 = OpCompositeExtract %177 %326 0
+        %328 = OpCompositeExtract %177 %326 1
+        %329 = OpCompositeExtract %177 %326 2
+        %330 = OpCompositeConstruct %181 %327 %328 %329 %196
+               OpStore %324 %330
+               OpReturn
+               OpFunctionEnd
+         %11 = OpFunction %2 None %8
+          %9 = OpFunctionParameter %7
+         %10 = OpFunctionParameter %7
+         %12 = OpLabel
+         %20 = OpVariable %7 Function
+         %28 = OpLoad %6 %9
+         %30 = OpAccessChain %29 %26 %27 %28
+         %31 = OpLoad %6 %30
+               OpStore %20 %31
+         %32 = OpLoad %6 %9
+         %33 = OpLoad %6 %10
+         %34 = OpAccessChain %29 %26 %27 %33
+         %35 = OpLoad %6 %34
+         %36 = OpAccessChain %29 %26 %27 %32
+               OpStore %36 %35
+         %37 = OpLoad %6 %10
+         %38 = OpLoad %6 %20
+         %39 = OpAccessChain %29 %26 %27 %37
+               OpStore %39 %38
+               OpReturn
+               OpFunctionEnd
+         %16 = OpFunction %6 None %13
+         %14 = OpFunctionParameter %7
+         %15 = OpFunctionParameter %7
+         %17 = OpLabel
+         %40 = OpVariable %7 Function
+         %44 = OpVariable %7 Function
+         %48 = OpVariable %7 Function
+         %69 = OpVariable %7 Function
+         %71 = OpVariable %7 Function
+         %78 = OpVariable %7 Function
+         %80 = OpVariable %7 Function
+         %41 = OpLoad %6 %15
+         %42 = OpAccessChain %29 %26 %27 %41
+         %43 = OpLoad %6 %42
+               OpStore %40 %43
+         %45 = OpLoad %6 %14
+         %47 = OpISub %6 %45 %46
+               OpStore %44 %47
+         %49 = OpLoad %6 %14
+               OpStore %48 %49
+               OpBranch %50
+         %50 = OpLabel
+               OpLoopMerge %52 %53 None
+               OpBranch %54
+         %54 = OpLabel
+         %55 = OpLoad %6 %48
+         %56 = OpLoad %6 %15
+         %57 = OpISub %6 %56 %46
+         %59 = OpSLessThanEqual %58 %55 %57
+               OpBranchConditional %59 %51 %52
+         %51 = OpLabel
+         %60 = OpLoad %6 %48
+         %61 = OpAccessChain %29 %26 %27 %60
+         %62 = OpLoad %6 %61
+         %63 = OpLoad %6 %40
+         %64 = OpSLessThanEqual %58 %62 %63
+               OpSelectionMerge %66 None
+               OpBranchConditional %64 %65 %66
+         %65 = OpLabel
+         %67 = OpLoad %6 %44
+         %68 = OpIAdd %6 %67 %46
+               OpStore %44 %68
+         %70 = OpLoad %6 %44
+               OpStore %69 %70
+         %72 = OpLoad %6 %48
+               OpStore %71 %72
+         %73 = OpFunctionCall %2 %11 %69 %71
+               OpBranch %66
+         %66 = OpLabel
+               OpBranch %53
+         %53 = OpLabel
+         %74 = OpLoad %6 %48
+         %75 = OpIAdd %6 %74 %46
+               OpStore %48 %75
+               OpBranch %50
+         %52 = OpLabel
+         %76 = OpLoad %6 %44
+         %77 = OpIAdd %6 %76 %46
+               OpStore %44 %77
+         %79 = OpLoad %6 %44
+               OpStore %78 %79
+         %81 = OpLoad %6 %15
+               OpStore %80 %81
+         %82 = OpFunctionCall %2 %11 %78 %80
+         %83 = OpLoad %6 %44
+               OpReturnValue %83
+               OpFunctionEnd
+         %18 = OpFunction %2 None %3
+         %19 = OpLabel
+         %86 = OpVariable %7 Function
+         %87 = OpVariable %7 Function
+         %89 = OpVariable %7 Function
+         %92 = OpVariable %91 Function
+        %116 = OpVariable %7 Function
+        %117 = OpVariable %7 Function
+        %119 = OpVariable %7 Function
+               OpStore %86 %27
+               OpStore %87 %88
+               OpStore %89 %90
+         %93 = OpLoad %6 %89
+         %94 = OpIAdd %6 %93 %46
+               OpStore %89 %94
+         %95 = OpLoad %6 %86
+         %96 = OpAccessChain %7 %92 %94
+               OpStore %96 %95
+         %97 = OpLoad %6 %89
+         %98 = OpIAdd %6 %97 %46
+               OpStore %89 %98
+         %99 = OpLoad %6 %87
+        %100 = OpAccessChain %7 %92 %98
+               OpStore %100 %99
+               OpBranch %101
+        %101 = OpLabel
+               OpLoopMerge %103 %104 None
+               OpBranch %105
+        %105 = OpLabel
+        %106 = OpLoad %6 %89
+        %107 = OpSGreaterThanEqual %58 %106 %27
+               OpBranchConditional %107 %102 %103
+        %102 = OpLabel
+        %108 = OpLoad %6 %89
+        %109 = OpISub %6 %108 %46
+               OpStore %89 %109
+        %110 = OpAccessChain %7 %92 %108
+        %111 = OpLoad %6 %110
+               OpStore %87 %111
+        %112 = OpLoad %6 %89
+        %113 = OpISub %6 %112 %46
+               OpStore %89 %113
+        %114 = OpAccessChain %7 %92 %112
+        %115 = OpLoad %6 %114
+               OpStore %86 %115
+        %118 = OpLoad %6 %86
+               OpStore %117 %118
+        %120 = OpLoad %6 %87
+               OpStore %119 %120
+        %121 = OpFunctionCall %6 %16 %117 %119
+               OpStore %116 %121
+        %122 = OpLoad %6 %116
+        %123 = OpISub %6 %122 %46
+        %124 = OpLoad %6 %86
+        %125 = OpSGreaterThan %58 %123 %124
+               OpSelectionMerge %127 None
+               OpBranchConditional %125 %126 %127
+        %126 = OpLabel
+        %128 = OpLoad %6 %89
+        %129 = OpIAdd %6 %128 %46
+               OpStore %89 %129
+        %130 = OpLoad %6 %86
+        %131 = OpAccessChain %7 %92 %129
+               OpStore %131 %130
+        %132 = OpLoad %6 %89
+        %133 = OpIAdd %6 %132 %46
+               OpStore %89 %133
+        %134 = OpLoad %6 %116
+        %135 = OpISub %6 %134 %46
+        %136 = OpAccessChain %7 %92 %133
+               OpStore %136 %135
+               OpBranch %127
+        %127 = OpLabel
+        %137 = OpLoad %6 %116
+        %138 = OpIAdd %6 %137 %46
+        %139 = OpLoad %6 %87
+        %140 = OpSLessThan %58 %138 %139
+               OpSelectionMerge %142 None
+               OpBranchConditional %140 %141 %142
+        %141 = OpLabel
+        %143 = OpLoad %6 %89
+        %144 = OpIAdd %6 %143 %46
+               OpStore %89 %144
+        %145 = OpLoad %6 %116
+        %146 = OpIAdd %6 %145 %46
+        %147 = OpAccessChain %7 %92 %144
+               OpStore %147 %146
+        %148 = OpLoad %6 %89
+        %149 = OpIAdd %6 %148 %46
+               OpStore %89 %149
+        %150 = OpLoad %6 %87
+        %151 = OpAccessChain %7 %92 %149
+               OpStore %151 %150
+               OpBranch %142
+        %142 = OpLabel
+               OpBranch %104
+        %104 = OpLabel
+               OpBranch %101
+        %103 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for reference
+
+# resolution
+BUFFER reference_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.0
+END
+
+BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics reference_pipeline
+  ATTACH reference_vertex_shader
+  ATTACH reference_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER reference_framebuffer AS color LOCATION 0
+  BIND BUFFER reference_resolution AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR reference_pipeline 0 0 0 255
+
+CLEAR reference_pipeline
+RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 resolution;
+# };
+# struct QuicksortObject
+# {
+#     int numbers[10];
+# };
+#
+# QuicksortObject obj;
+#
+# void swap(int i, int j)
+# {
+#     int temp = obj.numbers[i];
+#     obj.numbers[i] = obj.numbers[j];
+#     obj.numbers[j] = temp;
+# }
+# int performPartition(int l, int h)
+# {
+#     int pivot = obj.numbers[h];
+#     int i = l - 1;
+#     for (int j = l; j <= h - 1; j++)
+#     {
+#         if (obj.numbers[j] <= pivot)
+#         {
+#             i++;
+#             swap(i, j);
+#         }
+#     }
+#     i++;
+#     swap(i, h);
+#     return i;
+# }
+# void quicksort()
+# {
+#     int l = 0, h = 9;
+#     int stack[10];
+#     int top = -1;
+#     stack[++top] = l;
+#     // gl_FragCoord.y >= 0.0 is always true.
+#     // h | (h << 0) == h
+#     // int_a == h
+#     int int_a = ((gl_FragCoord.y >= 0.0) ? (h | ((false ? 1 : (h << 0)))) : 1);
+#     // clamp_a == h
+#     int clamp_a = (clamp(h, h, int_a));
+#     stack[++top] = (clamp_a / 1);
+#     while (top >= 0)
+#     {
+#         h = stack[top--];
+#         l = stack[top--];
+#         int p = performPartition(l, h);
+#         if (p - 1 > l)
+#         {
+#             stack[++top] = l;
+#             stack[++top] = p - 1;
+#         }
+#         if (p + 1 < h)
+#         {
+#             stack[++top] = p + 1;
+#             stack[++top] = h;
+#         }
+#     }
+# }
+# void main()
+# {
+#     for (int i = 0; i < 10; i++)
+#     {
+#         obj.numbers[i] = (10 - i);
+#         obj.numbers[i] = obj.numbers[i] * obj.numbers[i];
+#     }
+#     quicksort();
+#     vec2 uv = gl_FragCoord.xy / resolution;
+#     vec3 color = vec3(1.0, 2.0, 3.0);
+#     color.x += float(obj.numbers[0]);
+#     if (uv.x > (1.0 / 4.0))
+#     {
+#         color.x += float(obj.numbers[1]);
+#     }
+#     if (uv.x > (2.0 / 4.0))
+#     {
+#         color.y += float(obj.numbers[2]);
+#     }
+#     if (uv.x > (3.0 / 4.0))
+#     {
+#         color.z += float(obj.numbers[3]);
+#     }
+#     color.y += float(obj.numbers[4]);
+#     if (uv.y > (1.0 / 4.0))
+#     {
+#         color.x += float(obj.numbers[5]);
+#     }
+#     if (uv.y > (2.0 / 4.0))
+#     {
+#         color.y += float(obj.numbers[6]);
+#     }
+#     if (uv.y > (3.0 / 4.0))
+#     {
+#         color.z += float(obj.numbers[7]);
+#     }
+#     color.z += float(obj.numbers[8]);
+#     if (abs(uv.x - uv.y) < 0.25)
+#     {
+#         color.x += float(obj.numbers[9]);
+#     }
+#     _GLF_color = vec4(normalize(color), 1.0);
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 358
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %101 %351
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %11 "swap(i1;i1;"
+               OpName %9 "i"
+               OpName %10 "j"
+               OpName %16 "performPartition(i1;i1;"
+               OpName %14 "l"
+               OpName %15 "h"
+               OpName %18 "quicksort("
+               OpName %20 "temp"
+               OpName %24 "QuicksortObject"
+               OpMemberName %24 0 "numbers"
+               OpName %26 "obj"
+               OpName %40 "pivot"
+               OpName %44 "i"
+               OpName %48 "j"
+               OpName %69 "param"
+               OpName %71 "param"
+               OpName %78 "param"
+               OpName %80 "param"
+               OpName %86 "l"
+               OpName %87 "h"
+               OpName %89 "top"
+               OpName %92 "stack"
+               OpName %97 "int_a"
+               OpName %101 "gl_FragCoord"
+               OpName %123 "clamp_a"
+               OpName %148 "p"
+               OpName %149 "param"
+               OpName %151 "param"
+               OpName %184 "i"
+               OpName %211 "uv"
+               OpName %214 "buf0"
+               OpMemberName %214 0 "resolution"
+               OpName %216 ""
+               OpName %223 "color"
+               OpName %351 "_GLF_color"
+               OpDecorate %101 BuiltIn FragCoord
+               OpMemberDecorate %214 0 Offset 0
+               OpDecorate %214 Block
+               OpDecorate %216 DescriptorSet 0
+               OpDecorate %216 Binding 0
+               OpDecorate %351 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypePointer Function %6
+          %8 = OpTypeFunction %2 %7 %7
+         %13 = OpTypeFunction %6 %7 %7
+         %21 = OpTypeInt 32 0
+         %22 = OpConstant %21 10
+         %23 = OpTypeArray %6 %22
+         %24 = OpTypeStruct %23
+         %25 = OpTypePointer Private %24
+         %26 = OpVariable %25 Private
+         %27 = OpConstant %6 0
+         %29 = OpTypePointer Private %6
+         %46 = OpConstant %6 1
+         %58 = OpTypeBool
+         %88 = OpConstant %6 9
+         %90 = OpConstant %6 -1
+         %91 = OpTypePointer Function %23
+         %98 = OpTypeFloat 32
+         %99 = OpTypeVector %98 4
+        %100 = OpTypePointer Input %99
+        %101 = OpVariable %100 Input
+        %102 = OpConstant %21 1
+        %103 = OpTypePointer Input %98
+        %106 = OpConstant %98 0
+        %112 = OpConstantFalse %58
+        %191 = OpConstant %6 10
+        %209 = OpTypeVector %98 2
+        %210 = OpTypePointer Function %209
+        %214 = OpTypeStruct %209
+        %215 = OpTypePointer Uniform %214
+        %216 = OpVariable %215 Uniform
+        %217 = OpTypePointer Uniform %209
+        %221 = OpTypeVector %98 3
+        %222 = OpTypePointer Function %221
+        %224 = OpConstant %98 1
+        %225 = OpConstant %98 2
+        %226 = OpConstant %98 3
+        %227 = OpConstantComposite %221 %224 %225 %226
+        %231 = OpConstant %21 0
+        %232 = OpTypePointer Function %98
+        %239 = OpConstant %98 0.25
+        %252 = OpConstant %98 0.5
+        %256 = OpConstant %6 2
+        %266 = OpConstant %98 0.75
+        %270 = OpConstant %6 3
+        %274 = OpConstant %21 2
+        %279 = OpConstant %6 4
+        %292 = OpConstant %6 5
+        %305 = OpConstant %6 6
+        %318 = OpConstant %6 7
+        %326 = OpConstant %6 8
+        %350 = OpTypePointer Output %99
+        %351 = OpVariable %350 Output
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %184 = OpVariable %7 Function
+        %211 = OpVariable %210 Function
+        %223 = OpVariable %222 Function
+               OpStore %184 %27
+               OpBranch %185
+        %185 = OpLabel
+               OpLoopMerge %187 %188 None
+               OpBranch %189
+        %189 = OpLabel
+        %190 = OpLoad %6 %184
+        %192 = OpSLessThan %58 %190 %191
+               OpBranchConditional %192 %186 %187
+        %186 = OpLabel
+        %193 = OpLoad %6 %184
+        %194 = OpLoad %6 %184
+        %195 = OpISub %6 %191 %194
+        %196 = OpAccessChain %29 %26 %27 %193
+               OpStore %196 %195
+        %197 = OpLoad %6 %184
+        %198 = OpLoad %6 %184
+        %199 = OpAccessChain %29 %26 %27 %198
+        %200 = OpLoad %6 %199
+        %201 = OpLoad %6 %184
+        %202 = OpAccessChain %29 %26 %27 %201
+        %203 = OpLoad %6 %202
+        %204 = OpIMul %6 %200 %203
+        %205 = OpAccessChain %29 %26 %27 %197
+               OpStore %205 %204
+               OpBranch %188
+        %188 = OpLabel
+        %206 = OpLoad %6 %184
+        %207 = OpIAdd %6 %206 %46
+               OpStore %184 %207
+               OpBranch %185
+        %187 = OpLabel
+        %208 = OpFunctionCall %2 %18
+        %212 = OpLoad %99 %101
+        %213 = OpVectorShuffle %209 %212 %212 0 1
+        %218 = OpAccessChain %217 %216 %27
+        %219 = OpLoad %209 %218
+        %220 = OpFDiv %209 %213 %219
+               OpStore %211 %220
+               OpStore %223 %227
+        %228 = OpAccessChain %29 %26 %27 %27
+        %229 = OpLoad %6 %228
+        %230 = OpConvertSToF %98 %229
+        %233 = OpAccessChain %232 %223 %231
+        %234 = OpLoad %98 %233
+        %235 = OpFAdd %98 %234 %230
+        %236 = OpAccessChain %232 %223 %231
+               OpStore %236 %235
+        %237 = OpAccessChain %232 %211 %231
+        %238 = OpLoad %98 %237
+        %240 = OpFOrdGreaterThan %58 %238 %239
+               OpSelectionMerge %242 None
+               OpBranchConditional %240 %241 %242
+        %241 = OpLabel
+        %243 = OpAccessChain %29 %26 %27 %46
+        %244 = OpLoad %6 %243
+        %245 = OpConvertSToF %98 %244
+        %246 = OpAccessChain %232 %223 %231
+        %247 = OpLoad %98 %246
+        %248 = OpFAdd %98 %247 %245
+        %249 = OpAccessChain %232 %223 %231
+               OpStore %249 %248
+               OpBranch %242
+        %242 = OpLabel
+        %250 = OpAccessChain %232 %211 %231
+        %251 = OpLoad %98 %250
+        %253 = OpFOrdGreaterThan %58 %251 %252
+               OpSelectionMerge %255 None
+               OpBranchConditional %253 %254 %255
+        %254 = OpLabel
+        %257 = OpAccessChain %29 %26 %27 %256
+        %258 = OpLoad %6 %257
+        %259 = OpConvertSToF %98 %258
+        %260 = OpAccessChain %232 %223 %102
+        %261 = OpLoad %98 %260
+        %262 = OpFAdd %98 %261 %259
+        %263 = OpAccessChain %232 %223 %102
+               OpStore %263 %262
+               OpBranch %255
+        %255 = OpLabel
+        %264 = OpAccessChain %232 %211 %231
+        %265 = OpLoad %98 %264
+        %267 = OpFOrdGreaterThan %58 %265 %266
+               OpSelectionMerge %269 None
+               OpBranchConditional %267 %268 %269
+        %268 = OpLabel
+        %271 = OpAccessChain %29 %26 %27 %270
+        %272 = OpLoad %6 %271
+        %273 = OpConvertSToF %98 %272
+        %275 = OpAccessChain %232 %223 %274
+        %276 = OpLoad %98 %275
+        %277 = OpFAdd %98 %276 %273
+        %278 = OpAccessChain %232 %223 %274
+               OpStore %278 %277
+               OpBranch %269
+        %269 = OpLabel
+        %280 = OpAccessChain %29 %26 %27 %279
+        %281 = OpLoad %6 %280
+        %282 = OpConvertSToF %98 %281
+        %283 = OpAccessChain %232 %223 %102
+        %284 = OpLoad %98 %283
+        %285 = OpFAdd %98 %284 %282
+        %286 = OpAccessChain %232 %223 %102
+               OpStore %286 %285
+        %287 = OpAccessChain %232 %211 %102
+        %288 = OpLoad %98 %287
+        %289 = OpFOrdGreaterThan %58 %288 %239
+               OpSelectionMerge %291 None
+               OpBranchConditional %289 %290 %291
+        %290 = OpLabel
+        %293 = OpAccessChain %29 %26 %27 %292
+        %294 = OpLoad %6 %293
+        %295 = OpConvertSToF %98 %294
+        %296 = OpAccessChain %232 %223 %231
+        %297 = OpLoad %98 %296
+        %298 = OpFAdd %98 %297 %295
+        %299 = OpAccessChain %232 %223 %231
+               OpStore %299 %298
+               OpBranch %291
+        %291 = OpLabel
+        %300 = OpAccessChain %232 %211 %102
+        %301 = OpLoad %98 %300
+        %302 = OpFOrdGreaterThan %58 %301 %252
+               OpSelectionMerge %304 None
+               OpBranchConditional %302 %303 %304
+        %303 = OpLabel
+        %306 = OpAccessChain %29 %26 %27 %305
+        %307 = OpLoad %6 %306
+        %308 = OpConvertSToF %98 %307
+        %309 = OpAccessChain %232 %223 %102
+        %310 = OpLoad %98 %309
+        %311 = OpFAdd %98 %310 %308
+        %312 = OpAccessChain %232 %223 %102
+               OpStore %312 %311
+               OpBranch %304
+        %304 = OpLabel
+        %313 = OpAccessChain %232 %211 %102
+        %314 = OpLoad %98 %313
+        %315 = OpFOrdGreaterThan %58 %314 %266
+               OpSelectionMerge %317 None
+               OpBranchConditional %315 %316 %317
+        %316 = OpLabel
+        %319 = OpAccessChain %29 %26 %27 %318
+        %320 = OpLoad %6 %319
+        %321 = OpConvertSToF %98 %320
+        %322 = OpAccessChain %232 %223 %274
+        %323 = OpLoad %98 %322
+        %324 = OpFAdd %98 %323 %321
+        %325 = OpAccessChain %232 %223 %274
+               OpStore %325 %324
+               OpBranch %317
+        %317 = OpLabel
+        %327 = OpAccessChain %29 %26 %27 %326
+        %328 = OpLoad %6 %327
+        %329 = OpConvertSToF %98 %328
+        %330 = OpAccessChain %232 %223 %274
+        %331 = OpLoad %98 %330
+        %332 = OpFAdd %98 %331 %329
+        %333 = OpAccessChain %232 %223 %274
+               OpStore %333 %332
+        %334 = OpAccessChain %232 %211 %231
+        %335 = OpLoad %98 %334
+        %336 = OpAccessChain %232 %211 %102
+        %337 = OpLoad %98 %336
+        %338 = OpFSub %98 %335 %337
+        %339 = OpExtInst %98 %1 FAbs %338
+        %340 = OpFOrdLessThan %58 %339 %239
+               OpSelectionMerge %342 None
+               OpBranchConditional %340 %341 %342
+        %341 = OpLabel
+        %343 = OpAccessChain %29 %26 %27 %88
+        %344 = OpLoad %6 %343
+        %345 = OpConvertSToF %98 %344
+        %346 = OpAccessChain %232 %223 %231
+        %347 = OpLoad %98 %346
+        %348 = OpFAdd %98 %347 %345
+        %349 = OpAccessChain %232 %223 %231
+               OpStore %349 %348
+               OpBranch %342
+        %342 = OpLabel
+        %352 = OpLoad %221 %223
+        %353 = OpExtInst %221 %1 Normalize %352
+        %354 = OpCompositeExtract %98 %353 0
+        %355 = OpCompositeExtract %98 %353 1
+        %356 = OpCompositeExtract %98 %353 2
+        %357 = OpCompositeConstruct %99 %354 %355 %356 %224
+               OpStore %351 %357
+               OpReturn
+               OpFunctionEnd
+         %11 = OpFunction %2 None %8
+          %9 = OpFunctionParameter %7
+         %10 = OpFunctionParameter %7
+         %12 = OpLabel
+         %20 = OpVariable %7 Function
+         %28 = OpLoad %6 %9
+         %30 = OpAccessChain %29 %26 %27 %28
+         %31 = OpLoad %6 %30
+               OpStore %20 %31
+         %32 = OpLoad %6 %9
+         %33 = OpLoad %6 %10
+         %34 = OpAccessChain %29 %26 %27 %33
+         %35 = OpLoad %6 %34
+         %36 = OpAccessChain %29 %26 %27 %32
+               OpStore %36 %35
+         %37 = OpLoad %6 %10
+         %38 = OpLoad %6 %20
+         %39 = OpAccessChain %29 %26 %27 %37
+               OpStore %39 %38
+               OpReturn
+               OpFunctionEnd
+         %16 = OpFunction %6 None %13
+         %14 = OpFunctionParameter %7
+         %15 = OpFunctionParameter %7
+         %17 = OpLabel
+         %40 = OpVariable %7 Function
+         %44 = OpVariable %7 Function
+         %48 = OpVariable %7 Function
+         %69 = OpVariable %7 Function
+         %71 = OpVariable %7 Function
+         %78 = OpVariable %7 Function
+         %80 = OpVariable %7 Function
+         %41 = OpLoad %6 %15
+         %42 = OpAccessChain %29 %26 %27 %41
+         %43 = OpLoad %6 %42
+               OpStore %40 %43
+         %45 = OpLoad %6 %14
+         %47 = OpISub %6 %45 %46
+               OpStore %44 %47
+         %49 = OpLoad %6 %14
+               OpStore %48 %49
+               OpBranch %50
+         %50 = OpLabel
+               OpLoopMerge %52 %53 None
+               OpBranch %54
+         %54 = OpLabel
+         %55 = OpLoad %6 %48
+         %56 = OpLoad %6 %15
+         %57 = OpISub %6 %56 %46
+         %59 = OpSLessThanEqual %58 %55 %57
+               OpBranchConditional %59 %51 %52
+         %51 = OpLabel
+         %60 = OpLoad %6 %48
+         %61 = OpAccessChain %29 %26 %27 %60
+         %62 = OpLoad %6 %61
+         %63 = OpLoad %6 %40
+         %64 = OpSLessThanEqual %58 %62 %63
+               OpSelectionMerge %66 None
+               OpBranchConditional %64 %65 %66
+         %65 = OpLabel
+         %67 = OpLoad %6 %44
+         %68 = OpIAdd %6 %67 %46
+               OpStore %44 %68
+         %70 = OpLoad %6 %44
+               OpStore %69 %70
+         %72 = OpLoad %6 %48
+               OpStore %71 %72
+         %73 = OpFunctionCall %2 %11 %69 %71
+               OpBranch %66
+         %66 = OpLabel
+               OpBranch %53
+         %53 = OpLabel
+         %74 = OpLoad %6 %48
+         %75 = OpIAdd %6 %74 %46
+               OpStore %48 %75
+               OpBranch %50
+         %52 = OpLabel
+         %76 = OpLoad %6 %44
+         %77 = OpIAdd %6 %76 %46
+               OpStore %44 %77
+         %79 = OpLoad %6 %44
+               OpStore %78 %79
+         %81 = OpLoad %6 %15
+               OpStore %80 %81
+         %82 = OpFunctionCall %2 %11 %78 %80
+         %83 = OpLoad %6 %44
+               OpReturnValue %83
+               OpFunctionEnd
+         %18 = OpFunction %2 None %3
+         %19 = OpLabel
+         %86 = OpVariable %7 Function
+         %87 = OpVariable %7 Function
+         %89 = OpVariable %7 Function
+         %92 = OpVariable %91 Function
+         %97 = OpVariable %7 Function
+        %108 = OpVariable %7 Function
+        %113 = OpVariable %7 Function
+        %123 = OpVariable %7 Function
+        %148 = OpVariable %7 Function
+        %149 = OpVariable %7 Function
+        %151 = OpVariable %7 Function
+               OpStore %86 %27
+               OpStore %87 %88
+               OpStore %89 %90
+         %93 = OpLoad %6 %89
+         %94 = OpIAdd %6 %93 %46
+               OpStore %89 %94
+         %95 = OpLoad %6 %86
+         %96 = OpAccessChain %7 %92 %94
+               OpStore %96 %95
+        %104 = OpAccessChain %103 %101 %102
+        %105 = OpLoad %98 %104
+        %107 = OpFOrdGreaterThanEqual %58 %105 %106
+               OpSelectionMerge %110 None
+               OpBranchConditional %107 %109 %121
+        %109 = OpLabel
+        %111 = OpLoad %6 %87
+               OpSelectionMerge %115 None
+               OpBranchConditional %112 %114 %116
+        %114 = OpLabel
+               OpStore %113 %46
+               OpBranch %115
+        %116 = OpLabel
+        %117 = OpLoad %6 %87
+        %118 = OpShiftLeftLogical %6 %117 %27
+               OpStore %113 %118
+               OpBranch %115
+        %115 = OpLabel
+        %119 = OpLoad %6 %113
+        %120 = OpBitwiseOr %6 %111 %119
+               OpStore %108 %120
+               OpBranch %110
+        %121 = OpLabel
+               OpStore %108 %46
+               OpBranch %110
+        %110 = OpLabel
+        %122 = OpLoad %6 %108
+               OpStore %97 %122
+        %124 = OpLoad %6 %87
+        %125 = OpLoad %6 %87
+        %126 = OpLoad %6 %97
+        %127 = OpExtInst %6 %1 SClamp %124 %125 %126
+               OpStore %123 %127
+        %128 = OpLoad %6 %89
+        %129 = OpIAdd %6 %128 %46
+               OpStore %89 %129
+        %130 = OpLoad %6 %123
+        %131 = OpSDiv %6 %130 %46
+        %132 = OpAccessChain %7 %92 %129
+               OpStore %132 %131
+               OpBranch %133
+        %133 = OpLabel
+               OpLoopMerge %135 %136 None
+               OpBranch %137
+        %137 = OpLabel
+        %138 = OpLoad %6 %89
+        %139 = OpSGreaterThanEqual %58 %138 %27
+               OpBranchConditional %139 %134 %135
+        %134 = OpLabel
+        %140 = OpLoad %6 %89
+        %141 = OpISub %6 %140 %46
+               OpStore %89 %141
+        %142 = OpAccessChain %7 %92 %140
+        %143 = OpLoad %6 %142
+               OpStore %87 %143
+        %144 = OpLoad %6 %89
+        %145 = OpISub %6 %144 %46
+               OpStore %89 %145
+        %146 = OpAccessChain %7 %92 %144
+        %147 = OpLoad %6 %146
+               OpStore %86 %147
+        %150 = OpLoad %6 %86
+               OpStore %149 %150
+        %152 = OpLoad %6 %87
+               OpStore %151 %152
+        %153 = OpFunctionCall %6 %16 %149 %151
+               OpStore %148 %153
+        %154 = OpLoad %6 %148
+        %155 = OpISub %6 %154 %46
+        %156 = OpLoad %6 %86
+        %157 = OpSGreaterThan %58 %155 %156
+               OpSelectionMerge %159 None
+               OpBranchConditional %157 %158 %159
+        %158 = OpLabel
+        %160 = OpLoad %6 %89
+        %161 = OpIAdd %6 %160 %46
+               OpStore %89 %161
+        %162 = OpLoad %6 %86
+        %163 = OpAccessChain %7 %92 %161
+               OpStore %163 %162
+        %164 = OpLoad %6 %89
+        %165 = OpIAdd %6 %164 %46
+               OpStore %89 %165
+        %166 = OpLoad %6 %148
+        %167 = OpISub %6 %166 %46
+        %168 = OpAccessChain %7 %92 %165
+               OpStore %168 %167
+               OpBranch %159
+        %159 = OpLabel
+        %169 = OpLoad %6 %148
+        %170 = OpIAdd %6 %169 %46
+        %171 = OpLoad %6 %87
+        %172 = OpSLessThan %58 %170 %171
+               OpSelectionMerge %174 None
+               OpBranchConditional %172 %173 %174
+        %173 = OpLabel
+        %175 = OpLoad %6 %89
+        %176 = OpIAdd %6 %175 %46
+               OpStore %89 %176
+        %177 = OpLoad %6 %148
+        %178 = OpIAdd %6 %177 %46
+        %179 = OpAccessChain %7 %92 %176
+               OpStore %179 %178
+        %180 = OpLoad %6 %89
+        %181 = OpIAdd %6 %180 %46
+               OpStore %89 %181
+        %182 = OpLoad %6 %87
+        %183 = OpAccessChain %7 %92 %181
+               OpStore %183 %182
+               OpBranch %174
+        %174 = OpLabel
+               OpBranch %136
+        %136 = OpLabel
+               OpBranch %133
+        %135 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# resolution
+BUFFER variant_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_resolution 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 256 256
+
+EXPECT reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-clamp-conditional-mix.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-clamp-conditional-mix.amber
new file mode 100644 (file)
index 0000000..58333ba
--- /dev/null
@@ -0,0 +1,745 @@
+#!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 mix conditional in a clamp
+
+# The test passes because both shaders render the same image.
+
+# Optimized using spirv-opt with the following arguments:
+# '--vector-dce'
+# '--simplify-instructions'
+# '--redundancy-elimination'
+# '--ccp'
+# '--vector-dce'
+# spirv-opt commit hash: b78f4b1518e0052491f4e7e01ace4ee915cb5de2
+
+
+
+SHADER vertex reference_vertex_shader PASSTHROUGH
+
+# reference_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#   vec2 resolution;
+# };
+# float cross2d(vec2 a, vec2 b)
+# {
+#   return ((a.x) * (b.y) - (b.x) * (a.y));
+# }
+# int pointInTriangle(vec2 p, vec2 a, vec2 b, vec2 c)
+# {
+#   float pab = cross2d(vec2(p.x - a.x, p.y - a.y), vec2(b.x - a.x, b.y - a.y));
+#   float pbc = cross2d(vec2(p.x - b.x, p.y - b.y), vec2(c.x - b.x, c.y - b.y));
+#   if (!((pab < 0.0 && pbc < 0.0) || (pab >= 0.0 && pbc >= 0.0)))
+#   {
+#     return 0;
+#   }
+#   float pca = cross2d(vec2(p.x - c.x, p.y - c.y), vec2(a.x - c.x, a.y - c.y));
+#   if (!((pab < 0.0 && pca < 0.0) || (pab >= 0.0 && pca >= 0.0)))
+#   {
+#     return 0;
+#   }
+#   return 1;
+# }
+# void main()
+# {
+#   vec2 pos = gl_FragCoord.xy / resolution;
+#   if (pointInTriangle(pos, vec2(0.7, 0.3), vec2(0.5, 0.9), vec2(0.1, 0.4)) == 1)
+#   {
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#   }
+#   else
+#   {
+#     _GLF_color = vec4(0.0, 0.0, 0.0, 1.0);
+#   }
+# }
+SHADER fragment reference_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 196
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %162 %191
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %12 "cross2d(vf2;vf2;"
+               OpName %10 "a"
+               OpName %11 "b"
+               OpName %20 "pointInTriangle(vf2;vf2;vf2;vf2;"
+               OpName %16 "p"
+               OpName %17 "a"
+               OpName %18 "b"
+               OpName %19 "c"
+               OpName %39 "pab"
+               OpName %62 "param"
+               OpName %63 "param"
+               OpName %65 "pbc"
+               OpName %88 "param"
+               OpName %89 "param"
+               OpName %112 "pca"
+               OpName %135 "param"
+               OpName %136 "param"
+               OpName %159 "pos"
+               OpName %162 "gl_FragCoord"
+               OpName %165 "buf0"
+               OpMemberName %165 0 "resolution"
+               OpName %167 ""
+               OpName %181 "param"
+               OpName %183 "param"
+               OpName %184 "param"
+               OpName %185 "param"
+               OpName %191 "_GLF_color"
+               OpDecorate %162 BuiltIn FragCoord
+               OpMemberDecorate %165 0 Offset 0
+               OpDecorate %165 Block
+               OpDecorate %167 DescriptorSet 0
+               OpDecorate %167 Binding 0
+               OpDecorate %191 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypePointer Function %7
+          %9 = OpTypeFunction %6 %8 %8
+         %14 = OpTypeInt 32 1
+         %15 = OpTypeFunction %14 %8 %8 %8 %8
+         %22 = OpTypeInt 32 0
+         %23 = OpConstant %22 0
+         %24 = OpTypePointer Function %6
+         %27 = OpConstant %22 1
+         %91 = OpTypeBool
+         %93 = OpConstant %6 0
+        %110 = OpConstant %14 0
+        %156 = OpConstant %14 1
+        %160 = OpTypeVector %6 4
+        %161 = OpTypePointer Input %160
+        %162 = OpVariable %161 Input
+        %165 = OpTypeStruct %7
+        %166 = OpTypePointer Uniform %165
+        %167 = OpVariable %166 Uniform
+        %168 = OpTypePointer Uniform %7
+        %172 = OpConstant %6 0.699999988
+        %173 = OpConstant %6 0.300000012
+        %174 = OpConstantComposite %7 %172 %173
+        %175 = OpConstant %6 0.5
+        %176 = OpConstant %6 0.899999976
+        %177 = OpConstantComposite %7 %175 %176
+        %178 = OpConstant %6 0.100000001
+        %179 = OpConstant %6 0.400000006
+        %180 = OpConstantComposite %7 %178 %179
+        %190 = OpTypePointer Output %160
+        %191 = OpVariable %190 Output
+        %192 = OpConstant %6 1
+        %193 = OpConstantComposite %160 %192 %93 %93 %192
+        %195 = OpConstantComposite %160 %93 %93 %93 %192
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %159 = OpVariable %8 Function
+        %181 = OpVariable %8 Function
+        %183 = OpVariable %8 Function
+        %184 = OpVariable %8 Function
+        %185 = OpVariable %8 Function
+        %163 = OpLoad %160 %162
+        %164 = OpVectorShuffle %7 %163 %163 0 1
+        %169 = OpAccessChain %168 %167 %110
+        %170 = OpLoad %7 %169
+        %171 = OpFDiv %7 %164 %170
+               OpStore %159 %171
+        %182 = OpLoad %7 %159
+               OpStore %181 %182
+               OpStore %183 %174
+               OpStore %184 %177
+               OpStore %185 %180
+        %186 = OpFunctionCall %14 %20 %181 %183 %184 %185
+        %187 = OpIEqual %91 %186 %156
+               OpSelectionMerge %189 None
+               OpBranchConditional %187 %188 %194
+        %188 = OpLabel
+               OpStore %191 %193
+               OpBranch %189
+        %194 = OpLabel
+               OpStore %191 %195
+               OpBranch %189
+        %189 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %12 = OpFunction %6 None %9
+         %10 = OpFunctionParameter %8
+         %11 = OpFunctionParameter %8
+         %13 = OpLabel
+         %25 = OpAccessChain %24 %10 %23
+         %26 = OpLoad %6 %25
+         %28 = OpAccessChain %24 %11 %27
+         %29 = OpLoad %6 %28
+         %30 = OpFMul %6 %26 %29
+         %31 = OpAccessChain %24 %11 %23
+         %32 = OpLoad %6 %31
+         %33 = OpAccessChain %24 %10 %27
+         %34 = OpLoad %6 %33
+         %35 = OpFMul %6 %32 %34
+         %36 = OpFSub %6 %30 %35
+               OpReturnValue %36
+               OpFunctionEnd
+         %20 = OpFunction %14 None %15
+         %16 = OpFunctionParameter %8
+         %17 = OpFunctionParameter %8
+         %18 = OpFunctionParameter %8
+         %19 = OpFunctionParameter %8
+         %21 = OpLabel
+         %39 = OpVariable %24 Function
+         %62 = OpVariable %8 Function
+         %63 = OpVariable %8 Function
+         %65 = OpVariable %24 Function
+         %88 = OpVariable %8 Function
+         %89 = OpVariable %8 Function
+        %112 = OpVariable %24 Function
+        %135 = OpVariable %8 Function
+        %136 = OpVariable %8 Function
+         %40 = OpAccessChain %24 %16 %23
+         %41 = OpLoad %6 %40
+         %42 = OpAccessChain %24 %17 %23
+         %43 = OpLoad %6 %42
+         %44 = OpFSub %6 %41 %43
+         %45 = OpAccessChain %24 %16 %27
+         %46 = OpLoad %6 %45
+         %47 = OpAccessChain %24 %17 %27
+         %48 = OpLoad %6 %47
+         %49 = OpFSub %6 %46 %48
+         %50 = OpCompositeConstruct %7 %44 %49
+         %51 = OpAccessChain %24 %18 %23
+         %52 = OpLoad %6 %51
+         %54 = OpLoad %6 %42
+         %55 = OpFSub %6 %52 %54
+         %56 = OpAccessChain %24 %18 %27
+         %57 = OpLoad %6 %56
+         %59 = OpLoad %6 %47
+         %60 = OpFSub %6 %57 %59
+         %61 = OpCompositeConstruct %7 %55 %60
+               OpStore %62 %50
+               OpStore %63 %61
+         %64 = OpFunctionCall %6 %12 %62 %63
+               OpStore %39 %64
+         %67 = OpLoad %6 %40
+         %69 = OpLoad %6 %51
+         %70 = OpFSub %6 %67 %69
+         %72 = OpLoad %6 %45
+         %74 = OpLoad %6 %56
+         %75 = OpFSub %6 %72 %74
+         %76 = OpCompositeConstruct %7 %70 %75
+         %77 = OpAccessChain %24 %19 %23
+         %78 = OpLoad %6 %77
+         %80 = OpLoad %6 %51
+         %81 = OpFSub %6 %78 %80
+         %82 = OpAccessChain %24 %19 %27
+         %83 = OpLoad %6 %82
+         %85 = OpLoad %6 %56
+         %86 = OpFSub %6 %83 %85
+         %87 = OpCompositeConstruct %7 %81 %86
+               OpStore %88 %76
+               OpStore %89 %87
+         %90 = OpFunctionCall %6 %12 %88 %89
+               OpStore %65 %90
+         %92 = OpLoad %6 %39
+         %94 = OpFOrdLessThan %91 %92 %93
+         %95 = OpLoad %6 %65
+         %96 = OpFOrdLessThan %91 %95 %93
+         %97 = OpLogicalAnd %91 %94 %96
+         %98 = OpLogicalNot %91 %97
+               OpSelectionMerge %100 None
+               OpBranchConditional %98 %99 %100
+         %99 = OpLabel
+        %101 = OpLoad %6 %39
+        %102 = OpFOrdGreaterThanEqual %91 %101 %93
+        %103 = OpLoad %6 %65
+        %104 = OpFOrdGreaterThanEqual %91 %103 %93
+        %105 = OpLogicalAnd %91 %102 %104
+               OpBranch %100
+        %100 = OpLabel
+        %106 = OpPhi %91 %97 %21 %105 %99
+        %107 = OpLogicalNot %91 %106
+               OpSelectionMerge %109 None
+               OpBranchConditional %107 %108 %109
+        %108 = OpLabel
+               OpReturnValue %110
+        %109 = OpLabel
+        %114 = OpLoad %6 %40
+        %116 = OpLoad %6 %77
+        %117 = OpFSub %6 %114 %116
+        %119 = OpLoad %6 %45
+        %121 = OpLoad %6 %82
+        %122 = OpFSub %6 %119 %121
+        %123 = OpCompositeConstruct %7 %117 %122
+        %125 = OpLoad %6 %42
+        %127 = OpLoad %6 %77
+        %128 = OpFSub %6 %125 %127
+        %130 = OpLoad %6 %47
+        %132 = OpLoad %6 %82
+        %133 = OpFSub %6 %130 %132
+        %134 = OpCompositeConstruct %7 %128 %133
+               OpStore %135 %123
+               OpStore %136 %134
+        %137 = OpFunctionCall %6 %12 %135 %136
+               OpStore %112 %137
+        %138 = OpLoad %6 %39
+        %139 = OpFOrdLessThan %91 %138 %93
+        %140 = OpLoad %6 %112
+        %141 = OpFOrdLessThan %91 %140 %93
+        %142 = OpLogicalAnd %91 %139 %141
+        %143 = OpLogicalNot %91 %142
+               OpSelectionMerge %145 None
+               OpBranchConditional %143 %144 %145
+        %144 = OpLabel
+        %146 = OpLoad %6 %39
+        %147 = OpFOrdGreaterThanEqual %91 %146 %93
+        %148 = OpLoad %6 %112
+        %149 = OpFOrdGreaterThanEqual %91 %148 %93
+        %150 = OpLogicalAnd %91 %147 %149
+               OpBranch %145
+        %145 = OpLabel
+        %151 = OpPhi %91 %142 %109 %150 %144
+        %152 = OpLogicalNot %91 %151
+               OpSelectionMerge %154 None
+               OpBranchConditional %152 %153 %154
+        %153 = OpLabel
+               OpReturnValue %110
+        %154 = OpLabel
+               OpReturnValue %156
+               OpFunctionEnd
+END
+
+# uniforms for reference
+
+# resolution
+BUFFER reference_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.0
+END
+
+BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics reference_pipeline
+  ATTACH reference_vertex_shader
+  ATTACH reference_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER reference_framebuffer AS color LOCATION 0
+  BIND BUFFER reference_resolution AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR reference_pipeline 0 0 0 255
+
+CLEAR reference_pipeline
+RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#   vec2 resolution;
+# };
+# float cross2d(vec2 a, vec2 b)
+# {
+#   return ((a.x) * (b.y) - (b.x) * (a.y));
+# }
+# int pointInTriangle(vec2 p, vec2 a, vec2 b, vec2 c)
+# {
+#   // var_y == c.y
+#   float var_y = (
+#                   // Always true.
+#                   (resolution.x == resolution.y) ?
+#                   // mix == vec2(c.y, c.y), so var_y == c.y.
+#                    mix(vec2(c.y, c.y), vec2(1.0, max((true ? c.y : 1.0), c.y)), bvec2(false, false)).y :
+#                   (-1.0)
+#                 );
+#   // clamp_y == c.y
+#   float clamp_y = clamp(c.y, c.y, var_y);
+#   float pab = cross2d(vec2(p.x - a.x, p.y - a.y), vec2(b.x - a.x, b.y - a.y));
+#   float pbc = cross2d(vec2(p.x - b.x, p.y - b.y), vec2(c.x - b.x, clamp_y - b.y));
+#   if (!((pab < 0.0 && pbc < 0.0) || (pab >= 0.0 && pbc >= 0.0)))
+#   {
+#     return 0;
+#   }
+#   float pca = cross2d(vec2(p.x - c.x, p.y - c.y), vec2(a.x - c.x, a.y - c.y));
+#   if (!((pab < 0.0 && pca < 0.0) || (pab >= 0.0 && pca >= 0.0)))
+#   {
+#     return 0;
+#   }
+#   return 1;
+# }
+# void main()
+# {
+#   vec2 pos = gl_FragCoord.xy / resolution;
+#   if (pointInTriangle(pos, vec2(0.7, 0.3), vec2(0.5, 0.9), vec2(0.1, 0.4)) == 1)
+#   {
+#     _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#   }
+#   else
+#   {
+#     _GLF_color = vec4(0.0, 0.0, 0.0, 1.0);
+#   }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 238
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %207 %233
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %12 "cross2d(vf2;vf2;"
+               OpName %10 "a"
+               OpName %11 "b"
+               OpName %20 "pointInTriangle(vf2;vf2;vf2;vf2;"
+               OpName %16 "p"
+               OpName %17 "a"
+               OpName %18 "b"
+               OpName %19 "c"
+               OpName %39 "var_y"
+               OpName %40 "buf0"
+               OpMemberName %40 0 "resolution"
+               OpName %42 ""
+               OpName %80 "clamp_y"
+               OpName %87 "pab"
+               OpName %110 "param"
+               OpName %111 "param"
+               OpName %113 "pbc"
+               OpName %135 "param"
+               OpName %136 "param"
+               OpName %157 "pca"
+               OpName %180 "param"
+               OpName %181 "param"
+               OpName %204 "pos"
+               OpName %207 "gl_FragCoord"
+               OpName %223 "param"
+               OpName %225 "param"
+               OpName %226 "param"
+               OpName %227 "param"
+               OpName %233 "_GLF_color"
+               OpMemberDecorate %40 0 Offset 0
+               OpDecorate %40 Block
+               OpDecorate %42 DescriptorSet 0
+               OpDecorate %42 Binding 0
+               OpDecorate %207 BuiltIn FragCoord
+               OpDecorate %233 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypePointer Function %7
+          %9 = OpTypeFunction %6 %8 %8
+         %14 = OpTypeInt 32 1
+         %15 = OpTypeFunction %14 %8 %8 %8 %8
+         %22 = OpTypeInt 32 0
+         %23 = OpConstant %22 0
+         %24 = OpTypePointer Function %6
+         %27 = OpConstant %22 1
+         %40 = OpTypeStruct %7
+         %41 = OpTypePointer Uniform %40
+         %42 = OpVariable %41 Uniform
+         %43 = OpConstant %14 0
+         %44 = OpTypePointer Uniform %6
+         %49 = OpTypeBool
+         %59 = OpConstant %6 1
+         %60 = OpConstantTrue %49
+         %72 = OpTypeVector %49 2
+         %73 = OpConstantFalse %49
+         %74 = OpConstantComposite %72 %73 %73
+         %78 = OpConstant %6 -1
+        %139 = OpConstant %6 0
+        %201 = OpConstant %14 1
+        %205 = OpTypeVector %6 4
+        %206 = OpTypePointer Input %205
+        %207 = OpVariable %206 Input
+        %210 = OpTypePointer Uniform %7
+        %214 = OpConstant %6 0.699999988
+        %215 = OpConstant %6 0.300000012
+        %216 = OpConstantComposite %7 %214 %215
+        %217 = OpConstant %6 0.5
+        %218 = OpConstant %6 0.899999976
+        %219 = OpConstantComposite %7 %217 %218
+        %220 = OpConstant %6 0.100000001
+        %221 = OpConstant %6 0.400000006
+        %222 = OpConstantComposite %7 %220 %221
+        %232 = OpTypePointer Output %205
+        %233 = OpVariable %232 Output
+        %234 = OpConstantComposite %205 %59 %139 %139 %59
+        %236 = OpConstantComposite %205 %139 %139 %139 %59
+        %237 = OpUndef %6
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %204 = OpVariable %8 Function
+        %223 = OpVariable %8 Function
+        %225 = OpVariable %8 Function
+        %226 = OpVariable %8 Function
+        %227 = OpVariable %8 Function
+        %208 = OpLoad %205 %207
+        %209 = OpVectorShuffle %7 %208 %208 0 1
+        %211 = OpAccessChain %210 %42 %43
+        %212 = OpLoad %7 %211
+        %213 = OpFDiv %7 %209 %212
+               OpStore %204 %213
+        %224 = OpLoad %7 %204
+               OpStore %223 %224
+               OpStore %225 %216
+               OpStore %226 %219
+               OpStore %227 %222
+        %228 = OpFunctionCall %14 %20 %223 %225 %226 %227
+        %229 = OpIEqual %49 %228 %201
+               OpSelectionMerge %231 None
+               OpBranchConditional %229 %230 %235
+        %230 = OpLabel
+               OpStore %233 %234
+               OpBranch %231
+        %235 = OpLabel
+               OpStore %233 %236
+               OpBranch %231
+        %231 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %12 = OpFunction %6 None %9
+         %10 = OpFunctionParameter %8
+         %11 = OpFunctionParameter %8
+         %13 = OpLabel
+         %25 = OpAccessChain %24 %10 %23
+         %26 = OpLoad %6 %25
+         %28 = OpAccessChain %24 %11 %27
+         %29 = OpLoad %6 %28
+         %30 = OpFMul %6 %26 %29
+         %31 = OpAccessChain %24 %11 %23
+         %32 = OpLoad %6 %31
+         %33 = OpAccessChain %24 %10 %27
+         %34 = OpLoad %6 %33
+         %35 = OpFMul %6 %32 %34
+         %36 = OpFSub %6 %30 %35
+               OpReturnValue %36
+               OpFunctionEnd
+         %20 = OpFunction %14 None %15
+         %16 = OpFunctionParameter %8
+         %17 = OpFunctionParameter %8
+         %18 = OpFunctionParameter %8
+         %19 = OpFunctionParameter %8
+         %21 = OpLabel
+         %39 = OpVariable %24 Function
+         %51 = OpVariable %24 Function
+         %61 = OpVariable %24 Function
+         %80 = OpVariable %24 Function
+         %87 = OpVariable %24 Function
+        %110 = OpVariable %8 Function
+        %111 = OpVariable %8 Function
+        %113 = OpVariable %24 Function
+        %135 = OpVariable %8 Function
+        %136 = OpVariable %8 Function
+        %157 = OpVariable %24 Function
+        %180 = OpVariable %8 Function
+        %181 = OpVariable %8 Function
+         %45 = OpAccessChain %44 %42 %43 %23
+         %46 = OpLoad %6 %45
+         %47 = OpAccessChain %44 %42 %43 %27
+         %48 = OpLoad %6 %47
+         %50 = OpFOrdEqual %49 %46 %48
+               OpSelectionMerge %53 None
+               OpBranchConditional %50 %52 %77
+         %52 = OpLabel
+         %54 = OpAccessChain %24 %19 %27
+         %57 = OpLoad %6 %54
+         %58 = OpCompositeConstruct %7 %237 %57
+               OpSelectionMerge %63 None
+               OpBranchConditional %60 %62 %66
+         %62 = OpLabel
+         %65 = OpLoad %6 %54
+               OpStore %61 %65
+               OpBranch %63
+         %66 = OpLabel
+               OpStore %61 %59
+               OpBranch %63
+         %63 = OpLabel
+         %67 = OpLoad %6 %61
+         %69 = OpLoad %6 %54
+         %70 = OpExtInst %6 %1 FMax %67 %69
+         %71 = OpCompositeConstruct %7 %59 %70
+         %75 = OpVectorShuffle %7 %71 %58 2 3
+               OpStore %51 %57
+               OpBranch %53
+         %77 = OpLabel
+               OpStore %51 %78
+               OpBranch %53
+         %53 = OpLabel
+         %79 = OpLoad %6 %51
+               OpStore %39 %79
+         %81 = OpAccessChain %24 %19 %27
+         %82 = OpLoad %6 %81
+         %84 = OpLoad %6 %81
+         %85 = OpLoad %6 %39
+         %86 = OpExtInst %6 %1 FClamp %82 %84 %85
+               OpStore %80 %86
+         %88 = OpAccessChain %24 %16 %23
+         %89 = OpLoad %6 %88
+         %90 = OpAccessChain %24 %17 %23
+         %91 = OpLoad %6 %90
+         %92 = OpFSub %6 %89 %91
+         %93 = OpAccessChain %24 %16 %27
+         %94 = OpLoad %6 %93
+         %95 = OpAccessChain %24 %17 %27
+         %96 = OpLoad %6 %95
+         %97 = OpFSub %6 %94 %96
+         %98 = OpCompositeConstruct %7 %92 %97
+         %99 = OpAccessChain %24 %18 %23
+        %100 = OpLoad %6 %99
+        %102 = OpLoad %6 %90
+        %103 = OpFSub %6 %100 %102
+        %104 = OpAccessChain %24 %18 %27
+        %105 = OpLoad %6 %104
+        %107 = OpLoad %6 %95
+        %108 = OpFSub %6 %105 %107
+        %109 = OpCompositeConstruct %7 %103 %108
+               OpStore %110 %98
+               OpStore %111 %109
+        %112 = OpFunctionCall %6 %12 %110 %111
+               OpStore %87 %112
+        %115 = OpLoad %6 %88
+        %117 = OpLoad %6 %99
+        %118 = OpFSub %6 %115 %117
+        %120 = OpLoad %6 %93
+        %122 = OpLoad %6 %104
+        %123 = OpFSub %6 %120 %122
+        %124 = OpCompositeConstruct %7 %118 %123
+        %125 = OpAccessChain %24 %19 %23
+        %126 = OpLoad %6 %125
+        %128 = OpLoad %6 %99
+        %129 = OpFSub %6 %126 %128
+        %130 = OpLoad %6 %80
+        %132 = OpLoad %6 %104
+        %133 = OpFSub %6 %130 %132
+        %134 = OpCompositeConstruct %7 %129 %133
+               OpStore %135 %124
+               OpStore %136 %134
+        %137 = OpFunctionCall %6 %12 %135 %136
+               OpStore %113 %137
+        %138 = OpLoad %6 %87
+        %140 = OpFOrdLessThan %49 %138 %139
+        %141 = OpLoad %6 %113
+        %142 = OpFOrdLessThan %49 %141 %139
+        %143 = OpLogicalAnd %49 %140 %142
+        %144 = OpLogicalNot %49 %143
+               OpSelectionMerge %146 None
+               OpBranchConditional %144 %145 %146
+        %145 = OpLabel
+        %147 = OpLoad %6 %87
+        %148 = OpFOrdGreaterThanEqual %49 %147 %139
+        %149 = OpLoad %6 %113
+        %150 = OpFOrdGreaterThanEqual %49 %149 %139
+        %151 = OpLogicalAnd %49 %148 %150
+               OpBranch %146
+        %146 = OpLabel
+        %152 = OpPhi %49 %143 %53 %151 %145
+        %153 = OpLogicalNot %49 %152
+               OpSelectionMerge %155 None
+               OpBranchConditional %153 %154 %155
+        %154 = OpLabel
+               OpReturnValue %43
+        %155 = OpLabel
+        %159 = OpLoad %6 %88
+        %161 = OpLoad %6 %125
+        %162 = OpFSub %6 %159 %161
+        %164 = OpLoad %6 %93
+        %166 = OpLoad %6 %81
+        %167 = OpFSub %6 %164 %166
+        %168 = OpCompositeConstruct %7 %162 %167
+        %170 = OpLoad %6 %90
+        %172 = OpLoad %6 %125
+        %173 = OpFSub %6 %170 %172
+        %175 = OpLoad %6 %95
+        %177 = OpLoad %6 %81
+        %178 = OpFSub %6 %175 %177
+        %179 = OpCompositeConstruct %7 %173 %178
+               OpStore %180 %168
+               OpStore %181 %179
+        %182 = OpFunctionCall %6 %12 %180 %181
+               OpStore %157 %182
+        %183 = OpLoad %6 %87
+        %184 = OpFOrdLessThan %49 %183 %139
+        %185 = OpLoad %6 %157
+        %186 = OpFOrdLessThan %49 %185 %139
+        %187 = OpLogicalAnd %49 %184 %186
+        %188 = OpLogicalNot %49 %187
+               OpSelectionMerge %190 None
+               OpBranchConditional %188 %189 %190
+        %189 = OpLabel
+        %191 = OpLoad %6 %87
+        %192 = OpFOrdGreaterThanEqual %49 %191 %139
+        %193 = OpLoad %6 %157
+        %194 = OpFOrdGreaterThanEqual %49 %193 %139
+        %195 = OpLogicalAnd %49 %192 %194
+               OpBranch %190
+        %190 = OpLabel
+        %196 = OpPhi %49 %187 %155 %195 %189
+        %197 = OpLogicalNot %49 %196
+               OpSelectionMerge %199 None
+               OpBranchConditional %197 %198 %199
+        %198 = OpLabel
+               OpReturnValue %43
+        %199 = OpLabel
+               OpReturnValue %201
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# resolution
+BUFFER variant_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_resolution 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 256 256
+
+EXPECT reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-nested-conditional-clamped-float.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/stable-triangle-nested-conditional-clamped-float.amber
new file mode 100644 (file)
index 0000000..9744af2
--- /dev/null
@@ -0,0 +1,766 @@
+#!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 nested conditional float in clamp
+
+# The test passes because both shaders render the same imgae.
+
+SHADER vertex reference_vertex_shader PASSTHROUGH
+
+# reference_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 resolution;
+# };
+# float cross2d(vec2 a, vec2 b)
+# {
+#     return ((a.x) * (b.y) - (b.x) * (a.y));
+# }
+# int pointInTriangle(vec2 p, vec2 a, vec2 b, vec2 c)
+# {
+#     float pab = cross2d(vec2(p.x - a.x, p.y - a.y), vec2(b.x - a.x, b.y - a.y));
+#     float pbc = cross2d(vec2(p.x - b.x, p.y - b.y), vec2(c.x - b.x, c.y - b.y));
+#     if (!((pab < 0.0 && pbc < 0.0) || (pab >= 0.0 && pbc >= 0.0)))
+#     {
+#         return 0;
+#     }
+#     float pca = cross2d(vec2(p.x - c.x, p.y - c.y), vec2(a.x - c.x, a.y - c.y));
+#     if (!((pab < 0.0 && pca < 0.0) || (pab >= 0.0 && pca >= 0.0)))
+#     {
+#         return 0;
+#     }
+#     return 1;
+# }
+# void main()
+# {
+#     vec2 pos = gl_FragCoord.xy / resolution;
+#     if (pointInTriangle(pos, vec2(0.7, 0.3), vec2(0.5, 0.9), vec2(0.1, 0.4)) == 1)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(0.0, 0.0, 0.0, 1.0);
+#     }
+# }
+SHADER fragment reference_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 196
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %162 %191
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %12 "cross2d(vf2;vf2;"
+               OpName %10 "a"
+               OpName %11 "b"
+               OpName %20 "pointInTriangle(vf2;vf2;vf2;vf2;"
+               OpName %16 "p"
+               OpName %17 "a"
+               OpName %18 "b"
+               OpName %19 "c"
+               OpName %39 "pab"
+               OpName %62 "param"
+               OpName %63 "param"
+               OpName %65 "pbc"
+               OpName %88 "param"
+               OpName %89 "param"
+               OpName %112 "pca"
+               OpName %135 "param"
+               OpName %136 "param"
+               OpName %159 "pos"
+               OpName %162 "gl_FragCoord"
+               OpName %165 "buf0"
+               OpMemberName %165 0 "resolution"
+               OpName %167 ""
+               OpName %181 "param"
+               OpName %183 "param"
+               OpName %184 "param"
+               OpName %185 "param"
+               OpName %191 "_GLF_color"
+               OpDecorate %162 BuiltIn FragCoord
+               OpMemberDecorate %165 0 Offset 0
+               OpDecorate %165 Block
+               OpDecorate %167 DescriptorSet 0
+               OpDecorate %167 Binding 0
+               OpDecorate %191 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypePointer Function %7
+          %9 = OpTypeFunction %6 %8 %8
+         %14 = OpTypeInt 32 1
+         %15 = OpTypeFunction %14 %8 %8 %8 %8
+         %22 = OpTypeInt 32 0
+         %23 = OpConstant %22 0
+         %24 = OpTypePointer Function %6
+         %27 = OpConstant %22 1
+         %91 = OpTypeBool
+         %93 = OpConstant %6 0
+        %110 = OpConstant %14 0
+        %156 = OpConstant %14 1
+        %160 = OpTypeVector %6 4
+        %161 = OpTypePointer Input %160
+        %162 = OpVariable %161 Input
+        %165 = OpTypeStruct %7
+        %166 = OpTypePointer Uniform %165
+        %167 = OpVariable %166 Uniform
+        %168 = OpTypePointer Uniform %7
+        %172 = OpConstant %6 0.699999988
+        %173 = OpConstant %6 0.300000012
+        %174 = OpConstantComposite %7 %172 %173
+        %175 = OpConstant %6 0.5
+        %176 = OpConstant %6 0.899999976
+        %177 = OpConstantComposite %7 %175 %176
+        %178 = OpConstant %6 0.100000001
+        %179 = OpConstant %6 0.400000006
+        %180 = OpConstantComposite %7 %178 %179
+        %190 = OpTypePointer Output %160
+        %191 = OpVariable %190 Output
+        %192 = OpConstant %6 1
+        %193 = OpConstantComposite %160 %192 %93 %93 %192
+        %195 = OpConstantComposite %160 %93 %93 %93 %192
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %159 = OpVariable %8 Function
+        %181 = OpVariable %8 Function
+        %183 = OpVariable %8 Function
+        %184 = OpVariable %8 Function
+        %185 = OpVariable %8 Function
+        %163 = OpLoad %160 %162
+        %164 = OpVectorShuffle %7 %163 %163 0 1
+        %169 = OpAccessChain %168 %167 %110
+        %170 = OpLoad %7 %169
+        %171 = OpFDiv %7 %164 %170
+               OpStore %159 %171
+        %182 = OpLoad %7 %159
+               OpStore %181 %182
+               OpStore %183 %174
+               OpStore %184 %177
+               OpStore %185 %180
+        %186 = OpFunctionCall %14 %20 %181 %183 %184 %185
+        %187 = OpIEqual %91 %186 %156
+               OpSelectionMerge %189 None
+               OpBranchConditional %187 %188 %194
+        %188 = OpLabel
+               OpStore %191 %193
+               OpBranch %189
+        %194 = OpLabel
+               OpStore %191 %195
+               OpBranch %189
+        %189 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %12 = OpFunction %6 None %9
+         %10 = OpFunctionParameter %8
+         %11 = OpFunctionParameter %8
+         %13 = OpLabel
+         %25 = OpAccessChain %24 %10 %23
+         %26 = OpLoad %6 %25
+         %28 = OpAccessChain %24 %11 %27
+         %29 = OpLoad %6 %28
+         %30 = OpFMul %6 %26 %29
+         %31 = OpAccessChain %24 %11 %23
+         %32 = OpLoad %6 %31
+         %33 = OpAccessChain %24 %10 %27
+         %34 = OpLoad %6 %33
+         %35 = OpFMul %6 %32 %34
+         %36 = OpFSub %6 %30 %35
+               OpReturnValue %36
+               OpFunctionEnd
+         %20 = OpFunction %14 None %15
+         %16 = OpFunctionParameter %8
+         %17 = OpFunctionParameter %8
+         %18 = OpFunctionParameter %8
+         %19 = OpFunctionParameter %8
+         %21 = OpLabel
+         %39 = OpVariable %24 Function
+         %62 = OpVariable %8 Function
+         %63 = OpVariable %8 Function
+         %65 = OpVariable %24 Function
+         %88 = OpVariable %8 Function
+         %89 = OpVariable %8 Function
+        %112 = OpVariable %24 Function
+        %135 = OpVariable %8 Function
+        %136 = OpVariable %8 Function
+         %40 = OpAccessChain %24 %16 %23
+         %41 = OpLoad %6 %40
+         %42 = OpAccessChain %24 %17 %23
+         %43 = OpLoad %6 %42
+         %44 = OpFSub %6 %41 %43
+         %45 = OpAccessChain %24 %16 %27
+         %46 = OpLoad %6 %45
+         %47 = OpAccessChain %24 %17 %27
+         %48 = OpLoad %6 %47
+         %49 = OpFSub %6 %46 %48
+         %50 = OpCompositeConstruct %7 %44 %49
+         %51 = OpAccessChain %24 %18 %23
+         %52 = OpLoad %6 %51
+         %53 = OpAccessChain %24 %17 %23
+         %54 = OpLoad %6 %53
+         %55 = OpFSub %6 %52 %54
+         %56 = OpAccessChain %24 %18 %27
+         %57 = OpLoad %6 %56
+         %58 = OpAccessChain %24 %17 %27
+         %59 = OpLoad %6 %58
+         %60 = OpFSub %6 %57 %59
+         %61 = OpCompositeConstruct %7 %55 %60
+               OpStore %62 %50
+               OpStore %63 %61
+         %64 = OpFunctionCall %6 %12 %62 %63
+               OpStore %39 %64
+         %66 = OpAccessChain %24 %16 %23
+         %67 = OpLoad %6 %66
+         %68 = OpAccessChain %24 %18 %23
+         %69 = OpLoad %6 %68
+         %70 = OpFSub %6 %67 %69
+         %71 = OpAccessChain %24 %16 %27
+         %72 = OpLoad %6 %71
+         %73 = OpAccessChain %24 %18 %27
+         %74 = OpLoad %6 %73
+         %75 = OpFSub %6 %72 %74
+         %76 = OpCompositeConstruct %7 %70 %75
+         %77 = OpAccessChain %24 %19 %23
+         %78 = OpLoad %6 %77
+         %79 = OpAccessChain %24 %18 %23
+         %80 = OpLoad %6 %79
+         %81 = OpFSub %6 %78 %80
+         %82 = OpAccessChain %24 %19 %27
+         %83 = OpLoad %6 %82
+         %84 = OpAccessChain %24 %18 %27
+         %85 = OpLoad %6 %84
+         %86 = OpFSub %6 %83 %85
+         %87 = OpCompositeConstruct %7 %81 %86
+               OpStore %88 %76
+               OpStore %89 %87
+         %90 = OpFunctionCall %6 %12 %88 %89
+               OpStore %65 %90
+         %92 = OpLoad %6 %39
+         %94 = OpFOrdLessThan %91 %92 %93
+         %95 = OpLoad %6 %65
+         %96 = OpFOrdLessThan %91 %95 %93
+         %97 = OpLogicalAnd %91 %94 %96
+         %98 = OpLogicalNot %91 %97
+               OpSelectionMerge %100 None
+               OpBranchConditional %98 %99 %100
+         %99 = OpLabel
+        %101 = OpLoad %6 %39
+        %102 = OpFOrdGreaterThanEqual %91 %101 %93
+        %103 = OpLoad %6 %65
+        %104 = OpFOrdGreaterThanEqual %91 %103 %93
+        %105 = OpLogicalAnd %91 %102 %104
+               OpBranch %100
+        %100 = OpLabel
+        %106 = OpPhi %91 %97 %21 %105 %99
+        %107 = OpLogicalNot %91 %106
+               OpSelectionMerge %109 None
+               OpBranchConditional %107 %108 %109
+        %108 = OpLabel
+               OpReturnValue %110
+        %109 = OpLabel
+        %113 = OpAccessChain %24 %16 %23
+        %114 = OpLoad %6 %113
+        %115 = OpAccessChain %24 %19 %23
+        %116 = OpLoad %6 %115
+        %117 = OpFSub %6 %114 %116
+        %118 = OpAccessChain %24 %16 %27
+        %119 = OpLoad %6 %118
+        %120 = OpAccessChain %24 %19 %27
+        %121 = OpLoad %6 %120
+        %122 = OpFSub %6 %119 %121
+        %123 = OpCompositeConstruct %7 %117 %122
+        %124 = OpAccessChain %24 %17 %23
+        %125 = OpLoad %6 %124
+        %126 = OpAccessChain %24 %19 %23
+        %127 = OpLoad %6 %126
+        %128 = OpFSub %6 %125 %127
+        %129 = OpAccessChain %24 %17 %27
+        %130 = OpLoad %6 %129
+        %131 = OpAccessChain %24 %19 %27
+        %132 = OpLoad %6 %131
+        %133 = OpFSub %6 %130 %132
+        %134 = OpCompositeConstruct %7 %128 %133
+               OpStore %135 %123
+               OpStore %136 %134
+        %137 = OpFunctionCall %6 %12 %135 %136
+               OpStore %112 %137
+        %138 = OpLoad %6 %39
+        %139 = OpFOrdLessThan %91 %138 %93
+        %140 = OpLoad %6 %112
+        %141 = OpFOrdLessThan %91 %140 %93
+        %142 = OpLogicalAnd %91 %139 %141
+        %143 = OpLogicalNot %91 %142
+               OpSelectionMerge %145 None
+               OpBranchConditional %143 %144 %145
+        %144 = OpLabel
+        %146 = OpLoad %6 %39
+        %147 = OpFOrdGreaterThanEqual %91 %146 %93
+        %148 = OpLoad %6 %112
+        %149 = OpFOrdGreaterThanEqual %91 %148 %93
+        %150 = OpLogicalAnd %91 %147 %149
+               OpBranch %145
+        %145 = OpLabel
+        %151 = OpPhi %91 %142 %109 %150 %144
+        %152 = OpLogicalNot %91 %151
+               OpSelectionMerge %154 None
+               OpBranchConditional %152 %153 %154
+        %153 = OpLabel
+               OpReturnValue %110
+        %154 = OpLabel
+               OpReturnValue %156
+               OpFunctionEnd
+END
+
+# uniforms for reference
+
+# resolution
+BUFFER reference_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.0
+END
+
+BUFFER reference_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics reference_pipeline
+  ATTACH reference_vertex_shader
+  ATTACH reference_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER reference_framebuffer AS color LOCATION 0
+  BIND BUFFER reference_resolution AS uniform DESCRIPTOR_SET 0 BINDING 0
+END
+CLEAR_COLOR reference_pipeline 0 0 0 255
+
+CLEAR reference_pipeline
+RUN reference_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(push_constant) uniform buf_push
+# {
+#     vec2 injectionSwitch;   // x == 0.0, y == 1.0
+# };
+# layout(location = 0) out vec4 _GLF_color;
+#
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 resolution;
+# };
+# float cross2d(vec2 a, vec2 b)
+# {
+#     return ((a.x) * (b.y) - (b.x) * (a.y));
+# }
+# int pointInTriangle(vec2 p, vec2 a, vec2 b, vec2 c)
+# {
+#     float pab = cross2d(vec2(p.x - a.x, p.y - a.y), vec2(b.x - a.x, b.y - a.y));
+#     float pbc = cross2d(vec2(p.x - b.x, p.y - b.y), vec2(c.x - b.x, c.y - b.y));
+#     if (!((pab < 0.0 && pbc < 0.0) || (pab >= 0.0 && pbc >= 0.0)))
+#     {
+#         return 0;
+#     }
+#     float pca = cross2d(vec2(p.x - c.x, p.y - c.y), vec2(a.x - c.x, a.y - c.y));
+#     if (!((pab < 0.0 && pca < 0.0) || (pab >= 0.0 && pca >= 0.0)))
+#     {
+#         return 0;
+#     }
+#     return 1;
+# }
+# void main()
+# {
+#     // float_b == 0.4
+#     float float_b = ((gl_FragCoord.x >= 0.0) ? (true ? 0.4 : (float(injectionSwitch.y))) : (-1.0));
+#     // float_a == 0.4
+#     float float_a = (float(clamp(0.4, 0.4, float_b)));
+#     vec2 pos = gl_FragCoord.xy / resolution;
+#     if ((pointInTriangle(pos, vec2(0.7, 0.3), vec2(0.5, 0.9), vec2(0.1, float_a))) == 1)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(0.0, 0.0, 0.0, 1.0);
+#     }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 223
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %162 %218
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %12 "cross2d(vf2;vf2;"
+               OpName %10 "a"
+               OpName %11 "b"
+               OpName %20 "pointInTriangle(vf2;vf2;vf2;vf2;"
+               OpName %16 "p"
+               OpName %17 "a"
+               OpName %18 "b"
+               OpName %19 "c"
+               OpName %39 "pab"
+               OpName %62 "param"
+               OpName %63 "param"
+               OpName %65 "pbc"
+               OpName %88 "param"
+               OpName %89 "param"
+               OpName %112 "pca"
+               OpName %135 "param"
+               OpName %136 "param"
+               OpName %159 "float_b"
+               OpName %162 "gl_FragCoord"
+               OpName %176 "buf_push"
+               OpMemberName %176 0 "injectionSwitch"
+               OpName %178 ""
+               OpName %186 "float_a"
+               OpName %189 "pos"
+               OpName %192 "buf0"
+               OpMemberName %192 0 "resolution"
+               OpName %194 ""
+               OpName %208 "param"
+               OpName %210 "param"
+               OpName %211 "param"
+               OpName %212 "param"
+               OpName %218 "_GLF_color"
+               OpDecorate %162 BuiltIn FragCoord
+               OpMemberDecorate %176 0 Offset 0
+               OpDecorate %176 Block
+               OpMemberDecorate %192 0 Offset 0
+               OpDecorate %192 Block
+               OpDecorate %194 DescriptorSet 0
+               OpDecorate %194 Binding 0
+               OpDecorate %218 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeVector %6 2
+          %8 = OpTypePointer Function %7
+          %9 = OpTypeFunction %6 %8 %8
+         %14 = OpTypeInt 32 1
+         %15 = OpTypeFunction %14 %8 %8 %8 %8
+         %22 = OpTypeInt 32 0
+         %23 = OpConstant %22 0
+         %24 = OpTypePointer Function %6
+         %27 = OpConstant %22 1
+         %91 = OpTypeBool
+         %93 = OpConstant %6 0
+        %110 = OpConstant %14 0
+        %156 = OpConstant %14 1
+        %160 = OpTypeVector %6 4
+        %161 = OpTypePointer Input %160
+        %162 = OpVariable %161 Input
+        %163 = OpTypePointer Input %6
+        %170 = OpConstantTrue %91
+        %174 = OpConstant %6 0.400000006
+        %176 = OpTypeStruct %7
+        %177 = OpTypePointer PushConstant %176
+        %178 = OpVariable %177 PushConstant
+        %179 = OpTypePointer PushConstant %6
+        %184 = OpConstant %6 -1
+        %192 = OpTypeStruct %7
+        %193 = OpTypePointer Uniform %192
+        %194 = OpVariable %193 Uniform
+        %195 = OpTypePointer Uniform %7
+        %199 = OpConstant %6 0.699999988
+        %200 = OpConstant %6 0.300000012
+        %201 = OpConstantComposite %7 %199 %200
+        %202 = OpConstant %6 0.5
+        %203 = OpConstant %6 0.899999976
+        %204 = OpConstantComposite %7 %202 %203
+        %205 = OpConstant %6 0.100000001
+        %217 = OpTypePointer Output %160
+        %218 = OpVariable %217 Output
+        %219 = OpConstant %6 1
+        %220 = OpConstantComposite %160 %219 %93 %93 %219
+        %222 = OpConstantComposite %160 %93 %93 %93 %219
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+        %159 = OpVariable %24 Function
+        %167 = OpVariable %24 Function
+        %171 = OpVariable %24 Function
+        %186 = OpVariable %24 Function
+        %189 = OpVariable %8 Function
+        %208 = OpVariable %8 Function
+        %210 = OpVariable %8 Function
+        %211 = OpVariable %8 Function
+        %212 = OpVariable %8 Function
+        %164 = OpAccessChain %163 %162 %23
+        %165 = OpLoad %6 %164
+        %166 = OpFOrdGreaterThanEqual %91 %165 %93
+               OpSelectionMerge %169 None
+               OpBranchConditional %166 %168 %183
+        %168 = OpLabel
+               OpSelectionMerge %173 None
+               OpBranchConditional %170 %172 %175
+        %172 = OpLabel
+               OpStore %171 %174
+               OpBranch %173
+        %175 = OpLabel
+        %180 = OpAccessChain %179 %178 %110 %27
+        %181 = OpLoad %6 %180
+               OpStore %171 %181
+               OpBranch %173
+        %173 = OpLabel
+        %182 = OpLoad %6 %171
+               OpStore %167 %182
+               OpBranch %169
+        %183 = OpLabel
+               OpStore %167 %184
+               OpBranch %169
+        %169 = OpLabel
+        %185 = OpLoad %6 %167
+               OpStore %159 %185
+        %187 = OpLoad %6 %159
+        %188 = OpExtInst %6 %1 FClamp %174 %174 %187
+               OpStore %186 %188
+        %190 = OpLoad %160 %162
+        %191 = OpVectorShuffle %7 %190 %190 0 1
+        %196 = OpAccessChain %195 %194 %110
+        %197 = OpLoad %7 %196
+        %198 = OpFDiv %7 %191 %197
+               OpStore %189 %198
+        %206 = OpLoad %6 %186
+        %207 = OpCompositeConstruct %7 %205 %206
+        %209 = OpLoad %7 %189
+               OpStore %208 %209
+               OpStore %210 %201
+               OpStore %211 %204
+               OpStore %212 %207
+        %213 = OpFunctionCall %14 %20 %208 %210 %211 %212
+        %214 = OpIEqual %91 %213 %156
+               OpSelectionMerge %216 None
+               OpBranchConditional %214 %215 %221
+        %215 = OpLabel
+               OpStore %218 %220
+               OpBranch %216
+        %221 = OpLabel
+               OpStore %218 %222
+               OpBranch %216
+        %216 = OpLabel
+               OpReturn
+               OpFunctionEnd
+         %12 = OpFunction %6 None %9
+         %10 = OpFunctionParameter %8
+         %11 = OpFunctionParameter %8
+         %13 = OpLabel
+         %25 = OpAccessChain %24 %10 %23
+         %26 = OpLoad %6 %25
+         %28 = OpAccessChain %24 %11 %27
+         %29 = OpLoad %6 %28
+         %30 = OpFMul %6 %26 %29
+         %31 = OpAccessChain %24 %11 %23
+         %32 = OpLoad %6 %31
+         %33 = OpAccessChain %24 %10 %27
+         %34 = OpLoad %6 %33
+         %35 = OpFMul %6 %32 %34
+         %36 = OpFSub %6 %30 %35
+               OpReturnValue %36
+               OpFunctionEnd
+         %20 = OpFunction %14 None %15
+         %16 = OpFunctionParameter %8
+         %17 = OpFunctionParameter %8
+         %18 = OpFunctionParameter %8
+         %19 = OpFunctionParameter %8
+         %21 = OpLabel
+         %39 = OpVariable %24 Function
+         %62 = OpVariable %8 Function
+         %63 = OpVariable %8 Function
+         %65 = OpVariable %24 Function
+         %88 = OpVariable %8 Function
+         %89 = OpVariable %8 Function
+        %112 = OpVariable %24 Function
+        %135 = OpVariable %8 Function
+        %136 = OpVariable %8 Function
+         %40 = OpAccessChain %24 %16 %23
+         %41 = OpLoad %6 %40
+         %42 = OpAccessChain %24 %17 %23
+         %43 = OpLoad %6 %42
+         %44 = OpFSub %6 %41 %43
+         %45 = OpAccessChain %24 %16 %27
+         %46 = OpLoad %6 %45
+         %47 = OpAccessChain %24 %17 %27
+         %48 = OpLoad %6 %47
+         %49 = OpFSub %6 %46 %48
+         %50 = OpCompositeConstruct %7 %44 %49
+         %51 = OpAccessChain %24 %18 %23
+         %52 = OpLoad %6 %51
+         %53 = OpAccessChain %24 %17 %23
+         %54 = OpLoad %6 %53
+         %55 = OpFSub %6 %52 %54
+         %56 = OpAccessChain %24 %18 %27
+         %57 = OpLoad %6 %56
+         %58 = OpAccessChain %24 %17 %27
+         %59 = OpLoad %6 %58
+         %60 = OpFSub %6 %57 %59
+         %61 = OpCompositeConstruct %7 %55 %60
+               OpStore %62 %50
+               OpStore %63 %61
+         %64 = OpFunctionCall %6 %12 %62 %63
+               OpStore %39 %64
+         %66 = OpAccessChain %24 %16 %23
+         %67 = OpLoad %6 %66
+         %68 = OpAccessChain %24 %18 %23
+         %69 = OpLoad %6 %68
+         %70 = OpFSub %6 %67 %69
+         %71 = OpAccessChain %24 %16 %27
+         %72 = OpLoad %6 %71
+         %73 = OpAccessChain %24 %18 %27
+         %74 = OpLoad %6 %73
+         %75 = OpFSub %6 %72 %74
+         %76 = OpCompositeConstruct %7 %70 %75
+         %77 = OpAccessChain %24 %19 %23
+         %78 = OpLoad %6 %77
+         %79 = OpAccessChain %24 %18 %23
+         %80 = OpLoad %6 %79
+         %81 = OpFSub %6 %78 %80
+         %82 = OpAccessChain %24 %19 %27
+         %83 = OpLoad %6 %82
+         %84 = OpAccessChain %24 %18 %27
+         %85 = OpLoad %6 %84
+         %86 = OpFSub %6 %83 %85
+         %87 = OpCompositeConstruct %7 %81 %86
+               OpStore %88 %76
+               OpStore %89 %87
+         %90 = OpFunctionCall %6 %12 %88 %89
+               OpStore %65 %90
+         %92 = OpLoad %6 %39
+         %94 = OpFOrdLessThan %91 %92 %93
+         %95 = OpLoad %6 %65
+         %96 = OpFOrdLessThan %91 %95 %93
+         %97 = OpLogicalAnd %91 %94 %96
+         %98 = OpLogicalNot %91 %97
+               OpSelectionMerge %100 None
+               OpBranchConditional %98 %99 %100
+         %99 = OpLabel
+        %101 = OpLoad %6 %39
+        %102 = OpFOrdGreaterThanEqual %91 %101 %93
+        %103 = OpLoad %6 %65
+        %104 = OpFOrdGreaterThanEqual %91 %103 %93
+        %105 = OpLogicalAnd %91 %102 %104
+               OpBranch %100
+        %100 = OpLabel
+        %106 = OpPhi %91 %97 %21 %105 %99
+        %107 = OpLogicalNot %91 %106
+               OpSelectionMerge %109 None
+               OpBranchConditional %107 %108 %109
+        %108 = OpLabel
+               OpReturnValue %110
+        %109 = OpLabel
+        %113 = OpAccessChain %24 %16 %23
+        %114 = OpLoad %6 %113
+        %115 = OpAccessChain %24 %19 %23
+        %116 = OpLoad %6 %115
+        %117 = OpFSub %6 %114 %116
+        %118 = OpAccessChain %24 %16 %27
+        %119 = OpLoad %6 %118
+        %120 = OpAccessChain %24 %19 %27
+        %121 = OpLoad %6 %120
+        %122 = OpFSub %6 %119 %121
+        %123 = OpCompositeConstruct %7 %117 %122
+        %124 = OpAccessChain %24 %17 %23
+        %125 = OpLoad %6 %124
+        %126 = OpAccessChain %24 %19 %23
+        %127 = OpLoad %6 %126
+        %128 = OpFSub %6 %125 %127
+        %129 = OpAccessChain %24 %17 %27
+        %130 = OpLoad %6 %129
+        %131 = OpAccessChain %24 %19 %27
+        %132 = OpLoad %6 %131
+        %133 = OpFSub %6 %130 %132
+        %134 = OpCompositeConstruct %7 %128 %133
+               OpStore %135 %123
+               OpStore %136 %134
+        %137 = OpFunctionCall %6 %12 %135 %136
+               OpStore %112 %137
+        %138 = OpLoad %6 %39
+        %139 = OpFOrdLessThan %91 %138 %93
+        %140 = OpLoad %6 %112
+        %141 = OpFOrdLessThan %91 %140 %93
+        %142 = OpLogicalAnd %91 %139 %141
+        %143 = OpLogicalNot %91 %142
+               OpSelectionMerge %145 None
+               OpBranchConditional %143 %144 %145
+        %144 = OpLabel
+        %146 = OpLoad %6 %39
+        %147 = OpFOrdGreaterThanEqual %91 %146 %93
+        %148 = OpLoad %6 %112
+        %149 = OpFOrdGreaterThanEqual %91 %148 %93
+        %150 = OpLogicalAnd %91 %147 %149
+               OpBranch %145
+        %145 = OpLabel
+        %151 = OpPhi %91 %142 %109 %150 %144
+        %152 = OpLogicalNot %91 %151
+               OpSelectionMerge %154 None
+               OpBranchConditional %152 %153 %154
+        %153 = OpLabel
+               OpReturnValue %110
+        %154 = OpLabel
+               OpReturnValue %156
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# resolution
+BUFFER variant_resolution DATA_TYPE vec2<float> DATA
+ 256.0 256.0
+END
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_resolution AS uniform DESCRIPTOR_SET 0 BINDING 0
+  BIND BUFFER variant_injectionSwitch AS push_constant
+END
+CLEAR_COLOR variant_pipeline 0 0 0 255
+
+CLEAR variant_pipeline
+RUN variant_pipeline DRAW_RECT POS 0 0 SIZE 256 256
+
+EXPECT reference_framebuffer EQ_HISTOGRAM_EMD_BUFFER variant_framebuffer TOLERANCE 0.005
diff --git a/external/vulkancts/data/vulkan/amber/graphicsfuzz/struct-array-index.amber b/external/vulkancts/data/vulkan/amber/graphicsfuzz/struct-array-index.amber
new file mode 100644 (file)
index 0000000..aa58b4a
--- /dev/null
@@ -0,0 +1,198 @@
+#!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 the GraphicsFuzz project.
+
+# Short description: A fragment shader with struct array and always true if
+
+# The test passes because the shader always writes the color red.
+
+SHADER vertex variant_vertex_shader PASSTHROUGH
+
+# variant_fragment_shader is derived from the following GLSL:
+# #version 320 es
+# precision highp float;
+#
+# precision highp int;
+#
+# layout(location = 0) out vec4 _GLF_color;
+# layout(set = 0, binding = 0) uniform buf0
+# {
+#     vec2 injectionSwitch;   // x == 0.0, y == 1.0
+# };
+# struct struct_base
+# {
+#     int data;
+#     int leftIndex;
+#     int rightIndex;
+# };
+#
+# struct_base struct_array[3] = struct_base[3](struct_base(1, 1, 1), struct_base(1, 1, 1), struct_base(1, 1, 1));
+#
+#
+# void main()
+# {
+#     int index = 1;
+#     struct_array[1].rightIndex = 1;
+#     // Always true.
+#     if (struct_array[1].leftIndex == 1)
+#     {
+#         // index == 1
+#         index = struct_array[int(injectionSwitch.x)].rightIndex;
+#     }
+#     else
+#     {
+#         // index == 1
+#         index = struct_array[int(injectionSwitch.y)].leftIndex;
+#     }
+#     // Always true.
+#     if(struct_array[1].leftIndex == 1)
+#     {
+#         _GLF_color = vec4(1.0, 0.0, 0.0, 1.0);
+#     }
+#     else
+#     {
+#         _GLF_color = vec4(1.0);
+#     }
+# }
+SHADER fragment variant_fragment_shader SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 60
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main" %54
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpName %4 "main"
+               OpName %7 "struct_base"
+               OpMemberName %7 0 "data"
+               OpMemberName %7 1 "leftIndex"
+               OpMemberName %7 2 "rightIndex"
+               OpName %12 "struct_array"
+               OpName %17 "index"
+               OpName %29 "buf0"
+               OpMemberName %29 0 "injectionSwitch"
+               OpName %31 ""
+               OpName %54 "_GLF_color"
+               OpMemberDecorate %29 0 Offset 0
+               OpDecorate %29 Block
+               OpDecorate %31 DescriptorSet 0
+               OpDecorate %31 Binding 0
+               OpDecorate %54 Location 0
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeInt 32 1
+          %7 = OpTypeStruct %6 %6 %6
+          %8 = OpTypeInt 32 0
+          %9 = OpConstant %8 3
+         %10 = OpTypeArray %7 %9
+         %11 = OpTypePointer Private %10
+         %12 = OpVariable %11 Private
+         %13 = OpConstant %6 1
+         %14 = OpConstantComposite %7 %13 %13 %13
+         %15 = OpConstantComposite %10 %14 %14 %14
+         %16 = OpTypePointer Function %6
+         %18 = OpConstant %6 2
+         %19 = OpTypePointer Private %6
+         %23 = OpTypeBool
+         %27 = OpTypeFloat 32
+         %28 = OpTypeVector %27 2
+         %29 = OpTypeStruct %28
+         %30 = OpTypePointer Uniform %29
+         %31 = OpVariable %30 Uniform
+         %32 = OpConstant %6 0
+         %33 = OpConstant %8 0
+         %34 = OpTypePointer Uniform %27
+         %41 = OpConstant %8 1
+         %52 = OpTypeVector %27 4
+         %53 = OpTypePointer Output %52
+         %54 = OpVariable %53 Output
+         %55 = OpConstant %27 1
+         %56 = OpConstant %27 0
+         %57 = OpConstantComposite %52 %55 %56 %56 %55
+         %59 = OpConstantComposite %52 %55 %55 %55 %55
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %17 = OpVariable %16 Function
+               OpStore %12 %15
+               OpStore %17 %13
+         %20 = OpAccessChain %19 %12 %13 %18
+               OpStore %20 %13
+         %21 = OpAccessChain %19 %12 %13 %13
+         %22 = OpLoad %6 %21
+         %24 = OpIEqual %23 %22 %13
+               OpSelectionMerge %26 None
+               OpBranchConditional %24 %25 %40
+         %25 = OpLabel
+         %35 = OpAccessChain %34 %31 %32 %33
+         %36 = OpLoad %27 %35
+         %37 = OpConvertFToS %6 %36
+         %38 = OpAccessChain %19 %12 %37 %18
+         %39 = OpLoad %6 %38
+               OpStore %17 %39
+               OpBranch %26
+         %40 = OpLabel
+         %42 = OpAccessChain %34 %31 %32 %41
+         %43 = OpLoad %27 %42
+         %44 = OpConvertFToS %6 %43
+         %45 = OpAccessChain %19 %12 %44 %13
+         %46 = OpLoad %6 %45
+               OpStore %17 %46
+               OpBranch %26
+         %26 = OpLabel
+         %47 = OpAccessChain %19 %12 %13 %13
+         %48 = OpLoad %6 %47
+         %49 = OpIEqual %23 %48 %13
+               OpSelectionMerge %51 None
+               OpBranchConditional %49 %50 %58
+         %50 = OpLabel
+               OpStore %54 %57
+               OpBranch %51
+         %58 = OpLabel
+               OpStore %54 %59
+               OpBranch %51
+         %51 = OpLabel
+               OpReturn
+               OpFunctionEnd
+END
+
+# uniforms for variant
+
+# injectionSwitch
+BUFFER variant_injectionSwitch DATA_TYPE vec2<float> STD140 DATA
+ 0.0 1.0
+END
+
+BUFFER variant_framebuffer FORMAT B8G8R8A8_UNORM
+
+PIPELINE graphics variant_pipeline
+  ATTACH variant_vertex_shader
+  ATTACH variant_fragment_shader
+  FRAMEBUFFER_SIZE 256 256
+  BIND BUFFER variant_framebuffer AS color LOCATION 0
+  BIND BUFFER variant_injectionSwitch 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 256 256
+
+EXPECT variant_framebuffer IDX 0 0 SIZE 256 256 EQ_RGBA 255 0 0 255
index 24f6aab..552d227 100644 (file)
@@ -835632,6 +835632,7 @@ dEQP-VK.graphicsfuzz.discard-in-array-manipulating-loop
 dEQP-VK.graphicsfuzz.discard-in-loop
 dEQP-VK.graphicsfuzz.discard-in-loop-in-function
 dEQP-VK.graphicsfuzz.discards-in-control-flow
+dEQP-VK.graphicsfuzz.do-while-false-if
 dEQP-VK.graphicsfuzz.do-while-false-loops
 dEQP-VK.graphicsfuzz.do-while-if-return
 dEQP-VK.graphicsfuzz.do-while-loop-in-conditionals
@@ -835719,19 +835720,25 @@ dEQP-VK.graphicsfuzz.stable-binarysearch-tree-nested-if-and-conditional
 dEQP-VK.graphicsfuzz.stable-binarysearch-tree-with-loop-read-write-global
 dEQP-VK.graphicsfuzz.stable-collatz-push-constant-with-nested-min-max
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-double-always-false-discard
+dEQP-VK.graphicsfuzz.stable-mergesort-for-always-false-if-discard
+dEQP-VK.graphicsfuzz.stable-mergesort-reversed-for-loop
+dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-float-mat-determinant-clamp
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-injected-conditional-true
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-true-conditional-simple-loop
 dEQP-VK.graphicsfuzz.stable-colorgrid-modulo-vec3-values-from-matrix
-dEQP-VK.graphicsfuzz.stable-mergesort-for-always-false-if-discard
-dEQP-VK.graphicsfuzz.stable-mergesort-reversed-for-loop
+dEQP-VK.graphicsfuzz.stable-mergesort-clamped-conditional-bit-shift
+dEQP-VK.graphicsfuzz.stable-quicksort-conditional-bitwise-or-clamp
 dEQP-VK.graphicsfuzz.stable-quicksort-for-loop-with-injection
 dEQP-VK.graphicsfuzz.stable-quicksort-if-false-else-return
 dEQP-VK.graphicsfuzz.stable-quicksort-max-value-as-index
 dEQP-VK.graphicsfuzz.stable-rects-vec4-clamp-conditional-min-mix
 dEQP-VK.graphicsfuzz.stable-triangle-array-nested-loop
 dEQP-VK.graphicsfuzz.stable-triangle-nested-for-loop-and-true-if
+dEQP-VK.graphicsfuzz.stable-triangle-clamp-conditional-mix
+dEQP-VK.graphicsfuzz.stable-triangle-nested-conditional-clamped-float
 dEQP-VK.graphicsfuzz.struct-and-unreachable-infinite-loop
 dEQP-VK.graphicsfuzz.struct-array-data-as-loop-iterator
+dEQP-VK.graphicsfuzz.struct-array-index
 dEQP-VK.graphicsfuzz.struct-controlled-loop
 dEQP-VK.graphicsfuzz.struct-used-as-temporary
 dEQP-VK.graphicsfuzz.switch-case-with-undefined-expression