docs/bevy/release-content/migration-guides/shader_buffer_changes.md 2.7 K · 71 lines · raw · history

1 ---
2 title: "`ShaderBuffer` stores typed data in an `AlignedVec` with an explicit buffer size"
3 pull_requests: [24938, 25426]
4 ---
5
6 `ShaderBuffer` CPU data is now stored in an `AlignedVec` whose alignment can be
7 configured at runtime. The allocation is guaranteed to be aligned to the element
8 type used to fill it, which allows typed reads and writes through
9 `bytemuck::cast_slice` / `cast_slice_mut` without extra copies or unaligned
10 access.
11
12 The GPU buffer size is now explicit and decoupled from the CPU data length:
13 `ShaderBufferData::Initialized` carries a `buffer_size` that can differ from the
14 length of `data`, so a larger GPU allocation can be kept while CPU data is
15 cleared or resized, avoiding reallocations.
16
17 When creating the GPU buffer, `buffer_size` always wins over the data length:
18 the data is truncated when it is longer than `buffer_size`, and the buffer is
19 zero-filled when it is shorter.
20
21 The public fields of `ShaderBuffer` have changed:
22
23 - `data: Option<Vec<u8>>` is now `data: ShaderBufferData`
24 (`Initialized { data, buffer_size }` or `Uninitialized(size)`).
25 - `buffer_description: wgpu::BufferDescriptor<'static>` has been replaced by the
26 `label: Cow<'static, str>` and `buffer_usage: BufferUsages` fields.
27
28 The following methods changed:
29
30 - `ShaderBuffer::new` now takes a `Vec<T>` of `bytemuck::NoUninit` elements
31 instead of a byte slice:
32
33 ```rust
34 // Bevy 0.19
35 let buffer = ShaderBuffer::new(&bytes, RenderAssetUsages::default());
36
37 // Bevy 0.20
38 let buffer = ShaderBuffer::new(bytes, RenderAssetUsages::default());
39 ```
40
41 - `ShaderBuffer::set_data` which uses `encase::ShaderType`, has been removed. Build the buffer with `new` or fill
42 an existing one with `extend` / `extend_from_slice` instead:
43
44 ```rust
45 // Bevy 0.19
46 let mut buffer = ShaderBuffer::default();
47 buffer.set_data(my_struct);
48
49 // Bevy 0.20
50 let mut buffer = ShaderBuffer::default();
51 buffer.extend([my_struct]);
52 ```
53
54 - `From<T>` which uses `encase::ShaderType`, is replaced by `From<Vec<T>>` which reuses the memory:
55
56 ```rust
57 // Bevy 0.19
58 let buffer = ShaderBuffer::from(my_struct);
59
60 // Bevy 0.20
61 let buffer = ShaderBuffer::from(vec![my_struct]);
62 ```
63
64 - `ShaderBuffer::with_size` now takes a `u64` instead of a `usize`.
65 - `ShaderBuffer::resize_in_place` has been removed. Use `ShaderBuffer::resize_buffer`
66 to resize the GPU buffer without touching the CPU data, or `resize` for both.
67 - `ShaderBuffer::cast_slice` / `cast_slice_mut` provide typed access to the data
68 (new in 0.20). In 0.19 the data was only reachable as raw bytes through the
69 `data` field; casting that `Vec<u8>` was not guaranteed to be aligned.
70 - `ShaderBuffer::buffer_size()` returns the GPU buffer size; use
71 `buffer_size() == 0` to check for a zero-sized buffer.