Skip to content

Commit

Permalink
Added buffer usage field to buffers (#7423)
Browse files Browse the repository at this point in the history
# Objective

Buffers in bevy do not allow for setting buffer usage flags which can be useful for setting COPY_SRC, MAP_READ, MAP_WRITE, which allows for buffers to be copied from gpu to cpu for inspection.

## Solution

Add buffer_usage field to buffers and a set_usage function to set them
  • Loading branch information
SpeedRoll committed Feb 6, 2023
1 parent 357a160 commit 952735f
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 26 deletions.
51 changes: 38 additions & 13 deletions crates/bevy_render/src/render_resource/storage_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ pub struct StorageBuffer<T: ShaderType> {
buffer: Option<Buffer>,
capacity: usize,
label: Option<String>,
label_changed: bool,
changed: bool,
buffer_usage: BufferUsages,
}

impl<T: ShaderType> From<T> for StorageBuffer<T> {
Expand All @@ -44,7 +45,8 @@ impl<T: ShaderType> From<T> for StorageBuffer<T> {
buffer: None,
capacity: 0,
label: None,
label_changed: false,
changed: false,
buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
}
}
}
Expand All @@ -57,7 +59,8 @@ impl<T: ShaderType + Default> Default for StorageBuffer<T> {
buffer: None,
capacity: 0,
label: None,
label_changed: false,
changed: false,
buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
}
}
}
Expand Down Expand Up @@ -91,7 +94,7 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
let label = label.map(str::to_string);

if label != self.label {
self.label_changed = true;
self.changed = true;
}

self.label = label;
Expand All @@ -101,6 +104,16 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
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).
///
Expand All @@ -111,14 +124,14 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {

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());
}
Expand Down Expand Up @@ -152,7 +165,8 @@ pub struct DynamicStorageBuffer<T: ShaderType> {
buffer: Option<Buffer>,
capacity: usize,
label: Option<String>,
label_changed: bool,
changed: bool,
buffer_usage: BufferUsages,
}

impl<T: ShaderType> Default for DynamicStorageBuffer<T> {
Expand All @@ -163,7 +177,8 @@ impl<T: ShaderType> Default for DynamicStorageBuffer<T> {
buffer: None,
capacity: 0,
label: None,
label_changed: false,
changed: false,
buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
}
}
}
Expand Down Expand Up @@ -204,7 +219,7 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
let label = label.map(str::to_string);

if label != self.label {
self.label_changed = true;
self.changed = true;
}

self.label = label;
Expand All @@ -214,18 +229,28 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
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());
}
Expand Down
51 changes: 38 additions & 13 deletions crates/bevy_render/src/render_resource/uniform_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ pub struct UniformBuffer<T: ShaderType> {
scratch: UniformBufferWrapper<Vec<u8>>,
buffer: Option<Buffer>,
label: Option<String>,
label_changed: bool,
changed: bool,
buffer_usage: BufferUsages,
}

impl<T: ShaderType> From<T> for UniformBuffer<T> {
Expand All @@ -42,7 +43,8 @@ impl<T: ShaderType> From<T> for UniformBuffer<T> {
scratch: UniformBufferWrapper::new(Vec::new()),
buffer: None,
label: None,
label_changed: false,
changed: false,
buffer_usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
}
}
}
Expand All @@ -54,7 +56,8 @@ impl<T: ShaderType + Default> Default for UniformBuffer<T> {
scratch: UniformBufferWrapper::new(Vec::new()),
buffer: None,
label: None,
label_changed: false,
changed: false,
buffer_usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
}
}
}
Expand Down Expand Up @@ -89,7 +92,7 @@ impl<T: ShaderType + WriteInto> UniformBuffer<T> {
let label = label.map(str::to_string);

if label != self.label {
self.label_changed = true;
self.changed = true;
}

self.label = label;
Expand All @@ -99,6 +102,16 @@ impl<T: ShaderType + WriteInto> UniformBuffer<T> {
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.
///
Expand All @@ -107,13 +120,13 @@ impl<T: ShaderType + WriteInto> UniformBuffer<T> {
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());
}
Expand Down Expand Up @@ -145,7 +158,8 @@ pub struct DynamicUniformBuffer<T: ShaderType> {
buffer: Option<Buffer>,
capacity: usize,
label: Option<String>,
label_changed: bool,
changed: bool,
buffer_usage: BufferUsages,
}

impl<T: ShaderType> Default for DynamicUniformBuffer<T> {
Expand All @@ -156,7 +170,8 @@ impl<T: ShaderType> Default for DynamicUniformBuffer<T> {
buffer: None,
capacity: 0,
label: None,
label_changed: false,
changed: false,
buffer_usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
}
}
}
Expand Down Expand Up @@ -198,7 +213,7 @@ impl<T: ShaderType + WriteInto> DynamicUniformBuffer<T> {
let label = label.map(str::to_string);

if label != self.label {
self.label_changed = true;
self.changed = true;
}

self.label = label;
Expand All @@ -208,6 +223,16 @@ impl<T: ShaderType + WriteInto> DynamicUniformBuffer<T> {
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).
///
Expand All @@ -217,14 +242,14 @@ impl<T: ShaderType + WriteInto> DynamicUniformBuffer<T> {
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());
}
Expand Down

0 comments on commit 952735f

Please sign in to comment.