teoxoy / encase

Provides a mechanism to lay out data into GPU buffers according to WGSL's memory layout rules
https://crates.io/crates/encase
MIT No Attribution
155 stars 27 forks source link

Vector of Structs support #79

Closed davids91 closed 3 months ago

davids91 commented 3 months ago

I used to think it doe, because it worked really great. I have some rendering logic, based on bevy, and upon increasing support for bevy 0.14.0 suddenly the program crashes frequently ; And I encounter this error :

Caused by:
    In Device::create_compute_pipeline
    Error matching shader requirements against the pipeline
    Shader global ResourceBinding { group: 1, binding: 0 } is not available in the pipeline layout
    Buffer structure size 48, added to one element of an unbound array, if it's the last field, ended up greater than the given `min_binding_size`

With the following struct:

#[cfg_attr(feature = "bevy_wgpu", derive(ShaderType))]
#[derive(Default, Clone, Copy, Debug, PartialEq)]
pub struct Albedo {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32,
}

#[derive(Clone, ShaderType)]
pub(crate) struct Voxelement {
    pub(crate) albedo: Albedo,
    pub(crate) content: u32
}

#[derive(Resource, Clone, AsBindGroup, TypePath, ExtractResource)]
#[type_path = "shocovox::gpu::ShocoVoxRenderData"]
pub struct ShocoVoxRenderData {

   ...

    #[storage(3, visibility(compute))]
    pub(crate) voxels: Vec<Voxelement>,
}

In shader:

struct Voxelement {
    albedo : vec4f,
    content: u32,
}

...

@group(1) @binding(3)
var<storage, read_write> voxels: array<Voxelement>;

I am not sure anymore, because if I add a _padding variable to Voxelement as: _padding: Vec3,, evaluations pass, but the program crashes...

are vectors of structs supported, or should I try to manually arrange its structure, with e.g. #[repr(C)]?

Thank you for the help in advance!

teoxoy commented 3 months ago

This should work but I doubt the issue is with the Voxelement. Your voxels are in @group(1) @binding(3) but the error is about ResourceBinding { group: 1, binding: 0 }.

davids91 commented 3 months ago

Sorry, wrong struct..... I have this for OctreeMetaData:

#[repr(C)]
#[derive(Clone, ShaderType)]
pub struct OctreeMetaData {
    pub ambient_light_color: V3cf32,
    pub(crate) voxel_brick_dim: u32,
    pub ambient_light_position: V3cf32,
    pub(crate) octree_size: u32,
}

And :

struct OctreeMetaData {
    octree_size: u32,
    voxel_brick_dim: u32,
    ambient_light_color: vec4f,
    ambient_light_position: vec3f,
}

group(1) @binding(0)
var<uniform> octreeMetaData: OctreeMetaData;

Is it because the different ordering in the shader struct ordering?

teoxoy commented 3 months ago

Yes, the order and types must match across the rust and WGSL structs.