summaryrefslogtreecommitdiff
path: root/tests/spec/arb_gl_spirv
diff options
context:
space:
mode:
authorAlejandro PiƱeiro <apinheiro@igalia.com>2018-06-07 16:23:13 +0200
committerArcady Goldmints-Orlov <agoldmints@igalia.com>2020-01-23 13:57:22 -0500
commit55c23f147f4fe8d28952fb2660206f82915539ad (patch)
tree28581d7fe2eff3ab9784f9267bf98c6b1054b326 /tests/spec/arb_gl_spirv
parent8d2ce04a13bfffa7f8b6f6e854a3b8160bfaf185 (diff)
arb_gl_spirv: add some arrays of arrays ubo/ssbo tests
Arrays of arrays of ubo/ssbo doesn't need to be supported on Vulkan, but, from ARB_gl_spirv spec: "Changes of system features, relative to Vulkan: <skip> . Vulkan does not allow multi-dimensional arrays of resources like UBOs and SSBOs in its SPIR-V environment spec. SPIR-V supports it and OpenGL already allows this for GLSL shaders. SPIR-V for OpenGL also allows it." Acked-by: Timothy Arceri <tarceri@itsqueeze.com>
Diffstat (limited to 'tests/spec/arb_gl_spirv')
-rw-r--r--tests/spec/arb_gl_spirv/execution/ssbo/aoa-2.shader_test294
-rw-r--r--tests/spec/arb_gl_spirv/execution/ssbo/aoa.shader_test199
-rw-r--r--tests/spec/arb_gl_spirv/execution/ubo/aoa-2.shader_test281
-rw-r--r--tests/spec/arb_gl_spirv/execution/ubo/aoa.shader_test197
4 files changed, 971 insertions, 0 deletions
diff --git a/tests/spec/arb_gl_spirv/execution/ssbo/aoa-2.shader_test b/tests/spec/arb_gl_spirv/execution/ssbo/aoa-2.shader_test
new file mode 100644
index 000000000..efeba3843
--- /dev/null
+++ b/tests/spec/arb_gl_spirv/execution/ssbo/aoa-2.shader_test
@@ -0,0 +1,294 @@
+# SSBO test using an array of arrays of ubos. UBO with two members.
+
+[require]
+SPIRV YES
+GL >= 3.3
+GLSL >= 4.50
+GL_ARB_gl_spirv
+
+[vertex shader passthrough]
+
+[fragment shader spirv]
+; Automatically generated from the GLSL by shader_test_spirv.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 120
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %color
+ OpExecutionMode %main OriginLowerLeft
+ OpSource GLSL 450
+ OpDecorate %color Location 0
+ OpMemberDecorate %AOA 0 Offset 0
+ OpMemberDecorate %AOA 1 Offset 16
+ OpDecorate %AOA BufferBlock
+ OpDecorate %arr DescriptorSet 0
+ OpDecorate %arr Binding 5
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %float_1 = OpConstant %float 1
+ %float_0 = OpConstant %float 0
+ %12 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %color = OpVariable %_ptr_Output_v4float Output
+ %15 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
+ %v2float = OpTypeVector %float 2
+ %AOA = OpTypeStruct %v4float %v2float
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_AOA_uint_2 = OpTypeArray %AOA %uint_2
+%_arr__arr_AOA_uint_2_uint_2 = OpTypeArray %_arr_AOA_uint_2 %uint_2
+%_ptr_Uniform__arr__arr_AOA_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_AOA_uint_2_uint_2
+ %arr = OpVariable %_ptr_Uniform__arr__arr_AOA_uint_2_uint_2 Uniform
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%float_610_072205 = OpConstant %float 610.072205
+%float_24998_1719 = OpConstant %float 24998.1719
+%float_8190_74414 = OpConstant %float 8190.74414
+%float_26479_0312 = OpConstant %float 26479.0312
+ %33 = OpConstantComposite %v4float %float_610_072205 %float_24998_1719 %float_8190_74414 %float_26479_0312
+ %bool = OpTypeBool
+ %v4bool = OpTypeVector %bool 4
+ %int_1 = OpConstant %int 1
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
+%float_n27681_2891 = OpConstant %float -27681.2891
+%float_9081_78711 = OpConstant %float 9081.78711
+ %47 = OpConstantComposite %v2float %float_n27681_2891 %float_9081_78711
+ %v2bool = OpTypeVector %bool 2
+%float_15538_2891 = OpConstant %float 15538.2891
+%float_5642_53711 = OpConstant %float 5642.53711
+%float_n23131_3867 = OpConstant %float -23131.3867
+%float_18541_5391 = OpConstant %float 18541.5391
+ %60 = OpConstantComposite %v4float %float_15538_2891 %float_5642_53711 %float_n23131_3867 %float_18541_5391
+%float_n12496_1973 = OpConstant %float -12496.1973
+%float_n5854_81055 = OpConstant %float -5854.81055
+ %70 = OpConstantComposite %v2float %float_n12496_1973 %float_n5854_81055
+%float_n32637_8945 = OpConstant %float -32637.8945
+%float_12265_4824 = OpConstant %float 12265.4824
+%float_n13669_0615 = OpConstant %float -13669.0615
+%float_27760_8262 = OpConstant %float 27760.8262
+ %82 = OpConstantComposite %v4float %float_n32637_8945 %float_12265_4824 %float_n13669_0615 %float_27760_8262
+%float_20530_7109 = OpConstant %float 20530.7109
+%float_n10508_5107 = OpConstant %float -10508.5107
+ %92 = OpConstantComposite %v2float %float_20530_7109 %float_n10508_5107
+%float_n1013_09918 = OpConstant %float -1013.09918
+%float_n23371_9824 = OpConstant %float -23371.9824
+%float_n3101_10449 = OpConstant %float -3101.10449
+%float_n19908_5312 = OpConstant %float -19908.5312
+ %104 = OpConstantComposite %v4float %float_n1013_09918 %float_n23371_9824 %float_n3101_10449 %float_n19908_5312
+%float_n29557_3516 = OpConstant %float -29557.3516
+%float_30238_998 = OpConstant %float 30238.998
+ %114 = OpConstantComposite %v2float %float_n29557_3516 %float_30238_998
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %fail_color = OpVariable %_ptr_Function_v4float Function
+ OpStore %fail_color %12
+ OpStore %color %15
+ %27 = OpAccessChain %_ptr_Uniform_v4float %arr %int_0 %int_0 %int_0
+ %28 = OpLoad %v4float %27
+ %36 = OpFOrdNotEqual %v4bool %28 %33
+ %37 = OpAny %bool %36
+ OpSelectionMerge %39 None
+ OpBranchConditional %37 %38 %39
+ %38 = OpLabel
+ %40 = OpLoad %v4float %fail_color
+ OpStore %color %40
+ OpBranch %39
+ %39 = OpLabel
+ %43 = OpAccessChain %_ptr_Uniform_v2float %arr %int_0 %int_0 %int_1
+ %44 = OpLoad %v2float %43
+ %49 = OpFOrdNotEqual %v2bool %44 %47
+ %50 = OpAny %bool %49
+ OpSelectionMerge %52 None
+ OpBranchConditional %50 %51 %52
+ %51 = OpLabel
+ %53 = OpLoad %v4float %fail_color
+ OpStore %color %53
+ OpBranch %52
+ %52 = OpLabel
+ %54 = OpAccessChain %_ptr_Uniform_v4float %arr %int_0 %int_1 %int_0
+ %55 = OpLoad %v4float %54
+ %61 = OpFOrdNotEqual %v4bool %55 %60
+ %62 = OpAny %bool %61
+ OpSelectionMerge %64 None
+ OpBranchConditional %62 %63 %64
+ %63 = OpLabel
+ %65 = OpLoad %v4float %fail_color
+ OpStore %color %65
+ OpBranch %64
+ %64 = OpLabel
+ %66 = OpAccessChain %_ptr_Uniform_v2float %arr %int_0 %int_1 %int_1
+ %67 = OpLoad %v2float %66
+ %71 = OpFOrdNotEqual %v2bool %67 %70
+ %72 = OpAny %bool %71
+ OpSelectionMerge %74 None
+ OpBranchConditional %72 %73 %74
+ %73 = OpLabel
+ %75 = OpLoad %v4float %fail_color
+ OpStore %color %75
+ OpBranch %74
+ %74 = OpLabel
+ %76 = OpAccessChain %_ptr_Uniform_v4float %arr %int_1 %int_0 %int_0
+ %77 = OpLoad %v4float %76
+ %83 = OpFOrdNotEqual %v4bool %77 %82
+ %84 = OpAny %bool %83
+ OpSelectionMerge %86 None
+ OpBranchConditional %84 %85 %86
+ %85 = OpLabel
+ %87 = OpLoad %v4float %fail_color
+ OpStore %color %87
+ OpBranch %86
+ %86 = OpLabel
+ %88 = OpAccessChain %_ptr_Uniform_v2float %arr %int_1 %int_0 %int_1
+ %89 = OpLoad %v2float %88
+ %93 = OpFOrdNotEqual %v2bool %89 %92
+ %94 = OpAny %bool %93
+ OpSelectionMerge %96 None
+ OpBranchConditional %94 %95 %96
+ %95 = OpLabel
+ %97 = OpLoad %v4float %fail_color
+ OpStore %color %97
+ OpBranch %96
+ %96 = OpLabel
+ %98 = OpAccessChain %_ptr_Uniform_v4float %arr %int_1 %int_1 %int_0
+ %99 = OpLoad %v4float %98
+ %105 = OpFOrdNotEqual %v4bool %99 %104
+ %106 = OpAny %bool %105
+ OpSelectionMerge %108 None
+ OpBranchConditional %106 %107 %108
+ %107 = OpLabel
+ %109 = OpLoad %v4float %fail_color
+ OpStore %color %109
+ OpBranch %108
+ %108 = OpLabel
+ %110 = OpAccessChain %_ptr_Uniform_v2float %arr %int_1 %int_1 %int_1
+ %111 = OpLoad %v2float %110
+ %115 = OpFOrdNotEqual %v2bool %111 %114
+ %116 = OpAny %bool %115
+ OpSelectionMerge %118 None
+ OpBranchConditional %116 %117 %118
+ %117 = OpLabel
+ %119 = OpLoad %v4float %fail_color
+ OpStore %color %119
+ OpBranch %118
+ %118 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+[fragment shader]
+
+#version 450
+
+layout (location = 0) out vec4 color;
+layout (std430, binding = 5) buffer AOA
+ {
+ vec4 c1;
+ vec2 c2;
+ } arr[2][2];
+
+void main()
+{
+ vec4 fail_color = vec4(1.0, 0.0, 0.0, 1.0);
+ color = vec4(0.0, 1.0, 0.0, 1.0);
+
+ if (arr[0][0].c1 != vec4(610.072190433, 24998.1713741, 8190.74402991, 26479.0313725)) {
+ color = fail_color;
+ }
+ if (arr[0][0].c2 != vec2(-27681.288716, 9081.78673991)) {
+ color = fail_color;
+ }
+
+ if (arr[0][1].c1 != vec4(15538.2894026, 5642.53723964, -23131.3873198, 18541.5383078)) {
+ color = fail_color;
+ }
+ if (arr[0][1].c2 != vec2(-12496.1967803, -5854.8105745)) {
+ color = fail_color;
+ }
+
+ if (arr[1][0].c1 != vec4(-32637.8949874, 12265.4819562, -13669.0617838, 27760.8253605)) {
+ color = fail_color;
+ }
+ if (arr[1][0].c2 != vec2(20530.7108263, -10508.5105669)) {
+ color = fail_color;
+ }
+
+ if (arr[1][1].c1 != vec4(-1013.0991989, -23371.9822385, -3101.104448, -19908.5317922)) {
+ color = fail_color;
+ }
+ if (arr[1][1].c2 != vec2(-29557.3508507, 30238.9989166)) {
+ color = fail_color;
+ }
+}
+
+[test]
+clear color 1.0 0.0 0.0 0.0
+clear
+
+clear color 1.0 0.0 0.0 0.0
+clear
+
+ssbo 5 32
+#c1
+ssbo 5 subdata float 0 610.072190433
+ssbo 5 subdata float 4 24998.1713741
+ssbo 5 subdata float 8 8190.74402991
+ssbo 5 subdata float 12 26479.0313725
+#c2
+ssbo 5 subdata float 16 -27681.288716
+ssbo 5 subdata float 20 9081.78673991
+
+ssbo 6 32
+#c1
+ssbo 6 subdata float 0 15538.2894026
+ssbo 6 subdata float 4 5642.53723964
+ssbo 6 subdata float 8 -23131.3873198
+ssbo 6 subdata float 12 18541.5383078
+#c2
+ssbo 6 subdata float 16 -12496.1967803
+ssbo 6 subdata float 20 -5854.8105745
+
+ssbo 7 32
+#c1
+ssbo 7 subdata float 0 -32637.8949874
+ssbo 7 subdata float 4 12265.4819562
+ssbo 7 subdata float 8 -13669.0617838
+ssbo 7 subdata float 12 27760.8253605
+#c2
+ssbo 7 subdata float 16 20530.7108263
+ssbo 7 subdata float 20 -10508.5105669
+
+ssbo 8 32
+#c1
+ssbo 8 subdata float 0 -1013.0991989
+ssbo 8 subdata float 4 -23371.9822385
+ssbo 8 subdata float 8 -3101.104448
+ssbo 8 subdata float 12 -19908.5317922
+#c2
+ssbo 8 subdata float 16 -29557.3508507
+ssbo 8 subdata float 20 30238.9989166
+
+block binding 5
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[0][0] GL_NUM_ACTIVE_VARIABLES 2
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[0][0] GL_BUFFER_DATA_SIZE 32
+
+block binding 6
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[0][1] GL_NUM_ACTIVE_VARIABLES 2
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[0][1] GL_BUFFER_DATA_SIZE 32
+
+block binding 7
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[1][0] GL_NUM_ACTIVE_VARIABLES 2
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[1][0] GL_BUFFER_DATA_SIZE 32
+
+block binding 8
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[1][1] GL_NUM_ACTIVE_VARIABLES 2
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[1][1] GL_BUFFER_DATA_SIZE 32
+
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0
diff --git a/tests/spec/arb_gl_spirv/execution/ssbo/aoa.shader_test b/tests/spec/arb_gl_spirv/execution/ssbo/aoa.shader_test
new file mode 100644
index 000000000..ec21e5e15
--- /dev/null
+++ b/tests/spec/arb_gl_spirv/execution/ssbo/aoa.shader_test
@@ -0,0 +1,199 @@
+# SSBO test using an array of arrays of ubos. UBO with just one member.
+
+[require]
+SPIRV YES
+GL >= 3.3
+GLSL >= 4.50
+GL_ARB_gl_spirv
+
+[vertex shader passthrough]
+
+[fragment shader spirv]
+; Automatically generated from the GLSL by shader_test_spirv.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 77
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %color
+ OpExecutionMode %main OriginLowerLeft
+ OpSource GLSL 450
+ OpDecorate %color Location 0
+ OpMemberDecorate %AOA 0 Offset 0
+ OpDecorate %AOA BufferBlock
+ OpDecorate %arr DescriptorSet 0
+ OpDecorate %arr Binding 5
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %float_1 = OpConstant %float 1
+ %float_0 = OpConstant %float 0
+ %12 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %color = OpVariable %_ptr_Output_v4float Output
+ %15 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
+ %AOA = OpTypeStruct %v4float
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_AOA_uint_2 = OpTypeArray %AOA %uint_2
+%_arr__arr_AOA_uint_2_uint_2 = OpTypeArray %_arr_AOA_uint_2 %uint_2
+%_ptr_Uniform__arr__arr_AOA_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_AOA_uint_2_uint_2
+ %arr = OpVariable %_ptr_Uniform__arr__arr_AOA_uint_2_uint_2 Uniform
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%float_610_072205 = OpConstant %float 610.072205
+%float_24998_1719 = OpConstant %float 24998.1719
+%float_8190_74414 = OpConstant %float 8190.74414
+%float_26479_0312 = OpConstant %float 26479.0312
+ %32 = OpConstantComposite %v4float %float_610_072205 %float_24998_1719 %float_8190_74414 %float_26479_0312
+ %bool = OpTypeBool
+ %v4bool = OpTypeVector %bool 4
+ %int_1 = OpConstant %int 1
+%float_15538_2891 = OpConstant %float 15538.2891
+%float_5642_53711 = OpConstant %float 5642.53711
+%float_n23131_3867 = OpConstant %float -23131.3867
+%float_18541_5391 = OpConstant %float 18541.5391
+ %47 = OpConstantComposite %v4float %float_15538_2891 %float_5642_53711 %float_n23131_3867 %float_18541_5391
+%float_n32637_8945 = OpConstant %float -32637.8945
+%float_12265_4824 = OpConstant %float 12265.4824
+%float_n13669_0615 = OpConstant %float -13669.0615
+%float_27760_8262 = OpConstant %float 27760.8262
+ %59 = OpConstantComposite %v4float %float_n32637_8945 %float_12265_4824 %float_n13669_0615 %float_27760_8262
+%float_n1013_09918 = OpConstant %float -1013.09918
+%float_n23371_9824 = OpConstant %float -23371.9824
+%float_n3101_10449 = OpConstant %float -3101.10449
+%float_n19908_5312 = OpConstant %float -19908.5312
+ %71 = OpConstantComposite %v4float %float_n1013_09918 %float_n23371_9824 %float_n3101_10449 %float_n19908_5312
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %fail_color = OpVariable %_ptr_Function_v4float Function
+ OpStore %fail_color %12
+ OpStore %color %15
+ %26 = OpAccessChain %_ptr_Uniform_v4float %arr %int_0 %int_0 %int_0
+ %27 = OpLoad %v4float %26
+ %35 = OpFOrdNotEqual %v4bool %27 %32
+ %36 = OpAny %bool %35
+ OpSelectionMerge %38 None
+ OpBranchConditional %36 %37 %38
+ %37 = OpLabel
+ %39 = OpLoad %v4float %fail_color
+ OpStore %color %39
+ OpBranch %38
+ %38 = OpLabel
+ %41 = OpAccessChain %_ptr_Uniform_v4float %arr %int_0 %int_1 %int_0
+ %42 = OpLoad %v4float %41
+ %48 = OpFOrdNotEqual %v4bool %42 %47
+ %49 = OpAny %bool %48
+ OpSelectionMerge %51 None
+ OpBranchConditional %49 %50 %51
+ %50 = OpLabel
+ %52 = OpLoad %v4float %fail_color
+ OpStore %color %52
+ OpBranch %51
+ %51 = OpLabel
+ %53 = OpAccessChain %_ptr_Uniform_v4float %arr %int_1 %int_0 %int_0
+ %54 = OpLoad %v4float %53
+ %60 = OpFOrdNotEqual %v4bool %54 %59
+ %61 = OpAny %bool %60
+ OpSelectionMerge %63 None
+ OpBranchConditional %61 %62 %63
+ %62 = OpLabel
+ %64 = OpLoad %v4float %fail_color
+ OpStore %color %64
+ OpBranch %63
+ %63 = OpLabel
+ %65 = OpAccessChain %_ptr_Uniform_v4float %arr %int_1 %int_1 %int_0
+ %66 = OpLoad %v4float %65
+ %72 = OpFOrdNotEqual %v4bool %66 %71
+ %73 = OpAny %bool %72
+ OpSelectionMerge %75 None
+ OpBranchConditional %73 %74 %75
+ %74 = OpLabel
+ %76 = OpLoad %v4float %fail_color
+ OpStore %color %76
+ OpBranch %75
+ %75 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+[fragment shader]
+
+#version 450
+
+layout (location = 0) out vec4 color;
+layout (std430, binding = 5) buffer AOA
+ {
+ vec4 c1;
+ } arr[2][2];
+
+void main()
+{
+ vec4 fail_color = vec4(1.0, 0.0, 0.0, 1.0);
+ color = vec4(0.0, 1.0, 0.0, 1.0);
+
+ if (arr[0][0].c1 != vec4(610.072190433, 24998.1713741, 8190.74402991, 26479.0313725)) {
+ color = fail_color;
+ }
+ if (arr[0][1].c1 != vec4(15538.2894026, 5642.53723964, -23131.3873198, 18541.5383078)) {
+ color = fail_color;
+ }
+ if (arr[1][0].c1 != vec4(-32637.8949874, 12265.4819562, -13669.0617838, 27760.8253605)) {
+ color = fail_color;
+ }
+ if (arr[1][1].c1 != vec4(-1013.0991989, -23371.9822385, -3101.104448, -19908.5317922)) {
+ color = fail_color;
+ }
+}
+
+[test]
+clear color 1.0 0.0 0.0 0.0
+clear
+
+ssbo 5 16
+ssbo 5 subdata float 0 610.072190433
+ssbo 5 subdata float 4 24998.1713741
+ssbo 5 subdata float 8 8190.74402991
+ssbo 5 subdata float 12 26479.0313725
+
+ssbo 6 16
+ssbo 6 subdata float 0 15538.2894026
+ssbo 6 subdata float 4 5642.53723964
+ssbo 6 subdata float 8 -23131.3873198
+ssbo 6 subdata float 12 18541.5383078
+
+ssbo 7 16
+ssbo 7 subdata float 0 -32637.8949874
+ssbo 7 subdata float 4 12265.4819562
+ssbo 7 subdata float 8 -13669.0617838
+ssbo 7 subdata float 12 27760.8253605
+
+ssbo 8 16
+ssbo 8 subdata float 0 -1013.0991989
+ssbo 8 subdata float 4 -23371.9822385
+ssbo 8 subdata float 8 -3101.104448
+ssbo 8 subdata float 12 -19908.5317922
+
+block binding 5
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[0][0] GL_NUM_ACTIVE_VARIABLES 1
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[0][0] GL_BUFFER_DATA_SIZE 16
+
+block binding 6
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[0][1] GL_NUM_ACTIVE_VARIABLES 1
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[0][1] GL_BUFFER_DATA_SIZE 16
+
+block binding 7
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[1][0] GL_NUM_ACTIVE_VARIABLES 1
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[1][0] GL_BUFFER_DATA_SIZE 16
+
+block binding 8
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[1][1] GL_NUM_ACTIVE_VARIABLES 1
+verify program_interface_query GL_SHADER_STORAGE_BLOCK AOA[1][1] GL_BUFFER_DATA_SIZE 16
+
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0
diff --git a/tests/spec/arb_gl_spirv/execution/ubo/aoa-2.shader_test b/tests/spec/arb_gl_spirv/execution/ubo/aoa-2.shader_test
new file mode 100644
index 000000000..647144275
--- /dev/null
+++ b/tests/spec/arb_gl_spirv/execution/ubo/aoa-2.shader_test
@@ -0,0 +1,281 @@
+# UBO test using an array of arrays of ubos. UBO with two members.
+
+[require]
+SPIRV YES
+GL >= 3.3
+GLSL >= 4.50
+GL_ARB_gl_spirv
+
+[vertex shader passthrough]
+
+[fragment shader spirv]
+; Automatically generated from the GLSL by shader_test_spirv.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 120
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %color
+ OpExecutionMode %main OriginLowerLeft
+ OpSource GLSL 450
+ OpDecorate %color Location 0
+ OpMemberDecorate %AOA 0 Offset 0
+ OpMemberDecorate %AOA 1 Offset 16
+ OpDecorate %AOA Block
+ OpDecorate %arr DescriptorSet 0
+ OpDecorate %arr Binding 5
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %float_1 = OpConstant %float 1
+ %float_0 = OpConstant %float 0
+ %12 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %color = OpVariable %_ptr_Output_v4float Output
+ %15 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
+ %v2float = OpTypeVector %float 2
+ %AOA = OpTypeStruct %v4float %v2float
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_AOA_uint_2 = OpTypeArray %AOA %uint_2
+%_arr__arr_AOA_uint_2_uint_2 = OpTypeArray %_arr_AOA_uint_2 %uint_2
+%_ptr_Uniform__arr__arr_AOA_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_AOA_uint_2_uint_2
+ %arr = OpVariable %_ptr_Uniform__arr__arr_AOA_uint_2_uint_2 Uniform
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%float_610_072205 = OpConstant %float 610.072205
+%float_24998_1719 = OpConstant %float 24998.1719
+%float_8190_74414 = OpConstant %float 8190.74414
+%float_26479_0312 = OpConstant %float 26479.0312
+ %33 = OpConstantComposite %v4float %float_610_072205 %float_24998_1719 %float_8190_74414 %float_26479_0312
+ %bool = OpTypeBool
+ %v4bool = OpTypeVector %bool 4
+ %int_1 = OpConstant %int 1
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
+%float_n27681_2891 = OpConstant %float -27681.2891
+%float_9081_78711 = OpConstant %float 9081.78711
+ %47 = OpConstantComposite %v2float %float_n27681_2891 %float_9081_78711
+ %v2bool = OpTypeVector %bool 2
+%float_15538_2891 = OpConstant %float 15538.2891
+%float_5642_53711 = OpConstant %float 5642.53711
+%float_n23131_3867 = OpConstant %float -23131.3867
+%float_18541_5391 = OpConstant %float 18541.5391
+ %60 = OpConstantComposite %v4float %float_15538_2891 %float_5642_53711 %float_n23131_3867 %float_18541_5391
+%float_n12496_1973 = OpConstant %float -12496.1973
+%float_n5854_81055 = OpConstant %float -5854.81055
+ %70 = OpConstantComposite %v2float %float_n12496_1973 %float_n5854_81055
+%float_n32637_8945 = OpConstant %float -32637.8945
+%float_12265_4824 = OpConstant %float 12265.4824
+%float_n13669_0615 = OpConstant %float -13669.0615
+%float_27760_8262 = OpConstant %float 27760.8262
+ %82 = OpConstantComposite %v4float %float_n32637_8945 %float_12265_4824 %float_n13669_0615 %float_27760_8262
+%float_20530_7109 = OpConstant %float 20530.7109
+%float_n10508_5107 = OpConstant %float -10508.5107
+ %92 = OpConstantComposite %v2float %float_20530_7109 %float_n10508_5107
+%float_n1013_09918 = OpConstant %float -1013.09918
+%float_n23371_9824 = OpConstant %float -23371.9824
+%float_n3101_10449 = OpConstant %float -3101.10449
+%float_n19908_5312 = OpConstant %float -19908.5312
+ %104 = OpConstantComposite %v4float %float_n1013_09918 %float_n23371_9824 %float_n3101_10449 %float_n19908_5312
+%float_n29557_3516 = OpConstant %float -29557.3516
+%float_30238_998 = OpConstant %float 30238.998
+ %114 = OpConstantComposite %v2float %float_n29557_3516 %float_30238_998
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %fail_color = OpVariable %_ptr_Function_v4float Function
+ OpStore %fail_color %12
+ OpStore %color %15
+ %27 = OpAccessChain %_ptr_Uniform_v4float %arr %int_0 %int_0 %int_0
+ %28 = OpLoad %v4float %27
+ %36 = OpFOrdNotEqual %v4bool %28 %33
+ %37 = OpAny %bool %36
+ OpSelectionMerge %39 None
+ OpBranchConditional %37 %38 %39
+ %38 = OpLabel
+ %40 = OpLoad %v4float %fail_color
+ OpStore %color %40
+ OpBranch %39
+ %39 = OpLabel
+ %43 = OpAccessChain %_ptr_Uniform_v2float %arr %int_0 %int_0 %int_1
+ %44 = OpLoad %v2float %43
+ %49 = OpFOrdNotEqual %v2bool %44 %47
+ %50 = OpAny %bool %49
+ OpSelectionMerge %52 None
+ OpBranchConditional %50 %51 %52
+ %51 = OpLabel
+ %53 = OpLoad %v4float %fail_color
+ OpStore %color %53
+ OpBranch %52
+ %52 = OpLabel
+ %54 = OpAccessChain %_ptr_Uniform_v4float %arr %int_0 %int_1 %int_0
+ %55 = OpLoad %v4float %54
+ %61 = OpFOrdNotEqual %v4bool %55 %60
+ %62 = OpAny %bool %61
+ OpSelectionMerge %64 None
+ OpBranchConditional %62 %63 %64
+ %63 = OpLabel
+ %65 = OpLoad %v4float %fail_color
+ OpStore %color %65
+ OpBranch %64
+ %64 = OpLabel
+ %66 = OpAccessChain %_ptr_Uniform_v2float %arr %int_0 %int_1 %int_1
+ %67 = OpLoad %v2float %66
+ %71 = OpFOrdNotEqual %v2bool %67 %70
+ %72 = OpAny %bool %71
+ OpSelectionMerge %74 None
+ OpBranchConditional %72 %73 %74
+ %73 = OpLabel
+ %75 = OpLoad %v4float %fail_color
+ OpStore %color %75
+ OpBranch %74
+ %74 = OpLabel
+ %76 = OpAccessChain %_ptr_Uniform_v4float %arr %int_1 %int_0 %int_0
+ %77 = OpLoad %v4float %76
+ %83 = OpFOrdNotEqual %v4bool %77 %82
+ %84 = OpAny %bool %83
+ OpSelectionMerge %86 None
+ OpBranchConditional %84 %85 %86
+ %85 = OpLabel
+ %87 = OpLoad %v4float %fail_color
+ OpStore %color %87
+ OpBranch %86
+ %86 = OpLabel
+ %88 = OpAccessChain %_ptr_Uniform_v2float %arr %int_1 %int_0 %int_1
+ %89 = OpLoad %v2float %88
+ %93 = OpFOrdNotEqual %v2bool %89 %92
+ %94 = OpAny %bool %93
+ OpSelectionMerge %96 None
+ OpBranchConditional %94 %95 %96
+ %95 = OpLabel
+ %97 = OpLoad %v4float %fail_color
+ OpStore %color %97
+ OpBranch %96
+ %96 = OpLabel
+ %98 = OpAccessChain %_ptr_Uniform_v4float %arr %int_1 %int_1 %int_0
+ %99 = OpLoad %v4float %98
+ %105 = OpFOrdNotEqual %v4bool %99 %104
+ %106 = OpAny %bool %105
+ OpSelectionMerge %108 None
+ OpBranchConditional %106 %107 %108
+ %107 = OpLabel
+ %109 = OpLoad %v4float %fail_color
+ OpStore %color %109
+ OpBranch %108
+ %108 = OpLabel
+ %110 = OpAccessChain %_ptr_Uniform_v2float %arr %int_1 %int_1 %int_1
+ %111 = OpLoad %v2float %110
+ %115 = OpFOrdNotEqual %v2bool %111 %114
+ %116 = OpAny %bool %115
+ OpSelectionMerge %118 None
+ OpBranchConditional %116 %117 %118
+ %117 = OpLabel
+ %119 = OpLoad %v4float %fail_color
+ OpStore %color %119
+ OpBranch %118
+ %118 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+[fragment shader]
+
+#version 450
+
+layout (location = 0) out vec4 color;
+layout (binding = 5, row_major) uniform AOA
+ {
+ vec4 c1;
+ vec2 c2;
+ } arr[2][2];
+
+void main()
+{
+ vec4 fail_color = vec4(1.0, 0.0, 0.0, 1.0);
+ color = vec4(0.0, 1.0, 0.0, 1.0);
+
+ if (arr[0][0].c1 != vec4(610.072190433, 24998.1713741, 8190.74402991, 26479.0313725)) {
+ color = fail_color;
+ }
+ if (arr[0][0].c2 != vec2(-27681.288716, 9081.78673991)) {
+ color = fail_color;
+ }
+
+ if (arr[0][1].c1 != vec4(15538.2894026, 5642.53723964, -23131.3873198, 18541.5383078)) {
+ color = fail_color;
+ }
+ if (arr[0][1].c2 != vec2(-12496.1967803, -5854.8105745)) {
+ color = fail_color;
+ }
+
+ if (arr[1][0].c1 != vec4(-32637.8949874, 12265.4819562, -13669.0617838, 27760.8253605)) {
+ color = fail_color;
+ }
+ if (arr[1][0].c2 != vec2(20530.7108263, -10508.5105669)) {
+ color = fail_color;
+ }
+
+ if (arr[1][1].c1 != vec4(-1013.0991989, -23371.9822385, -3101.104448, -19908.5317922)) {
+ color = fail_color;
+ }
+ if (arr[1][1].c2 != vec2(-29557.3508507, 30238.9989166)) {
+ color = fail_color;
+ }
+}
+
+[test]
+clear color 1.0 0.0 0.0 0.0
+clear
+
+# Note that to fill the data we use the first binding, even if each
+# individual index would be associated with a different binding. We
+# keep using array index for that.
+
+block binding 5
+
+block array index 0
+block offset 0
+uniform vec4 AOA.c1 610.072190433 24998.1713741 8190.74402991 26479.0313725
+block offset 16
+uniform vec4 AOA.c2 -27681.288716 9081.78673991
+
+block array index 1
+block offset 0
+uniform vec4 AOA.c1 15538.2894026 5642.53723964 -23131.3873198 18541.5383078
+block offset 16
+uniform vec4 AOA.c2 -12496.1967803 -5854.8105745
+
+block array index 2
+block offset 0
+uniform vec4 AOA.c1 -32637.8949874 12265.4819562 -13669.0617838 27760.8253605
+block offset 16
+uniform vec4 AOA.c2 20530.7108263 -10508.5105669
+
+block array index 3
+block offset 0
+uniform vec4 AOA.c1 -1013.0991989 -23371.9822385 -3101.104448 -19908.5317922
+block offset 16
+uniform vec4 AOA.c2 -29557.3508507 30238.9989166
+
+block binding 5
+verify program_interface_query GL_UNIFORM_BLOCK AOA[0][0] GL_NUM_ACTIVE_VARIABLES 2
+verify program_interface_query GL_UNIFORM_BLOCK AOA[0][0] GL_BUFFER_DATA_SIZE 32
+
+block binding 6
+verify program_interface_query GL_UNIFORM_BLOCK AOA[0][1] GL_NUM_ACTIVE_VARIABLES 2
+verify program_interface_query GL_UNIFORM_BLOCK AOA[0][1] GL_BUFFER_DATA_SIZE 32
+
+block binding 7
+verify program_interface_query GL_UNIFORM_BLOCK AOA[1][0] GL_NUM_ACTIVE_VARIABLES 2
+verify program_interface_query GL_UNIFORM_BLOCK AOA[1][0] GL_BUFFER_DATA_SIZE 32
+
+block binding 8
+verify program_interface_query GL_UNIFORM_BLOCK AOA[1][1] GL_NUM_ACTIVE_VARIABLES 2
+verify program_interface_query GL_UNIFORM_BLOCK AOA[1][1] GL_BUFFER_DATA_SIZE 32
+
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0
diff --git a/tests/spec/arb_gl_spirv/execution/ubo/aoa.shader_test b/tests/spec/arb_gl_spirv/execution/ubo/aoa.shader_test
new file mode 100644
index 000000000..c18bdb689
--- /dev/null
+++ b/tests/spec/arb_gl_spirv/execution/ubo/aoa.shader_test
@@ -0,0 +1,197 @@
+# UBO test using an array of arrays of ubos. UBO with just one member.
+
+[require]
+SPIRV YES
+GL >= 3.3
+GLSL >= 4.50
+GL_ARB_gl_spirv
+
+[vertex shader passthrough]
+
+[fragment shader spirv]
+; Automatically generated from the GLSL by shader_test_spirv.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 77
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %color
+ OpExecutionMode %main OriginLowerLeft
+ OpSource GLSL 450
+ OpDecorate %color Location 0
+ OpMemberDecorate %AOA 0 Offset 0
+ OpDecorate %AOA Block
+ OpDecorate %arr DescriptorSet 0
+ OpDecorate %arr Binding 5
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %float_1 = OpConstant %float 1
+ %float_0 = OpConstant %float 0
+ %12 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %color = OpVariable %_ptr_Output_v4float Output
+ %15 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
+ %AOA = OpTypeStruct %v4float
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_AOA_uint_2 = OpTypeArray %AOA %uint_2
+%_arr__arr_AOA_uint_2_uint_2 = OpTypeArray %_arr_AOA_uint_2 %uint_2
+%_ptr_Uniform__arr__arr_AOA_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_AOA_uint_2_uint_2
+ %arr = OpVariable %_ptr_Uniform__arr__arr_AOA_uint_2_uint_2 Uniform
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%float_610_072205 = OpConstant %float 610.072205
+%float_24998_1719 = OpConstant %float 24998.1719
+%float_8190_74414 = OpConstant %float 8190.74414
+%float_26479_0312 = OpConstant %float 26479.0312
+ %32 = OpConstantComposite %v4float %float_610_072205 %float_24998_1719 %float_8190_74414 %float_26479_0312
+ %bool = OpTypeBool
+ %v4bool = OpTypeVector %bool 4
+ %int_1 = OpConstant %int 1
+%float_15538_2891 = OpConstant %float 15538.2891
+%float_5642_53711 = OpConstant %float 5642.53711
+%float_n23131_3867 = OpConstant %float -23131.3867
+%float_18541_5391 = OpConstant %float 18541.5391
+ %47 = OpConstantComposite %v4float %float_15538_2891 %float_5642_53711 %float_n23131_3867 %float_18541_5391
+%float_n32637_8945 = OpConstant %float -32637.8945
+%float_12265_4824 = OpConstant %float 12265.4824
+%float_n13669_0615 = OpConstant %float -13669.0615
+%float_27760_8262 = OpConstant %float 27760.8262
+ %59 = OpConstantComposite %v4float %float_n32637_8945 %float_12265_4824 %float_n13669_0615 %float_27760_8262
+%float_n1013_09918 = OpConstant %float -1013.09918
+%float_n23371_9824 = OpConstant %float -23371.9824
+%float_n3101_10449 = OpConstant %float -3101.10449
+%float_n19908_5312 = OpConstant %float -19908.5312
+ %71 = OpConstantComposite %v4float %float_n1013_09918 %float_n23371_9824 %float_n3101_10449 %float_n19908_5312
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %fail_color = OpVariable %_ptr_Function_v4float Function
+ OpStore %fail_color %12
+ OpStore %color %15
+ %26 = OpAccessChain %_ptr_Uniform_v4float %arr %int_0 %int_0 %int_0
+ %27 = OpLoad %v4float %26
+ %35 = OpFOrdNotEqual %v4bool %27 %32
+ %36 = OpAny %bool %35
+ OpSelectionMerge %38 None
+ OpBranchConditional %36 %37 %38
+ %37 = OpLabel
+ %39 = OpLoad %v4float %fail_color
+ OpStore %color %39
+ OpBranch %38
+ %38 = OpLabel
+ %41 = OpAccessChain %_ptr_Uniform_v4float %arr %int_0 %int_1 %int_0
+ %42 = OpLoad %v4float %41
+ %48 = OpFOrdNotEqual %v4bool %42 %47
+ %49 = OpAny %bool %48
+ OpSelectionMerge %51 None
+ OpBranchConditional %49 %50 %51
+ %50 = OpLabel
+ %52 = OpLoad %v4float %fail_color
+ OpStore %color %52
+ OpBranch %51
+ %51 = OpLabel
+ %53 = OpAccessChain %_ptr_Uniform_v4float %arr %int_1 %int_0 %int_0
+ %54 = OpLoad %v4float %53
+ %60 = OpFOrdNotEqual %v4bool %54 %59
+ %61 = OpAny %bool %60
+ OpSelectionMerge %63 None
+ OpBranchConditional %61 %62 %63
+ %62 = OpLabel
+ %64 = OpLoad %v4float %fail_color
+ OpStore %color %64
+ OpBranch %63
+ %63 = OpLabel
+ %65 = OpAccessChain %_ptr_Uniform_v4float %arr %int_1 %int_1 %int_0
+ %66 = OpLoad %v4float %65
+ %72 = OpFOrdNotEqual %v4bool %66 %71
+ %73 = OpAny %bool %72
+ OpSelectionMerge %75 None
+ OpBranchConditional %73 %74 %75
+ %74 = OpLabel
+ %76 = OpLoad %v4float %fail_color
+ OpStore %color %76
+ OpBranch %75
+ %75 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+[fragment shader]
+
+#version 450
+
+layout (location = 0) out vec4 color;
+layout (binding = 5, row_major) uniform AOA
+ {
+ vec4 c1;
+ } arr[2][2];
+
+void main()
+{
+ vec4 fail_color = vec4(1.0, 0.0, 0.0, 1.0);
+ color = vec4(0.0, 1.0, 0.0, 1.0);
+
+ if (arr[0][0].c1 != vec4(610.072190433, 24998.1713741, 8190.74402991, 26479.0313725)) {
+ color = fail_color;
+ }
+ if (arr[0][1].c1 != vec4(15538.2894026, 5642.53723964, -23131.3873198, 18541.5383078)) {
+ color = fail_color;
+ }
+ if (arr[1][0].c1 != vec4(-32637.8949874, 12265.4819562, -13669.0617838, 27760.8253605)) {
+ color = fail_color;
+ }
+ if (arr[1][1].c1 != vec4(-1013.0991989, -23371.9822385, -3101.104448, -19908.5317922)) {
+ color = fail_color;
+ }
+}
+
+[test]
+clear color 1.0 0.0 0.0 0.0
+clear
+
+# Note that to fill the data we use the first binding, even if each
+# individual index would be associated with a different binding. We
+# keep using array index for that.
+
+block binding 5
+
+block array index 0
+block offset 0
+uniform vec4 AOA.c1 610.072190433 24998.1713741 8190.74402991 26479.0313725
+
+block array index 1
+block offset 0
+uniform vec4 AOA.c1 15538.2894026 5642.53723964 -23131.3873198 18541.5383078
+
+block array index 2
+block offset 0
+uniform vec4 AOA.c1 -32637.8949874 12265.4819562 -13669.0617838 27760.8253605
+
+block array index 3
+block offset 0
+uniform vec4 AOA.c1 -1013.0991989 -23371.9822385 -3101.104448 -19908.5317922
+
+block binding 5
+verify program_interface_query GL_UNIFORM_BLOCK AOA[0][0] GL_NUM_ACTIVE_VARIABLES 1
+verify program_interface_query GL_UNIFORM_BLOCK AOA[0][0] GL_BUFFER_DATA_SIZE 16
+
+block binding 6
+verify program_interface_query GL_UNIFORM_BLOCK AOA[0][1] GL_NUM_ACTIVE_VARIABLES 1
+verify program_interface_query GL_UNIFORM_BLOCK AOA[0][1] GL_BUFFER_DATA_SIZE 16
+
+block binding 7
+verify program_interface_query GL_UNIFORM_BLOCK AOA[1][0] GL_NUM_ACTIVE_VARIABLES 1
+verify program_interface_query GL_UNIFORM_BLOCK AOA[1][0] GL_BUFFER_DATA_SIZE 16
+
+block binding 8
+verify program_interface_query GL_UNIFORM_BLOCK AOA[1][1] GL_NUM_ACTIVE_VARIABLES 1
+verify program_interface_query GL_UNIFORM_BLOCK AOA[1][1] GL_BUFFER_DATA_SIZE 16
+
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0