diff --git a/src/back/glsl/features.rs b/src/back/glsl/features.rs index 1e6a6ade0d..e76003f211 100644 --- a/src/back/glsl/features.rs +++ b/src/back/glsl/features.rs @@ -26,7 +26,7 @@ bitflags::bitflags! { const TEXTURE_1D = 1 << 10; /// Interpolation and auxiliary qualifiers. Perspective, Flat, and /// Centroid are available in all GLSL versions we support. - const LINEAR_QUALIFIER = 1 << 11; + const NOPERSPECTIVE_QUALIFIER = 1 << 11; const SAMPLE_QUALIFIER = 1 << 12; } } @@ -88,7 +88,7 @@ impl FeaturesManager { // 1D textures are supported by all core versions and aren't supported by an es versions // so use 0 that way the check will always be false and can be optimized away check_feature!(TEXTURE_1D, 0); - check_feature!(LINEAR_QUALIFIER, 130); + check_feature!(NOPERSPECTIVE_QUALIFIER, 130); check_feature!(SAMPLE_QUALIFIER, 400, 320); // Return an error if there are missing features @@ -290,7 +290,7 @@ impl<'a, W> Writer<'a, W> { _ => { if let Some(&Binding::Location(_, Some(interpolation))) = binding { match interpolation { - Interpolation::Linear => self.features.request(Features::LINEAR_QUALIFIER), + Interpolation::Linear => self.features.request(Features::NOPERSPECTIVE_QUALIFIER), Interpolation::Sample => self.features.request(Features::SAMPLE_QUALIFIER), _ => () }; diff --git a/tests/in/interpolate.param.ron b/tests/in/interpolate.param.ron new file mode 100644 index 0000000000..dfd15dc16b --- /dev/null +++ b/tests/in/interpolate.param.ron @@ -0,0 +1,8 @@ +( + spv_version: (1, 0), + spv_capabilities: [ Shader, SampleRateShading ], + spv_debug: true, + spv_adjust_coordinate_space: true, + msl_custom: false, + glsl_desktop_version: Some(400) +) diff --git a/tests/in/interpolate.wgsl b/tests/in/interpolate.wgsl new file mode 100644 index 0000000000..0bdad96922 --- /dev/null +++ b/tests/in/interpolate.wgsl @@ -0,0 +1,25 @@ +struct FragmentInput { + [[builtin(position)]] position: vec4; + [[location(0), interpolate(flat)]] flat : u32; + [[location(1), interpolate(linear)]] linear: f32; + [[location(2), interpolate(centroid)]] centroid: vec2; + [[location(3), interpolate(sample)]] sample: vec3; + [[location(4), interpolate(perspective)]] perspective: vec4; +}; + +[[stage(vertex)]] +fn main() -> FragmentInput { + var out: FragmentInput; + + out.position = vec4(2.0, 4.0, 5.0, 6.0); + out.flat = 8u32; + out.linear = 27.0; + out.centroid = vec2(64.0, 125.0); + out.sample = vec3(216.0, 343.0, 512.0); + out.perspective = vec4(729.0, 1000.0, 1331.0, 1728.0); + + return out; +} + +[[stage(fragment)]] +fn main(val : FragmentInput) { } diff --git a/tests/out/interpolate.Fragment.glsl b/tests/out/interpolate.Fragment.glsl new file mode 100644 index 0000000000..6ec1a66ad7 --- /dev/null +++ b/tests/out/interpolate.Fragment.glsl @@ -0,0 +1,21 @@ +#version 400 core +struct FragmentInput { + vec4 position; + uint flat1; + float linear; + vec2 centroid1; + vec3 sample1; + vec4 perspective; +}; + +flat in uint _vs2fs_location0; +noperspective in float _vs2fs_location1; +centroid in vec2 _vs2fs_location2; +sample in vec3 _vs2fs_location3; +smooth in vec4 _vs2fs_location4; + +void main() { + FragmentInput val = FragmentInput(gl_FragCoord, _vs2fs_location0, _vs2fs_location1, _vs2fs_location2, _vs2fs_location3, _vs2fs_location4); + return; +} + diff --git a/tests/out/interpolate.Vertex.glsl b/tests/out/interpolate.Vertex.glsl new file mode 100644 index 0000000000..3f105dccf3 --- /dev/null +++ b/tests/out/interpolate.Vertex.glsl @@ -0,0 +1,33 @@ +#version 400 core +struct FragmentInput { + vec4 position; + uint flat1; + float linear; + vec2 centroid1; + vec3 sample1; + vec4 perspective; +}; + +out uint _vs2fs_location0; +out float _vs2fs_location1; +out vec2 _vs2fs_location2; +out vec3 _vs2fs_location3; +out vec4 _vs2fs_location4; + +void main() { + FragmentInput out1; + out1.position = vec4(2.0, 4.0, 5.0, 6.0); + out1.flat1 = 8u; + out1.linear = 27.0; + out1.centroid1 = vec2(64.0, 125.0); + out1.sample1 = vec3(216.0, 343.0, 512.0); + out1.perspective = vec4(729.0, 1000.0, 1331.0, 1728.0); + gl_Position = out1.position; + _vs2fs_location0 = out1.flat1; + _vs2fs_location1 = out1.linear; + _vs2fs_location2 = out1.centroid1; + _vs2fs_location3 = out1.sample1; + _vs2fs_location4 = out1.perspective; + return; +} + diff --git a/tests/out/interpolate.msl b/tests/out/interpolate.msl new file mode 100644 index 0000000000..713dc4ef94 --- /dev/null +++ b/tests/out/interpolate.msl @@ -0,0 +1,48 @@ +#include +#include + +struct FragmentInput { + metal::float4 position; + metal::uint flat; + float linear; + metal::float2 centroid; + metal::float3 sample; + metal::float4 perspective; +}; + +struct main1Output { + metal::float4 position [[position]]; + metal::uint flat [[user(loc0)]]; + float linear [[user(loc1)]]; + metal::float2 centroid [[user(loc2)]]; + metal::float3 sample [[user(loc3)]]; + metal::float4 perspective [[user(loc4)]]; +}; +vertex main1Output main1( +) { + FragmentInput out; + out.position = metal::float4(2.0, 4.0, 5.0, 6.0); + out.flat = 8u; + out.linear = 27.0; + out.centroid = metal::float2(64.0, 125.0); + out.sample = metal::float3(216.0, 343.0, 512.0); + out.perspective = metal::float4(729.0, 1000.0, 1331.0, 1728.0); + const auto _tmp = out; + return main1Output { _tmp.position, _tmp.flat, _tmp.linear, _tmp.centroid, _tmp.sample, _tmp.perspective }; +} + + +struct main2Input { + metal::uint flat [[user(loc0)]]; + float linear [[user(loc1)]]; + metal::float2 centroid [[user(loc2)]]; + metal::float3 sample [[user(loc3)]]; + metal::float4 perspective [[user(loc4)]]; +}; +fragment void main2( + main2Input varyings1 [[stage_in]] +, metal::float4 position [[position]] +) { + const FragmentInput val = { position, varyings1.flat, varyings1.linear, varyings1.centroid, varyings1.sample, varyings1.perspective }; + return; +} diff --git a/tests/out/interpolate.spvasm b/tests/out/interpolate.spvasm new file mode 100644 index 0000000000..063b86f7fc --- /dev/null +++ b/tests/out/interpolate.spvasm @@ -0,0 +1,174 @@ +; SPIR-V +; Version: 1.0 +; Generator: rspirv +; Bound: 95 +OpCapability Shader +OpCapability SampleRateShading +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Vertex %38 "main" %27 %29 %31 %33 %35 %37 +OpEntryPoint Fragment %93 "main" %76 %79 %82 %85 %88 %91 +OpExecutionMode %93 OriginUpperLeft +OpSource GLSL 450 +OpName %23 "FragmentInput" +OpMemberName %23 0 "position" +OpMemberName %23 1 "flat" +OpMemberName %23 2 "linear" +OpMemberName %23 3 "centroid" +OpMemberName %23 4 "sample" +OpMemberName %23 5 "perspective" +OpName %24 "out" +OpName %27 "position" +OpName %29 "flat" +OpName %31 "linear" +OpName %33 "centroid" +OpName %35 "sample" +OpName %37 "perspective" +OpName %38 "main" +OpName %38 "main" +OpName %76 "position" +OpName %79 "flat" +OpName %82 "linear" +OpName %85 "centroid" +OpName %88 "sample" +OpName %91 "perspective" +OpName %93 "main" +OpName %93 "main" +OpMemberDecorate %23 0 Offset 0 +OpMemberDecorate %23 1 Offset 16 +OpMemberDecorate %23 2 Offset 20 +OpMemberDecorate %23 3 Offset 24 +OpMemberDecorate %23 4 Offset 32 +OpMemberDecorate %23 5 Offset 48 +OpDecorate %27 BuiltIn Position +OpDecorate %29 Location 0 +OpDecorate %29 Flat +OpDecorate %31 Location 1 +OpDecorate %31 NoPerspective +OpDecorate %33 Location 2 +OpDecorate %33 Centroid +OpDecorate %35 Location 3 +OpDecorate %35 Sample +OpDecorate %37 Location 4 +OpDecorate %76 BuiltIn FragCoord +OpDecorate %79 Location 0 +OpDecorate %79 Flat +OpDecorate %82 Location 1 +OpDecorate %82 NoPerspective +OpDecorate %85 Location 2 +OpDecorate %85 Centroid +OpDecorate %88 Location 3 +OpDecorate %88 Sample +OpDecorate %91 Location 4 +%2 = OpTypeVoid +%4 = OpTypeFloat 32 +%3 = OpConstant %4 2.0 +%5 = OpConstant %4 4.0 +%6 = OpConstant %4 5.0 +%7 = OpConstant %4 6.0 +%9 = OpTypeInt 32 0 +%8 = OpConstant %9 8 +%10 = OpConstant %4 27.0 +%11 = OpConstant %4 64.0 +%12 = OpConstant %4 125.0 +%13 = OpConstant %4 216.0 +%14 = OpConstant %4 343.0 +%15 = OpConstant %4 512.0 +%16 = OpConstant %4 729.0 +%17 = OpConstant %4 1000.0 +%18 = OpConstant %4 1331.0 +%19 = OpConstant %4 1728.0 +%20 = OpTypeVector %4 4 +%21 = OpTypeVector %4 2 +%22 = OpTypeVector %4 3 +%23 = OpTypeStruct %20 %9 %4 %21 %22 %20 +%25 = OpTypePointer Function %23 +%28 = OpTypePointer Output %20 +%27 = OpVariable %28 Output +%30 = OpTypePointer Output %9 +%29 = OpVariable %30 Output +%32 = OpTypePointer Output %4 +%31 = OpVariable %32 Output +%34 = OpTypePointer Output %21 +%33 = OpVariable %34 Output +%36 = OpTypePointer Output %22 +%35 = OpVariable %36 Output +%37 = OpVariable %28 Output +%39 = OpTypeFunction %2 +%41 = OpTypePointer Function %20 +%43 = OpTypeInt 32 1 +%44 = OpConstant %43 0 +%46 = OpTypePointer Function %9 +%47 = OpConstant %43 1 +%49 = OpTypePointer Function %4 +%50 = OpConstant %43 2 +%52 = OpTypePointer Function %21 +%54 = OpConstant %43 3 +%56 = OpTypePointer Function %22 +%58 = OpConstant %43 4 +%61 = OpConstant %43 5 +%66 = OpTypePointer Output %4 +%77 = OpTypePointer Input %20 +%76 = OpVariable %77 Input +%80 = OpTypePointer Input %9 +%79 = OpVariable %80 Input +%83 = OpTypePointer Input %4 +%82 = OpVariable %83 Input +%86 = OpTypePointer Input %21 +%85 = OpVariable %86 Input +%89 = OpTypePointer Input %22 +%88 = OpVariable %89 Input +%91 = OpVariable %77 Input +%38 = OpFunction %2 None %39 +%26 = OpLabel +%24 = OpVariable %25 Function +OpBranch %40 +%40 = OpLabel +%42 = OpCompositeConstruct %20 %3 %5 %6 %7 +%45 = OpAccessChain %41 %24 %44 +OpStore %45 %42 +%48 = OpAccessChain %46 %24 %47 +OpStore %48 %8 +%51 = OpAccessChain %49 %24 %50 +OpStore %51 %10 +%53 = OpCompositeConstruct %21 %11 %12 +%55 = OpAccessChain %52 %24 %54 +OpStore %55 %53 +%57 = OpCompositeConstruct %22 %13 %14 %15 +%59 = OpAccessChain %56 %24 %58 +OpStore %59 %57 +%60 = OpCompositeConstruct %20 %16 %17 %18 %19 +%62 = OpAccessChain %41 %24 %61 +OpStore %62 %60 +%63 = OpLoad %23 %24 +%64 = OpCompositeExtract %20 %63 0 +OpStore %27 %64 +%65 = OpAccessChain %66 %27 %47 +%67 = OpLoad %4 %65 +%68 = OpFNegate %4 %67 +OpStore %65 %68 +%69 = OpCompositeExtract %9 %63 1 +OpStore %29 %69 +%70 = OpCompositeExtract %4 %63 2 +OpStore %31 %70 +%71 = OpCompositeExtract %21 %63 3 +OpStore %33 %71 +%72 = OpCompositeExtract %22 %63 4 +OpStore %35 %72 +%73 = OpCompositeExtract %20 %63 5 +OpStore %37 %73 +OpReturn +OpFunctionEnd +%93 = OpFunction %2 None %39 +%74 = OpLabel +%78 = OpLoad %20 %76 +%81 = OpLoad %9 %79 +%84 = OpLoad %4 %82 +%87 = OpLoad %21 %85 +%90 = OpLoad %22 %88 +%92 = OpLoad %20 %91 +%75 = OpCompositeConstruct %23 %78 %81 %84 %87 %90 %92 +OpBranch %94 +%94 = OpLabel +OpReturn +OpFunctionEnd \ No newline at end of file diff --git a/tests/snapshots.rs b/tests/snapshots.rs index 587bef4398..bc5b566143 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -225,6 +225,7 @@ fn convert_wgsl() { ("image-copy", Targets::METAL), ("texture-array", Targets::SPIRV | Targets::METAL), ("operators", Targets::SPIRV | Targets::METAL | Targets::GLSL), + ("interpolate", Targets::SPIRV | Targets::METAL | Targets::GLSL), ]; for &(name, targets) in inputs.iter() {