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