add a debug label to storage buffers (#5341)
# Objective - Expose the wgpu debug label on storage buffer types. ## Solution 🐄 - Add an optional cow static string and pass that to the label field of create_buffer_with_data - This pattern is already used by Bevy for debug tags on bind group and layout descriptors. --- Example Usage: A buffer is given a label using the label function. Alternatively a buffer may be labeled when it is created if the default() convention is not used.  Here is the buffer appearing with the correct name in RenderDoc. Previously the buffer would have an anonymous name such as "Buffer223":  Co-authored-by: rebelroad-reinhart <reinhart@rebelroad.gg>
This commit is contained in:
parent
4e2600b788
commit
2d2ea337dd
@ -33,6 +33,8 @@ pub struct BufferVec<T: Pod> {
|
||||
capacity: usize,
|
||||
item_size: usize,
|
||||
buffer_usage: BufferUsages,
|
||||
label: Option<String>,
|
||||
label_changed: bool,
|
||||
}
|
||||
|
||||
impl<T: Pod> BufferVec<T> {
|
||||
@ -43,6 +45,8 @@ impl<T: Pod> BufferVec<T> {
|
||||
capacity: 0,
|
||||
item_size: std::mem::size_of::<T>(),
|
||||
buffer_usage,
|
||||
label: None,
|
||||
label_changed: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,6 +76,20 @@ impl<T: Pod> BufferVec<T> {
|
||||
index
|
||||
}
|
||||
|
||||
pub fn set_label(&mut self, label: Option<&str>) {
|
||||
let label = label.map(str::to_string);
|
||||
|
||||
if label != self.label {
|
||||
self.label_changed = true;
|
||||
}
|
||||
|
||||
self.label = label;
|
||||
}
|
||||
|
||||
pub fn get_label(&self) -> Option<&str> {
|
||||
self.label.as_deref()
|
||||
}
|
||||
|
||||
/// Creates a [`Buffer`](crate::render_resource::Buffer) on the [`RenderDevice`](crate::renderer::RenderDevice) with size
|
||||
/// at least `std::mem::size_of::<T>() * capacity`, unless a such a buffer already exists.
|
||||
///
|
||||
@ -84,15 +102,16 @@ impl<T: Pod> BufferVec<T> {
|
||||
/// the `BufferVec` was created, the buffer on the [`RenderDevice`](crate::renderer::RenderDevice)
|
||||
/// is marked as [`BufferUsages::COPY_DST`](crate::render_resource::BufferUsages).
|
||||
pub fn reserve(&mut self, capacity: usize, device: &RenderDevice) {
|
||||
if capacity > self.capacity {
|
||||
if capacity > self.capacity || self.label_changed {
|
||||
self.capacity = capacity;
|
||||
let size = self.item_size * capacity;
|
||||
self.buffer = Some(device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
label: self.label.as_deref(),
|
||||
size: size as wgpu::BufferAddress,
|
||||
usage: BufferUsages::COPY_DST | self.buffer_usage,
|
||||
mapped_at_creation: false,
|
||||
}));
|
||||
self.label_changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,8 @@ pub struct StorageBuffer<T: ShaderType> {
|
||||
scratch: StorageBufferWrapper<Vec<u8>>,
|
||||
buffer: Option<Buffer>,
|
||||
capacity: usize,
|
||||
label: Option<String>,
|
||||
label_changed: bool,
|
||||
}
|
||||
|
||||
impl<T: ShaderType> From<T> for StorageBuffer<T> {
|
||||
@ -41,6 +43,8 @@ impl<T: ShaderType> From<T> for StorageBuffer<T> {
|
||||
scratch: StorageBufferWrapper::new(Vec::new()),
|
||||
buffer: None,
|
||||
capacity: 0,
|
||||
label: None,
|
||||
label_changed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,6 +56,8 @@ impl<T: ShaderType + Default> Default for StorageBuffer<T> {
|
||||
scratch: StorageBufferWrapper::new(Vec::new()),
|
||||
buffer: None,
|
||||
capacity: 0,
|
||||
label: None,
|
||||
label_changed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,6 +87,20 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
|
||||
&mut self.value
|
||||
}
|
||||
|
||||
pub fn set_label(&mut self, label: Option<&str>) {
|
||||
let label = label.map(str::to_string);
|
||||
|
||||
if label != self.label {
|
||||
self.label_changed = true;
|
||||
}
|
||||
|
||||
self.label = label;
|
||||
}
|
||||
|
||||
pub fn get_label(&self) -> Option<&str> {
|
||||
self.label.as_deref()
|
||||
}
|
||||
|
||||
/// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice)
|
||||
/// and the provided [`RenderQueue`](crate::renderer::RenderQueue).
|
||||
///
|
||||
@ -91,13 +111,14 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
|
||||
|
||||
let size = self.scratch.as_ref().len();
|
||||
|
||||
if self.capacity < size {
|
||||
if self.capacity < size || self.label_changed {
|
||||
self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
label: None,
|
||||
label: self.label.as_deref(),
|
||||
usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
|
||||
contents: self.scratch.as_ref(),
|
||||
}));
|
||||
self.capacity = size;
|
||||
self.label_changed = false;
|
||||
} else if let Some(buffer) = &self.buffer {
|
||||
queue.write_buffer(buffer, 0, self.scratch.as_ref());
|
||||
}
|
||||
@ -130,6 +151,8 @@ pub struct DynamicStorageBuffer<T: ShaderType> {
|
||||
scratch: DynamicStorageBufferWrapper<Vec<u8>>,
|
||||
buffer: Option<Buffer>,
|
||||
capacity: usize,
|
||||
label: Option<String>,
|
||||
label_changed: bool,
|
||||
}
|
||||
|
||||
impl<T: ShaderType> Default for DynamicStorageBuffer<T> {
|
||||
@ -139,6 +162,8 @@ impl<T: ShaderType> Default for DynamicStorageBuffer<T> {
|
||||
scratch: DynamicStorageBufferWrapper::new(Vec::new()),
|
||||
buffer: None,
|
||||
capacity: 0,
|
||||
label: None,
|
||||
label_changed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,17 +200,32 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
|
||||
offset
|
||||
}
|
||||
|
||||
pub fn set_label(&mut self, label: Option<&str>) {
|
||||
let label = label.map(str::to_string);
|
||||
|
||||
if label != self.label {
|
||||
self.label_changed = true;
|
||||
}
|
||||
|
||||
self.label = label;
|
||||
}
|
||||
|
||||
pub fn get_label(&self) -> Option<&str> {
|
||||
self.label.as_deref()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) {
|
||||
let size = self.scratch.as_ref().len();
|
||||
|
||||
if self.capacity < size {
|
||||
if self.capacity < size || self.label_changed {
|
||||
self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
label: None,
|
||||
label: self.label.as_deref(),
|
||||
usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
|
||||
contents: self.scratch.as_ref(),
|
||||
}));
|
||||
self.capacity = size;
|
||||
self.label_changed = false;
|
||||
} else if let Some(buffer) = &self.buffer {
|
||||
queue.write_buffer(buffer, 0, self.scratch.as_ref());
|
||||
}
|
||||
|
@ -31,6 +31,8 @@ pub struct UniformBuffer<T: ShaderType> {
|
||||
value: T,
|
||||
scratch: UniformBufferWrapper<Vec<u8>>,
|
||||
buffer: Option<Buffer>,
|
||||
label: Option<String>,
|
||||
label_changed: bool,
|
||||
}
|
||||
|
||||
impl<T: ShaderType> From<T> for UniformBuffer<T> {
|
||||
@ -39,6 +41,8 @@ impl<T: ShaderType> From<T> for UniformBuffer<T> {
|
||||
value,
|
||||
scratch: UniformBufferWrapper::new(Vec::new()),
|
||||
buffer: None,
|
||||
label: None,
|
||||
label_changed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,6 +53,8 @@ impl<T: ShaderType + Default> Default for UniformBuffer<T> {
|
||||
value: T::default(),
|
||||
scratch: UniformBufferWrapper::new(Vec::new()),
|
||||
buffer: None,
|
||||
label: None,
|
||||
label_changed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -79,6 +85,20 @@ impl<T: ShaderType + WriteInto> UniformBuffer<T> {
|
||||
&mut self.value
|
||||
}
|
||||
|
||||
pub fn set_label(&mut self, label: Option<&str>) {
|
||||
let label = label.map(str::to_string);
|
||||
|
||||
if label != self.label {
|
||||
self.label_changed = true;
|
||||
}
|
||||
|
||||
self.label = label;
|
||||
}
|
||||
|
||||
pub fn get_label(&self) -> Option<&str> {
|
||||
self.label.as_deref()
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
@ -87,15 +107,15 @@ impl<T: ShaderType + WriteInto> UniformBuffer<T> {
|
||||
pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) {
|
||||
self.scratch.write(&self.value).unwrap();
|
||||
|
||||
match &self.buffer {
|
||||
Some(buffer) => queue.write_buffer(buffer, 0, self.scratch.as_ref()),
|
||||
None => {
|
||||
self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
label: None,
|
||||
usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
|
||||
contents: self.scratch.as_ref(),
|
||||
}));
|
||||
}
|
||||
if self.label_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,
|
||||
contents: self.scratch.as_ref(),
|
||||
}));
|
||||
self.label_changed = false;
|
||||
} else if let Some(buffer) = &self.buffer {
|
||||
queue.write_buffer(buffer, 0, self.scratch.as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,6 +144,8 @@ pub struct DynamicUniformBuffer<T: ShaderType> {
|
||||
scratch: DynamicUniformBufferWrapper<Vec<u8>>,
|
||||
buffer: Option<Buffer>,
|
||||
capacity: usize,
|
||||
label: Option<String>,
|
||||
label_changed: bool,
|
||||
}
|
||||
|
||||
impl<T: ShaderType> Default for DynamicUniformBuffer<T> {
|
||||
@ -133,6 +155,8 @@ impl<T: ShaderType> Default for DynamicUniformBuffer<T> {
|
||||
scratch: DynamicUniformBufferWrapper::new(Vec::new()),
|
||||
buffer: None,
|
||||
capacity: 0,
|
||||
label: None,
|
||||
label_changed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -170,6 +194,20 @@ impl<T: ShaderType + WriteInto> DynamicUniformBuffer<T> {
|
||||
offset
|
||||
}
|
||||
|
||||
pub fn set_label(&mut self, label: Option<&str>) {
|
||||
let label = label.map(str::to_string);
|
||||
|
||||
if label != self.label {
|
||||
self.label_changed = true;
|
||||
}
|
||||
|
||||
self.label = label;
|
||||
}
|
||||
|
||||
pub fn get_label(&self) -> Option<&str> {
|
||||
self.label.as_deref()
|
||||
}
|
||||
|
||||
/// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice)
|
||||
/// and the provided [`RenderQueue`](crate::renderer::RenderQueue).
|
||||
///
|
||||
@ -179,13 +217,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 {
|
||||
if self.capacity < size || self.label_changed {
|
||||
self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
label: None,
|
||||
label: self.label.as_deref(),
|
||||
usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
|
||||
contents: self.scratch.as_ref(),
|
||||
}));
|
||||
self.capacity = size;
|
||||
self.label_changed = false;
|
||||
} else if let Some(buffer) = &self.buffer {
|
||||
queue.write_buffer(buffer, 0, self.scratch.as_ref());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user