Skip to main content

shader_struct

Macro shader_struct 

Source
macro_rules! shader_struct {
    { $struct:ident [
        $( $num:tt $field:ident => $ty:ident ),* $(,)?
    ] } => { ... };
}
Expand description

Define a shader struct (to use in a storage or uniform buffer).

Give each field a name and a standard shader type from shaderprimitive.

Uniform buffers are another can of worms, with their own weird alignment rules. The best way to deal with them is probably to make

Note that fields must be numbered correctly, starting from 0. This is because I don’t know how to teach macros how to count and still be able to index tuples.
Also, the fields are not rearranged to be optimized to their alignment rules, though they should be padded correctly for regular shader structs.

shader_struct! { ShaderStruct [
    0 int => I32,
    1 mat => Mat4x4f,
    2 float => F32,
] }

buffer! { ShaderBuffer <ShaderStruct> as STORAGE | COPY_DST }

// Big enough to store 10 ShaderStructs, including padding
let buffer: ShaderBuffer = context.new_buffer(10);

When you create a shader struct on the Rust side, its memory layout should match exactly as it is shader-side. You can write directly to each field (though everything’s in arrays) and then safely-ish transmute it to a byte slice to write to the buffer.

let single_struct: ShaderStruct = (
    [5_i32],
    [[0.0, 1.0, 2.0, 3.0]; 4],
    [4.0],
).into();
let mut lotsa_structs = [single_struct; 10];
*lotsa_structs[7].float = [5.0];

context.queue.write_buffer(
    &buffer,
    some_offset * size_of::<ShaderStruct>() as u64,
    lotsa_structs.as_byte_slice(),
);