vulkano
vulkano copied to clipboard
How to construct unsized types for shader
This isn't really an issue per se, more of a question. I couldn't find anything about this in the documentation, but I might be missing something.
I'm trying to pass some data to a compute shader with an input like this:
struct Sphere {
vec2 pos;
float r;
};
layout(set = 0, binding = 1) readonly buffer Objects {
Sphere spheres[];
};
The vulkano_shaders::shader!
macro generates Rust equivalents to theses structs, they look like this:
#[repr(C)]
#[allow(non_snake_case)]
pub struct Sphere {
pub pos: [f32; 2usize],
pub r: f32,
pub _dummy0: [u8; 4u32 as usize],
}
#[repr(C)]
#[allow(non_snake_case)]
pub struct Objects {
pub spheres: [Sphere],
}
How do I construct an Objects
instance in Rust? My understanding is that you can't really create unsized structs, https://github.com/rust-lang/rust/issues/18598 isn't stable yet.
In this case I can create a Vec<Sphere>
and put that in a buffer using CpuAccessibleBuffer::from_iter
, but that's brittle if anything about Objects
ever changes. Is there another more typesafe way to do this?
Another related question:
Is there an easy way to create instances of structs like Sphere
without having to specify the dummy fields all the time? Or should I just write my own Sphere
struct and then write some convertor functions?
@flaghacker
Is there an easy way to create instances of structs like Sphere without having to specify the dummy fields all the time?
You can define impl Default
for each type you are actively using in your code that will fill all the fields with defaults including dummies, then instantiate them through Sphere::default()
.
@Eliah-Lakhin I could do that but then I might forget to initialize any fields I might add in the future, but it looks like that's indeed the best solution for now. Thanks!
I'm thinking that for cases like this, the generated struct should have a const usize
parameter specifying the size of the array. So it should be this:
#[repr(C)]
#[allow(non_snake_case)]
pub struct Objects<const NSPHERES: usize> {
pub spheres: [Sphere; NSPHERES],
}
That's not always general enough, in my case the length was not known at compile time.