rustcompute-shaderbevy

trouble with using compute shaders for bevy 0.12


I am trying to just test out the compute shaders so I'm trying to add 2 arrays together but I get this error during run time:

    thread 'Compute Task Pool (6)' panicked at C:\Users\bramb\.cargo\registry\src\index.crates.io-6f17d22bba15001f\wgpu-0.17.2\src\backend\direct.rs:3056:5:
wgpu error: Validation Error

Caused by:
    In Queue::write_buffer
    Copy of 0..32 would end up overrunning the bounds of the Destination buffer of size 16

This is my code in bevy:

(calc_gpu_things is run every frame)

    fn calc_gpu_things(mut compute_worker: ResMut<AppComputeWorker<SimpleComputeWorker>>) {
    if !compute_worker.ready() {
        return;
    };

    compute_worker.write("firstArray", &[2.0, 3.0, 4.0, 5.0]);
    compute_worker.write("secondArray", &[2.0, 3.0, 4.0, 5.0]);
    let result: [f32; 4] = compute_worker.read("resultArray");

    println!("got {:?}", result);
}

    #[derive(TypeUuid)]
    #[uuid = "2545ae14-a9bc-4f03-9ea4-4eb43d1075a7"]
    struct SimpleShader;

impl ComputeShader for SimpleShader {
    fn shader() -> ShaderRef {
        "compute1.wgsl".into()
    }
}
    
    #[derive(Resource)]
    struct SimpleComputeWorker;
    
    impl ComputeWorker for SimpleComputeWorker {
        fn build(world: &mut World) -> AppComputeWorker<Self> {
            let worker = AppComputeWorkerBuilder::new(world)
                // Add a staging buffer, it will be available from
                // both CPU and GPU land.
                .add_staging("firstArray", &[2.0, 3.0, 4.0, 5.0])
                .add_staging("secondArray", &[2.0, 3.0, 4.0, 5.0])
                .add_staging("resultArray", &[0.0, 0.0, 0.0, 0.0])
                // Create a compute pass from your compute shader
                // and define used variables
                .add_pass::<SimpleShader>([1, 1, 1], &["firstArray", "secondArray", "resultArray"])
                .build();
    
            worker
        }
    }

and this is my shader code I wrote in babylonjs with WEBGPU:

    @group(0) @binding(0) var<storage,read> firstArray: array<f32>;
@group(0) @binding(1) var<storage,read> secondArray: array<f32>;
@group(0) @binding(2) var<storage,read_write> resultArray: array<f32>;

@compute @workgroup_size(1, 1, 1)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
    let index: u32 = global_id.x;

    resultArray[index] = firstArray[index] + secondArray[index];
}

I'm using bevy_app_compute for the connection between the cpu and gpu.


Solution

  • The error message gives you a hint. You write 32 bytes into a buffer of size 16 bytes:

    compute_worker.write("firstArray", &[2.0, 3.0, 4.0, 5.0]);
    

    RFC 212:

    Integer literals whose type is unconstrained will default to i32 [...] Floating point literals will default to f64.

    So that's 4 f64s, aka 32 bytes. Your buffer expects f32's though:

    @group(0) @binding(0) var<storage,read> firstArray: array<f32>;
    

    4 f32s would be 16 bytes.


    You can fix this by specifying the float type you're writing:

    compute_worker.write("firstArray", &[2.0f32, 3.0, 4.0, 5.0]);