Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to construct unsized types for shader #1329

Closed
KarelPeeters opened this issue Mar 6, 2020 · 5 comments · Fixed by #2132
Closed

How to construct unsized types for shader #1329

KarelPeeters opened this issue Mar 6, 2020 · 5 comments · Fixed by #2132

Comments

@KarelPeeters
Copy link

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, rust-lang/rust#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?

@KarelPeeters
Copy link
Author

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?

@KarelPeeters KarelPeeters changed the title How to construct unsized types to shader How to construct unsized types for shader Mar 6, 2020
@Eliah-Lakhin
Copy link
Contributor

@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().

@KarelPeeters
Copy link
Author

@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!

@Rua
Copy link
Contributor

Rua commented Dec 28, 2022

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],
}

@KarelPeeters
Copy link
Author

That's not always general enough, in my case the length was not known at compile time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants