vulkan: Add tests for block layout location calculations

Submitted by Neil Roberts on Nov. 8, 2018, 12:24 p.m.

Details

Message ID 20181108122432.14084-1-nroberts@igalia.com
State New
Headers show
Series "vulkan: Add tests for block layout location calculations" ( rev: 1 ) in Piglit

Not browsing as part of any series.

Commit Message

Neil Roberts Nov. 8, 2018, 12:24 p.m.
All but one of these are currently broken on anv.

See: https://patchwork.freedesktop.org/series/40797/
---
 .../block-layout-location.vk_shader_test      | 117 +++++++++++++++++
 ...lock-member-layout-location.vk_shader_test |  68 ++++++++++
 ...block-mixed-layout-location.vk_shader_test | 120 ++++++++++++++++++
 .../double-vertex-input-block.vk_shader_test  |  98 ++++++++++++++
 4 files changed, 403 insertions(+)
 create mode 100644 tests/vulkan/shaders/block-layout-location.vk_shader_test
 create mode 100644 tests/vulkan/shaders/block-member-layout-location.vk_shader_test
 create mode 100644 tests/vulkan/shaders/block-mixed-layout-location.vk_shader_test
 create mode 100644 tests/vulkan/shaders/double-vertex-input-block.vk_shader_test

Patch hide | download patch | download mbox

diff --git a/tests/vulkan/shaders/block-layout-location.vk_shader_test b/tests/vulkan/shaders/block-layout-location.vk_shader_test
new file mode 100644
index 000000000..2c81375d8
--- /dev/null
+++ b/tests/vulkan/shaders/block-layout-location.vk_shader_test
@@ -0,0 +1,117 @@ 
+# Test that interface block members are correctly matched by explicit
+# location.
+
+[vertex shader spirv]
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %main "main" %name %_ %piglit_vertex
+               OpSource GLSL 440
+               OpName %main "main"
+               OpName %block "block"
+               OpMemberName %block 0 "a"
+               OpMemberName %block 1 "b"
+               OpMemberName %block 2 "c"
+               OpMemberName %block 3 "d"
+               OpName %name "name"
+               OpName %gl_PerVertex "gl_PerVertex"
+               OpMemberName %gl_PerVertex 0 "gl_Position"
+               OpMemberName %gl_PerVertex 1 "gl_PointSize"
+               OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
+               OpName %_ ""
+               OpName %piglit_vertex "piglit_vertex"
+               OpDecorate %block Block
+; Only the main name variable has a location. The locations of the members
+; should be derived from this.
+               OpDecorate %name Location 0
+               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+               OpDecorate %gl_PerVertex Block
+               OpDecorate %piglit_vertex Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+      %block = OpTypeStruct %v4float %v4float %v4float %v4float
+%_ptr_Output_block = OpTypePointer Output %block
+       %name = OpVariable %_ptr_Output_block Output
+        %int = OpTypeInt 32 1
+      %int_0 = OpConstant %int 0
+    %float_1 = OpConstant %float 1
+    %float_0 = OpConstant %float 0
+         %15 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+      %int_1 = OpConstant %int 1
+         %19 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
+      %int_2 = OpConstant %int 2
+         %22 = OpConstantComposite %v4float %float_0 %float_0 %float_1 %float_1
+      %int_3 = OpConstant %int 3
+         %25 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+       %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
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+          %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%piglit_vertex = OpVariable %_ptr_Input_v4float Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %17 = OpAccessChain %_ptr_Output_v4float %name %int_0
+               OpStore %17 %15
+         %20 = OpAccessChain %_ptr_Output_v4float %name %int_1
+               OpStore %20 %19
+         %23 = OpAccessChain %_ptr_Output_v4float %name %int_2
+               OpStore %23 %22
+         %26 = OpAccessChain %_ptr_Output_v4float %name %int_3
+               OpStore %26 %25
+         %35 = OpLoad %v4float %piglit_vertex
+         %36 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+               OpStore %36 %35
+               OpReturn
+               OpFunctionEnd
+
+[fragment shader]
+#version 440
+
+layout(location = 0) in vec4 a;
+layout(location = 1) in vec4 b;
+layout(location = 2) in vec4 c;
+layout(location = 3) in vec4 d;
+
+layout(std140, push_constant) uniform block {
+        int i;
+};
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+        if (i == 0) {
+                color = a;
+        } else if (i == 1) {
+                color = b;
+        } else if (i == 2) {
+                color = c;
+        } else if (i == 3) {
+                color = d;
+        }
+}
+
+[test]
+uniform int 0 0
+draw rect -1 -1 1 1
+relative probe rect rgb (0.0, 0.0, 0.5, 0.5) (1.0, 0.0, 0.0)
+
+uniform int 0 1
+draw rect 0 -1 1 1
+relative probe rect rgb (0.5, 0.0, 0.5, 0.5) (0.0, 1.0, 0.0)
+
+uniform int 0 2
+draw rect -1 0 1 1
+relative probe rect rgb (0.0, 0.5, 0.5, 0.5) (0.0, 0.0, 1.0)
+
+uniform int 0 3
+draw rect 0 0 1 1
+relative probe rect rgb (0.5, 0.5, 0.5, 0.5) (1.0, 1.0, 1.0)
diff --git a/tests/vulkan/shaders/block-member-layout-location.vk_shader_test b/tests/vulkan/shaders/block-member-layout-location.vk_shader_test
new file mode 100644
index 000000000..f3287f24c
--- /dev/null
+++ b/tests/vulkan/shaders/block-member-layout-location.vk_shader_test
@@ -0,0 +1,68 @@ 
+# Test that interface block members are correctly matched by explicit
+# location.
+
+[vertex shader]
+#version 440
+
+layout(location = 0) in vec4 piglit_vertex;
+
+out block {
+        layout(location = 2) vec4 c;
+        layout(location = 3) vec4 d;
+        layout(location = 0) vec4 a;
+        layout(location = 1) vec4 b;
+} name;
+
+void main()
+{
+        name.a = vec4(1.0, 0.0, 0.0, 1.0);
+        name.b = vec4(0.0, 1.0, 0.0, 1.0);
+        name.c = vec4(0.0, 0.0, 1.0, 1.0);
+        name.d = vec4(1.0, 1.0, 1.0, 1.0);
+
+        gl_Position = piglit_vertex;
+}
+
+[fragment shader]
+#version 440
+
+layout(location = 0) in vec4 a;
+layout(location = 1) in vec4 b;
+layout(location = 2) in vec4 c;
+layout(location = 3) in vec4 d;
+
+layout(std140, push_constant) uniform block {
+        int i;
+};
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+        if (i == 0) {
+                color = a;
+        } else if (i == 1) {
+                color = b;
+        } else if (i == 2) {
+                color = c;
+        } else if (i == 3) {
+                color = d;
+        }
+}
+
+[test]
+uniform int 0 0
+draw rect -1 -1 1 1
+relative probe rect rgb (0.0, 0.0, 0.5, 0.5) (1.0, 0.0, 0.0)
+
+uniform int 0 1
+draw rect 0 -1 1 1
+relative probe rect rgb (0.5, 0.0, 0.5, 0.5) (0.0, 1.0, 0.0)
+
+uniform int 0 2
+draw rect -1 0 1 1
+relative probe rect rgb (0.0, 0.5, 0.5, 0.5) (0.0, 0.0, 1.0)
+
+uniform int 0 3
+draw rect 0 0 1 1
+relative probe rect rgb (0.5, 0.5, 0.5, 0.5) (1.0, 1.0, 1.0)
diff --git a/tests/vulkan/shaders/block-mixed-layout-location.vk_shader_test b/tests/vulkan/shaders/block-mixed-layout-location.vk_shader_test
new file mode 100644
index 000000000..7f32edf18
--- /dev/null
+++ b/tests/vulkan/shaders/block-mixed-layout-location.vk_shader_test
@@ -0,0 +1,120 @@ 
+# Test that interface block members are correctly matched by explicit
+# location.
+
+[vertex shader spirv]
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %main "main" %name %_ %piglit_vertex
+               OpSource GLSL 440
+               OpName %main "main"
+               OpName %block "block"
+               OpMemberName %block 0 "c"
+               OpMemberName %block 1 "d"
+               OpMemberName %block 2 "a"
+               OpMemberName %block 3 "b"
+               OpName %name "name"
+               OpName %gl_PerVertex "gl_PerVertex"
+               OpMemberName %gl_PerVertex 0 "gl_Position"
+               OpMemberName %gl_PerVertex 1 "gl_PointSize"
+               OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
+               OpName %_ ""
+               OpName %piglit_vertex "piglit_vertex"
+; The block is given a location of 2. The first two members don’t
+; have a location so they should be derived from the block location.
+               OpDecorate %name Location 2
+; The 3rd member has an explicit location. The 4th member should be
+; derived from this.
+               OpMemberDecorate %block 2 Location 0
+               OpDecorate %block Block
+               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+               OpDecorate %gl_PerVertex Block
+               OpDecorate %piglit_vertex Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+      %block = OpTypeStruct %v4float %v4float %v4float %v4float
+%_ptr_Output_block = OpTypePointer Output %block
+       %name = OpVariable %_ptr_Output_block Output
+        %int = OpTypeInt 32 1
+      %int_2 = OpConstant %int 2
+    %float_1 = OpConstant %float 1
+    %float_0 = OpConstant %float 0
+         %15 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+      %int_3 = OpConstant %int 3
+         %19 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
+      %int_0 = OpConstant %int 0
+         %22 = OpConstantComposite %v4float %float_0 %float_0 %float_1 %float_1
+      %int_1 = OpConstant %int 1
+         %25 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+       %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
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+          %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%piglit_vertex = OpVariable %_ptr_Input_v4float Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %17 = OpAccessChain %_ptr_Output_v4float %name %int_2
+               OpStore %17 %15
+         %20 = OpAccessChain %_ptr_Output_v4float %name %int_3
+               OpStore %20 %19
+         %23 = OpAccessChain %_ptr_Output_v4float %name %int_0
+               OpStore %23 %22
+         %26 = OpAccessChain %_ptr_Output_v4float %name %int_1
+               OpStore %26 %25
+         %35 = OpLoad %v4float %piglit_vertex
+         %36 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+               OpStore %36 %35
+               OpReturn
+               OpFunctionEnd
+
+[fragment shader]
+#version 440
+
+layout(location = 0) in vec4 a;
+layout(location = 1) in vec4 b;
+layout(location = 2) in vec4 c;
+layout(location = 3) in vec4 d;
+
+layout(std140, push_constant) uniform block {
+        int i;
+};
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+        if (i == 0) {
+                color = a;
+        } else if (i == 1) {
+                color = b;
+        } else if (i == 2) {
+                color = c;
+        } else if (i == 3) {
+                color = d;
+        }
+}
+
+[test]
+uniform int 0 0
+draw rect -1 -1 1 1
+relative probe rect rgb (0.0, 0.0, 0.5, 0.5) (1.0, 0.0, 0.0)
+
+uniform int 0 1
+draw rect 0 -1 1 1
+relative probe rect rgb (0.5, 0.0, 0.5, 0.5) (0.0, 1.0, 0.0)
+
+uniform int 0 2
+draw rect -1 0 1 1
+relative probe rect rgb (0.0, 0.5, 0.5, 0.5) (0.0, 0.0, 1.0)
+
+uniform int 0 3
+draw rect 0 0 1 1
+relative probe rect rgb (0.5, 0.5, 0.5, 0.5) (1.0, 1.0, 1.0)
diff --git a/tests/vulkan/shaders/double-vertex-input-block.vk_shader_test b/tests/vulkan/shaders/double-vertex-input-block.vk_shader_test
new file mode 100644
index 000000000..bb3c7f84b
--- /dev/null
+++ b/tests/vulkan/shaders/double-vertex-input-block.vk_shader_test
@@ -0,0 +1,98 @@ 
+# Tests that the driver assigns the correct locations to a vertex
+# input with doubles in it. The inputs are declared in a block with a
+# location so that the driver itself has to decide the locations of
+# the members. The first attribute is a dvec4 so the driver should
+# assign two locations to it.
+
+[require]
+shaderFloat64
+
+[vertex shader spirv]
+               OpCapability Shader
+               OpCapability Float64
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %main "main" %_ %piglit_vertex %color_out %name
+               OpSource GLSL 440
+               OpName %main "main"
+               OpName %gl_PerVertex "gl_PerVertex"
+               OpMemberName %gl_PerVertex 0 "gl_Position"
+               OpMemberName %gl_PerVertex 1 "gl_PointSize"
+               OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
+               OpName %_ ""
+               OpName %piglit_vertex "piglit_vertex"
+               OpName %color_out "color_out"
+               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+               OpDecorate %name Location 1
+               OpDecorate %gl_PerVertex Block
+               OpDecorate %piglit_vertex Location 0
+               OpDecorate %color_out Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %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
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+          %_ = OpVariable %_ptr_Output_gl_PerVertex Output
+        %int = OpTypeInt 32 1
+      %int_0 = OpConstant %int 0
+      %int_1 = OpConstant %int 1
+     %double = OpTypeFloat 64
+   %v4double = OpTypeVector %double 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_v4double = OpTypePointer Input %v4double
+%_ptr_Input_double = OpTypePointer Input %double
+%piglit_vertex = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+  %color_out = OpVariable %_ptr_Output_v4float Output
+      %block = OpTypeStruct %v4double %double
+%_ptr_Input_block = OpTypePointer Input %block
+       %name = OpVariable %_ptr_Input_block Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %18 = OpLoad %v4float %piglit_vertex
+         %20 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+               OpStore %20 %18
+         %color_in = OpAccessChain %_ptr_Input_v4double %name %int_0
+         %multiplier = OpAccessChain %_ptr_Input_double %name %int_1
+         %26 = OpLoad %v4double %color_in
+         %29 = OpLoad %double %multiplier
+         %30 = OpVectorTimesScalar %v4double %26 %29
+         %31 = OpFConvert %v4float %30
+               OpStore %color_out %31
+               OpReturn
+               OpFunctionEnd
+
+[fragment shader]
+#version 440
+
+layout(location = 0) in vec4 color_in;
+layout(location = 0) out vec4 color_out;
+
+void main()
+{
+        color_out = color_in;
+}
+
+[vertex data]
+# pos           / color                 / multiplier
+0/r32g32_sfloat   1/r64g64b64a64_sfloat   3/r64_sfloat
+-1 -1             0.0 0.8 0.0 1.0         1.0
+1 -1              0.0 0.4 0.0 0.5         2.0
+-1 1              0.0 0.2 0.0 0.25        4.0
+1 -1              0.0 0.1 0.0 0.125       8.0
+-1 1              0.0 0.05 0.0 0.0625     16.0
+1 1               0.0 0.025 0.0 0.03125   32.0
+
+[test]
+clear color 0.8 0.0 0.0 1.0
+clear
+
+draw arrays TRIANGLE_LIST 0 6
+
+probe all rgba 0.0 0.8 0.0 1.0

Comments

On 08/11/18 13:24, Neil Roberts wrote:
> All but one of these are currently broken on anv.
>
> See: https://patchwork.freedesktop.org/series/40797/

FWIW, the first patch of that series is outdated, due all the changes on
master since then. A updated version was included on the ubo/ssbo
support series for ARB_gl_spirv:
https://github.com/Igalia/mesa/commit/0e933ed9848c6eea7ad1d664ec3aacbdba111b41

Don't  know about the status of the other two.
> ---
>  .../block-layout-location.vk_shader_test      | 117 +++++++++++++++++
>  ...lock-member-layout-location.vk_shader_test |  68 ++++++++++
>  ...block-mixed-layout-location.vk_shader_test | 120 ++++++++++++++++++
>  .../double-vertex-input-block.vk_shader_test  |  98 ++++++++++++++
>  4 files changed, 403 insertions(+)
>  create mode 100644 tests/vulkan/shaders/block-layout-location.vk_shader_test
>  create mode 100644 tests/vulkan/shaders/block-member-layout-location.vk_shader_test
>  create mode 100644 tests/vulkan/shaders/block-mixed-layout-location.vk_shader_test
>  create mode 100644 tests/vulkan/shaders/double-vertex-input-block.vk_shader_test
>
> diff --git a/tests/vulkan/shaders/block-layout-location.vk_shader_test b/tests/vulkan/shaders/block-layout-location.vk_shader_test
> new file mode 100644
> index 000000000..2c81375d8
> --- /dev/null
> +++ b/tests/vulkan/shaders/block-layout-location.vk_shader_test
> @@ -0,0 +1,117 @@
> +# Test that interface block members are correctly matched by explicit
> +# location.
> +
> +[vertex shader spirv]
> +               OpCapability Shader
> +          %1 = OpExtInstImport "GLSL.std.450"
> +               OpMemoryModel Logical GLSL450
> +               OpEntryPoint Vertex %main "main" %name %_ %piglit_vertex
> +               OpSource GLSL 440
> +               OpName %main "main"
> +               OpName %block "block"
> +               OpMemberName %block 0 "a"
> +               OpMemberName %block 1 "b"
> +               OpMemberName %block 2 "c"
> +               OpMemberName %block 3 "d"
> +               OpName %name "name"
> +               OpName %gl_PerVertex "gl_PerVertex"
> +               OpMemberName %gl_PerVertex 0 "gl_Position"
> +               OpMemberName %gl_PerVertex 1 "gl_PointSize"
> +               OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
> +               OpName %_ ""
> +               OpName %piglit_vertex "piglit_vertex"
> +               OpDecorate %block Block
> +; Only the main name variable has a location. The locations of the members
> +; should be derived from this.
> +               OpDecorate %name Location 0
> +               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
> +               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
> +               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
> +               OpDecorate %gl_PerVertex Block
> +               OpDecorate %piglit_vertex Location 0
> +       %void = OpTypeVoid
> +          %3 = OpTypeFunction %void
> +      %float = OpTypeFloat 32
> +    %v4float = OpTypeVector %float 4
> +      %block = OpTypeStruct %v4float %v4float %v4float %v4float
> +%_ptr_Output_block = OpTypePointer Output %block
> +       %name = OpVariable %_ptr_Output_block Output
> +        %int = OpTypeInt 32 1
> +      %int_0 = OpConstant %int 0
> +    %float_1 = OpConstant %float 1
> +    %float_0 = OpConstant %float 0
> +         %15 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
> +%_ptr_Output_v4float = OpTypePointer Output %v4float
> +      %int_1 = OpConstant %int 1
> +         %19 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
> +      %int_2 = OpConstant %int 2
> +         %22 = OpConstantComposite %v4float %float_0 %float_0 %float_1 %float_1
> +      %int_3 = OpConstant %int 3
> +         %25 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
> +       %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
> +%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
> +          %_ = OpVariable %_ptr_Output_gl_PerVertex Output
> +%_ptr_Input_v4float = OpTypePointer Input %v4float
> +%piglit_vertex = OpVariable %_ptr_Input_v4float Input
> +       %main = OpFunction %void None %3
> +          %5 = OpLabel
> +         %17 = OpAccessChain %_ptr_Output_v4float %name %int_0
> +               OpStore %17 %15
> +         %20 = OpAccessChain %_ptr_Output_v4float %name %int_1
> +               OpStore %20 %19
> +         %23 = OpAccessChain %_ptr_Output_v4float %name %int_2
> +               OpStore %23 %22
> +         %26 = OpAccessChain %_ptr_Output_v4float %name %int_3
> +               OpStore %26 %25
> +         %35 = OpLoad %v4float %piglit_vertex
> +         %36 = OpAccessChain %_ptr_Output_v4float %_ %int_0
> +               OpStore %36 %35
> +               OpReturn
> +               OpFunctionEnd
> +
> +[fragment shader]
> +#version 440
> +
> +layout(location = 0) in vec4 a;
> +layout(location = 1) in vec4 b;
> +layout(location = 2) in vec4 c;
> +layout(location = 3) in vec4 d;
> +
> +layout(std140, push_constant) uniform block {
> +        int i;
> +};
> +
> +layout(location = 0) out vec4 color;
> +
> +void main()
> +{
> +        if (i == 0) {
> +                color = a;
> +        } else if (i == 1) {
> +                color = b;
> +        } else if (i == 2) {
> +                color = c;
> +        } else if (i == 3) {
> +                color = d;
> +        }
> +}
> +
> +[test]
> +uniform int 0 0
> +draw rect -1 -1 1 1
> +relative probe rect rgb (0.0, 0.0, 0.5, 0.5) (1.0, 0.0, 0.0)
> +
> +uniform int 0 1
> +draw rect 0 -1 1 1
> +relative probe rect rgb (0.5, 0.0, 0.5, 0.5) (0.0, 1.0, 0.0)
> +
> +uniform int 0 2
> +draw rect -1 0 1 1
> +relative probe rect rgb (0.0, 0.5, 0.5, 0.5) (0.0, 0.0, 1.0)
> +
> +uniform int 0 3
> +draw rect 0 0 1 1
> +relative probe rect rgb (0.5, 0.5, 0.5, 0.5) (1.0, 1.0, 1.0)
> diff --git a/tests/vulkan/shaders/block-member-layout-location.vk_shader_test b/tests/vulkan/shaders/block-member-layout-location.vk_shader_test
> new file mode 100644
> index 000000000..f3287f24c
> --- /dev/null
> +++ b/tests/vulkan/shaders/block-member-layout-location.vk_shader_test
> @@ -0,0 +1,68 @@
> +# Test that interface block members are correctly matched by explicit
> +# location.
> +
> +[vertex shader]
> +#version 440
> +
> +layout(location = 0) in vec4 piglit_vertex;
> +
> +out block {
> +        layout(location = 2) vec4 c;
> +        layout(location = 3) vec4 d;
> +        layout(location = 0) vec4 a;
> +        layout(location = 1) vec4 b;
> +} name;
> +
> +void main()
> +{
> +        name.a = vec4(1.0, 0.0, 0.0, 1.0);
> +        name.b = vec4(0.0, 1.0, 0.0, 1.0);
> +        name.c = vec4(0.0, 0.0, 1.0, 1.0);
> +        name.d = vec4(1.0, 1.0, 1.0, 1.0);
> +
> +        gl_Position = piglit_vertex;
> +}
> +
> +[fragment shader]
> +#version 440
> +
> +layout(location = 0) in vec4 a;
> +layout(location = 1) in vec4 b;
> +layout(location = 2) in vec4 c;
> +layout(location = 3) in vec4 d;
> +
> +layout(std140, push_constant) uniform block {
> +        int i;
> +};
> +
> +layout(location = 0) out vec4 color;
> +
> +void main()
> +{
> +        if (i == 0) {
> +                color = a;
> +        } else if (i == 1) {
> +                color = b;
> +        } else if (i == 2) {
> +                color = c;
> +        } else if (i == 3) {
> +                color = d;
> +        }
> +}
> +
> +[test]
> +uniform int 0 0
> +draw rect -1 -1 1 1
> +relative probe rect rgb (0.0, 0.0, 0.5, 0.5) (1.0, 0.0, 0.0)
> +
> +uniform int 0 1
> +draw rect 0 -1 1 1
> +relative probe rect rgb (0.5, 0.0, 0.5, 0.5) (0.0, 1.0, 0.0)
> +
> +uniform int 0 2
> +draw rect -1 0 1 1
> +relative probe rect rgb (0.0, 0.5, 0.5, 0.5) (0.0, 0.0, 1.0)
> +
> +uniform int 0 3
> +draw rect 0 0 1 1
> +relative probe rect rgb (0.5, 0.5, 0.5, 0.5) (1.0, 1.0, 1.0)
> diff --git a/tests/vulkan/shaders/block-mixed-layout-location.vk_shader_test b/tests/vulkan/shaders/block-mixed-layout-location.vk_shader_test
> new file mode 100644
> index 000000000..7f32edf18
> --- /dev/null
> +++ b/tests/vulkan/shaders/block-mixed-layout-location.vk_shader_test
> @@ -0,0 +1,120 @@
> +# Test that interface block members are correctly matched by explicit
> +# location.
> +
> +[vertex shader spirv]
> +               OpCapability Shader
> +          %1 = OpExtInstImport "GLSL.std.450"
> +               OpMemoryModel Logical GLSL450
> +               OpEntryPoint Vertex %main "main" %name %_ %piglit_vertex
> +               OpSource GLSL 440
> +               OpName %main "main"
> +               OpName %block "block"
> +               OpMemberName %block 0 "c"
> +               OpMemberName %block 1 "d"
> +               OpMemberName %block 2 "a"
> +               OpMemberName %block 3 "b"
> +               OpName %name "name"
> +               OpName %gl_PerVertex "gl_PerVertex"
> +               OpMemberName %gl_PerVertex 0 "gl_Position"
> +               OpMemberName %gl_PerVertex 1 "gl_PointSize"
> +               OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
> +               OpName %_ ""
> +               OpName %piglit_vertex "piglit_vertex"
> +; The block is given a location of 2. The first two members don’t
> +; have a location so they should be derived from the block location.
> +               OpDecorate %name Location 2
> +; The 3rd member has an explicit location. The 4th member should be
> +; derived from this.
> +               OpMemberDecorate %block 2 Location 0
> +               OpDecorate %block Block
> +               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
> +               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
> +               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
> +               OpDecorate %gl_PerVertex Block
> +               OpDecorate %piglit_vertex Location 0
> +       %void = OpTypeVoid
> +          %3 = OpTypeFunction %void
> +      %float = OpTypeFloat 32
> +    %v4float = OpTypeVector %float 4
> +      %block = OpTypeStruct %v4float %v4float %v4float %v4float
> +%_ptr_Output_block = OpTypePointer Output %block
> +       %name = OpVariable %_ptr_Output_block Output
> +        %int = OpTypeInt 32 1
> +      %int_2 = OpConstant %int 2
> +    %float_1 = OpConstant %float 1
> +    %float_0 = OpConstant %float 0
> +         %15 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
> +%_ptr_Output_v4float = OpTypePointer Output %v4float
> +      %int_3 = OpConstant %int 3
> +         %19 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
> +      %int_0 = OpConstant %int 0
> +         %22 = OpConstantComposite %v4float %float_0 %float_0 %float_1 %float_1
> +      %int_1 = OpConstant %int 1
> +         %25 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
> +       %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
> +%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
> +          %_ = OpVariable %_ptr_Output_gl_PerVertex Output
> +%_ptr_Input_v4float = OpTypePointer Input %v4float
> +%piglit_vertex = OpVariable %_ptr_Input_v4float Input
> +       %main = OpFunction %void None %3
> +          %5 = OpLabel
> +         %17 = OpAccessChain %_ptr_Output_v4float %name %int_2
> +               OpStore %17 %15
> +         %20 = OpAccessChain %_ptr_Output_v4float %name %int_3
> +               OpStore %20 %19
> +         %23 = OpAccessChain %_ptr_Output_v4float %name %int_0
> +               OpStore %23 %22
> +         %26 = OpAccessChain %_ptr_Output_v4float %name %int_1
> +               OpStore %26 %25
> +         %35 = OpLoad %v4float %piglit_vertex
> +         %36 = OpAccessChain %_ptr_Output_v4float %_ %int_0
> +               OpStore %36 %35
> +               OpReturn
> +               OpFunctionEnd
> +
> +[fragment shader]
> +#version 440
> +
> +layout(location = 0) in vec4 a;
> +layout(location = 1) in vec4 b;
> +layout(location = 2) in vec4 c;
> +layout(location = 3) in vec4 d;
> +
> +layout(std140, push_constant) uniform block {
> +        int i;
> +};
> +
> +layout(location = 0) out vec4 color;
> +
> +void main()
> +{
> +        if (i == 0) {
> +                color = a;
> +        } else if (i == 1) {
> +                color = b;
> +        } else if (i == 2) {
> +                color = c;
> +        } else if (i == 3) {
> +                color = d;
> +        }
> +}
> +
> +[test]
> +uniform int 0 0
> +draw rect -1 -1 1 1
> +relative probe rect rgb (0.0, 0.0, 0.5, 0.5) (1.0, 0.0, 0.0)
> +
> +uniform int 0 1
> +draw rect 0 -1 1 1
> +relative probe rect rgb (0.5, 0.0, 0.5, 0.5) (0.0, 1.0, 0.0)
> +
> +uniform int 0 2
> +draw rect -1 0 1 1
> +relative probe rect rgb (0.0, 0.5, 0.5, 0.5) (0.0, 0.0, 1.0)
> +
> +uniform int 0 3
> +draw rect 0 0 1 1
> +relative probe rect rgb (0.5, 0.5, 0.5, 0.5) (1.0, 1.0, 1.0)
> diff --git a/tests/vulkan/shaders/double-vertex-input-block.vk_shader_test b/tests/vulkan/shaders/double-vertex-input-block.vk_shader_test
> new file mode 100644
> index 000000000..bb3c7f84b
> --- /dev/null
> +++ b/tests/vulkan/shaders/double-vertex-input-block.vk_shader_test
> @@ -0,0 +1,98 @@
> +# Tests that the driver assigns the correct locations to a vertex
> +# input with doubles in it. The inputs are declared in a block with a
> +# location so that the driver itself has to decide the locations of
> +# the members. The first attribute is a dvec4 so the driver should
> +# assign two locations to it.
> +
> +[require]
> +shaderFloat64
> +
> +[vertex shader spirv]
> +               OpCapability Shader
> +               OpCapability Float64
> +          %1 = OpExtInstImport "GLSL.std.450"
> +               OpMemoryModel Logical GLSL450
> +               OpEntryPoint Vertex %main "main" %_ %piglit_vertex %color_out %name
> +               OpSource GLSL 440
> +               OpName %main "main"
> +               OpName %gl_PerVertex "gl_PerVertex"
> +               OpMemberName %gl_PerVertex 0 "gl_Position"
> +               OpMemberName %gl_PerVertex 1 "gl_PointSize"
> +               OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
> +               OpName %_ ""
> +               OpName %piglit_vertex "piglit_vertex"
> +               OpName %color_out "color_out"
> +               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
> +               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
> +               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
> +               OpDecorate %name Location 1
> +               OpDecorate %gl_PerVertex Block
> +               OpDecorate %piglit_vertex Location 0
> +               OpDecorate %color_out Location 0
> +       %void = OpTypeVoid
> +          %3 = OpTypeFunction %void
> +      %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
> +%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
> +          %_ = OpVariable %_ptr_Output_gl_PerVertex Output
> +        %int = OpTypeInt 32 1
> +      %int_0 = OpConstant %int 0
> +      %int_1 = OpConstant %int 1
> +     %double = OpTypeFloat 64
> +   %v4double = OpTypeVector %double 4
> +%_ptr_Input_v4float = OpTypePointer Input %v4float
> +%_ptr_Input_v4double = OpTypePointer Input %v4double
> +%_ptr_Input_double = OpTypePointer Input %double
> +%piglit_vertex = OpVariable %_ptr_Input_v4float Input
> +%_ptr_Output_v4float = OpTypePointer Output %v4float
> +  %color_out = OpVariable %_ptr_Output_v4float Output
> +      %block = OpTypeStruct %v4double %double
> +%_ptr_Input_block = OpTypePointer Input %block
> +       %name = OpVariable %_ptr_Input_block Input
> +       %main = OpFunction %void None %3
> +          %5 = OpLabel
> +         %18 = OpLoad %v4float %piglit_vertex
> +         %20 = OpAccessChain %_ptr_Output_v4float %_ %int_0
> +               OpStore %20 %18
> +         %color_in = OpAccessChain %_ptr_Input_v4double %name %int_0
> +         %multiplier = OpAccessChain %_ptr_Input_double %name %int_1
> +         %26 = OpLoad %v4double %color_in
> +         %29 = OpLoad %double %multiplier
> +         %30 = OpVectorTimesScalar %v4double %26 %29
> +         %31 = OpFConvert %v4float %30
> +               OpStore %color_out %31
> +               OpReturn
> +               OpFunctionEnd
> +
> +[fragment shader]
> +#version 440
> +
> +layout(location = 0) in vec4 color_in;
> +layout(location = 0) out vec4 color_out;
> +
> +void main()
> +{
> +        color_out = color_in;
> +}
> +
> +[vertex data]
> +# pos           / color                 / multiplier
> +0/r32g32_sfloat   1/r64g64b64a64_sfloat   3/r64_sfloat
> +-1 -1             0.0 0.8 0.0 1.0         1.0
> +1 -1              0.0 0.4 0.0 0.5         2.0
> +-1 1              0.0 0.2 0.0 0.25        4.0
> +1 -1              0.0 0.1 0.0 0.125       8.0
> +-1 1              0.0 0.05 0.0 0.0625     16.0
> +1 1               0.0 0.025 0.0 0.03125   32.0
> +
> +[test]
> +clear color 0.8 0.0 0.0 1.0
> +clear
> +
> +draw arrays TRIANGLE_LIST 0 6
> +
> +probe all rgba 0.0 0.8 0.0 1.0