Description
Is your feature request related to a problem? Please describe.
I think it is fairly common to have code like this:
#[repr(C)]
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
struct TessVertex {
position: [f32; 2],
normal: [f32; 2],
prim_id: u32,
}
impl TessVertex {
fn desc() -> wgpu::VertexBufferLayout<'static> {
wgpu::VertexBufferLayout {
array_stride: mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &[
wgpu::VertexAttribute {
offset: 0,
shader_location: 0,
format: wgpu::VertexFormat::Float32x2,
},
wgpu::VertexAttribute {
offset: 8,
shader_location: 1,
format: wgpu::VertexFormat::Float32x2,
},
wgpu::VertexAttribute {
offset: 16,
shader_location: 2,
format: wgpu::VertexFormat::Uint32,
},
],
}
}
}
This is a bit tedious to maintain but is fairly boilerplate, so a macro could help usability here.
Describe the solution you'd like
Probably extract the vertex format to a trait:
trait GpuFormat {
const VERTEX_FORMAT: VertexFormat;
}
// implement this for relevant primitives
impl GpuFormat for f32 { const VERTEX_FORMAT: VertexFormat = VertexFormat::Float32; }
impl GpuFormat for [f32; 2] { const VERTEX_FORMAT: VertexFormat = VertexFormat::Float32x2; }
// ...
And then add a derive macro that leveragesGpuFormat
and the recently-stabilized offset_of
:
// trait to be implemented
trait BufferLayout {
fn vertex_buffer_layout() -> VertexBufferLayout<'static>;
}
// usage
#[derive(BufferLayout)]
struct TessVertex {
#[wgpu(shader_location = 0)]
position: [f32; 2],
#[wgpu(shader_location = 10)]
normal: [f32; 2],
#[wgpu(shader_location = 4)]
prim_id: u32,
}
// code generated by the macro
impl BufferLayout for TessVertex {
fn vertex_buffer_layout() -> VertexBufferLayout<'static> {
VertexBufferLayout {
array_stride: mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &[
wgpu::VertexAttribute {
offset: std::mem::offset_of!(Self, position),
shader_location: 0,
format: [f32; 2]::VERTEX_FORMAT,
},
wgpu::VertexAttribute {
offset: std::mem::offset_of!(Self, normal),
shader_location: 10,
format: [f32; 2]::VERTEX_FORMAT,
},
wgpu::VertexAttribute {
offset: std::mem::offset_of!(Self, prim_id),
shader_location: 4,
format: u32::VERTEX_FORMAT,
},
],
}
}
}
Note that this exact code above currently hits rust-lang/rust#124478, but that should be fixed soon in rust-lang/rust#124484.
Describe alternatives you've considered
It would be nice if more information could be reflected from the shader, rather than needing to keep the shader and the Rust code in sync (pretty big source of my errors when just getting started). Maybe an alternative to include_wgsl!
could create a rust module with automatically created types for everything in WGSL shader?
I am sure this has been talked about somewhere :)