From dca51ce676e64cfd14f9f1e3676e87e185bf8544 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Wed, 19 Feb 2020 13:31:59 +0000 Subject: [PATCH] Add vertex_attr_array macro --- examples/boids/main.rs | 26 ++----------- examples/cube/main.rs | 15 ++------ examples/mipmap/main.rs | 8 ++-- examples/msaa-line/main.rs | 15 ++------ examples/shadow/main.rs | 15 ++------ src/lib.rs | 3 ++ src/macros.rs | 77 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 96 insertions(+), 63 deletions(-) create mode 100644 src/macros.rs diff --git a/examples/boids/main.rs b/examples/boids/main.rs index cd1af6eed5..eacd7a9765 100644 --- a/examples/boids/main.rs +++ b/examples/boids/main.rs @@ -9,6 +9,8 @@ mod framework; use std::fmt::Write; use zerocopy::{AsBytes}; +use wgpu::vertex_attr_array; + // number of boid particles to simulate @@ -123,32 +125,12 @@ impl framework::Example for Example { wgpu::VertexBufferDescriptor { stride: 4 * 4, step_mode: wgpu::InputStepMode::Instance, - attributes: &[ - // instance position - wgpu::VertexAttributeDescriptor { - offset: 0, - format: wgpu::VertexFormat::Float2, - shader_location: 0, - }, - // instance velocity - wgpu::VertexAttributeDescriptor { - offset: 2 * 4, - format: wgpu::VertexFormat::Float2, - shader_location: 1, - }, - ] + attributes: &vertex_attr_array![0 => Float2, 1 => Float2], }, wgpu::VertexBufferDescriptor { stride: 2 * 4, step_mode: wgpu::InputStepMode::Vertex, - attributes: &[ - // vertex positions - wgpu::VertexAttributeDescriptor { - offset: 0, - format: wgpu::VertexFormat::Float2, - shader_location: 2, - }, - ] + attributes: &vertex_attr_array![2 => Float2], }, ], sample_count: 1, diff --git a/examples/cube/main.rs b/examples/cube/main.rs index 8eef61ebc7..454a89a52d 100644 --- a/examples/cube/main.rs +++ b/examples/cube/main.rs @@ -3,6 +3,8 @@ mod framework; use zerocopy::{AsBytes, FromBytes}; +use wgpu::vertex_attr_array; + #[repr(C)] #[derive(Clone, Copy, AsBytes, FromBytes)] struct Vertex { @@ -275,18 +277,7 @@ impl framework::Example for Example { vertex_buffers: &[wgpu::VertexBufferDescriptor { stride: vertex_size as wgpu::BufferAddress, step_mode: wgpu::InputStepMode::Vertex, - attributes: &[ - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float4, - offset: 0, - shader_location: 0, - }, - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float2, - offset: 4 * 4, - shader_location: 1, - }, - ], + attributes: &vertex_attr_array![0 => Float4, 1 => Float2], }], sample_count: 1, sample_mask: !0, diff --git a/examples/mipmap/main.rs b/examples/mipmap/main.rs index dbc2f3c84c..35022867d0 100644 --- a/examples/mipmap/main.rs +++ b/examples/mipmap/main.rs @@ -3,6 +3,8 @@ mod framework; use zerocopy::{AsBytes, FromBytes}; +use wgpu::vertex_attr_array; + const TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8UnormSrgb; #[repr(C)] @@ -359,11 +361,7 @@ impl framework::Example for Example { vertex_buffers: &[wgpu::VertexBufferDescriptor { stride: vertex_size as wgpu::BufferAddress, step_mode: wgpu::InputStepMode::Vertex, - attributes: &[wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float4, - offset: 0, - shader_location: 0, - }], + attributes: &vertex_attr_array![0 => Float4], }], sample_count: 1, sample_mask: !0, diff --git a/examples/msaa-line/main.rs b/examples/msaa-line/main.rs index caaa70dc05..faccfb9790 100644 --- a/examples/msaa-line/main.rs +++ b/examples/msaa-line/main.rs @@ -12,6 +12,8 @@ mod framework; use zerocopy::{AsBytes, FromBytes}; +use wgpu::vertex_attr_array; + #[repr(C)] #[derive(Clone, Copy, AsBytes, FromBytes)] struct Vertex { @@ -71,18 +73,7 @@ impl Example { vertex_buffers: &[wgpu::VertexBufferDescriptor { stride: std::mem::size_of::() as wgpu::BufferAddress, step_mode: wgpu::InputStepMode::Vertex, - attributes: &[ - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float2, - offset: 0, - shader_location: 0, - }, - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Float4, - offset: 2 * 4, - shader_location: 1, - }, - ], + attributes: &vertex_attr_array![0 => Float2, 1 => Float4], }], sample_count, sample_mask: !0, diff --git a/examples/shadow/main.rs b/examples/shadow/main.rs index 1bda583d64..4978365b95 100644 --- a/examples/shadow/main.rs +++ b/examples/shadow/main.rs @@ -5,6 +5,8 @@ mod framework; use zerocopy::{AsBytes, FromBytes}; +use wgpu::vertex_attr_array; + #[repr(C)] #[derive(Clone, Copy, AsBytes, FromBytes)] @@ -394,18 +396,7 @@ impl framework::Example for Example { let vb_desc = wgpu::VertexBufferDescriptor { stride: vertex_size as wgpu::BufferAddress, step_mode: wgpu::InputStepMode::Vertex, - attributes: &[ - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Char4, - offset: 0, - shader_location: 0, - }, - wgpu::VertexAttributeDescriptor { - format: wgpu::VertexFormat::Char4, - offset: 4 * 1, - shader_location: 1, - }, - ], + attributes: &vertex_attr_array![0 => Char4, 1 => Char4], }; let shadow_pass = { diff --git a/src/lib.rs b/src/lib.rs index 7e07e55bc0..6852e0094d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,9 @@ mod future; use future::GpuFutureCompletion; pub use future::GpuFuture; +#[macro_use] +mod macros; + use arrayvec::ArrayVec; use smallvec::SmallVec; diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000000..6a930ed52b --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,77 @@ +//! Convenience macros + +/// Macro to produce an array of [`VertexAttributeDescriptor`] +/// +/// Output has type: `[VertexAttributeDescriptor; _]`. Usage is as follows: +/// ``` +/// # use wgpu::vertex_attr_array; +/// let attrs = vertex_attr_array![0 => Float2, 1 => Float, 2 => Ushort4]; +/// ``` +/// This example specifies a list of three [`VertexAttributeDescriptor`], +/// each with the given `shader_location` and `format`. +/// Offsets are calculated automatically. +#[macro_export] +macro_rules! vertex_attr_array { + ($($loc:expr => $fmt:ident),*) => { + vertex_attr_array!([] ; 0; $($loc => $fmt ,)*) + }; + ([$($t:expr,)*] ; $off:expr ;) => { [$($t,)*] }; + ([$($t:expr,)*] ; $off:expr ; $loc:expr => $item:ident, $($ll:expr => $ii:ident ,)*) => { + vertex_attr_array!( + [$($t,)* + $crate::VertexAttributeDescriptor { + format: $crate::VertexFormat :: $item, + offset: $off, + shader_location: $loc, + },]; + $off + $crate::vertex_format_size!($item); + $($ll => $ii ,)* + ) + }; +} + +// For internal usage +#[macro_export] +macro_rules! vertex_format_size { + (Uchar2) => { 2 }; + (Uchar4) => { 4 }; + (Char2) => { 2 }; + (Char4) => { 4 }; + (Uchar2Norm) => { 2 }; + (Uchar4Norm) => { 4 }; + (Char2Norm) => { 2 }; + (Char4Norm) => { 4 }; + (Ushort2) => { 4 }; + (Ushort4) => { 8 }; + (Short2) => { 4 }; + (Short4) => { 8 }; + (Ushort2Norm) => { 4 }; + (Ushort4Norm) => { 8 }; + (Short2Norm) => { 4 }; + (Short4Norm) => { 8 }; + (Half2) => { 4 }; + (Half4) => { 8 }; + (Float) => { 4 }; + (Float2) => { 8 }; + (Float3) => { 12 }; + (Float4) => { 16 }; + (Uint) => { 4 }; + (Uint2) => { 8 }; + (Uint3) => { 12 }; + (Uint4) => { 16 }; + (Int) => { 4 }; + (Int2) => { 8 }; + (Int3) => { 12 }; + (Int4) => { 16 }; +} + +#[test] +fn test_vertex_attr_array() { + let attrs = vertex_attr_array![0 => Float2, 3 => Ushort4]; + // VertexAttributeDescriptor does not support PartialEq, so we cannot test directly + assert_eq!(attrs.len(), 2); + assert_eq!(attrs[0].offset, 0); + assert_eq!(attrs[0].shader_location, 0); + assert_eq!(attrs[1].offset, std::mem::size_of::<(f32, f32)>() as u64); + assert_eq!(attrs[1].shader_location, 3); +}