Skip to content

Commit 2d2ea33

Browse files
Brandon Reinhartrebelroad-reinhart
Brandon Reinhart
andcommitted
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. ![ray_buf](https://user-images.githubusercontent.com/106117615/179366494-f037bd8c-4d65-4b37-8135-01ac0c5c8ee0.png) Here is the buffer appearing with the correct name in RenderDoc. Previously the buffer would have an anonymous name such as "Buffer223": ![buffer_named](https://user-images.githubusercontent.com/106117615/179366552-faeb6c27-5373-4e4e-a0e2-c04446f95a4b.png) Co-authored-by: rebelroad-reinhart <[email protected]>
1 parent 4e2600b commit 2d2ea33

File tree

3 files changed

+115
-17
lines changed

3 files changed

+115
-17
lines changed

crates/bevy_render/src/render_resource/buffer_vec.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ pub struct BufferVec<T: Pod> {
3333
capacity: usize,
3434
item_size: usize,
3535
buffer_usage: BufferUsages,
36+
label: Option<String>,
37+
label_changed: bool,
3638
}
3739

3840
impl<T: Pod> BufferVec<T> {
@@ -43,6 +45,8 @@ impl<T: Pod> BufferVec<T> {
4345
capacity: 0,
4446
item_size: std::mem::size_of::<T>(),
4547
buffer_usage,
48+
label: None,
49+
label_changed: false,
4650
}
4751
}
4852

@@ -72,6 +76,20 @@ impl<T: Pod> BufferVec<T> {
7276
index
7377
}
7478

79+
pub fn set_label(&mut self, label: Option<&str>) {
80+
let label = label.map(str::to_string);
81+
82+
if label != self.label {
83+
self.label_changed = true;
84+
}
85+
86+
self.label = label;
87+
}
88+
89+
pub fn get_label(&self) -> Option<&str> {
90+
self.label.as_deref()
91+
}
92+
7593
/// Creates a [`Buffer`](crate::render_resource::Buffer) on the [`RenderDevice`](crate::renderer::RenderDevice) with size
7694
/// at least `std::mem::size_of::<T>() * capacity`, unless a such a buffer already exists.
7795
///
@@ -84,15 +102,16 @@ impl<T: Pod> BufferVec<T> {
84102
/// the `BufferVec` was created, the buffer on the [`RenderDevice`](crate::renderer::RenderDevice)
85103
/// is marked as [`BufferUsages::COPY_DST`](crate::render_resource::BufferUsages).
86104
pub fn reserve(&mut self, capacity: usize, device: &RenderDevice) {
87-
if capacity > self.capacity {
105+
if capacity > self.capacity || self.label_changed {
88106
self.capacity = capacity;
89107
let size = self.item_size * capacity;
90108
self.buffer = Some(device.create_buffer(&wgpu::BufferDescriptor {
91-
label: None,
109+
label: self.label.as_deref(),
92110
size: size as wgpu::BufferAddress,
93111
usage: BufferUsages::COPY_DST | self.buffer_usage,
94112
mapped_at_creation: false,
95113
}));
114+
self.label_changed = false;
96115
}
97116
}
98117

crates/bevy_render/src/render_resource/storage_buffer.rs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ pub struct StorageBuffer<T: ShaderType> {
3232
scratch: StorageBufferWrapper<Vec<u8>>,
3333
buffer: Option<Buffer>,
3434
capacity: usize,
35+
label: Option<String>,
36+
label_changed: bool,
3537
}
3638

3739
impl<T: ShaderType> From<T> for StorageBuffer<T> {
@@ -41,6 +43,8 @@ impl<T: ShaderType> From<T> for StorageBuffer<T> {
4143
scratch: StorageBufferWrapper::new(Vec::new()),
4244
buffer: None,
4345
capacity: 0,
46+
label: None,
47+
label_changed: false,
4448
}
4549
}
4650
}
@@ -52,6 +56,8 @@ impl<T: ShaderType + Default> Default for StorageBuffer<T> {
5256
scratch: StorageBufferWrapper::new(Vec::new()),
5357
buffer: None,
5458
capacity: 0,
59+
label: None,
60+
label_changed: false,
5561
}
5662
}
5763
}
@@ -81,6 +87,20 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
8187
&mut self.value
8288
}
8389

90+
pub fn set_label(&mut self, label: Option<&str>) {
91+
let label = label.map(str::to_string);
92+
93+
if label != self.label {
94+
self.label_changed = true;
95+
}
96+
97+
self.label = label;
98+
}
99+
100+
pub fn get_label(&self) -> Option<&str> {
101+
self.label.as_deref()
102+
}
103+
84104
/// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice)
85105
/// and the provided [`RenderQueue`](crate::renderer::RenderQueue).
86106
///
@@ -91,13 +111,14 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
91111

92112
let size = self.scratch.as_ref().len();
93113

94-
if self.capacity < size {
114+
if self.capacity < size || self.label_changed {
95115
self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
96-
label: None,
116+
label: self.label.as_deref(),
97117
usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
98118
contents: self.scratch.as_ref(),
99119
}));
100120
self.capacity = size;
121+
self.label_changed = false;
101122
} else if let Some(buffer) = &self.buffer {
102123
queue.write_buffer(buffer, 0, self.scratch.as_ref());
103124
}
@@ -130,6 +151,8 @@ pub struct DynamicStorageBuffer<T: ShaderType> {
130151
scratch: DynamicStorageBufferWrapper<Vec<u8>>,
131152
buffer: Option<Buffer>,
132153
capacity: usize,
154+
label: Option<String>,
155+
label_changed: bool,
133156
}
134157

135158
impl<T: ShaderType> Default for DynamicStorageBuffer<T> {
@@ -139,6 +162,8 @@ impl<T: ShaderType> Default for DynamicStorageBuffer<T> {
139162
scratch: DynamicStorageBufferWrapper::new(Vec::new()),
140163
buffer: None,
141164
capacity: 0,
165+
label: None,
166+
label_changed: false,
142167
}
143168
}
144169
}
@@ -175,17 +200,32 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
175200
offset
176201
}
177202

203+
pub fn set_label(&mut self, label: Option<&str>) {
204+
let label = label.map(str::to_string);
205+
206+
if label != self.label {
207+
self.label_changed = true;
208+
}
209+
210+
self.label = label;
211+
}
212+
213+
pub fn get_label(&self) -> Option<&str> {
214+
self.label.as_deref()
215+
}
216+
178217
#[inline]
179218
pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) {
180219
let size = self.scratch.as_ref().len();
181220

182-
if self.capacity < size {
221+
if self.capacity < size || self.label_changed {
183222
self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
184-
label: None,
223+
label: self.label.as_deref(),
185224
usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
186225
contents: self.scratch.as_ref(),
187226
}));
188227
self.capacity = size;
228+
self.label_changed = false;
189229
} else if let Some(buffer) = &self.buffer {
190230
queue.write_buffer(buffer, 0, self.scratch.as_ref());
191231
}

crates/bevy_render/src/render_resource/uniform_buffer.rs

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub struct UniformBuffer<T: ShaderType> {
3131
value: T,
3232
scratch: UniformBufferWrapper<Vec<u8>>,
3333
buffer: Option<Buffer>,
34+
label: Option<String>,
35+
label_changed: bool,
3436
}
3537

3638
impl<T: ShaderType> From<T> for UniformBuffer<T> {
@@ -39,6 +41,8 @@ impl<T: ShaderType> From<T> for UniformBuffer<T> {
3941
value,
4042
scratch: UniformBufferWrapper::new(Vec::new()),
4143
buffer: None,
44+
label: None,
45+
label_changed: false,
4246
}
4347
}
4448
}
@@ -49,6 +53,8 @@ impl<T: ShaderType + Default> Default for UniformBuffer<T> {
4953
value: T::default(),
5054
scratch: UniformBufferWrapper::new(Vec::new()),
5155
buffer: None,
56+
label: None,
57+
label_changed: false,
5258
}
5359
}
5460
}
@@ -79,6 +85,20 @@ impl<T: ShaderType + WriteInto> UniformBuffer<T> {
7985
&mut self.value
8086
}
8187

88+
pub fn set_label(&mut self, label: Option<&str>) {
89+
let label = label.map(str::to_string);
90+
91+
if label != self.label {
92+
self.label_changed = true;
93+
}
94+
95+
self.label = label;
96+
}
97+
98+
pub fn get_label(&self) -> Option<&str> {
99+
self.label.as_deref()
100+
}
101+
82102
/// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice)
83103
/// and the provided [`RenderQueue`](crate::renderer::RenderQueue), if a GPU-side backing buffer already exists.
84104
///
@@ -87,15 +107,15 @@ impl<T: ShaderType + WriteInto> UniformBuffer<T> {
87107
pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) {
88108
self.scratch.write(&self.value).unwrap();
89109

90-
match &self.buffer {
91-
Some(buffer) => queue.write_buffer(buffer, 0, self.scratch.as_ref()),
92-
None => {
93-
self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
94-
label: None,
95-
usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
96-
contents: self.scratch.as_ref(),
97-
}));
98-
}
110+
if self.label_changed || self.buffer.is_none() {
111+
self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
112+
label: self.label.as_deref(),
113+
usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
114+
contents: self.scratch.as_ref(),
115+
}));
116+
self.label_changed = false;
117+
} else if let Some(buffer) = &self.buffer {
118+
queue.write_buffer(buffer, 0, self.scratch.as_ref());
99119
}
100120
}
101121
}
@@ -124,6 +144,8 @@ pub struct DynamicUniformBuffer<T: ShaderType> {
124144
scratch: DynamicUniformBufferWrapper<Vec<u8>>,
125145
buffer: Option<Buffer>,
126146
capacity: usize,
147+
label: Option<String>,
148+
label_changed: bool,
127149
}
128150

129151
impl<T: ShaderType> Default for DynamicUniformBuffer<T> {
@@ -133,6 +155,8 @@ impl<T: ShaderType> Default for DynamicUniformBuffer<T> {
133155
scratch: DynamicUniformBufferWrapper::new(Vec::new()),
134156
buffer: None,
135157
capacity: 0,
158+
label: None,
159+
label_changed: false,
136160
}
137161
}
138162
}
@@ -170,6 +194,20 @@ impl<T: ShaderType + WriteInto> DynamicUniformBuffer<T> {
170194
offset
171195
}
172196

197+
pub fn set_label(&mut self, label: Option<&str>) {
198+
let label = label.map(str::to_string);
199+
200+
if label != self.label {
201+
self.label_changed = true;
202+
}
203+
204+
self.label = label;
205+
}
206+
207+
pub fn get_label(&self) -> Option<&str> {
208+
self.label.as_deref()
209+
}
210+
173211
/// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice)
174212
/// and the provided [`RenderQueue`](crate::renderer::RenderQueue).
175213
///
@@ -179,13 +217,14 @@ impl<T: ShaderType + WriteInto> DynamicUniformBuffer<T> {
179217
pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) {
180218
let size = self.scratch.as_ref().len();
181219

182-
if self.capacity < size {
220+
if self.capacity < size || self.label_changed {
183221
self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
184-
label: None,
222+
label: self.label.as_deref(),
185223
usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
186224
contents: self.scratch.as_ref(),
187225
}));
188226
self.capacity = size;
227+
self.label_changed = false;
189228
} else if let Some(buffer) = &self.buffer {
190229
queue.write_buffer(buffer, 0, self.scratch.as_ref());
191230
}

0 commit comments

Comments
 (0)