Skip to content

Commit a8ee620

Browse files
JMS55mockersf
authored andcommitted
Bind only the written parts of storage buffers. (#16405)
# Objective - Fix part of #15920 ## Solution - Keep track of the last written amount of bytes, and bind only that much of the buffer. ## Testing - Did you test these changes? If so, how? No - Are there any parts that need more testing? - How can other people (reviewers) test your changes? Is there anything specific they need to know? - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? --- ## Migration Guide - Fixed a bug with StorageBuffer and DynamicStorageBuffer binding data from the previous frame(s) due to caching GPU buffers between frames.
1 parent d0f755d commit a8ee620

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

crates/bevy_render/src/render_resource/storage_buffer.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use encase::{
66
internal::WriteInto, DynamicStorageBuffer as DynamicStorageBufferWrapper, ShaderType,
77
StorageBuffer as StorageBufferWrapper,
88
};
9-
use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsages};
9+
use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferSize, BufferUsages};
1010

1111
use super::IntoBinding;
1212

@@ -39,6 +39,7 @@ pub struct StorageBuffer<T: ShaderType> {
3939
label: Option<String>,
4040
changed: bool,
4141
buffer_usage: BufferUsages,
42+
last_written_size: Option<BufferSize>,
4243
}
4344

4445
impl<T: ShaderType> From<T> for StorageBuffer<T> {
@@ -50,6 +51,7 @@ impl<T: ShaderType> From<T> for StorageBuffer<T> {
5051
label: None,
5152
changed: false,
5253
buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
54+
last_written_size: None,
5355
}
5456
}
5557
}
@@ -63,6 +65,7 @@ impl<T: ShaderType + Default> Default for StorageBuffer<T> {
6365
label: None,
6466
changed: false,
6567
buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
68+
last_written_size: None,
6669
}
6770
}
6871
}
@@ -75,9 +78,11 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
7578

7679
#[inline]
7780
pub fn binding(&self) -> Option<BindingResource> {
78-
Some(BindingResource::Buffer(
79-
self.buffer()?.as_entire_buffer_binding(),
80-
))
81+
Some(BindingResource::Buffer(BufferBinding {
82+
buffer: self.buffer()?,
83+
offset: 0,
84+
size: self.last_written_size,
85+
}))
8186
}
8287

8388
pub fn set(&mut self, value: T) {
@@ -137,16 +142,15 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
137142
} else if let Some(buffer) = &self.buffer {
138143
queue.write_buffer(buffer, 0, self.scratch.as_ref());
139144
}
145+
146+
self.last_written_size = BufferSize::new(size);
140147
}
141148
}
142149

143150
impl<'a, T: ShaderType + WriteInto> IntoBinding<'a> for &'a StorageBuffer<T> {
144151
#[inline]
145152
fn into_binding(self) -> BindingResource<'a> {
146-
self.buffer()
147-
.expect("Failed to get buffer")
148-
.as_entire_buffer_binding()
149-
.into_binding()
153+
self.binding().expect("Failed to get buffer")
150154
}
151155
}
152156

@@ -180,6 +184,7 @@ pub struct DynamicStorageBuffer<T: ShaderType> {
180184
label: Option<String>,
181185
changed: bool,
182186
buffer_usage: BufferUsages,
187+
last_written_size: Option<BufferSize>,
183188
_marker: PhantomData<fn() -> T>,
184189
}
185190

@@ -191,6 +196,7 @@ impl<T: ShaderType> Default for DynamicStorageBuffer<T> {
191196
label: None,
192197
changed: false,
193198
buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
199+
last_written_size: None,
194200
_marker: PhantomData,
195201
}
196202
}
@@ -207,7 +213,7 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
207213
Some(BindingResource::Buffer(BufferBinding {
208214
buffer: self.buffer()?,
209215
offset: 0,
210-
size: Some(T::min_size()),
216+
size: self.last_written_size,
211217
}))
212218
}
213219

@@ -260,6 +266,8 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
260266
} else if let Some(buffer) = &self.buffer {
261267
queue.write_buffer(buffer, 0, self.scratch.as_ref());
262268
}
269+
270+
self.last_written_size = BufferSize::new(size);
263271
}
264272

265273
#[inline]
@@ -272,6 +280,6 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
272280
impl<'a, T: ShaderType + WriteInto> IntoBinding<'a> for &'a DynamicStorageBuffer<T> {
273281
#[inline]
274282
fn into_binding(self) -> BindingResource<'a> {
275-
self.binding().unwrap()
283+
self.binding().expect("Failed to get buffer")
276284
}
277285
}

0 commit comments

Comments
 (0)