[45/63] arb_gl_spirv: add tests equivalent to component-layout SSO

Submitted by apinheiro on Feb. 23, 2019, 11:45 p.m.

Details

Message ID 20190223234551.21111-46-apinheiro@igalia.com
State New
Headers show
Series "ARB_gl_spirv full series" ( rev: 1 ) in Piglit

Not browsing as part of any series.

Commit Message

apinheiro Feb. 23, 2019, 11:45 p.m.
From: Arcady Goldmints-Orlov <agoldmints@igalia.com>

The difference is that we explicitly specify locations for inputs and outputs in
component-layout tests.

The current version of glslang doesn't handle a mixture of explicit and implicit
locations for inputs and outputs, so make all locations explicit.
---
 ...-sso-vs-gs-fs-array-interleave.shader_test | 438 ++++++++++++++++++
 ...mponent-layout-vs-gs-fs-double.shader_test | 312 +++++++++++++
 .../component-layout-vs-gs-fs.shader_test     | 291 ++++++++++++
 3 files changed, 1041 insertions(+)
 create mode 100644 tests/spec/arb_gl_spirv/execution/component-layout-sso-vs-gs-fs-array-interleave.shader_test
 create mode 100644 tests/spec/arb_gl_spirv/execution/component-layout-vs-gs-fs-double.shader_test
 create mode 100644 tests/spec/arb_gl_spirv/execution/component-layout-vs-gs-fs.shader_test

Patch hide | download patch | download mbox

diff --git a/tests/spec/arb_gl_spirv/execution/component-layout-sso-vs-gs-fs-array-interleave.shader_test b/tests/spec/arb_gl_spirv/execution/component-layout-sso-vs-gs-fs-array-interleave.shader_test
new file mode 100644
index 000000000..5b9d672b7
--- /dev/null
+++ b/tests/spec/arb_gl_spirv/execution/component-layout-sso-vs-gs-fs-array-interleave.shader_test
@@ -0,0 +1,438 @@ 
+# Test layout component qualifier between multiple shader stages with SSO
+# enabled.
+#
+# Copied from
+# arb_enhanced_layouts/execution/component-layout/sso-vs-gs-fs-array-interleave.shader_test,
+# the difference is that we explicitly specify locations for inputs and outputs
+# in component-layout tests.  The current version of glslang doesn't handle a
+# mixture of explicit and implicit locations for inputs and outputs, so we made
+# all locations explicit.
+
+[require]
+SPIRV YES
+GLSL >= 1.50
+GL_ARB_enhanced_layouts
+GL_ARB_separate_shader_objects
+SSO ENABLED
+
+[vertex shader spirv]
+; Automatically generated from the GLSL by gen_gl_spirv_tests.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 64
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %main "main" %a %b %vertex_to_gs %piglit_vertex %gl_VertexID %gl_InstanceID
+               OpSource GLSL 450
+               OpSourceExtension "GL_ARB_enhanced_layouts"
+               OpSourceExtension "GL_ARB_separate_shader_objects"
+               OpDecorate %a Location 0
+               OpDecorate %b Component 3
+               OpDecorate %b Location 0
+               OpDecorate %vertex_to_gs Location 6
+               OpDecorate %piglit_vertex Location 0
+               OpDecorate %gl_VertexID BuiltIn VertexId
+               OpDecorate %gl_InstanceID BuiltIn InstanceId
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+       %uint = OpTypeInt 32 0
+     %uint_6 = OpConstant %uint 6
+%_arr_v3float_uint_6 = OpTypeArray %v3float %uint_6
+%_ptr_Output__arr_v3float_uint_6 = OpTypePointer Output %_arr_v3float_uint_6
+          %a = OpVariable %_ptr_Output__arr_v3float_uint_6 Output
+        %int = OpTypeInt 32 1
+      %int_0 = OpConstant %int 0
+    %float_0 = OpConstant %float 0
+         %16 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+      %int_1 = OpConstant %int 1
+    %float_1 = OpConstant %float 1
+         %21 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+      %int_2 = OpConstant %int 2
+    %float_2 = OpConstant %float 2
+         %25 = OpConstantComposite %v3float %float_2 %float_2 %float_2
+      %int_3 = OpConstant %int 3
+    %float_3 = OpConstant %float 3
+         %29 = OpConstantComposite %v3float %float_3 %float_3 %float_3
+      %int_4 = OpConstant %int 4
+    %float_4 = OpConstant %float 4
+         %33 = OpConstantComposite %v3float %float_4 %float_4 %float_4
+      %int_5 = OpConstant %int 5
+    %float_5 = OpConstant %float 5
+         %37 = OpConstantComposite %v3float %float_5 %float_5 %float_5
+%_arr_float_uint_6 = OpTypeArray %float %uint_6
+%_ptr_Output__arr_float_uint_6 = OpTypePointer Output %_arr_float_uint_6
+          %b = OpVariable %_ptr_Output__arr_float_uint_6 Output
+    %float_6 = OpConstant %float 6
+%_ptr_Output_float = OpTypePointer Output %float
+    %float_7 = OpConstant %float 7
+    %float_8 = OpConstant %float 8
+    %float_9 = OpConstant %float 9
+   %float_10 = OpConstant %float 10
+   %float_11 = OpConstant %float 11
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%vertex_to_gs = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%piglit_vertex = OpVariable %_ptr_Input_v4float Input
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_VertexID = OpVariable %_ptr_Input_int Input
+%gl_InstanceID = OpVariable %_ptr_Input_int Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %18 = OpAccessChain %_ptr_Output_v3float %a %int_0
+               OpStore %18 %16
+         %22 = OpAccessChain %_ptr_Output_v3float %a %int_1
+               OpStore %22 %21
+         %26 = OpAccessChain %_ptr_Output_v3float %a %int_2
+               OpStore %26 %25
+         %30 = OpAccessChain %_ptr_Output_v3float %a %int_3
+               OpStore %30 %29
+         %34 = OpAccessChain %_ptr_Output_v3float %a %int_4
+               OpStore %34 %33
+         %38 = OpAccessChain %_ptr_Output_v3float %a %int_5
+               OpStore %38 %37
+         %44 = OpAccessChain %_ptr_Output_float %b %int_0
+               OpStore %44 %float_6
+         %46 = OpAccessChain %_ptr_Output_float %b %int_1
+               OpStore %46 %float_7
+         %48 = OpAccessChain %_ptr_Output_float %b %int_2
+               OpStore %48 %float_8
+         %50 = OpAccessChain %_ptr_Output_float %b %int_3
+               OpStore %50 %float_9
+         %52 = OpAccessChain %_ptr_Output_float %b %int_4
+               OpStore %52 %float_10
+         %54 = OpAccessChain %_ptr_Output_float %b %int_5
+               OpStore %54 %float_11
+         %60 = OpLoad %v4float %piglit_vertex
+               OpStore %vertex_to_gs %60
+               OpReturn
+               OpFunctionEnd
+
+[vertex shader]
+#version 150
+#extension GL_ARB_enhanced_layouts: require
+#extension GL_ARB_separate_shader_objects: require
+
+// consume X/Y/Z components of 6 vectors
+layout(location = 0) out vec3 a[6];
+
+// consumes W component of 6 vectors
+layout(location = 0, component = 3) out float b[6];
+
+layout(location = 6) out vec4 vertex_to_gs;
+
+in vec4 piglit_vertex;
+
+void main()
+{
+  a[0] = vec3(0.0);
+  a[1] = vec3(1.0);
+  a[2] = vec3(2.0);
+  a[3] = vec3(3.0);
+  a[4] = vec3(4.0);
+  a[5] = vec3(5.0);
+  b[0] = 6.0;
+  b[1] = 7.0;
+  b[2] = 8.0;
+  b[3] = 9.0;
+  b[4] = 10.0;
+  b[5] = 11.0;
+
+  vertex_to_gs = piglit_vertex;
+}
+
+[geometry shader spirv]
+; Automatically generated from the GLSL by gen_gl_spirv_tests.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 62
+; Schema: 0
+               OpCapability Geometry
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Geometry %main "main" %_ %vertex_to_gs %a_to_fs %a %b_to_fs %b
+               OpExecutionMode %main Triangles
+               OpExecutionMode %main Invocations 1
+               OpExecutionMode %main OutputTriangleStrip
+               OpExecutionMode %main OutputVertices 3
+               OpSource GLSL 450
+               OpSourceExtension "GL_ARB_enhanced_layouts"
+               OpSourceExtension "GL_ARB_separate_shader_objects"
+               OpName %_ ""
+               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
+               OpDecorate %gl_PerVertex Block
+               OpDecorate %vertex_to_gs Location 6
+               OpDecorate %a_to_fs Location 0
+               OpDecorate %a Location 0
+               OpDecorate %b_to_fs Component 3
+               OpDecorate %b_to_fs Location 0
+               OpDecorate %b Component 3
+               OpDecorate %b Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+      %int_0 = OpConstant %int 0
+      %int_3 = OpConstant %int 3
+       %bool = OpTypeBool
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+          %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+     %uint_3 = OpConstant %uint 3
+%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3
+%_ptr_Input__arr_v4float_uint_3 = OpTypePointer Input %_arr_v4float_uint_3
+%vertex_to_gs = OpVariable %_ptr_Input__arr_v4float_uint_3 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+    %v3float = OpTypeVector %float 3
+     %uint_6 = OpConstant %uint 6
+%_arr_v3float_uint_6 = OpTypeArray %v3float %uint_6
+%_ptr_Output__arr_v3float_uint_6 = OpTypePointer Output %_arr_v3float_uint_6
+    %a_to_fs = OpVariable %_ptr_Output__arr_v3float_uint_6 Output
+%_arr__arr_v3float_uint_6_uint_3 = OpTypeArray %_arr_v3float_uint_6 %uint_3
+%_ptr_Input__arr__arr_v3float_uint_6_uint_3 = OpTypePointer Input %_arr__arr_v3float_uint_6_uint_3
+          %a = OpVariable %_ptr_Input__arr__arr_v3float_uint_6_uint_3 Input
+%_ptr_Input__arr_v3float_uint_6 = OpTypePointer Input %_arr_v3float_uint_6
+%_arr_float_uint_6 = OpTypeArray %float %uint_6
+%_ptr_Output__arr_float_uint_6 = OpTypePointer Output %_arr_float_uint_6
+    %b_to_fs = OpVariable %_ptr_Output__arr_float_uint_6 Output
+%_arr__arr_float_uint_6_uint_3 = OpTypeArray %_arr_float_uint_6 %uint_3
+%_ptr_Input__arr__arr_float_uint_6_uint_3 = OpTypePointer Input %_arr__arr_float_uint_6_uint_3
+          %b = OpVariable %_ptr_Input__arr__arr_float_uint_6_uint_3 Input
+%_ptr_Input__arr_float_uint_6 = OpTypePointer Input %_arr_float_uint_6
+      %int_1 = OpConstant %int 1
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+          %i = OpVariable %_ptr_Function_int Function
+               OpStore %i %int_0
+               OpBranch %10
+         %10 = OpLabel
+               OpLoopMerge %12 %13 None
+               OpBranch %14
+         %14 = OpLabel
+         %15 = OpLoad %int %i
+         %18 = OpSLessThan %bool %15 %int_3
+               OpBranchConditional %18 %11 %12
+         %11 = OpLabel
+         %31 = OpLoad %int %i
+         %33 = OpAccessChain %_ptr_Input_v4float %vertex_to_gs %31
+         %34 = OpLoad %v4float %33
+         %36 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+               OpStore %36 %34
+         %45 = OpLoad %int %i
+         %47 = OpAccessChain %_ptr_Input__arr_v3float_uint_6 %a %45
+         %48 = OpLoad %_arr_v3float_uint_6 %47
+               OpStore %a_to_fs %48
+         %55 = OpLoad %int %i
+         %57 = OpAccessChain %_ptr_Input__arr_float_uint_6 %b %55
+         %58 = OpLoad %_arr_float_uint_6 %57
+               OpStore %b_to_fs %58
+               OpEmitVertex
+               OpBranch %13
+         %13 = OpLabel
+         %59 = OpLoad %int %i
+         %61 = OpIAdd %int %59 %int_1
+               OpStore %i %61
+               OpBranch %10
+         %12 = OpLabel
+               OpReturn
+               OpFunctionEnd
+
+[geometry shader]
+#version 150
+#extension GL_ARB_enhanced_layouts: require
+#extension GL_ARB_separate_shader_objects: require
+#extension GL_ARB_arrays_of_arrays: require
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 3) out;
+
+// consume X/Y/Z components of 6 vectors
+layout(location = 0) in vec3 a[3][6];
+
+// consumes W component of 6 vectors
+layout(location = 0, component = 3) in float b[3][6];
+
+layout(location = 6) in vec4 vertex_to_gs[3];
+
+// consume X/Y/Z components of 6 vectors
+layout(location = 0) out vec3 a_to_fs[6];
+
+// consumes W component of 6 vectors
+layout(location = 0, component = 3) out float b_to_fs[6];
+
+void main()
+{
+  for (int i = 0; i < 3; i++) {
+    gl_Position = vertex_to_gs[i];
+    a_to_fs = a[i];
+    b_to_fs = b[i];
+    EmitVertex();
+  }
+}
+
+[fragment shader spirv]
+; Automatically generated from the GLSL by gen_gl_spirv_tests.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 72
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %color %a_to_fs %b_to_fs
+               OpExecutionMode %main OriginLowerLeft
+               OpSource GLSL 450
+               OpSourceExtension "GL_ARB_enhanced_layouts"
+               OpSourceExtension "GL_ARB_separate_shader_objects"
+               OpDecorate %color Location 0
+               OpDecorate %a_to_fs Location 0
+               OpDecorate %b_to_fs Component 3
+               OpDecorate %b_to_fs Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+      %color = OpVariable %_ptr_Output_v4float Output
+    %float_1 = OpConstant %float 1
+    %float_0 = OpConstant %float 0
+         %12 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+        %int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+      %int_0 = OpConstant %int 0
+      %int_6 = OpConstant %int 6
+       %bool = OpTypeBool
+    %v3float = OpTypeVector %float 3
+       %uint = OpTypeInt 32 0
+     %uint_6 = OpConstant %uint 6
+%_arr_v3float_uint_6 = OpTypeArray %v3float %uint_6
+%_ptr_Input__arr_v3float_uint_6 = OpTypePointer Input %_arr_v3float_uint_6
+    %a_to_fs = OpVariable %_ptr_Input__arr_v3float_uint_6 Input
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+     %v3bool = OpTypeVector %bool 3
+         %44 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
+      %int_1 = OpConstant %int 1
+     %int_12 = OpConstant %int 12
+%_arr_float_uint_6 = OpTypeArray %float %uint_6
+%_ptr_Input__arr_float_uint_6 = OpTypePointer Input %_arr_float_uint_6
+    %b_to_fs = OpVariable %_ptr_Input__arr_float_uint_6 Input
+%_ptr_Input_float = OpTypePointer Input %float
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+          %i = OpVariable %_ptr_Function_int Function
+        %i_0 = OpVariable %_ptr_Function_int Function
+               OpStore %color %12
+               OpStore %i %int_0
+               OpBranch %17
+         %17 = OpLabel
+               OpLoopMerge %19 %20 None
+               OpBranch %21
+         %21 = OpLabel
+         %22 = OpLoad %int %i
+         %25 = OpSLessThan %bool %22 %int_6
+               OpBranchConditional %25 %18 %19
+         %18 = OpLabel
+         %32 = OpLoad %int %i
+         %34 = OpAccessChain %_ptr_Input_v3float %a_to_fs %32
+         %35 = OpLoad %v3float %34
+         %36 = OpLoad %int %i
+         %37 = OpConvertSToF %float %36
+         %38 = OpCompositeConstruct %v3float %37 %37 %37
+         %40 = OpFOrdNotEqual %v3bool %35 %38
+         %41 = OpAny %bool %40
+               OpSelectionMerge %43 None
+               OpBranchConditional %41 %42 %43
+         %42 = OpLabel
+               OpStore %color %44
+               OpBranch %43
+         %43 = OpLabel
+               OpBranch %20
+         %20 = OpLabel
+         %45 = OpLoad %int %i
+         %47 = OpIAdd %int %45 %int_1
+               OpStore %i %47
+               OpBranch %17
+         %19 = OpLabel
+               OpStore %i_0 %int_6
+               OpBranch %49
+         %49 = OpLabel
+               OpLoopMerge %51 %52 None
+               OpBranch %53
+         %53 = OpLabel
+         %54 = OpLoad %int %i_0
+         %56 = OpSLessThan %bool %54 %int_12
+               OpBranchConditional %56 %50 %51
+         %50 = OpLabel
+         %60 = OpLoad %int %i_0
+         %61 = OpISub %int %60 %int_6
+         %63 = OpAccessChain %_ptr_Input_float %b_to_fs %61
+         %64 = OpLoad %float %63
+         %65 = OpLoad %int %i_0
+         %66 = OpConvertSToF %float %65
+         %67 = OpFOrdNotEqual %bool %64 %66
+               OpSelectionMerge %69 None
+               OpBranchConditional %67 %68 %69
+         %68 = OpLabel
+               OpStore %color %44
+               OpBranch %69
+         %69 = OpLabel
+               OpBranch %52
+         %52 = OpLabel
+         %70 = OpLoad %int %i_0
+         %71 = OpIAdd %int %70 %int_1
+               OpStore %i_0 %71
+               OpBranch %49
+         %51 = OpLabel
+               OpReturn
+               OpFunctionEnd
+
+[fragment shader]
+#version 150
+#extension GL_ARB_enhanced_layouts: require
+#extension GL_ARB_separate_shader_objects: require
+
+out vec4 color;
+
+// consume X/Y/Z components of 6 vectors
+layout(location = 0) in vec3 a_to_fs[6];
+
+// consumes W component of 6 vectors
+layout(location = 0, component = 3) in float b_to_fs[6];
+
+void main()
+{
+  color = vec4(1, 0, 0, 1);
+
+  for (int i = 0; i < 6; i++) {
+    if (a_to_fs[i] != vec3(float(i)))
+      color = vec4(0, 1, 0, 1);
+  }
+
+  for (int i = 6; i < 12; i++) {
+    if (b_to_fs[i-6] != float(i))
+      color = vec4(0, 1, 0, 1);
+  }
+}
+
+[test]
+clear color 0.2 0.2 0.2 1.0
+clear
+draw rect -1 -1 2 2
+probe all rgb 1 0 0
diff --git a/tests/spec/arb_gl_spirv/execution/component-layout-vs-gs-fs-double.shader_test b/tests/spec/arb_gl_spirv/execution/component-layout-vs-gs-fs-double.shader_test
new file mode 100644
index 000000000..b96453efe
--- /dev/null
+++ b/tests/spec/arb_gl_spirv/execution/component-layout-vs-gs-fs-double.shader_test
@@ -0,0 +1,312 @@ 
+# Test layout component qualifier on a double between multiple shader stages.
+#
+# Copied from
+# arb_enhanced_layouts/execution/component-layout/vs-gs-fs-double.shader_test,
+# the difference is that we explicitly specify locations for inputs and outputs
+# in component-layout tests.  The current version of glslang doesn't handle a
+# mixture of explicit and implicit locations for inputs and outputs, so we made
+# all locations explicit.
+
+[require]
+SPIRV YES
+GLSL >= 1.50
+GL_ARB_enhanced_layouts
+GL_ARB_separate_shader_objects
+GL_ARB_gpu_shader_fp64
+
+[vertex shader spirv]
+; Automatically generated from the GLSL by gen_gl_spirv_tests.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 28
+; Schema: 0
+               OpCapability Shader
+               OpCapability Float64
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %main "main" %a %b %vertex_to_gs %piglit_vertex %gl_VertexID %gl_InstanceID
+               OpSource GLSL 450
+               OpSourceExtension "GL_ARB_enhanced_layouts"
+               OpSourceExtension "GL_ARB_separate_shader_objects"
+               OpDecorate %a Flat
+               OpDecorate %a Location 0
+               OpDecorate %b Flat
+               OpDecorate %b Component 2
+               OpDecorate %b Location 1
+               OpDecorate %vertex_to_gs Location 2
+               OpDecorate %piglit_vertex Location 0
+               OpDecorate %gl_VertexID BuiltIn VertexId
+               OpDecorate %gl_InstanceID BuiltIn InstanceId
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+     %double = OpTypeFloat 64
+   %v3double = OpTypeVector %double 3
+%_ptr_Output_v3double = OpTypePointer Output %v3double
+          %a = OpVariable %_ptr_Output_v3double Output
+   %double_0 = OpConstant %double 0
+%double_0_75 = OpConstant %double 0.75
+   %double_1 = OpConstant %double 1
+         %13 = OpConstantComposite %v3double %double_0 %double_0_75 %double_1
+%_ptr_Output_double = OpTypePointer Output %double
+          %b = OpVariable %_ptr_Output_double Output
+ %double_0_5 = OpConstant %double 0.5
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%vertex_to_gs = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%piglit_vertex = OpVariable %_ptr_Input_v4float Input
+        %int = OpTypeInt 32 1
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_VertexID = OpVariable %_ptr_Input_int Input
+%gl_InstanceID = OpVariable %_ptr_Input_int Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+               OpStore %a %13
+               OpStore %b %double_0_5
+         %23 = OpLoad %v4float %piglit_vertex
+               OpStore %vertex_to_gs %23
+               OpReturn
+               OpFunctionEnd
+
+[vertex shader]
+#version 150
+#extension GL_ARB_enhanced_layouts: require
+#extension GL_ARB_separate_shader_objects: require
+#extension GL_ARB_gpu_shader_fp64: require
+
+// consume X/Y/Z components
+layout(location = 0) flat out dvec3 a;
+
+// consumes W component
+layout(location = 1, component = 2) flat out double b;
+
+layout(location = 2) out vec4 vertex_to_gs;
+
+in vec4 piglit_vertex;
+
+void main()
+{
+  a = dvec3(0.0, 0.75, 1.0);
+  b = 0.5LF;
+
+  vertex_to_gs = piglit_vertex;
+}
+
+[geometry shader spirv]
+; Automatically generated from the GLSL by gen_gl_spirv_tests.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 60
+; Schema: 0
+               OpCapability Geometry
+               OpCapability Float64
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Geometry %main "main" %_ %vertex_to_gs %a_to_fs %a %b_to_fs %b
+               OpExecutionMode %main Triangles
+               OpExecutionMode %main Invocations 1
+               OpExecutionMode %main OutputTriangleStrip
+               OpExecutionMode %main OutputVertices 3
+               OpSource GLSL 450
+               OpSourceExtension "GL_ARB_enhanced_layouts"
+               OpSourceExtension "GL_ARB_separate_shader_objects"
+               OpName %_ ""
+               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
+               OpDecorate %gl_PerVertex Block
+               OpDecorate %vertex_to_gs Location 2
+               OpDecorate %a_to_fs Flat
+               OpDecorate %a_to_fs Location 0
+               OpDecorate %a Flat
+               OpDecorate %a Location 0
+               OpDecorate %b_to_fs Flat
+               OpDecorate %b_to_fs Component 2
+               OpDecorate %b_to_fs Location 1
+               OpDecorate %b Flat
+               OpDecorate %b Component 2
+               OpDecorate %b Location 1
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+      %int_0 = OpConstant %int 0
+      %int_3 = OpConstant %int 3
+       %bool = OpTypeBool
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+          %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+     %uint_3 = OpConstant %uint 3
+%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3
+%_ptr_Input__arr_v4float_uint_3 = OpTypePointer Input %_arr_v4float_uint_3
+%vertex_to_gs = OpVariable %_ptr_Input__arr_v4float_uint_3 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+     %double = OpTypeFloat 64
+   %v3double = OpTypeVector %double 3
+%_ptr_Output_v3double = OpTypePointer Output %v3double
+    %a_to_fs = OpVariable %_ptr_Output_v3double Output
+%_arr_v3double_uint_3 = OpTypeArray %v3double %uint_3
+%_ptr_Input__arr_v3double_uint_3 = OpTypePointer Input %_arr_v3double_uint_3
+          %a = OpVariable %_ptr_Input__arr_v3double_uint_3 Input
+%_ptr_Input_v3double = OpTypePointer Input %v3double
+%_ptr_Output_double = OpTypePointer Output %double
+    %b_to_fs = OpVariable %_ptr_Output_double Output
+%_arr_double_uint_3 = OpTypeArray %double %uint_3
+%_ptr_Input__arr_double_uint_3 = OpTypePointer Input %_arr_double_uint_3
+          %b = OpVariable %_ptr_Input__arr_double_uint_3 Input
+%_ptr_Input_double = OpTypePointer Input %double
+      %int_1 = OpConstant %int 1
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+          %i = OpVariable %_ptr_Function_int Function
+               OpStore %i %int_0
+               OpBranch %10
+         %10 = OpLabel
+               OpLoopMerge %12 %13 None
+               OpBranch %14
+         %14 = OpLabel
+         %15 = OpLoad %int %i
+         %18 = OpSLessThan %bool %15 %int_3
+               OpBranchConditional %18 %11 %12
+         %11 = OpLabel
+         %31 = OpLoad %int %i
+         %33 = OpAccessChain %_ptr_Input_v4float %vertex_to_gs %31
+         %34 = OpLoad %v4float %33
+         %36 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+               OpStore %36 %34
+         %44 = OpLoad %int %i
+         %46 = OpAccessChain %_ptr_Input_v3double %a %44
+         %47 = OpLoad %v3double %46
+               OpStore %a_to_fs %47
+         %53 = OpLoad %int %i
+         %55 = OpAccessChain %_ptr_Input_double %b %53
+         %56 = OpLoad %double %55
+               OpStore %b_to_fs %56
+               OpEmitVertex
+               OpBranch %13
+         %13 = OpLabel
+         %57 = OpLoad %int %i
+         %59 = OpIAdd %int %57 %int_1
+               OpStore %i %59
+               OpBranch %10
+         %12 = OpLabel
+               OpReturn
+               OpFunctionEnd
+
+[geometry shader]
+#version 150
+#extension GL_ARB_enhanced_layouts: require
+#extension GL_ARB_separate_shader_objects: require
+#extension GL_ARB_gpu_shader_fp64: require
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 3) out;
+
+// consume X/Y/Z components
+layout(location = 0) flat in dvec3 a[3];
+
+// consumes W component
+layout(location = 1, component = 2) flat in double b[3];
+
+layout(location = 2) in vec4 vertex_to_gs[3];
+
+// consume X/Y/Z components
+layout(location = 0) flat out dvec3 a_to_fs;
+
+// consumes W component
+layout(location = 1, component = 2) flat out double b_to_fs;
+
+void main()
+{
+  for (int i = 0; i < 3; i++) {
+    gl_Position = vertex_to_gs[i];
+    a_to_fs = a[i];
+    b_to_fs = b[i];
+    EmitVertex();
+  }
+}
+
+[fragment shader spirv]
+; Automatically generated from the GLSL by gen_gl_spirv_tests.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 25
+; Schema: 0
+               OpCapability Shader
+               OpCapability Float64
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %color %b_to_fs %a_to_fs
+               OpExecutionMode %main OriginLowerLeft
+               OpSource GLSL 450
+               OpSourceExtension "GL_ARB_enhanced_layouts"
+               OpSourceExtension "GL_ARB_separate_shader_objects"
+               OpDecorate %color Location 0
+               OpDecorate %b_to_fs Flat
+               OpDecorate %b_to_fs Component 2
+               OpDecorate %b_to_fs Location 1
+               OpDecorate %a_to_fs Flat
+               OpDecorate %a_to_fs Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+      %color = OpVariable %_ptr_Output_v4float Output
+     %double = OpTypeFloat 64
+%_ptr_Input_double = OpTypePointer Input %double
+    %b_to_fs = OpVariable %_ptr_Input_double Input
+   %v3double = OpTypeVector %double 3
+%_ptr_Input_v3double = OpTypePointer Input %v3double
+    %a_to_fs = OpVariable %_ptr_Input_v3double Input
+    %v3float = OpTypeVector %float 3
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %13 = OpLoad %double %b_to_fs
+         %14 = OpFConvert %float %13
+         %18 = OpLoad %v3double %a_to_fs
+         %20 = OpFConvert %v3float %18
+         %21 = OpCompositeExtract %float %20 0
+         %22 = OpCompositeExtract %float %20 1
+         %23 = OpCompositeExtract %float %20 2
+         %24 = OpCompositeConstruct %v4float %14 %21 %22 %23
+               OpStore %color %24
+               OpReturn
+               OpFunctionEnd
+
+[fragment shader]
+#version 150
+#extension GL_ARB_enhanced_layouts: require
+#extension GL_ARB_separate_shader_objects: require
+#extension GL_ARB_gpu_shader_fp64: require
+
+out vec4 color;
+
+// consume X/Y/Z components
+layout(location = 0) flat in dvec3 a_to_fs;
+
+// consumes W component
+layout(location = 1, component = 2) flat in double b_to_fs;
+
+void main()
+{
+  color = vec4(b_to_fs, a_to_fs);
+}
+
+[test]
+clear color 0.1 0.1 0.1 0.1
+clear
+
+draw rect -1 -1 2 2
+probe all rgb 0.5 0 0.75
diff --git a/tests/spec/arb_gl_spirv/execution/component-layout-vs-gs-fs.shader_test b/tests/spec/arb_gl_spirv/execution/component-layout-vs-gs-fs.shader_test
new file mode 100644
index 000000000..8234810ff
--- /dev/null
+++ b/tests/spec/arb_gl_spirv/execution/component-layout-vs-gs-fs.shader_test
@@ -0,0 +1,291 @@ 
+# Test layout component qualifier between multiple shader stages.
+#
+# Copied from
+# arb_enhanced_layouts/execution/component-layout/vs-gs-fs.shader_test,
+# the difference is that we explicitly specify locations for inputs and outputs
+# in component-layout tests.  The current version of glslang doesn't handle a
+# mixture of explicit and implicit locations for inputs and outputs, so we made
+# all locations explicit.
+
+[require]
+SPIRV YES
+GLSL >= 1.50
+GL_ARB_enhanced_layouts
+GL_ARB_separate_shader_objects
+
+[vertex shader spirv]
+; Automatically generated from the GLSL by gen_gl_spirv_tests.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 27
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %main "main" %a %b %vertex_to_gs %piglit_vertex %gl_VertexID %gl_InstanceID
+               OpSource GLSL 450
+               OpSourceExtension "GL_ARB_enhanced_layouts"
+               OpSourceExtension "GL_ARB_separate_shader_objects"
+               OpDecorate %a Location 0
+               OpDecorate %b Component 3
+               OpDecorate %b Location 0
+               OpDecorate %vertex_to_gs Location 1
+               OpDecorate %piglit_vertex Location 0
+               OpDecorate %gl_VertexID BuiltIn VertexId
+               OpDecorate %gl_InstanceID BuiltIn InstanceId
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+          %a = OpVariable %_ptr_Output_v3float Output
+    %float_0 = OpConstant %float 0
+ %float_0_75 = OpConstant %float 0.75
+    %float_1 = OpConstant %float 1
+         %13 = OpConstantComposite %v3float %float_0 %float_0_75 %float_1
+%_ptr_Output_float = OpTypePointer Output %float
+          %b = OpVariable %_ptr_Output_float Output
+  %float_0_5 = OpConstant %float 0.5
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%vertex_to_gs = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%piglit_vertex = OpVariable %_ptr_Input_v4float Input
+        %int = OpTypeInt 32 1
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_VertexID = OpVariable %_ptr_Input_int Input
+%gl_InstanceID = OpVariable %_ptr_Input_int Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+               OpStore %a %13
+               OpStore %b %float_0_5
+         %22 = OpLoad %v4float %piglit_vertex
+               OpStore %vertex_to_gs %22
+               OpReturn
+               OpFunctionEnd
+
+[vertex shader]
+#version 150
+#extension GL_ARB_enhanced_layouts: require
+#extension GL_ARB_separate_shader_objects: require
+
+// consume X/Y/Z components
+layout(location = 0) out vec3 a;
+
+// consumes W component
+layout(location = 0, component = 3) out float b;
+
+layout(location = 1) out vec4 vertex_to_gs;
+
+in vec4 piglit_vertex;
+
+void main()
+{
+  a = vec3(0.0, 0.75, 1.0);
+  b = 0.5;
+
+  vertex_to_gs = piglit_vertex;
+}
+
+[geometry shader spirv]
+; Automatically generated from the GLSL by gen_gl_spirv_tests.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 59
+; Schema: 0
+               OpCapability Geometry
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Geometry %main "main" %_ %vertex_to_gs %a_to_fs %a %b_to_fs %b
+               OpExecutionMode %main Triangles
+               OpExecutionMode %main Invocations 1
+               OpExecutionMode %main OutputTriangleStrip
+               OpExecutionMode %main OutputVertices 3
+               OpSource GLSL 450
+               OpSourceExtension "GL_ARB_enhanced_layouts"
+               OpSourceExtension "GL_ARB_separate_shader_objects"
+               OpName %_ ""
+               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
+               OpDecorate %gl_PerVertex Block
+               OpDecorate %vertex_to_gs Location 1
+               OpDecorate %a_to_fs Location 0
+               OpDecorate %a Location 0
+               OpDecorate %b_to_fs Component 3
+               OpDecorate %b_to_fs Location 0
+               OpDecorate %b Component 3
+               OpDecorate %b Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+      %int_0 = OpConstant %int 0
+      %int_3 = OpConstant %int 3
+       %bool = OpTypeBool
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+          %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+     %uint_3 = OpConstant %uint 3
+%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3
+%_ptr_Input__arr_v4float_uint_3 = OpTypePointer Input %_arr_v4float_uint_3
+%vertex_to_gs = OpVariable %_ptr_Input__arr_v4float_uint_3 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+    %v3float = OpTypeVector %float 3
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+    %a_to_fs = OpVariable %_ptr_Output_v3float Output
+%_arr_v3float_uint_3 = OpTypeArray %v3float %uint_3
+%_ptr_Input__arr_v3float_uint_3 = OpTypePointer Input %_arr_v3float_uint_3
+          %a = OpVariable %_ptr_Input__arr_v3float_uint_3 Input
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+%_ptr_Output_float = OpTypePointer Output %float
+    %b_to_fs = OpVariable %_ptr_Output_float Output
+%_arr_float_uint_3 = OpTypeArray %float %uint_3
+%_ptr_Input__arr_float_uint_3 = OpTypePointer Input %_arr_float_uint_3
+          %b = OpVariable %_ptr_Input__arr_float_uint_3 Input
+%_ptr_Input_float = OpTypePointer Input %float
+      %int_1 = OpConstant %int 1
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+          %i = OpVariable %_ptr_Function_int Function
+               OpStore %i %int_0
+               OpBranch %10
+         %10 = OpLabel
+               OpLoopMerge %12 %13 None
+               OpBranch %14
+         %14 = OpLabel
+         %15 = OpLoad %int %i
+         %18 = OpSLessThan %bool %15 %int_3
+               OpBranchConditional %18 %11 %12
+         %11 = OpLabel
+         %31 = OpLoad %int %i
+         %33 = OpAccessChain %_ptr_Input_v4float %vertex_to_gs %31
+         %34 = OpLoad %v4float %33
+         %36 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+               OpStore %36 %34
+         %43 = OpLoad %int %i
+         %45 = OpAccessChain %_ptr_Input_v3float %a %43
+         %46 = OpLoad %v3float %45
+               OpStore %a_to_fs %46
+         %52 = OpLoad %int %i
+         %54 = OpAccessChain %_ptr_Input_float %b %52
+         %55 = OpLoad %float %54
+               OpStore %b_to_fs %55
+               OpEmitVertex
+               OpBranch %13
+         %13 = OpLabel
+         %56 = OpLoad %int %i
+         %58 = OpIAdd %int %56 %int_1
+               OpStore %i %58
+               OpBranch %10
+         %12 = OpLabel
+               OpReturn
+               OpFunctionEnd
+
+[geometry shader]
+#version 150
+#extension GL_ARB_enhanced_layouts: require
+#extension GL_ARB_separate_shader_objects: require
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 3) out;
+
+// consume X/Y/Z components
+layout(location = 0) in vec3 a[3];
+
+// consumes W component
+layout(location = 0, component = 3) in float b[3];
+
+layout(location = 1) in vec4 vertex_to_gs[3];
+
+// consume X/Y/Z components
+layout(location = 0) out vec3 a_to_fs;
+
+// consumes W component
+layout(location = 0, component = 3) out float b_to_fs;
+
+void main()
+{
+  for (int i = 0; i < 3; i++) {
+    gl_Position = vertex_to_gs[i];
+    a_to_fs = a[i];
+    b_to_fs = b[i];
+    EmitVertex();
+  }
+}
+
+[fragment shader spirv]
+; Automatically generated from the GLSL by gen_gl_spirv_tests.py. DO NOT EDIT
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 21
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %color %b_to_fs %a_to_fs
+               OpExecutionMode %main OriginLowerLeft
+               OpSource GLSL 450
+               OpSourceExtension "GL_ARB_enhanced_layouts"
+               OpSourceExtension "GL_ARB_separate_shader_objects"
+               OpDecorate %color Location 0
+               OpDecorate %b_to_fs Component 3
+               OpDecorate %b_to_fs Location 0
+               OpDecorate %a_to_fs Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+      %color = OpVariable %_ptr_Output_v4float Output
+%_ptr_Input_float = OpTypePointer Input %float
+    %b_to_fs = OpVariable %_ptr_Input_float Input
+    %v3float = OpTypeVector %float 3
+%_ptr_Input_v3float = OpTypePointer Input %v3float
+    %a_to_fs = OpVariable %_ptr_Input_v3float Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %12 = OpLoad %float %b_to_fs
+         %16 = OpLoad %v3float %a_to_fs
+         %17 = OpCompositeExtract %float %16 0
+         %18 = OpCompositeExtract %float %16 1
+         %19 = OpCompositeExtract %float %16 2
+         %20 = OpCompositeConstruct %v4float %12 %17 %18 %19
+               OpStore %color %20
+               OpReturn
+               OpFunctionEnd
+
+[fragment shader]
+#version 150
+#extension GL_ARB_enhanced_layouts: require
+#extension GL_ARB_separate_shader_objects: require
+
+out vec4 color;
+
+// consume X/Y/Z components
+layout(location = 0) in vec3 a_to_fs;
+
+// consumes W component
+layout(location = 0, component = 3) in float b_to_fs;
+
+void main()
+{
+  color = vec4(b_to_fs, a_to_fs);
+}
+
+[test]
+clear color 0.1 0.1 0.1 0.1
+clear
+
+draw rect -1 -1 2 2
+probe all rgb 0.5 0 0.75