From 65f892eb5075b86bcca5df2fca7b2d3895acb004 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 25 Oct 2022 02:13:48 +0300 Subject: [PATCH] attr: fix `#[spirv(flat)]` checking to match the Vulkan spec. --- .../src/codegen_cx/entry.rs | 100 ++++++++++++++---- tests/ui/byte_addressable_buffer/arr.rs | 2 +- .../ui/byte_addressable_buffer/big_struct.rs | 2 +- .../byte_addressable_buffer/empty_struct.rs | 2 +- .../byte_addressable_buffer/small_struct.rs | 2 +- tests/ui/byte_addressable_buffer/u32.rs | 2 +- tests/ui/dis/pass-mode-cast-struct.rs | 2 +- tests/ui/image/issue-330.rs | 1 - tests/ui/image/query/query_levels.rs | 2 +- tests/ui/image/query/query_samples.rs | 2 +- tests/ui/image/query/query_size.rs | 2 +- tests/ui/image/query/query_size_lod.rs | 2 +- tests/ui/lang/consts/issue-329.rs | 3 +- .../ui/lang/consts/nested-ref-in-composite.rs | 4 +- tests/ui/lang/consts/nested-ref.rs | 4 +- tests/ui/lang/consts/shallow-ref.rs | 7 +- tests/ui/lang/control_flow/closure_multi.rs | 2 +- tests/ui/lang/core/ops/range-contains.rs | 2 +- tests/ui/lang/core/unwrap_or.rs | 2 +- tests/ui/lang/f32/packing.rs | 12 +-- tests/ui/lang/issue-836.rs | 2 +- tests/ui/spirv-attr/all-builtins.rs | 14 +-- tests/ui/spirv-attr/bool-inputs-err.stderr | 8 +- tests/ui/spirv-attr/int-without-flat.stderr | 4 +- 24 files changed, 116 insertions(+), 69 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs index a1142adc96..7f2062b92f 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs @@ -1,6 +1,6 @@ use super::CodegenCx; use crate::abi::ConvSpirvType; -use crate::attr::{AggregatedSpirvAttributes, Entry}; +use crate::attr::{AggregatedSpirvAttributes, Entry, Spanned}; use crate::builder::Builder; use crate::builder_spirv::{SpirvValue, SpirvValueExt}; use crate::spirv_type::SpirvType; @@ -144,6 +144,7 @@ impl<'tcx> CodegenCx<'tcx> { for (entry_arg_abi, hir_param) in arg_abis.iter().zip(hir_params) { bx.set_span(hir_param.span); self.declare_shader_interface_for_param( + execution_model, entry_arg_abi, hir_param, &mut op_entry_point_interface_operands, @@ -284,8 +285,10 @@ impl<'tcx> CodegenCx<'tcx> { (spirv_ty, storage_class) } + #[allow(clippy::too_many_arguments)] fn declare_shader_interface_for_param( &self, + execution_model: ExecutionModel, entry_arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, hir_param: &hir::Param<'tcx>, op_entry_point_interface_operands: &mut Vec, @@ -522,11 +525,12 @@ impl<'tcx> CodegenCx<'tcx> { } self.check_for_bad_types( + execution_model, hir_param.ty_span, var_ptr_spirv_type, storage_class, attrs.builtin.is_some(), - attrs.flat.is_some(), + attrs.flat, ); // Assign locations from left to right, incrementing each storage class @@ -568,45 +572,95 @@ impl<'tcx> CodegenCx<'tcx> { } // Booleans are only allowed in some storage classes. Error if they're in others. - // Integers and f64s must be decorated with `#[spirv(flat)]`. + // Integers and `f64`s must be decorated with `#[spirv(flat)]`. fn check_for_bad_types( &self, + execution_model: ExecutionModel, span: Span, ty: Word, storage_class: StorageClass, is_builtin: bool, - is_flat: bool, + flat_attr: Option>, ) { // private and function are allowed here, but they can't happen. + if matches!( + storage_class, + StorageClass::Workgroup | StorageClass::CrossWorkgroup + ) { + return; + } + + let mut has_bool = false; + let mut type_must_be_flat = false; + recurse(self, ty, &mut has_bool, &mut type_must_be_flat); + // SPIR-V technically allows all input/output variables to be booleans, not just builtins, // but has a note: // > Khronos Issue #363: OpTypeBool can be used in the Input and Output storage classes, // but the client APIs still only allow built-in Boolean variables (e.g. FrontFacing), // not user variables. // spirv-val disallows non-builtin inputs/outputs, so we do too, I guess. - if matches!( - storage_class, - StorageClass::Workgroup | StorageClass::CrossWorkgroup - ) || is_builtin && matches!(storage_class, StorageClass::Input | StorageClass::Output) - { - return; - } - let mut has_bool = false; - let mut must_be_flat = false; - recurse(self, ty, &mut has_bool, &mut must_be_flat); - if has_bool { - self.tcx - .sess - .span_err(span, "entrypoint parameter cannot contain a boolean"); - } - if matches!(storage_class, StorageClass::Input | StorageClass::Output) - && must_be_flat - && !is_flat + if has_bool + && !(is_builtin && matches!(storage_class, StorageClass::Input | StorageClass::Output)) { self.tcx .sess - .span_err(span, "parameter must be decorated with #[spirv(flat)]"); + .span_err(span, "entry-point parameter cannot contain `bool`s"); } + + // Enforce Vulkan validation rules around `Flat` as accurately as possible, + // i.e. "interpolation control" can only be used "within" the rasterization + // pipeline (roughly: `vertex (outputs) -> ... -> (inputs for) fragment`), + // but not at the "outer" interface (vertex inputs/fragment outputs). + // Also, fragment inputs *require* it for some ("uninterpolatable") types. + // FIXME(eddyb) maybe this kind of `enum` could be placed elsewhere? + enum Force { + Disallow, + Require, + } + #[allow(clippy::match_same_arms)] + let flat_forced = match (execution_model, storage_class) { + // VUID-StandaloneSpirv-Flat-06202 + // > The `Flat`, `NoPerspective`, `Sample`, and `Centroid` decorations **must** + // > not be used on variables with the `Input` storage class in a vertex shader + (ExecutionModel::Vertex, StorageClass::Input) => Some(Force::Disallow), + + // VUID-StandaloneSpirv-Flat-04744 + // > Any variable with integer or double-precision floating-point type and + // > with `Input` storage class in a fragment shader, **must** be decorated `Flat` + (ExecutionModel::Fragment, StorageClass::Input) if type_must_be_flat => { + // FIXME(eddyb) shouldn't this be automatic then? (maybe with a warning?) + Some(Force::Require) + } + + // VUID-StandaloneSpirv-Flat-06201 + // > The `Flat`, `NoPerspective`, `Sample`, and `Centroid` decorations **must** + // > not be used on variables with the `Output` storage class in a fragment shader + (ExecutionModel::Fragment, StorageClass::Output) => Some(Force::Disallow), + + // VUID-StandaloneSpirv-Flat-04670 + // > The `Flat`, `NoPerspective`, `Sample`, and `Centroid` decorations **must** + // > only be used on variables with the `Output` or `Input` storage class + (_, StorageClass::Input | StorageClass::Output) => None, + _ => Some(Force::Disallow), + }; + + let flat_mismatch = match (flat_forced, flat_attr) { + (Some(Force::Disallow), Some(flat_attr)) => Some((flat_attr.span, "cannot")), + // FIXME(eddyb) it would be useful to show the type that required it. + (Some(Force::Require), None) => Some((span, "must")), + _ => None, + }; + if let Some((span, must_or_cannot)) = flat_mismatch { + self.tcx.sess.span_err( + span, + format!( + "`{execution_model:?}` entry-point `{storage_class:?}` parameter \ + {must_or_cannot} be decorated with `#[spirv(flat)]`" + ), + ); + } + fn recurse(cx: &CodegenCx<'_>, ty: Word, has_bool: &mut bool, must_be_flat: &mut bool) { match cx.lookup_type(ty) { SpirvType::Bool => *has_bool = true, diff --git a/tests/ui/byte_addressable_buffer/arr.rs b/tests/ui/byte_addressable_buffer/arr.rs index af871451e5..4cacbcf906 100644 --- a/tests/ui/byte_addressable_buffer/arr.rs +++ b/tests/ui/byte_addressable_buffer/arr.rs @@ -6,7 +6,7 @@ use spirv_std::{glam::Vec4, ByteAddressableBuffer}; #[spirv(fragment)] pub fn load( #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], - #[spirv(flat)] out: &mut [i32; 4], + out: &mut [i32; 4], ) { unsafe { let buf = ByteAddressableBuffer::new(buf); diff --git a/tests/ui/byte_addressable_buffer/big_struct.rs b/tests/ui/byte_addressable_buffer/big_struct.rs index ca13800ec1..27907afe3c 100644 --- a/tests/ui/byte_addressable_buffer/big_struct.rs +++ b/tests/ui/byte_addressable_buffer/big_struct.rs @@ -15,7 +15,7 @@ pub struct BigStruct { #[spirv(fragment)] pub fn load( #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], - #[spirv(flat)] out: &mut BigStruct, + out: &mut BigStruct, ) { unsafe { let buf = ByteAddressableBuffer::new(buf); diff --git a/tests/ui/byte_addressable_buffer/empty_struct.rs b/tests/ui/byte_addressable_buffer/empty_struct.rs index 2f7886a1cd..b586139d3a 100644 --- a/tests/ui/byte_addressable_buffer/empty_struct.rs +++ b/tests/ui/byte_addressable_buffer/empty_struct.rs @@ -8,7 +8,7 @@ pub struct EmptyStruct {} #[spirv(fragment)] pub fn load( #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], - #[spirv(flat)] out: &mut EmptyStruct, + out: &mut EmptyStruct, ) { unsafe { let buf = ByteAddressableBuffer::new(buf); diff --git a/tests/ui/byte_addressable_buffer/small_struct.rs b/tests/ui/byte_addressable_buffer/small_struct.rs index 43a92db9dd..d6959db768 100644 --- a/tests/ui/byte_addressable_buffer/small_struct.rs +++ b/tests/ui/byte_addressable_buffer/small_struct.rs @@ -11,7 +11,7 @@ pub struct SmallStruct { #[spirv(fragment)] pub fn load( #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], - #[spirv(flat)] out: &mut SmallStruct, + out: &mut SmallStruct, ) { unsafe { let buf = ByteAddressableBuffer::new(buf); diff --git a/tests/ui/byte_addressable_buffer/u32.rs b/tests/ui/byte_addressable_buffer/u32.rs index c1922356b9..8d5d03ad65 100644 --- a/tests/ui/byte_addressable_buffer/u32.rs +++ b/tests/ui/byte_addressable_buffer/u32.rs @@ -6,7 +6,7 @@ use spirv_std::ByteAddressableBuffer; #[spirv(fragment)] pub fn load( #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], - #[spirv(flat)] out: &mut u32, + out: &mut u32, ) { unsafe { let buf = ByteAddressableBuffer::new(buf); diff --git a/tests/ui/dis/pass-mode-cast-struct.rs b/tests/ui/dis/pass-mode-cast-struct.rs index 7bcb4570bd..c86e170d49 100644 --- a/tests/ui/dis/pass-mode-cast-struct.rs +++ b/tests/ui/dis/pass-mode-cast-struct.rs @@ -24,7 +24,7 @@ impl Foo { } #[spirv(fragment)] -pub fn main(#[spirv(flat)] in_packed: u64, #[spirv(flat)] out_sum: &mut u32) { +pub fn main(#[spirv(flat)] in_packed: u64, out_sum: &mut u32) { let foo = Foo::unpack(in_packed); *out_sum = foo.a + (foo.b + foo.c) as u32; } diff --git a/tests/ui/image/issue-330.rs b/tests/ui/image/issue-330.rs index ded6796be3..5d60ac88c7 100644 --- a/tests/ui/image/issue-330.rs +++ b/tests/ui/image/issue-330.rs @@ -2,7 +2,6 @@ use spirv_std::glam::Vec4; use spirv_std::spirv; use spirv_std::{image::Image2dArray, Sampler}; -#[allow(unused_attributes)] #[spirv(fragment)] pub fn ps_main_stereo( output: &mut Vec4, diff --git a/tests/ui/image/query/query_levels.rs b/tests/ui/image/query/query_levels.rs index 2660f36cdc..79f51bd7a5 100644 --- a/tests/ui/image/query/query_levels.rs +++ b/tests/ui/image/query/query_levels.rs @@ -7,7 +7,7 @@ use spirv_std::{arch, Image}; #[spirv(fragment)] pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), - #[spirv(flat)] output: &mut u32, + output: &mut u32, ) { *output = image.query_levels(); } diff --git a/tests/ui/image/query/query_samples.rs b/tests/ui/image/query/query_samples.rs index c2cf6d0912..eeeb1e15cf 100644 --- a/tests/ui/image/query/query_samples.rs +++ b/tests/ui/image/query/query_samples.rs @@ -7,7 +7,7 @@ use spirv_std::{arch, Image}; #[spirv(fragment)] pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled, multisampled), - #[spirv(flat)] output: &mut u32, + output: &mut u32, ) { *output = image.query_samples(); } diff --git a/tests/ui/image/query/query_size.rs b/tests/ui/image/query/query_size.rs index 9c03eb0c14..af2a71994c 100644 --- a/tests/ui/image/query/query_size.rs +++ b/tests/ui/image/query/query_size.rs @@ -7,7 +7,7 @@ use spirv_std::{arch, Image}; #[spirv(fragment)] pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled=false), - #[spirv(flat)] output: &mut glam::UVec2, + output: &mut glam::UVec2, ) { *output = image.query_size(); } diff --git a/tests/ui/image/query/query_size_lod.rs b/tests/ui/image/query/query_size_lod.rs index 507af953a5..c80c0ca216 100644 --- a/tests/ui/image/query/query_size_lod.rs +++ b/tests/ui/image/query/query_size_lod.rs @@ -7,7 +7,7 @@ use spirv_std::{arch, Image}; #[spirv(fragment)] pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), - #[spirv(flat)] output: &mut glam::UVec2, + output: &mut glam::UVec2, ) { *output = image.query_size_lod(0); } diff --git a/tests/ui/lang/consts/issue-329.rs b/tests/ui/lang/consts/issue-329.rs index 59d911cc23..8026968496 100644 --- a/tests/ui/lang/consts/issue-329.rs +++ b/tests/ui/lang/consts/issue-329.rs @@ -8,8 +8,7 @@ const OFFSETS: [f32; 18] = [ 33.368627, ]; -#[allow(unused_attributes)] #[spirv(fragment)] -pub fn main(#[spirv(flat)] x: &mut u32) { +pub fn main(x: &mut u32) { *x = OFFSETS.len() as u32; } diff --git a/tests/ui/lang/consts/nested-ref-in-composite.rs b/tests/ui/lang/consts/nested-ref-in-composite.rs index fa5d6dafcb..311a0d7bfc 100644 --- a/tests/ui/lang/consts/nested-ref-in-composite.rs +++ b/tests/ui/lang/consts/nested-ref-in-composite.rs @@ -18,11 +18,11 @@ fn array3_deep_load(r: &'static [&'static u32; 3]) -> [u32; 3] { } #[spirv(fragment)] -pub fn main_pair(#[spirv(flat)] pair_out: &mut (u32, f32)) { +pub fn main_pair(pair_out: &mut (u32, f32)) { *pair_out = pair_deep_load(&(&123, &3.14)); } #[spirv(fragment)] -pub fn main_array3(#[spirv(flat)] array3_out: &mut [u32; 3]) { +pub fn main_array3(array3_out: &mut [u32; 3]) { *array3_out = array3_deep_load(&[&0, &1, &2]); } diff --git a/tests/ui/lang/consts/nested-ref.rs b/tests/ui/lang/consts/nested-ref.rs index 1617d10ef2..9f41fd05dc 100644 --- a/tests/ui/lang/consts/nested-ref.rs +++ b/tests/ui/lang/consts/nested-ref.rs @@ -22,9 +22,9 @@ fn deep_transpose(r: &'static &'static Mat2) -> Mat2 { #[spirv(fragment)] pub fn main( - #[spirv(flat)] scalar_out: &mut u32, + scalar_out: &mut u32, #[spirv(push_constant)] vec_in: &Vec2, - #[spirv(flat)] bool_out: &mut u32, + bool_out: &mut u32, vec_out: &mut Vec2, ) { *scalar_out = deep_load(&&123); diff --git a/tests/ui/lang/consts/shallow-ref.rs b/tests/ui/lang/consts/shallow-ref.rs index f54497183e..06fd1cdfb4 100644 --- a/tests/ui/lang/consts/shallow-ref.rs +++ b/tests/ui/lang/consts/shallow-ref.rs @@ -15,12 +15,7 @@ fn scalar_load(r: &'static u32) -> u32 { const ROT90: Mat2 = const_mat2![[0.0, 1.0], [-1.0, 0.0]]; #[spirv(fragment)] -pub fn main( - #[spirv(flat)] scalar_out: &mut u32, - vec_in: Vec2, - #[spirv(flat)] bool_out: &mut u32, - vec_out: &mut Vec2, -) { +pub fn main(scalar_out: &mut u32, vec_in: Vec2, bool_out: &mut u32, vec_out: &mut Vec2) { *scalar_out = scalar_load(&123); *bool_out = (vec_in == Vec2::ZERO) as u32; *vec_out = ROT90.transpose() * vec_in; diff --git a/tests/ui/lang/control_flow/closure_multi.rs b/tests/ui/lang/control_flow/closure_multi.rs index 1a947bf890..0bedf85361 100644 --- a/tests/ui/lang/control_flow/closure_multi.rs +++ b/tests/ui/lang/control_flow/closure_multi.rs @@ -10,7 +10,7 @@ fn closure_user(ptr: &u32, xmax: u32, mut callback: F) { } #[spirv(fragment)] -pub fn main(#[spirv(flat)] ptr: &mut u32) { +pub fn main(ptr: &mut u32) { closure_user(ptr, 10, |ptr, i| { if *ptr == i { spirv_std::arch::kill(); diff --git a/tests/ui/lang/core/ops/range-contains.rs b/tests/ui/lang/core/ops/range-contains.rs index 3438376d7f..0372795793 100644 --- a/tests/ui/lang/core/ops/range-contains.rs +++ b/tests/ui/lang/core/ops/range-contains.rs @@ -11,6 +11,6 @@ fn has_two_decimal_digits(x: u32) -> bool { } #[spirv(fragment)] -pub fn main(#[spirv(flat)] i: u32, #[spirv(flat)] o: &mut u32) { +pub fn main(#[spirv(flat)] i: u32, o: &mut u32) { *o = has_two_decimal_digits(i) as u32; } diff --git a/tests/ui/lang/core/unwrap_or.rs b/tests/ui/lang/core/unwrap_or.rs index 4a474e39f1..71efc51bb5 100644 --- a/tests/ui/lang/core/unwrap_or.rs +++ b/tests/ui/lang/core/unwrap_or.rs @@ -7,6 +7,6 @@ use spirv_std::spirv; #[spirv(fragment)] -pub fn main(#[spirv(flat)] out: &mut u32) { +pub fn main(out: &mut u32) { *out = None.unwrap_or(15); } diff --git a/tests/ui/lang/f32/packing.rs b/tests/ui/lang/f32/packing.rs index b03a912243..0cb1c47da9 100644 --- a/tests/ui/lang/f32/packing.rs +++ b/tests/ui/lang/f32/packing.rs @@ -6,7 +6,7 @@ use spirv_std::glam::{Vec2, Vec4}; use spirv_std::spirv; #[spirv(fragment)] -pub fn test_vec2_to_f16x2(i: Vec2, #[spirv(flat)] o: &mut u32) { +pub fn test_vec2_to_f16x2(i: Vec2, o: &mut u32) { *o = vec2_to_f16x2(i); } @@ -16,7 +16,7 @@ pub fn test_f16x2_to_vec2(#[spirv(flat)] i: u32, o: &mut Vec2) { } #[spirv(fragment)] -pub fn test_f32_to_f16(i: f32, #[spirv(flat)] o: &mut u32) { +pub fn test_f32_to_f16(i: f32, o: &mut u32) { *o = f32_to_f16(i); } @@ -26,22 +26,22 @@ pub fn test_f16_to_f32(#[spirv(flat)] i: u32, o: &mut f32) { } #[spirv(fragment)] -pub fn test_vec4_to_u8x4_snorm(i: Vec4, #[spirv(flat)] o: &mut u32) { +pub fn test_vec4_to_u8x4_snorm(i: Vec4, o: &mut u32) { *o = vec4_to_u8x4_snorm(i); } #[spirv(fragment)] -pub fn test_vec4_to_u8x4_unorm(i: Vec4, #[spirv(flat)] o: &mut u32) { +pub fn test_vec4_to_u8x4_unorm(i: Vec4, o: &mut u32) { *o = vec4_to_u8x4_unorm(i); } #[spirv(fragment)] -pub fn test_vec2_to_u16x2_snorm(i: Vec2, #[spirv(flat)] o: &mut u32) { +pub fn test_vec2_to_u16x2_snorm(i: Vec2, o: &mut u32) { *o = vec2_to_u16x2_snorm(i); } #[spirv(fragment)] -pub fn test_vec2_to_u16x2_unorm(i: Vec2, #[spirv(flat)] o: &mut u32) { +pub fn test_vec2_to_u16x2_unorm(i: Vec2, o: &mut u32) { *o = vec2_to_u16x2_unorm(i); } diff --git a/tests/ui/lang/issue-836.rs b/tests/ui/lang/issue-836.rs index 5af1cdbe1b..1919fa3b32 100644 --- a/tests/ui/lang/issue-836.rs +++ b/tests/ui/lang/issue-836.rs @@ -29,7 +29,7 @@ struct CustomPair(u32, u32); #[spirv(fragment)] pub fn main( #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] slice: &[u32], - #[spirv(flat)] out: &mut u32, + out: &mut u32, ) { let newtype_slice = Newtype(slice); *out = newtype_slice.get()[0]; diff --git a/tests/ui/spirv-attr/all-builtins.rs b/tests/ui/spirv-attr/all-builtins.rs index d4df7b93ea..3108306428 100644 --- a/tests/ui/spirv-attr/all-builtins.rs +++ b/tests/ui/spirv-attr/all-builtins.rs @@ -94,18 +94,18 @@ pub fn fragment( #[spirv(clip_distance)] clip_distance: [f32; 1], #[spirv(cull_distance)] cull_distance: [f32; 1], #[spirv(frag_coord)] frag_coord: Vec4, - #[spirv(frag_invocation_count_ext)] frag_invocation_count_ext: u32, - #[spirv(frag_size_ext)] frag_size_ext: UVec2, + #[spirv(frag_invocation_count_ext, flat)] frag_invocation_count_ext: u32, + #[spirv(frag_size_ext, flat)] frag_size_ext: UVec2, #[spirv(front_facing)] front_facing: bool, #[spirv(fully_covered_ext)] fully_covered_ext: bool, #[spirv(helper_invocation)] helper_invocation: bool, - #[spirv(layer)] layer: u32, + #[spirv(layer, flat)] layer: u32, #[spirv(point_coord)] point_coord: Vec2, - #[spirv(primitive_id)] primitive_id: u32, - #[spirv(sample_id)] sample_id: u32, - #[spirv(sample_mask)] sample_mask: [u32; 1], + #[spirv(primitive_id, flat)] primitive_id: u32, + #[spirv(sample_id, flat)] sample_id: u32, + #[spirv(sample_mask, flat)] sample_mask: [u32; 1], #[spirv(sample_position)] sample_position: Vec2, - #[spirv(viewport_index)] viewport_index: u32, + #[spirv(viewport_index, flat)] viewport_index: u32, ) { } #[spirv(closest_hit)] diff --git a/tests/ui/spirv-attr/bool-inputs-err.stderr b/tests/ui/spirv-attr/bool-inputs-err.stderr index 15d2ff45f6..2f79db13b5 100644 --- a/tests/ui/spirv-attr/bool-inputs-err.stderr +++ b/tests/ui/spirv-attr/bool-inputs-err.stderr @@ -1,22 +1,22 @@ -error: entrypoint parameter cannot contain a boolean +error: entry-point parameter cannot contain `bool`s --> $DIR/bool-inputs-err.rs:13:12 | 13 | input: bool, | ^^^^ -error: entrypoint parameter cannot contain a boolean +error: entry-point parameter cannot contain `bool`s --> $DIR/bool-inputs-err.rs:14:13 | 14 | output: &mut bool, | ^^^^^^^^^ -error: entrypoint parameter cannot contain a boolean +error: entry-point parameter cannot contain `bool`s --> $DIR/bool-inputs-err.rs:15:35 | 15 | #[spirv(push_constant)] push: &bool, | ^^^^^ -error: entrypoint parameter cannot contain a boolean +error: entry-point parameter cannot contain `bool`s --> $DIR/bool-inputs-err.rs:16:32 | 16 | #[spirv(uniform)] uniform: &Boolthing, diff --git a/tests/ui/spirv-attr/int-without-flat.stderr b/tests/ui/spirv-attr/int-without-flat.stderr index 70c49609c4..45b5fcbc6b 100644 --- a/tests/ui/spirv-attr/int-without-flat.stderr +++ b/tests/ui/spirv-attr/int-without-flat.stderr @@ -1,10 +1,10 @@ -error: parameter must be decorated with #[spirv(flat)] +error: `Fragment` entry-point `Input` parameter must be decorated with `#[spirv(flat)]` --> $DIR/int-without-flat.rs:6:22 | 6 | pub fn fragment(int: u32, double: f64) {} | ^^^ -error: parameter must be decorated with #[spirv(flat)] +error: `Fragment` entry-point `Input` parameter must be decorated with `#[spirv(flat)]` --> $DIR/int-without-flat.rs:6:35 | 6 | pub fn fragment(int: u32, double: f64) {}