mirror of
https://github.com/bevyengine/bevy
synced 2024-11-28 23:50:20 +00:00
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.
This commit is contained in:
parent
d0f755dbfd
commit
a8ee620b96
1 changed files with 18 additions and 10 deletions
|
@ -6,7 +6,7 @@ use encase::{
|
|||
internal::WriteInto, DynamicStorageBuffer as DynamicStorageBufferWrapper, ShaderType,
|
||||
StorageBuffer as StorageBufferWrapper,
|
||||
};
|
||||
use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsages};
|
||||
use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferSize, BufferUsages};
|
||||
|
||||
use super::IntoBinding;
|
||||
|
||||
|
@ -39,6 +39,7 @@ pub struct StorageBuffer<T: ShaderType> {
|
|||
label: Option<String>,
|
||||
changed: bool,
|
||||
buffer_usage: BufferUsages,
|
||||
last_written_size: Option<BufferSize>,
|
||||
}
|
||||
|
||||
impl<T: ShaderType> From<T> for StorageBuffer<T> {
|
||||
|
@ -50,6 +51,7 @@ impl<T: ShaderType> From<T> for StorageBuffer<T> {
|
|||
label: None,
|
||||
changed: false,
|
||||
buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
|
||||
last_written_size: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +65,7 @@ impl<T: ShaderType + Default> Default for StorageBuffer<T> {
|
|||
label: None,
|
||||
changed: false,
|
||||
buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
|
||||
last_written_size: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,9 +78,11 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
|
|||
|
||||
#[inline]
|
||||
pub fn binding(&self) -> Option<BindingResource> {
|
||||
Some(BindingResource::Buffer(
|
||||
self.buffer()?.as_entire_buffer_binding(),
|
||||
))
|
||||
Some(BindingResource::Buffer(BufferBinding {
|
||||
buffer: self.buffer()?,
|
||||
offset: 0,
|
||||
size: self.last_written_size,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn set(&mut self, value: T) {
|
||||
|
@ -137,16 +142,15 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
|
|||
} else if let Some(buffer) = &self.buffer {
|
||||
queue.write_buffer(buffer, 0, self.scratch.as_ref());
|
||||
}
|
||||
|
||||
self.last_written_size = BufferSize::new(size);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ShaderType + WriteInto> IntoBinding<'a> for &'a StorageBuffer<T> {
|
||||
#[inline]
|
||||
fn into_binding(self) -> BindingResource<'a> {
|
||||
self.buffer()
|
||||
.expect("Failed to get buffer")
|
||||
.as_entire_buffer_binding()
|
||||
.into_binding()
|
||||
self.binding().expect("Failed to get buffer")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +184,7 @@ pub struct DynamicStorageBuffer<T: ShaderType> {
|
|||
label: Option<String>,
|
||||
changed: bool,
|
||||
buffer_usage: BufferUsages,
|
||||
last_written_size: Option<BufferSize>,
|
||||
_marker: PhantomData<fn() -> T>,
|
||||
}
|
||||
|
||||
|
@ -191,6 +196,7 @@ impl<T: ShaderType> Default for DynamicStorageBuffer<T> {
|
|||
label: None,
|
||||
changed: false,
|
||||
buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
|
||||
last_written_size: None,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -207,7 +213,7 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
|
|||
Some(BindingResource::Buffer(BufferBinding {
|
||||
buffer: self.buffer()?,
|
||||
offset: 0,
|
||||
size: Some(T::min_size()),
|
||||
size: self.last_written_size,
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -260,6 +266,8 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
|
|||
} else if let Some(buffer) = &self.buffer {
|
||||
queue.write_buffer(buffer, 0, self.scratch.as_ref());
|
||||
}
|
||||
|
||||
self.last_written_size = BufferSize::new(size);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -272,6 +280,6 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
|
|||
impl<'a, T: ShaderType + WriteInto> IntoBinding<'a> for &'a DynamicStorageBuffer<T> {
|
||||
#[inline]
|
||||
fn into_binding(self) -> BindingResource<'a> {
|
||||
self.binding().unwrap()
|
||||
self.binding().expect("Failed to get buffer")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue