From 9404ff109905ef035ced4bf17d6cb249aac93cd6 Mon Sep 17 00:00:00 2001 From: Daniel Tang Date: Sun, 28 Mar 2021 09:21:36 -0400 Subject: [PATCH] Allow arrays in graphics in addition to from_iter --- CHANGELOG_VULKANO.md | 1 + vulkano/src/buffer/slice.rs | 42 +++++++++++ vulkano/src/buffer/traits.rs | 2 +- .../src/pipeline/vertex/instance_buffer.rs | 11 +++ vulkano/src/pipeline/vertex/one_one.rs | 65 ++++++++++++++-- vulkano/src/pipeline/vertex/single.rs | 11 +++ vulkano/src/pipeline/vertex/two.rs | 75 +++++++++++++++++-- 7 files changed, 191 insertions(+), 16 deletions(-) diff --git a/CHANGELOG_VULKANO.md b/CHANGELOG_VULKANO.md index 7dff03afe2..cb1f655220 100644 --- a/CHANGELOG_VULKANO.md +++ b/CHANGELOG_VULKANO.md @@ -29,6 +29,7 @@ - Fixed missing barriers in dispatch calls - **Breaking** `shader!` no longer marks descriptor sets as readonly as a fallback when it doesn't know - **Breaking** The keyword `readonly` might need to be added in front of the `buffer` keyword in GLSL files to get them working again +- Add support in `AutoCommandbufferBuilder::draw` for taking `[T; N]` in addition to `[T]` # Version 0.21.0 (2021-03-05) diff --git a/vulkano/src/buffer/slice.rs b/vulkano/src/buffer/slice.rs index dbbfe7ce53..074a96a5fd 100644 --- a/vulkano/src/buffer/slice.rs +++ b/vulkano/src/buffer/slice.rs @@ -214,6 +214,48 @@ impl BufferSlice<[T], B> { } } +impl BufferSlice<[T; N], B> { + /// Returns the number of elements in this slice. + #[inline] + pub fn len(&self) -> usize { + N + } + + /// Reduces the slice to just one element of the array. + /// + /// Returns `None` if out of range. + #[inline] + pub fn index(self, index: usize) -> Option> { + if index >= N { + return None; + } + + Some(BufferSlice { + marker: PhantomData, + resource: self.resource, + offset: self.offset + index * mem::size_of::(), + size: mem::size_of::(), + }) + } + + /// Reduces the slice to just a range of the array. + /// + /// Returns `None` if out of range. + #[inline] + pub fn slice(self, range: Range) -> Option> { + if range.end > N { + return None; + } + + Some(BufferSlice { + marker: PhantomData, + resource: self.resource, + offset: self.offset + range.start * mem::size_of::(), + size: (range.end - range.start) * mem::size_of::(), + }) + } +} + unsafe impl BufferAccess for BufferSlice where B: BufferAccess, diff --git a/vulkano/src/buffer/traits.rs b/vulkano/src/buffer/traits.rs index 41c40ddc54..a82f664a2b 100644 --- a/vulkano/src/buffer/traits.rs +++ b/vulkano/src/buffer/traits.rs @@ -56,7 +56,7 @@ pub unsafe trait BufferAccess: DeviceOwned { where Self: Sized + TypedBufferAccess, { - BufferSlice::slice(self.as_buffer_slice(), range) + >::slice(self.as_buffer_slice(), range) } /// Builds a `BufferSlice` object holding the buffer by value. diff --git a/vulkano/src/pipeline/vertex/instance_buffer.rs b/vulkano/src/pipeline/vertex/instance_buffer.rs index d1675be622..0d502f6687 100644 --- a/vulkano/src/pipeline/vertex/instance_buffer.rs +++ b/vulkano/src/pipeline/vertex/instance_buffer.rs @@ -121,3 +121,14 @@ where (vec![Box::new(source) as Box<_>], 1, len) } } + +unsafe impl<'a, B, V, const N: usize> VertexSource<[B; 1]> for SingleInstanceBufferDefinition +where + B: TypedBufferAccess + Send + Sync + 'static, + V: Vertex, +{ + #[inline] + fn decode(&self, [source]: [B; 1]) -> (Vec>, usize, usize) { + (vec![Box::new(source) as Box<_>], 1, N) + } +} diff --git a/vulkano/src/pipeline/vertex/one_one.rs b/vulkano/src/pipeline/vertex/one_one.rs index 2ed5c966be..c77ca11bdb 100644 --- a/vulkano/src/pipeline/vertex/one_one.rs +++ b/vulkano/src/pipeline/vertex/one_one.rs @@ -133,13 +133,62 @@ where Bu: TypedBufferAccess + Send + Sync + 'static, { #[inline] - fn decode(&self, source: (Bt, Bu)) -> (Vec>, usize, usize) { - let s1l = source.0.len(); - let s2l = source.1.len(); - ( - vec![Box::new(source.0) as Box<_>, Box::new(source.1) as Box<_>], - s1l, - s2l, - ) + fn decode(&self, (t, u): (Bt, Bu)) -> (Vec>, usize, usize) { + let t_l = t.len(); + let u_l = u.len(); + (vec![Box::new(t) as Box<_>, Box::new(u) as Box<_>], t_l, u_l) + } +} + +unsafe impl<'a, T, U, Bt, Bu, const T_N: usize> VertexSource<([Bt; 1], Bu)> + for OneVertexOneInstanceDefinition +where + T: Vertex, + Bt: TypedBufferAccess + Send + Sync + 'static, + U: Vertex, + Bu: TypedBufferAccess + Send + Sync + 'static, +{ + #[inline] + fn decode( + &self, + ([t], u): ([Bt; 1], Bu), + ) -> (Vec>, usize, usize) { + let u_l = u.len(); + (vec![Box::new(t) as Box<_>, Box::new(u) as Box<_>], T_N, u_l) + } +} + +unsafe impl<'a, T, U, Bt, Bu, const U_N: usize> VertexSource<(Bt, [Bu; 1])> + for OneVertexOneInstanceDefinition +where + T: Vertex, + Bt: TypedBufferAccess + Send + Sync + 'static, + U: Vertex, + Bu: TypedBufferAccess + Send + Sync + 'static, +{ + #[inline] + fn decode( + &self, + (t, [u]): (Bt, [Bu; 1]), + ) -> (Vec>, usize, usize) { + let t_l = t.len(); + (vec![Box::new(t) as Box<_>, Box::new(u) as Box<_>], t_l, U_N) + } +} + +unsafe impl<'a, T, U, Bt, Bu, const T_N: usize, const U_N: usize> VertexSource<([Bt; 1], [Bu; 1])> + for OneVertexOneInstanceDefinition +where + T: Vertex, + Bt: TypedBufferAccess + Send + Sync + 'static, + U: Vertex, + Bu: TypedBufferAccess + Send + Sync + 'static, +{ + #[inline] + fn decode( + &self, + ([t], [u]): ([Bt; 1], [Bu; 1]), + ) -> (Vec>, usize, usize) { + (vec![Box::new(t) as Box<_>, Box::new(u) as Box<_>], T_N, U_N) } } diff --git a/vulkano/src/pipeline/vertex/single.rs b/vulkano/src/pipeline/vertex/single.rs index 4a64ec7239..22da49c434 100644 --- a/vulkano/src/pipeline/vertex/single.rs +++ b/vulkano/src/pipeline/vertex/single.rs @@ -120,3 +120,14 @@ where (vec![Box::new(source) as Box<_>], len, 1) } } + +unsafe impl<'a, B, V, const N: usize> VertexSource<[B; 1]> for SingleBufferDefinition +where + B: TypedBufferAccess + Send + Sync + 'static, + V: Vertex, +{ + #[inline] + fn decode(&self, [source]: [B; 1]) -> (Vec>, usize, usize) { + (vec![Box::new(source) as Box<_>], N, 1) + } +} diff --git a/vulkano/src/pipeline/vertex/two.rs b/vulkano/src/pipeline/vertex/two.rs index f3296beddf..fe3b77456f 100644 --- a/vulkano/src/pipeline/vertex/two.rs +++ b/vulkano/src/pipeline/vertex/two.rs @@ -137,16 +137,77 @@ where Bu: TypedBufferAccess + Send + Sync + 'static, { #[inline] - fn decode(&self, source: (Bt, Bu)) -> (Vec>, usize, usize) { - let vertices = [source.0.len(), source.1.len()] - .iter() - .cloned() - .min() - .unwrap(); + fn decode(&self, (t, u): (Bt, Bu)) -> (Vec>, usize, usize) { + let vertices = t.len().min(u.len()); ( - vec![Box::new(source.0) as Box<_>, Box::new(source.1) as Box<_>], + vec![Box::new(t) as Box<_>, Box::new(u) as Box<_>], vertices, 1, ) } } + +unsafe impl<'a, T, U, Bt, Bu, const T_N: usize> VertexSource<([Bt; 1], Bu)> + for TwoBuffersDefinition +where + T: Vertex, + Bt: TypedBufferAccess + Send + Sync + 'static, + U: Vertex, + Bu: TypedBufferAccess + Send + Sync + 'static, +{ + #[inline] + fn decode( + &self, + ([t], u): ([Bt; 1], Bu), + ) -> (Vec>, usize, usize) { + let u_l = u.len(); + ( + vec![Box::new(t) as Box<_>, Box::new(u) as Box<_>], + T_N.min(u_l), + 1, + ) + } +} + +unsafe impl<'a, T, U, Bt, Bu, const U_N: usize> VertexSource<(Bt, [Bu; 1])> + for TwoBuffersDefinition +where + T: Vertex, + Bt: TypedBufferAccess + Send + Sync + 'static, + U: Vertex, + Bu: TypedBufferAccess + Send + Sync + 'static, +{ + #[inline] + fn decode( + &self, + (t, [u]): (Bt, [Bu; 1]), + ) -> (Vec>, usize, usize) { + let t_l = t.len(); + ( + vec![Box::new(t) as Box<_>, Box::new(u) as Box<_>], + t_l.min(U_N), + 1, + ) + } +} + +unsafe impl<'a, T, U, Bt, Bu, const T_N: usize, const U_N: usize> VertexSource<([Bt; 1], [Bu; 1])> + for TwoBuffersDefinition +where + T: Vertex, + Bt: TypedBufferAccess + Send + Sync + 'static, + U: Vertex, + Bu: TypedBufferAccess + Send + Sync + 'static, +{ + #[inline] + fn decode( + &self, + ([t], [u]): ([Bt; 1], [Bu; 1]), + ) -> (Vec>, usize, usize) { + ( + vec![Box::new(t) as Box<_>, Box::new(u) as Box<_>], + T_N.min(U_N), + 1, + ) + } +}