diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index 666b86667b908..19bdb00909ad5 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -33,7 +33,8 @@ pub struct StorageBuffer { buffer: Option, capacity: usize, label: Option, - label_changed: bool, + changed: bool, + buffer_usage: BufferUsages, } impl From for StorageBuffer { @@ -44,7 +45,8 @@ impl From for StorageBuffer { buffer: None, capacity: 0, label: None, - label_changed: false, + changed: false, + buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE, } } } @@ -57,7 +59,8 @@ impl Default for StorageBuffer { buffer: None, capacity: 0, label: None, - label_changed: false, + changed: false, + buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE, } } } @@ -91,7 +94,7 @@ impl StorageBuffer { let label = label.map(str::to_string); if label != self.label { - self.label_changed = true; + self.changed = true; } self.label = label; @@ -101,6 +104,16 @@ impl StorageBuffer { self.label.as_deref() } + /// Add more [`BufferUsages`] to the buffer. + /// + /// This method only allows addition of flags to the default usage flags. + /// + /// The default values for buffer usage are `BufferUsages::COPY_DST` and `BufferUsages::STORAGE`. + pub fn add_usages(&mut self, usage: BufferUsages) { + self.buffer_usage |= usage; + self.changed = true; + } + /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice) /// and the provided [`RenderQueue`](crate::renderer::RenderQueue). /// @@ -111,14 +124,14 @@ impl StorageBuffer { let size = self.scratch.as_ref().len(); - if self.capacity < size || self.label_changed { + if self.capacity < size || self.changed { self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor { label: self.label.as_deref(), - usage: BufferUsages::COPY_DST | BufferUsages::STORAGE, + usage: self.buffer_usage, contents: self.scratch.as_ref(), })); self.capacity = size; - self.label_changed = false; + self.changed = false; } else if let Some(buffer) = &self.buffer { queue.write_buffer(buffer, 0, self.scratch.as_ref()); } @@ -152,7 +165,8 @@ pub struct DynamicStorageBuffer { buffer: Option, capacity: usize, label: Option, - label_changed: bool, + changed: bool, + buffer_usage: BufferUsages, } impl Default for DynamicStorageBuffer { @@ -163,7 +177,8 @@ impl Default for DynamicStorageBuffer { buffer: None, capacity: 0, label: None, - label_changed: false, + changed: false, + buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE, } } } @@ -204,7 +219,7 @@ impl DynamicStorageBuffer { let label = label.map(str::to_string); if label != self.label { - self.label_changed = true; + self.changed = true; } self.label = label; @@ -214,18 +229,28 @@ impl DynamicStorageBuffer { self.label.as_deref() } + /// Add more [`BufferUsages`] to the buffer. + /// + /// This method only allows addition of flags to the default usage flags. + /// + /// The default values for buffer usage are `BufferUsages::COPY_DST` and `BufferUsages::STORAGE`. + pub fn add_usages(&mut self, usage: BufferUsages) { + self.buffer_usage |= usage; + self.changed = true; + } + #[inline] pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { let size = self.scratch.as_ref().len(); - if self.capacity < size || self.label_changed { + if self.capacity < size || self.changed { self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor { label: self.label.as_deref(), - usage: BufferUsages::COPY_DST | BufferUsages::STORAGE, + usage: self.buffer_usage, contents: self.scratch.as_ref(), })); self.capacity = size; - self.label_changed = false; + self.changed = false; } else if let Some(buffer) = &self.buffer { queue.write_buffer(buffer, 0, self.scratch.as_ref()); } diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index aa66ee08da278..e59b21ec555e2 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -32,7 +32,8 @@ pub struct UniformBuffer { scratch: UniformBufferWrapper>, buffer: Option, label: Option, - label_changed: bool, + changed: bool, + buffer_usage: BufferUsages, } impl From for UniformBuffer { @@ -42,7 +43,8 @@ impl From for UniformBuffer { scratch: UniformBufferWrapper::new(Vec::new()), buffer: None, label: None, - label_changed: false, + changed: false, + buffer_usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM, } } } @@ -54,7 +56,8 @@ impl Default for UniformBuffer { scratch: UniformBufferWrapper::new(Vec::new()), buffer: None, label: None, - label_changed: false, + changed: false, + buffer_usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM, } } } @@ -89,7 +92,7 @@ impl UniformBuffer { let label = label.map(str::to_string); if label != self.label { - self.label_changed = true; + self.changed = true; } self.label = label; @@ -99,6 +102,16 @@ impl UniformBuffer { self.label.as_deref() } + /// Add more [`BufferUsages`] to the buffer. + /// + /// This method only allows addition of flags to the default usage flags. + /// + /// The default values for buffer usage are `BufferUsages::COPY_DST` and `BufferUsages::UNIFORM`. + pub fn add_usages(&mut self, usage: BufferUsages) { + self.buffer_usage |= usage; + self.changed = true; + } + /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice) /// and the provided [`RenderQueue`](crate::renderer::RenderQueue), if a GPU-side backing buffer already exists. /// @@ -107,13 +120,13 @@ impl UniformBuffer { pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { self.scratch.write(&self.value).unwrap(); - if self.label_changed || self.buffer.is_none() { + if self.changed || self.buffer.is_none() { self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor { label: self.label.as_deref(), - usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM, + usage: self.buffer_usage, contents: self.scratch.as_ref(), })); - self.label_changed = false; + self.changed = false; } else if let Some(buffer) = &self.buffer { queue.write_buffer(buffer, 0, self.scratch.as_ref()); } @@ -145,7 +158,8 @@ pub struct DynamicUniformBuffer { buffer: Option, capacity: usize, label: Option, - label_changed: bool, + changed: bool, + buffer_usage: BufferUsages, } impl Default for DynamicUniformBuffer { @@ -156,7 +170,8 @@ impl Default for DynamicUniformBuffer { buffer: None, capacity: 0, label: None, - label_changed: false, + changed: false, + buffer_usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM, } } } @@ -198,7 +213,7 @@ impl DynamicUniformBuffer { let label = label.map(str::to_string); if label != self.label { - self.label_changed = true; + self.changed = true; } self.label = label; @@ -208,6 +223,16 @@ impl DynamicUniformBuffer { self.label.as_deref() } + /// Add more [`BufferUsages`] to the buffer. + /// + /// This method only allows addition of flags to the default usage flags. + /// + /// The default values for buffer usage are `BufferUsages::COPY_DST` and `BufferUsages::UNIFORM`. + pub fn add_usages(&mut self, usage: BufferUsages) { + self.buffer_usage |= usage; + self.changed = true; + } + /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice) /// and the provided [`RenderQueue`](crate::renderer::RenderQueue). /// @@ -217,14 +242,14 @@ impl DynamicUniformBuffer { pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { let size = self.scratch.as_ref().len(); - if self.capacity < size || self.label_changed { + if self.capacity < size || self.changed { self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor { label: self.label.as_deref(), - usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM, + usage: self.buffer_usage, contents: self.scratch.as_ref(), })); self.capacity = size; - self.label_changed = false; + self.changed = false; } else if let Some(buffer) = &self.buffer { queue.write_buffer(buffer, 0, self.scratch.as_ref()); }