From b420f9648049ac358007958adf7d32f346989e55 Mon Sep 17 00:00:00 2001 From: Niklas Voss Date: Thu, 29 Dec 2022 13:51:57 +0100 Subject: [PATCH] Reduce the amount of types required, remove VertexInfo, expose VertexBufferInfo methods on Vertex and use std HashMap transparently instead. --- vulkano/macros/src/derive_vertex.rs | 45 +++++---- .../pipeline/graphics/vertex_input/buffers.rs | 6 +- .../graphics/vertex_input/impl_vertex.rs | 24 +++-- .../src/pipeline/graphics/vertex_input/mod.rs | 4 +- .../pipeline/graphics/vertex_input/vertex.rs | 96 +++++++------------ 5 files changed, 83 insertions(+), 92 deletions(-) diff --git a/vulkano/macros/src/derive_vertex.rs b/vulkano/macros/src/derive_vertex.rs index 1e34b835a6..9a97a30f8a 100644 --- a/vulkano/macros/src/derive_vertex.rs +++ b/vulkano/macros/src/derive_vertex.rs @@ -43,7 +43,7 @@ pub fn derive_vertex(ast: syn::DeriveInput) -> Result { let mut members = quote! { let mut offset = 0; - let mut members = VertexMemberMap::default(); + let mut members = HashMap::default(); }; for field in fields.iter() { @@ -99,24 +99,37 @@ pub fn derive_vertex(ast: syn::DeriveInput) -> Result { } } - Ok(TokenStream::from(quote! { - #[allow(unsafe_code)] - unsafe impl #crate_ident::pipeline::graphics::vertex_input::Vertex for #struct_name { - #[inline(always)] - fn info() -> #crate_ident::pipeline::graphics::vertex_input::VertexInfo { - #[allow(unused_imports)] - use #crate_ident::format::Format; - use #crate_ident::pipeline::graphics::vertex_input::VertexMemberInfo; - use #crate_ident::pipeline::graphics::vertex_input::VertexMemberMap; + let function_body = quote! { + #[allow(unused_imports)] + use std::collections::HashMap; + use #crate_ident::format::Format; + use #crate_ident::pipeline::graphics::vertex_input::{VertexInputRate, VertexMemberInfo}; - #members + #members - #crate_ident::pipeline::graphics::vertex_input::VertexInfo { - members, - stride: std::mem::size_of::<#struct_name>() as u32, - } - } + #crate_ident::pipeline::graphics::vertex_input::VertexBufferInfo { + members, + stride: std::mem::size_of::<#struct_name>() as u32, + input_rate: VertexInputRate::Vertex, } + }; + + Ok(TokenStream::from(quote! { + #[allow(unsafe_code)] + unsafe impl #crate_ident::pipeline::graphics::vertex_input::Vertex for #struct_name { + #[inline(always)] + fn per_vertex() -> #crate_ident::pipeline::graphics::vertex_input::VertexBufferInfo { + #function_body + } + #[inline(always)] + fn per_instance() -> #crate_ident::pipeline::graphics::vertex_input::VertexBufferInfo { + #function_body.per_instance() + } + #[inline(always)] + fn per_instance_with_divisor(divisor: u32) -> #crate_ident::pipeline::graphics::vertex_input::VertexBufferInfo { + #function_body.per_instance_with_divisor(divisor) + } + } })) } diff --git a/vulkano/src/pipeline/graphics/vertex_input/buffers.rs b/vulkano/src/pipeline/graphics/vertex_input/buffers.rs index a8bad8e871..669ec8f64f 100644 --- a/vulkano/src/pipeline/graphics/vertex_input/buffers.rs +++ b/vulkano/src/pipeline/graphics/vertex_input/buffers.rs @@ -28,13 +28,13 @@ impl BuffersDefinition { /// Adds a new vertex buffer containing elements of type `V` to the definition. pub fn vertex(mut self) -> Self { - self.0.push(V::info().per_vertex()); + self.0.push(V::per_vertex()); self } /// Adds a new instance buffer containing elements of type `V` to the definition. pub fn instance(mut self) -> Self { - self.0.push(V::info().per_instance()); + self.0.push(V::per_instance()); self } @@ -50,7 +50,7 @@ impl BuffersDefinition { /// [`vertex_attribute_instance_rate_divisor`]: crate::device::Features::vertex_attribute_instance_rate_divisor /// [`vertex_attribute_instance_rate_zero_divisor`]: crate::device::Features::vertex_attribute_instance_rate_zero_divisor pub fn instance_with_divisor(mut self, divisor: u32) -> Self { - self.0.push(V::info().per_instance_with_divisor(divisor)); + self.0.push(V::per_instance_with_divisor(divisor)); self } } diff --git a/vulkano/src/pipeline/graphics/vertex_input/impl_vertex.rs b/vulkano/src/pipeline/graphics/vertex_input/impl_vertex.rs index 08ba70ada7..c43ca4e22a 100644 --- a/vulkano/src/pipeline/graphics/vertex_input/impl_vertex.rs +++ b/vulkano/src/pipeline/graphics/vertex_input/impl_vertex.rs @@ -35,14 +35,14 @@ macro_rules! impl_vertex { unsafe impl $crate::pipeline::graphics::vertex_input::Vertex for $out { #[inline(always)] #[allow(deprecated)] - fn info() -> $crate::pipeline::graphics::vertex_input::VertexInfo { + fn per_vertex() -> $crate::pipeline::graphics::vertex_input::VertexBufferInfo { #[allow(unused_imports)] + use std::collections::HashMap; use $crate::format::Format; - use $crate::pipeline::graphics::vertex_input::VertexMemberInfo; use $crate::pipeline::graphics::vertex_input::VertexMember; - use $crate::pipeline::graphics::vertex_input::VertexMemberMap; + use $crate::pipeline::graphics::vertex_input::{VertexInputRate, VertexMemberInfo}; - let mut members = VertexMemberMap::default(); + let mut members = HashMap::default(); $( { let dummy = <$out>::default(); @@ -73,11 +73,23 @@ macro_rules! impl_vertex { } )* - $crate::pipeline::graphics::vertex_input::VertexInfo { + $crate::pipeline::graphics::vertex_input::VertexBufferInfo { members, stride: std::mem::size_of::<$out>() as u32, + input_rate: VertexInputRate::Vertex, } } + #[inline(always)] + #[allow(deprecated)] + fn per_instance() -> $crate::pipeline::graphics::vertex_input::VertexBufferInfo { + <$out as Vertex>::per_vertex().per_instance() + } + #[inline(always)] + #[allow(deprecated)] + fn per_instance_with_divisor(divisor: u32) -> $crate::pipeline::graphics::vertex_input::VertexBufferInfo { + <$out as Vertex>::per_vertex().per_instance_with_divisor(divisor) + } + } ) } @@ -228,7 +240,7 @@ mod tests { } impl_vertex!(TestVertex, scalar, vector, matrix); - let info = TestVertex::info(); + let info = TestVertex::per_vertex(); let matrix = info.members.get("matrix").unwrap(); let vector = info.members.get("vector").unwrap(); let scalar = info.members.get("scalar").unwrap(); diff --git a/vulkano/src/pipeline/graphics/vertex_input/mod.rs b/vulkano/src/pipeline/graphics/vertex_input/mod.rs index 0ca8e82b6c..49374df492 100644 --- a/vulkano/src/pipeline/graphics/vertex_input/mod.rs +++ b/vulkano/src/pipeline/graphics/vertex_input/mod.rs @@ -104,9 +104,7 @@ pub use self::{ collection::VertexBuffersCollection, definition::{IncompatibleVertexDefinitionError, VertexDefinition}, impl_vertex::VertexMember, - vertex::{ - Vertex, VertexBufferInfo, VertexInfo, VertexInput, VertexMemberInfo, VertexMemberMap, - }, + vertex::{Vertex, VertexBufferInfo, VertexMemberInfo}, }; use crate::format::Format; use ahash::HashMap; diff --git a/vulkano/src/pipeline/graphics/vertex_input/vertex.rs b/vulkano/src/pipeline/graphics/vertex_input/vertex.rs index c54465af33..39e2c0968b 100644 --- a/vulkano/src/pipeline/graphics/vertex_input/vertex.rs +++ b/vulkano/src/pipeline/graphics/vertex_input/vertex.rs @@ -7,8 +7,9 @@ // notice may not be copied, modified, or distributed except // according to those terms. +use std::collections::HashMap; + use crate::format::Format; -use ahash::HashMap; use bytemuck::Pod; pub use vulkano_macros::Vertex; @@ -41,46 +42,54 @@ use super::{VertexInputBindingDescription, VertexInputRate}; /// ``` pub unsafe trait Vertex: Pod + Send + Sync + 'static { /// Returns the information about this Vertex type. - fn info() -> VertexInfo; -} - -// TODO: still required? -unsafe impl Vertex for () { - #[inline] - fn info() -> VertexInfo { - VertexInfo { - members: VertexMemberMap::default(), - stride: 0, - } - } + fn per_vertex() -> VertexBufferInfo; + fn per_instance() -> VertexBufferInfo; + fn per_instance_with_divisor(divisor: u32) -> VertexBufferInfo; } -pub type VertexMemberMap = HashMap; - -pub struct VertexInfo { +/// Information about the contents of a VertexBuffer. +#[derive(Clone, Debug)] +pub struct VertexBufferInfo { /// List of member names with their detailed information. - pub members: VertexMemberMap, - /// Stride of the vertex type. + pub members: HashMap, + /// Stride of the vertex type in a buffer. pub stride: u32, + /// How the vertex buffer is unrolled in the shader. + pub input_rate: VertexInputRate, } -impl VertexInfo { +impl From for VertexInputBindingDescription { + fn from(val: VertexBufferInfo) -> Self { + Self { + stride: val.stride, + input_rate: val.input_rate, + } + } +} + +impl VertexBufferInfo { #[inline] pub fn per_vertex(self) -> VertexBufferInfo { - let VertexInfo { members, stride } = self; + let VertexBufferInfo { + members, stride, .. + } = self; VertexBufferInfo { members, stride, input_rate: VertexInputRate::Vertex, } } + #[inline] pub fn per_instance(self) -> VertexBufferInfo { self.per_instance_with_divisor(1) } + #[inline] pub fn per_instance_with_divisor(self, divisor: u32) -> VertexBufferInfo { - let VertexInfo { members, stride } = self; + let VertexBufferInfo { + members, stride, .. + } = self; VertexBufferInfo { members, stride, @@ -111,47 +120,6 @@ impl VertexMemberInfo { } } -/// Information about the contents of a VertexBuffer. -#[derive(Clone, Debug)] -pub struct VertexBufferInfo { - /// List of member names with their detailed information. - pub members: VertexMemberMap, - /// Stride of the vertex type in a buffer. - pub stride: u32, - /// How the vertex buffer is unrolled in the shader. - pub input_rate: VertexInputRate, -} - -impl From for VertexInputBindingDescription { - fn from(val: VertexBufferInfo) -> Self { - Self { - stride: val.stride, - input_rate: val.input_rate, - } - } -} - -pub unsafe trait VertexInput { - fn per_vertex() -> VertexBufferInfo; - fn per_instance() -> VertexBufferInfo; - fn per_instance_with_divisor(divisor: u32) -> VertexBufferInfo; -} - -unsafe impl VertexInput for T { - #[inline] - fn per_vertex() -> VertexBufferInfo { - ::info().per_vertex() - } - #[inline] - fn per_instance() -> VertexBufferInfo { - ::info().per_instance() - } - #[inline] - fn per_instance_with_divisor(divisor: u32) -> VertexBufferInfo { - ::info().per_instance_with_divisor(divisor) - } -} - #[cfg(test)] mod tests { use crate::format::Format; @@ -169,7 +137,7 @@ mod tests { a: [f32; 16], } - let info = TestVertex::info(); + let info = TestVertex::per_vertex(); let b = info.members.get("b").unwrap(); let c = info.members.get("c").unwrap(); assert_eq!(b.format, Format::R32G32B32A32_SFLOAT); @@ -187,7 +155,7 @@ mod tests { unorm: u8, } - let info = TestVertex::info(); + let info = TestVertex::per_instance(); let unorm = info.members.get("unorm").unwrap(); assert_eq!(unorm.format, Format::R8_UNORM); assert_eq!(unorm.num_elements, 1);