From 9e640b720adddcbc81826a8f4613b501e3419a50 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 7 Jan 2023 06:26:31 +0200 Subject: [PATCH 1/2] [eddyb's version/leftovers] add `#[spirv(typed_buffer)]` for explicit `SpirvType::InterfaceBlock`s. --- crates/rustc_codegen_spirv/src/abi.rs | 4 ++-- crates/spirv-std/src/typed_buffer.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/abi.rs b/crates/rustc_codegen_spirv/src/abi.rs index 04d1bf9860..79815c0dbb 100644 --- a/crates/rustc_codegen_spirv/src/abi.rs +++ b/crates/rustc_codegen_spirv/src/abi.rs @@ -500,8 +500,8 @@ impl<'tcx> ConvSpirvType<'tcx> for TyAndLayout<'tcx> { // perfectly, in every way that could potentially affect ABI. if self.fields.offset(i) == Size::ZERO && field.size == self.size - && field.align == self.align - && field.backend_repr == self.backend_repr + && field.align.abi == self.align.abi + && field.backend_repr.eq_up_to_validity(&self.backend_repr) { return field.spirv_type(span, cx); } diff --git a/crates/spirv-std/src/typed_buffer.rs b/crates/spirv-std/src/typed_buffer.rs index 7b04f541f1..5386f4dcd0 100644 --- a/crates/spirv-std/src/typed_buffer.rs +++ b/crates/spirv-std/src/typed_buffer.rs @@ -74,7 +74,7 @@ impl Deref for TypedBuffer<[T]> { "%result = OpCompositeConstruct typeof*{result_slot} %inner_ptr %inner_len", "OpStore {result_slot} %result", buffer = in(reg) self, - result_slot = in(reg) &mut result_slot, + result_slot = in(reg) result_slot.as_mut_ptr(), } result_slot.assume_init() } @@ -94,7 +94,7 @@ impl DerefMut for TypedBuffer<[T]> { "%result = OpCompositeConstruct typeof*{result_slot} %inner_ptr %inner_len", "OpStore {result_slot} %result", buffer = in(reg) self, - result_slot = in(reg) &mut result_slot, + result_slot = in(reg) result_slot.as_mut_ptr(), } result_slot.assume_init() } From 11884510499214cfe632bd1c71dcd0084fd0fef4 Mon Sep 17 00:00:00 2001 From: Tendsin Mende Date: Wed, 17 Jul 2024 12:54:48 +0200 Subject: [PATCH 2/2] add test cases for `TypedBuffer` --- .../ui/storage_class/typed-buffer-simple.rs | 25 ++++++++++++++++++ .../typed-buffer-unbound-struct.rs | 26 +++++++++++++++++++ .../ui/storage_class/typed-buffer-unbound.rs | 20 ++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 tests/compiletests/ui/storage_class/typed-buffer-simple.rs create mode 100644 tests/compiletests/ui/storage_class/typed-buffer-unbound-struct.rs create mode 100644 tests/compiletests/ui/storage_class/typed-buffer-unbound.rs diff --git a/tests/compiletests/ui/storage_class/typed-buffer-simple.rs b/tests/compiletests/ui/storage_class/typed-buffer-simple.rs new file mode 100644 index 0000000000..a308cbc9ab --- /dev/null +++ b/tests/compiletests/ui/storage_class/typed-buffer-simple.rs @@ -0,0 +1,25 @@ +// build-pass +// compile-flags: -C target-feature=+RuntimeDescriptorArray,+ext:SPV_EXT_descriptor_indexing + +// Tests the simplest `TypedBuffer` case: Multiple structs of of the same type and size. + +use spirv_std::{RuntimeArray, TypedBuffer, glam::UVec3, spirv}; + +#[derive(Clone, Copy)] +pub struct MyData { + some_big_data: [u32; 1 << 24], +} + +#[spirv(compute(threads(1)))] +pub fn compute( + #[spirv(global_invocation_id)] global_invocation_id: UVec3, + #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] my_data: &mut RuntimeArray< + TypedBuffer, + >, +) { + let mut load_dta = unsafe { my_data.index(global_invocation_id.x as usize) }.some_big_data[0]; + load_dta = 32; + + let mut target = unsafe { &mut my_data.index_mut(global_invocation_id.y as usize) }; + target.some_big_data[0] = load_dta; +} diff --git a/tests/compiletests/ui/storage_class/typed-buffer-unbound-struct.rs b/tests/compiletests/ui/storage_class/typed-buffer-unbound-struct.rs new file mode 100644 index 0000000000..43cf63e679 --- /dev/null +++ b/tests/compiletests/ui/storage_class/typed-buffer-unbound-struct.rs @@ -0,0 +1,26 @@ +// build-pass +// compile-flags: -C target-feature=+RuntimeDescriptorArray,+ext:SPV_EXT_descriptor_indexing + +// Tests the more complex `TypedBuffer` case, where the size of each buffer in the binding is unbound, and also the data type is a struct. + +use spirv_std::{RuntimeArray, TypedBuffer, glam::UVec3, spirv}; + +#[derive(Clone, Copy)] +pub struct MyData { + a: f32, + b: [u32; 3], +} + +#[spirv(compute(threads(1)))] +pub fn compute( + #[spirv(global_invocation_id)] global_invocation_id: UVec3, + #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] my_data: &mut RuntimeArray< + TypedBuffer<[MyData]>, + >, +) { + let mut load_dta: MyData = unsafe { my_data.index(global_invocation_id.x as usize) }[0]; + load_dta.b[0] = 32; + + let mut target = unsafe { &mut my_data.index_mut(global_invocation_id.y as usize)[0] }; + *target = load_dta; +} diff --git a/tests/compiletests/ui/storage_class/typed-buffer-unbound.rs b/tests/compiletests/ui/storage_class/typed-buffer-unbound.rs new file mode 100644 index 0000000000..2d951f73cd --- /dev/null +++ b/tests/compiletests/ui/storage_class/typed-buffer-unbound.rs @@ -0,0 +1,20 @@ +// build-pass +// compile-flags: -C target-feature=+RuntimeDescriptorArray,+ext:SPV_EXT_descriptor_indexing + +// Tests the more complex `TypedBuffer` case, where the size of each buffer in the binding is unbound. + +use spirv_std::{RuntimeArray, TypedBuffer, glam::UVec3, spirv}; + +#[spirv(compute(threads(1)))] +pub fn compute( + #[spirv(global_invocation_id)] global_invocation_id: UVec3, + #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] my_data: &mut RuntimeArray< + TypedBuffer<[u32]>, + >, +) { + let mut load_dta: u32 = unsafe { my_data.index(global_invocation_id.x as usize) }[0]; + load_dta = 32; + + let mut target = unsafe { &mut my_data.index_mut(global_invocation_id.y as usize)[0] }; + *target = load_dta; +}