mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 20:23:28 +00:00
Only create changed buffer if it already exists (#13242)
# Objective - `DynamicUniformBuffer` tries to create a buffer as soon as the changed flag is set to true. This doesn't work correctly when the buffer wasn't already created. This currently creates a crash because it's trying to create a buffer of size 0 if the flag is set but there's no buffer yet. ## Solution - Don't create a changed buffer until there's data that needs to be written to a buffer. ## Testing - run `cargo run --example scene_viewer` and see that it doesn't crash anymore Fixes #13235
This commit is contained in:
parent
088960f597
commit
a22ecede49
4 changed files with 10 additions and 9 deletions
|
@ -43,7 +43,7 @@ pub struct RawBufferVec<T: NoUninit> {
|
|||
item_size: usize,
|
||||
buffer_usage: BufferUsages,
|
||||
label: Option<String>,
|
||||
label_changed: bool,
|
||||
changed: bool,
|
||||
}
|
||||
|
||||
impl<T: NoUninit> RawBufferVec<T> {
|
||||
|
@ -55,7 +55,7 @@ impl<T: NoUninit> RawBufferVec<T> {
|
|||
item_size: std::mem::size_of::<T>(),
|
||||
buffer_usage,
|
||||
label: None,
|
||||
label_changed: false,
|
||||
changed: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ impl<T: NoUninit> RawBufferVec<T> {
|
|||
let label = label.map(str::to_string);
|
||||
|
||||
if label != self.label {
|
||||
self.label_changed = true;
|
||||
self.changed = true;
|
||||
}
|
||||
|
||||
self.label = label;
|
||||
|
@ -115,16 +115,16 @@ impl<T: NoUninit> RawBufferVec<T> {
|
|||
/// the `RawBufferVec` was created, the buffer on the [`RenderDevice`]
|
||||
/// is marked as [`BufferUsages::COPY_DST`](BufferUsages).
|
||||
pub fn reserve(&mut self, capacity: usize, device: &RenderDevice) {
|
||||
if capacity > self.capacity || self.label_changed {
|
||||
let size = self.item_size * capacity;
|
||||
if capacity > self.capacity || (self.changed && size > 0) {
|
||||
self.capacity = capacity;
|
||||
let size = self.item_size * capacity;
|
||||
self.buffer = Some(device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: self.label.as_deref(),
|
||||
size: size as BufferAddress,
|
||||
usage: BufferUsages::COPY_DST | self.buffer_usage,
|
||||
mapped_at_creation: false,
|
||||
}));
|
||||
self.label_changed = false;
|
||||
self.changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
|
|||
let capacity = self.buffer.as_deref().map(wgpu::Buffer::size).unwrap_or(0);
|
||||
let size = self.scratch.as_ref().len() as u64;
|
||||
|
||||
if capacity < size || self.changed {
|
||||
if capacity < size || (self.changed && size > 0) {
|
||||
self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
label: self.label.as_deref(),
|
||||
usage: self.buffer_usage,
|
||||
|
|
|
@ -295,7 +295,7 @@ impl<T: ShaderType + WriteInto> DynamicUniformBuffer<T> {
|
|||
.checked_mul(max_count as u64)
|
||||
.unwrap();
|
||||
|
||||
if capacity < size || self.changed {
|
||||
if capacity < size || (self.changed && size > 0) {
|
||||
let buffer = device.create_buffer(&BufferDescriptor {
|
||||
label: self.label.as_deref(),
|
||||
usage: self.buffer_usage,
|
||||
|
@ -336,7 +336,7 @@ impl<T: ShaderType + WriteInto> DynamicUniformBuffer<T> {
|
|||
let capacity = self.buffer.as_deref().map(wgpu::Buffer::size).unwrap_or(0);
|
||||
let size = self.scratch.as_ref().len() as u64;
|
||||
|
||||
if capacity < size || self.changed {
|
||||
if capacity < size || (self.changed && size > 0) {
|
||||
self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
label: self.label.as_deref(),
|
||||
usage: self.buffer_usage,
|
||||
|
|
|
@ -429,6 +429,7 @@ pub struct ViewUniforms {
|
|||
impl FromWorld for ViewUniforms {
|
||||
fn from_world(world: &mut World) -> Self {
|
||||
let mut uniforms = DynamicUniformBuffer::default();
|
||||
uniforms.set_label(Some("view_uniforms_buffer"));
|
||||
|
||||
let render_device = world.resource::<RenderDevice>();
|
||||
if render_device.limits().max_storage_buffers_per_shader_stage > 0 {
|
||||
|
|
Loading…
Reference in a new issue