Skip to content

Commit

Permalink
Reduce the amount of types required, remove VertexInfo, expose Vertex…
Browse files Browse the repository at this point in the history
…BufferInfo methods on Vertex and use std HashMap transparently instead.
  • Loading branch information
trevex committed Dec 29, 2022
1 parent 6238e72 commit b420f96
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 92 deletions.
45 changes: 29 additions & 16 deletions vulkano/macros/src/derive_vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn derive_vertex(ast: syn::DeriveInput) -> Result<TokenStream> {

let mut members = quote! {
let mut offset = 0;
let mut members = VertexMemberMap::default();
let mut members = HashMap::default();
};

for field in fields.iter() {
Expand Down Expand Up @@ -99,24 +99,37 @@ pub fn derive_vertex(ast: syn::DeriveInput) -> Result<TokenStream> {
}
}

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)
}
}
}))
}

Expand Down
6 changes: 3 additions & 3 deletions vulkano/src/pipeline/graphics/vertex_input/buffers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ impl BuffersDefinition {

/// Adds a new vertex buffer containing elements of type `V` to the definition.
pub fn vertex<V: 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<V: Vertex>(mut self) -> Self {
self.0.push(V::info().per_instance());
self.0.push(V::per_instance());
self
}

Expand All @@ -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<V: Vertex>(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
}
}
Expand Down
24 changes: 18 additions & 6 deletions vulkano/src/pipeline/graphics/vertex_input/impl_vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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)
}

}
)
}
Expand Down Expand Up @@ -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();
Expand Down
4 changes: 1 addition & 3 deletions vulkano/src/pipeline/graphics/vertex_input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
96 changes: 32 additions & 64 deletions vulkano/src/pipeline/graphics/vertex_input/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<String, VertexMemberInfo>;

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<String, VertexMemberInfo>,
/// 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<VertexBufferInfo> 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,
Expand Down Expand Up @@ -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<VertexBufferInfo> 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<T: Vertex> VertexInput for T {
#[inline]
fn per_vertex() -> VertexBufferInfo {
<T as Vertex>::info().per_vertex()
}
#[inline]
fn per_instance() -> VertexBufferInfo {
<T as Vertex>::info().per_instance()
}
#[inline]
fn per_instance_with_divisor(divisor: u32) -> VertexBufferInfo {
<T as Vertex>::info().per_instance_with_divisor(divisor)
}
}

#[cfg(test)]
mod tests {
use crate::format::Format;
Expand All @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit b420f96

Please sign in to comment.