From 7a69d764b0ba06997cd9837a7db4bf247b0ac449 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Tue, 7 Jan 2020 11:36:51 +0100 Subject: [PATCH] MSL: Add trivial tests for Component decoration. Verifies that Component decoration is honored for vertex outputs and fragment inputs. --- .../components/fragment-input-component.frag | 23 ++++++++++++++++ .../components/vertex-output-component.vert | 26 +++++++++++++++++++ .../components/fragment-input-component.frag | 10 +++++++ .../components/vertex-output-component.vert | 12 +++++++++ spirv_msl.cpp | 9 ++++++- 5 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 reference/shaders-msl-no-opt/components/fragment-input-component.frag create mode 100644 reference/shaders-msl-no-opt/components/vertex-output-component.vert create mode 100644 shaders-msl-no-opt/components/fragment-input-component.frag create mode 100644 shaders-msl-no-opt/components/vertex-output-component.vert diff --git a/reference/shaders-msl-no-opt/components/fragment-input-component.frag b/reference/shaders-msl-no-opt/components/fragment-input-component.frag new file mode 100644 index 00000000..9a65918a --- /dev/null +++ b/reference/shaders-msl-no-opt/components/fragment-input-component.frag @@ -0,0 +1,23 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 FragColor [[color(0)]]; +}; + +struct main0_in +{ + float3 Foo3 [[user(locn0)]]; + float Foo1 [[user(locn0_3)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + out.FragColor = float4(in.Foo3, in.Foo1); + return out; +} + diff --git a/reference/shaders-msl-no-opt/components/vertex-output-component.vert b/reference/shaders-msl-no-opt/components/vertex-output-component.vert new file mode 100644 index 00000000..cf135b51 --- /dev/null +++ b/reference/shaders-msl-no-opt/components/vertex-output-component.vert @@ -0,0 +1,26 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float3 Foo3 [[user(locn0)]]; + float Foo1 [[user(locn0_3)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float4 vFoo [[attribute(0)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + out.gl_Position = in.vFoo; + out.Foo3 = in.vFoo.xyz; + out.Foo1 = in.vFoo.w; + return out; +} + diff --git a/shaders-msl-no-opt/components/fragment-input-component.frag b/shaders-msl-no-opt/components/fragment-input-component.frag new file mode 100644 index 00000000..60d48bef --- /dev/null +++ b/shaders-msl-no-opt/components/fragment-input-component.frag @@ -0,0 +1,10 @@ +#version 450 + +layout(location = 0, component = 3) in float Foo1; +layout(location = 0, component = 0) in vec3 Foo3; +layout(location = 0) out vec4 FragColor; + +void main() +{ + FragColor = vec4(Foo3, Foo1); +} diff --git a/shaders-msl-no-opt/components/vertex-output-component.vert b/shaders-msl-no-opt/components/vertex-output-component.vert new file mode 100644 index 00000000..5abd8dc6 --- /dev/null +++ b/shaders-msl-no-opt/components/vertex-output-component.vert @@ -0,0 +1,12 @@ +#version 450 + +layout(location = 0) in vec4 vFoo; +layout(location = 0) out vec3 Foo3; +layout(location = 0, component = 3) out float Foo1; + +void main() +{ + gl_Position = vFoo; + Foo3 = vFoo.xyz; + Foo1 = vFoo.w; +} diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 53e6f32f..a2b3a349 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -8604,7 +8604,14 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in uint32_t locn = get_ordered_member_location(type.self, index, &comp); if (locn != k_unknown_location) { - if (comp != k_unknown_component) + // For user-defined attributes, this is fine. From Vulkan spec: + // A user-defined output variable is considered to match an input variable in the subsequent stage if + // the two variables are declared with the same Location and Component decoration and match in type + // and decoration, except that interpolation decorations are not required to match. For the purposes + // of interface matching, variables declared without a Component decoration are considered to have a + // Component decoration of zero. + + if (comp != k_unknown_component && comp != 0) quals = string("user(locn") + convert_to_string(locn) + "_" + convert_to_string(comp) + ")"; else quals = string("user(locn") + convert_to_string(locn) + ")";