Skip to content

Instantly share code, notes, and snippets.

@cart
Created October 31, 2023 21:41
Show Gist options
  • Save cart/3a9f190bd5e789a7d42317c28843ffca to your computer and use it in GitHub Desktop.
Save cart/3a9f190bd5e789a7d42317c28843ffca to your computer and use it in GitHub Desktop.
An example of using GpuArrayBuffer to support platforms without storage buffers (ex: WebGL2)
#[derive(Clone, ShaderType)]
struct MyType {
x: f32,
}
// Create a GPU array buffer
let mut buffer = GpuArrayBuffer::<MyType>::new(&render_device.limits());
// Push some items into it
for i in 0..N {
// indices is a GpuArrayBufferIndex<MyType> which contains a NonMaxU32
// index into the array and an Option<NonMaxU32> dynamic offset. If storage
// buffers are supported, it will be None, else Some with the dynamic
// offset that needs to be used when binding the bind group. indices should
// be stored somewhere for later lookup, often associated with an Entity.
let indices = buffer.push(MyType { x: i as f32 });
}
// Queue writing the buffer contents to VRAM
buffer.write_buffer(&render_device, &render_queue);
// The bind group layout entry to use when creating the pipeline
let binding = 0;
let visibility = ShaderStages::VERTEX;
let bind_group_layout_entry = buffer.binding_layout(
binding,
visibility,
&render_device,
);
// Get the binding resource to make a bind group entry to use when creating the
// bind group
let buffer_binding_resource = buffer.binding()?;
// Get the batch size. This will be None if storage buffers are supported, else
// it is the maximum number of elements that could fit in a batch
let buffer_batch_size = GpuArrayBuffer::<MyType>::batch_size(&render_device.limits());
// Set a shader def with the buffer batch size
if let Some(buffer_batch_size) = buffer_batch_size {
shader_defs.push(ShaderDefVal::UInt(
"BUFFER_BATCH_SIZE".into(),
buffer_batch_size,
));
}
#import bevy_render::instance_index get_instance_index
struct MyType {
x: f32,
}
// Declare the buffer binding
#ifdef BUFFER_BATCH_SIZE
@group(2) @binding(0) var<uniform> data: array<MyType, #{BUFFER_BATCH_SIZE}u>;
#else
@group(2) @binding(0) var<storage> data: array<MyType>;
#endif
// Access an instance
let my_type = data[get_instance_index(in.instance_index)];
@cart
Copy link
Author

cart commented Oct 31, 2023

Authored by @superdump

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment