From 11727c5dbbeba80380ce4d8ff58b71e73f4ea920 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Thu, 5 May 2022 20:12:37 -0700 Subject: [PATCH 01/20] Documenting `BufferVec`. --- .../src/render_resource/buffer_vec.rs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/crates/bevy_render/src/render_resource/buffer_vec.rs b/crates/bevy_render/src/render_resource/buffer_vec.rs index ad8f5ff2adfe1..2e17544741cd5 100644 --- a/crates/bevy_render/src/render_resource/buffer_vec.rs +++ b/crates/bevy_render/src/render_resource/buffer_vec.rs @@ -6,6 +6,18 @@ use bevy_core::{cast_slice, Pod}; use copyless::VecHelper; use wgpu::BufferUsages; +/// A structure for storing raw bytes that have already been properly formatted +/// for the [`RenderDevice`](crate::renderer::RenderDevice). +/// +/// "Properly formatted" means data that is [`#[repr(C)]`](https://doc.rust-lang.org/reference/type-layout.html#the-c-representation), [`Pod`] +/// and `Zeroable`. Unlike the [`DynamicUniformVec`](crate::render_resource::DynamicUniformVec), +/// [`UniformVec`](crate::render_resource::UniformVec) and [`StorageBuffer`](crate::render_resource::StorageBuffer) structures, +/// `BufferVec` does not provide padding or alignment between items, or within items. +/// +/// The data is stored on the host, calling [`reserve`](crate::render_resource::BufferVec::reserve) +/// allocates memory on the [`RenderDevice`](crate::renderer::RenderDevice). +/// [`write_buffer`](crate::render_resource::BufferVec::write_buffer) queues copying of the data +/// from the host to the [`RenderDevice`](crate::renderer::RenderDevice). pub struct BufferVec { values: Vec, buffer: Option, @@ -60,6 +72,17 @@ impl BufferVec { index } + /// Creates a [`Buffer`](crate::render_resource::Buffer) on the [`RenderDevice`](crate::renderer::RenderDevice) with size + /// at least `std::mem::size_of::() * capacity`, unless a such a buffer already exists. + /// + /// If a [`Buffer`](crate::render_resource::Buffer) exists, but is too small, references to it will be discarded, + /// and a new [`Buffer`](crate::render_resource::Buffer) will be created. Any previously created [`Buffer`](crate::render_resource::Buffer)s + /// that are no longer referenced will be deleted by the [`RenderDevice`](crate::renderer::RenderDevice) + /// once it is done using them (typically 1-2 frames). + /// + /// In addition to any [`BufferUsages`](crate::render_resource::BufferUsages) provided when + /// 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 { self.capacity = capacity; @@ -73,6 +96,11 @@ impl BufferVec { } } + /// Queues writing of memory from the host to [`RenderDevice`](crate::renderer::RenderDevice) using + /// the provided [`RenderQueue`](crate::renderer::RenderQueue). + /// + /// Before queueing the write, a [`reserve`](crate::render_resource::BufferVec::reserve) operation + /// is executed. pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { if self.values.is_empty() { return; From 9ef6d24c986dfcee92edf335faf18dafeb72e0a8 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 21 Jun 2022 09:33:53 -0700 Subject: [PATCH 02/20] Replace RenderDevice by GPU. Co-authored-by: Robert Swain --- crates/bevy_render/src/render_resource/buffer_vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/src/render_resource/buffer_vec.rs b/crates/bevy_render/src/render_resource/buffer_vec.rs index 2e17544741cd5..f78dc8f2e25bb 100644 --- a/crates/bevy_render/src/render_resource/buffer_vec.rs +++ b/crates/bevy_render/src/render_resource/buffer_vec.rs @@ -7,7 +7,7 @@ use copyless::VecHelper; use wgpu::BufferUsages; /// A structure for storing raw bytes that have already been properly formatted -/// for the [`RenderDevice`](crate::renderer::RenderDevice). +/// for use by the GPU. /// /// "Properly formatted" means data that is [`#[repr(C)]`](https://doc.rust-lang.org/reference/type-layout.html#the-c-representation), [`Pod`] /// and `Zeroable`. Unlike the [`DynamicUniformVec`](crate::render_resource::DynamicUniformVec), From 5ffd5800f7d9c867a5dc1dff3996a057fb9abfa5 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 21 Jun 2022 09:35:40 -0700 Subject: [PATCH 03/20] State Pod as the direct requirement; and reflect reality of encase now being merged. Co-authored-by: Robert Swain --- .../src/render_resource/buffer_vec.rs | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/crates/bevy_render/src/render_resource/buffer_vec.rs b/crates/bevy_render/src/render_resource/buffer_vec.rs index f78dc8f2e25bb..af2be8e79826b 100644 --- a/crates/bevy_render/src/render_resource/buffer_vec.rs +++ b/crates/bevy_render/src/render_resource/buffer_vec.rs @@ -9,15 +9,26 @@ use wgpu::BufferUsages; /// A structure for storing raw bytes that have already been properly formatted /// for use by the GPU. /// -/// "Properly formatted" means data that is [`#[repr(C)]`](https://doc.rust-lang.org/reference/type-layout.html#the-c-representation), [`Pod`] -/// and `Zeroable`. Unlike the [`DynamicUniformVec`](crate::render_resource::DynamicUniformVec), -/// [`UniformVec`](crate::render_resource::UniformVec) and [`StorageBuffer`](crate::render_resource::StorageBuffer) structures, -/// `BufferVec` does not provide padding or alignment between items, or within items. +/// "Properly formatted" means data that item data already meets the alignment and padding +/// requirements for how it will be used on the GPU. +/// +/// Index, vertex, and instance-rate vertex buffers have no alignment nor padding requirements and +/// so this helper type is a good choice for them. Uniform buffers must adhere to std140 +/// alignment/padding requirements, and storage buffers to std430. There are helper types for such +/// buffers: +/// - Uniform buffers +/// - Plain: [`UniformBuffer`](crate::render_resource::UniformBuffer) +/// - Dynamic offsets: [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer) +/// - Storage buffers +/// - Plain: [`StorageBuffer`](crate::render_resource::StorageBuffer) +/// - Dynamic offsets: [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) +/// +/// The item type must implement [`Pod`] for its data representation to be directly copyable. /// -/// The data is stored on the host, calling [`reserve`](crate::render_resource::BufferVec::reserve) -/// allocates memory on the [`RenderDevice`](crate::renderer::RenderDevice). +/// The contained data is stored in system RAM. Calling [`reserve`](crate::render_resource::BufferVec::reserve) +/// allocates VRAM from the [`RenderDevice`](crate::renderer::RenderDevice). /// [`write_buffer`](crate::render_resource::BufferVec::write_buffer) queues copying of the data -/// from the host to the [`RenderDevice`](crate::renderer::RenderDevice). +/// from system RAM to VRAM. pub struct BufferVec { values: Vec, buffer: Option, From da1f666d1ab473476f28751e491cd6fd6a3886fc Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 21 Jun 2022 09:36:43 -0700 Subject: [PATCH 04/20] Say "system RAM" instead of "host memory" and "VRAM" instead of "device memory" Co-authored-by: Robert Swain --- crates/bevy_render/src/render_resource/buffer_vec.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_render/src/render_resource/buffer_vec.rs b/crates/bevy_render/src/render_resource/buffer_vec.rs index af2be8e79826b..7ea8f6ccde272 100644 --- a/crates/bevy_render/src/render_resource/buffer_vec.rs +++ b/crates/bevy_render/src/render_resource/buffer_vec.rs @@ -107,10 +107,10 @@ impl BufferVec { } } - /// Queues writing of memory from the host to [`RenderDevice`](crate::renderer::RenderDevice) using - /// the provided [`RenderQueue`](crate::renderer::RenderQueue). + /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice) + /// and the provided [`RenderQueue`](crate::renderer::RenderQueue). /// - /// Before queueing the write, a [`reserve`](crate::render_resource::BufferVec::reserve) operation + /// Before queuing the write, a [`reserve`](crate::render_resource::BufferVec::reserve) operation /// is executed. pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { if self.values.is_empty() { From e407b97532d09febf611da69120a6a4f631cb322 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 21 Jun 2022 14:06:31 -0700 Subject: [PATCH 05/20] remove repetition of "data" Co-authored-by: Robert Swain --- crates/bevy_render/src/render_resource/buffer_vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/src/render_resource/buffer_vec.rs b/crates/bevy_render/src/render_resource/buffer_vec.rs index 7ea8f6ccde272..4648a6f8072b1 100644 --- a/crates/bevy_render/src/render_resource/buffer_vec.rs +++ b/crates/bevy_render/src/render_resource/buffer_vec.rs @@ -9,7 +9,7 @@ use wgpu::BufferUsages; /// A structure for storing raw bytes that have already been properly formatted /// for use by the GPU. /// -/// "Properly formatted" means data that item data already meets the alignment and padding +/// "Properly formatted" means that item data already meets the alignment and padding /// requirements for how it will be used on the GPU. /// /// Index, vertex, and instance-rate vertex buffers have no alignment nor padding requirements and From c50f80c4deae90a4c148f05d23d3f33bfa070a96 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Mon, 27 Jun 2022 10:01:40 -0700 Subject: [PATCH 06/20] run cargo fmt --- crates/bevy_render/src/render_resource/buffer_vec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/render_resource/buffer_vec.rs b/crates/bevy_render/src/render_resource/buffer_vec.rs index 4648a6f8072b1..b42802470af0b 100644 --- a/crates/bevy_render/src/render_resource/buffer_vec.rs +++ b/crates/bevy_render/src/render_resource/buffer_vec.rs @@ -11,7 +11,7 @@ use wgpu::BufferUsages; /// /// "Properly formatted" means that item data already meets the alignment and padding /// requirements for how it will be used on the GPU. -/// +/// /// Index, vertex, and instance-rate vertex buffers have no alignment nor padding requirements and /// so this helper type is a good choice for them. Uniform buffers must adhere to std140 /// alignment/padding requirements, and storage buffers to std430. There are helper types for such @@ -22,7 +22,7 @@ use wgpu::BufferUsages; /// - Storage buffers /// - Plain: [`StorageBuffer`](crate::render_resource::StorageBuffer) /// - Dynamic offsets: [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) -/// +/// /// The item type must implement [`Pod`] for its data representation to be directly copyable. /// /// The contained data is stored in system RAM. Calling [`reserve`](crate::render_resource::BufferVec::reserve) From b974929815beee19efc2ae2b76172c0362cdc840 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 5 Jul 2022 18:57:25 -0700 Subject: [PATCH 07/20] Add documentation for UniformBuffer and DynamicUniformBuffer. --- .../src/render_resource/uniform_buffer.rs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index 6f9ad642dcc48..625ec24f1b3ad 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -8,6 +8,20 @@ use encase::{ }; use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsages}; +/// A helper structure for storing data that will be transferred to the GPU and made accessible +/// to shaders as a uniform buffer. +/// +/// Uniform buffers are available to shaders on a read-only basis. Uniform buffers are commonly used to make available to shaders +/// parameters that are constant during shader execution. +/// +/// Uniform buffers must conform to std140 alignment/padding requirements, which this helper structure takes care of enforcing. +/// Per the [WGPU spec], uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. +/// If this is required, consider [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer). +/// +/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::UniformBuffer::write_buffer) queues +/// copying of the data from system RAM to VRAM. +/// +/// [WGPU spec]: https://www.w3.org/TR/WGSL/#address-spaces-uniform pub struct UniformBuffer { value: T, scratch: UniformBufferWrapper>, @@ -47,6 +61,7 @@ impl UniformBuffer { )) } + /// Set the data the buffer stores. pub fn set(&mut self, value: T) { self.value = value; } @@ -59,6 +74,11 @@ impl UniformBuffer { &mut self.value } + /// 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. + /// + /// If a GPU-side buffer does not already exist for this data, such a buffer is initialized with currently + /// available data. pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { self.scratch.write(&self.value).unwrap(); @@ -75,6 +95,14 @@ impl UniformBuffer { } } +/// A helper structure for storing data that will be transferred to the GPU and made accessible +/// to shaders as a dynamic uniform buffer. +/// +/// Dynamic uniform buffers are available to shaders on a read-only basis. Dynamic uniform buffers are commonly used to make +/// available to shaders runtime-sized arrays of parameters that are otherwise constant during shader execution. +/// +/// Dynamic uniform buffers must conform to std140 alignment/padding requirements, which this helper structure takes care of +/// enforcing. pub struct DynamicUniformBuffer { values: Vec, scratch: DynamicUniformBufferWrapper>, @@ -118,6 +146,7 @@ impl DynamicUniformBuffer { self.values.is_empty() } + /// Push data into the `DynamicUniformBuffer`'s internal vector (residing on system RAM). #[inline] pub fn push(&mut self, value: T) -> u32 { let offset = self.scratch.write(&value).unwrap() as u32; @@ -125,6 +154,11 @@ impl DynamicUniformBuffer { offset } + /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice) + /// and the provided [`RenderQueue`](crate::renderer::RenderQueue). + /// + /// If there is no GPU-side buffer allocated to hold the data currently stored, or if a GPU-side buffer previously + /// allocated does not have enough capacity, a new GPU-side buffer is created. #[inline] pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { let size = self.scratch.as_ref().len(); From 8a49be6acc9ca02ddcbbaad655677e9bcde673d1 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 5 Jul 2022 18:59:08 -0700 Subject: [PATCH 08/20] run cargo fmt --- .../src/render_resource/uniform_buffer.rs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index 625ec24f1b3ad..7cdb62b7c7b29 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -9,18 +9,18 @@ use encase::{ use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsages}; /// A helper structure for storing data that will be transferred to the GPU and made accessible -/// to shaders as a uniform buffer. -/// -/// Uniform buffers are available to shaders on a read-only basis. Uniform buffers are commonly used to make available to shaders -/// parameters that are constant during shader execution. -/// -/// Uniform buffers must conform to std140 alignment/padding requirements, which this helper structure takes care of enforcing. -/// Per the [WGPU spec], uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. -/// If this is required, consider [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer). -/// -/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::UniformBuffer::write_buffer) queues +/// to shaders as a uniform buffer. +/// +/// Uniform buffers are available to shaders on a read-only basis. Uniform buffers are commonly used to make available to shaders +/// parameters that are constant during shader execution. +/// +/// Uniform buffers must conform to std140 alignment/padding requirements, which this helper structure takes care of enforcing. +/// Per the [WGPU spec], uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. +/// If this is required, consider [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer). +/// +/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::UniformBuffer::write_buffer) queues /// copying of the data from system RAM to VRAM. -/// +/// /// [WGPU spec]: https://www.w3.org/TR/WGSL/#address-spaces-uniform pub struct UniformBuffer { value: T, @@ -96,13 +96,13 @@ impl UniformBuffer { } /// A helper structure for storing data that will be transferred to the GPU and made accessible -/// to shaders as a dynamic uniform buffer. -/// -/// Dynamic uniform buffers are available to shaders on a read-only basis. Dynamic uniform buffers are commonly used to make +/// to shaders as a dynamic uniform buffer. +/// +/// Dynamic uniform buffers are available to shaders on a read-only basis. Dynamic uniform buffers are commonly used to make /// available to shaders runtime-sized arrays of parameters that are otherwise constant during shader execution. -/// -/// Dynamic uniform buffers must conform to std140 alignment/padding requirements, which this helper structure takes care of -/// enforcing. +/// +/// Dynamic uniform buffers must conform to std140 alignment/padding requirements, which this helper structure takes care of +/// enforcing. pub struct DynamicUniformBuffer { values: Vec, scratch: DynamicUniformBufferWrapper>, @@ -146,7 +146,7 @@ impl DynamicUniformBuffer { self.values.is_empty() } - /// Push data into the `DynamicUniformBuffer`'s internal vector (residing on system RAM). + /// Push data into the `DynamicUniformBuffer`'s internal vector (residing on system RAM). #[inline] pub fn push(&mut self, value: T) -> u32 { let offset = self.scratch.write(&value).unwrap() as u32; @@ -157,8 +157,8 @@ impl DynamicUniformBuffer { /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice) /// and the provided [`RenderQueue`](crate::renderer::RenderQueue). /// - /// If there is no GPU-side buffer allocated to hold the data currently stored, or if a GPU-side buffer previously - /// allocated does not have enough capacity, a new GPU-side buffer is created. + /// If there is no GPU-side buffer allocated to hold the data currently stored, or if a GPU-side buffer previously + /// allocated does not have enough capacity, a new GPU-side buffer is created. #[inline] pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { let size = self.scratch.as_ref().len(); From f77cd5a9677e7621a8831354e189b4d5e8808073 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Wed, 6 Jul 2022 14:07:16 -0700 Subject: [PATCH 09/20] Clarifications regarding dynamic vs. non-dynamic buffers. Also added documentation for StorageBuffer. --- .../src/render_resource/storage_buffer.rs | 35 +++++++++++++++++++ .../src/render_resource/uniform_buffer.rs | 13 ++++--- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index 96c24a2c090eb..dfbbb617c38f6 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -6,6 +6,21 @@ use encase::{ }; use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsages}; +/// A helper structure for storing data that will be transferred to the GPU and made accessible +/// to shaders as a storage buffer. +/// +/// Storage buffers can be made available to shaders as some combination of read/write, unlike +/// [`UniformBuffer`](crate::render_resource::UniformBuffer) which is read-only. Furthermore, storage buffers +/// can store much larger data than uniform buffers, which are best suited to relatively small data. Finally, unlike +/// [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer), a storage buffer is automatically bound to +/// at the beginning of the buffer. +/// +/// Storage buffers must conform to [std430 alignment/padding requirements], which this helper structure takes care of enforcing. +/// +/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::StorageBuffer::write_buffer) queues +/// copying of the data from system RAM to VRAM. +/// +/// [std430 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-storage pub struct StorageBuffer { value: T, scratch: StorageBufferWrapper>, @@ -60,6 +75,11 @@ impl StorageBuffer { &mut self.value } + /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice) + /// and the provided [`RenderQueue`](crate::renderer::RenderQueue). + /// + /// If there is no GPU-side buffer allocated to hold the data currently stored, or if a GPU-side buffer previously + /// allocated does not have enough capacity, a new GPU-side buffer is created. pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { self.scratch.write(&self.value).unwrap(); @@ -78,6 +98,21 @@ impl StorageBuffer { } } +/// A helper structure for storing data that will be transferred to the GPU and made accessible +/// to shaders as a dynamic storage buffer. +/// +/// Storage buffers can be made available to shaders as some combination of read/write, unlike +/// [`DynamicUniformBuffer`](crate::render_resource::UniformBuffer) +/// which is read-only. Furthermore, storage buffers can store much larger data than uniform buffers, which are best suited +/// to relatively small data. Finally, dynamic storage buffers can be bound to at a custom offset that is not necessarily the +/// beginning of the buffer; if this is not required, consider using [`StorageBuffer`](crate::render_resource::StorageBuffer) +/// instead. +/// +/// Dynamic storage buffers must conform to std430 alignment/padding requirements, which this helper structure takes care of +/// enforcing. +/// +/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicStorageBuffer::write_buffer) queues +/// copying of the data from system RAM to VRAM. pub struct DynamicStorageBuffer { values: Vec, scratch: DynamicStorageBufferWrapper>, diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index 7cdb62b7c7b29..28d56d84a4fa2 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -12,16 +12,18 @@ use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsa /// to shaders as a uniform buffer. /// /// Uniform buffers are available to shaders on a read-only basis. Uniform buffers are commonly used to make available to shaders -/// parameters that are constant during shader execution. +/// parameters that are constant during shader execution. Uniform buffers are also best used for data that is relatively small +/// in size. For larger data, or data that must be made accessible to shaders on a read-write basis, consider +/// [`StorageBuffer`](crate::render_resource::StorageBuffer). /// -/// Uniform buffers must conform to std140 alignment/padding requirements, which this helper structure takes care of enforcing. -/// Per the [WGPU spec], uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. +/// Uniform buffers must conform to [std140 alignment/padding requirements], which this helper structure takes care of enforcing. +/// Per the WGPU spec, uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. /// If this is required, consider [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer). /// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::UniformBuffer::write_buffer) queues /// copying of the data from system RAM to VRAM. /// -/// [WGPU spec]: https://www.w3.org/TR/WGSL/#address-spaces-uniform +/// [std140 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-uniform pub struct UniformBuffer { value: T, scratch: UniformBufferWrapper>, @@ -103,6 +105,9 @@ impl UniformBuffer { /// /// Dynamic uniform buffers must conform to std140 alignment/padding requirements, which this helper structure takes care of /// enforcing. +/// +/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicUniformBuffer::write_buffer) queues +/// copying of the data from system RAM to VRAM. pub struct DynamicUniformBuffer { values: Vec, scratch: DynamicUniformBufferWrapper>, From 908bd6adf650cc66d874ad936aad35588c01a80d Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Fri, 8 Jul 2022 14:04:52 -0700 Subject: [PATCH 10/20] clarifying docs further. --- .../src/render_resource/storage_buffer.rs | 44 +++++++++---------- .../src/render_resource/uniform_buffer.rs | 37 +++++++++------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index dfbbb617c38f6..260416249ae31 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -6,19 +6,19 @@ use encase::{ }; use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsages}; -/// A helper structure for storing data that will be transferred to the GPU and made accessible -/// to shaders as a storage buffer. +/// Stores data to be transferred to the GPU and made accessible to shaders as a storage buffer. /// -/// Storage buffers can be made available to shaders as some combination of read/write, unlike -/// [`UniformBuffer`](crate::render_resource::UniformBuffer) which is read-only. Furthermore, storage buffers -/// can store much larger data than uniform buffers, which are best suited to relatively small data. Finally, unlike -/// [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer), a storage buffer is automatically bound to -/// at the beginning of the buffer. +/// Storage buffers can be made available to shaders as some combination of read/write, unlike +/// [`UniformBuffer`](crate::render_resource::UniformBuffer) which is read-only. Furthermore, storage buffers +/// can store much larger data than uniform buffers, which are best suited to relatively small data. /// -/// Storage buffers must conform to [std430 alignment/padding requirements], which this helper structure takes care of enforcing. +/// Storage buffers can store runtime-sized arrays, but only if they are the last field in a structure. To store a +/// runtime-sized array of data, use [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) instead. /// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::StorageBuffer::write_buffer) queues -/// copying of the data from system RAM to VRAM. +/// copying of the data from system RAM to VRAM. Storage buffers must conform to [std430 alignment/padding requirements], which +/// is automatically enforced by this structure. If data does not need to be automatically padded or aligned, +/// consider using [`BufferVec`](crate::render_resource::BufferVec). /// /// [std430 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-storage pub struct StorageBuffer { @@ -98,21 +98,21 @@ impl StorageBuffer { } } -/// A helper structure for storing data that will be transferred to the GPU and made accessible -/// to shaders as a dynamic storage buffer. +/// Stores data to be transferred to the GPU and made accessible to shaders as a storage buffer. /// -/// Storage buffers can be made available to shaders as some combination of read/write, unlike -/// [`DynamicUniformBuffer`](crate::render_resource::UniformBuffer) -/// which is read-only. Furthermore, storage buffers can store much larger data than uniform buffers, which are best suited -/// to relatively small data. Finally, dynamic storage buffers can be bound to at a custom offset that is not necessarily the -/// beginning of the buffer; if this is not required, consider using [`StorageBuffer`](crate::render_resource::StorageBuffer) -/// instead. +/// Storage buffers can be made available to shaders as some combination of read/write, unlike +/// [`UniformBuffer`](crate::render_resource::UniformBuffer) which is read-only. Furthermore, storage buffers +/// can store much larger data than uniform buffers, which are best suited to relatively small data. Dynamic storage buffers +/// are particularly well-suited to storing like a Rust-vector (wgpu's "runtime-sized arrays") and have a +/// [`push`](crate::render_resource::DynamicStorageBuffer::push) method, unlike +/// [`StorageBuffer`](crate::render_resource::StorageBuffer). /// -/// Dynamic storage buffers must conform to std430 alignment/padding requirements, which this helper structure takes care of -/// enforcing. -/// -/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicStorageBuffer::write_buffer) queues -/// copying of the data from system RAM to VRAM. +/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicStorageBuffer::write_buffer) +/// queues copying of the data from system RAM to VRAM. Storage buffers must conform to [std430 alignment/padding requirements], which +/// is automatically enforced by this structure. If data does not need to be automatically padded or aligned, +/// consider using [`BufferVec`](crate::render_resource::BufferVec). +/// +/// [std430 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-storage pub struct DynamicStorageBuffer { values: Vec, scratch: DynamicStorageBufferWrapper>, diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index 28d56d84a4fa2..228a253565f81 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -8,20 +8,19 @@ use encase::{ }; use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsages}; -/// A helper structure for storing data that will be transferred to the GPU and made accessible -/// to shaders as a uniform buffer. +/// Stores data to be transferred to the GPU and made accessible to shaders as a uniform buffer. /// /// Uniform buffers are available to shaders on a read-only basis. Uniform buffers are commonly used to make available to shaders -/// parameters that are constant during shader execution. Uniform buffers are also best used for data that is relatively small -/// in size. For larger data, or data that must be made accessible to shaders on a read-write basis, consider -/// [`StorageBuffer`](crate::render_resource::StorageBuffer). +/// parameters that are constant during shader execution, and are best used for data that is relatively small in size. For +/// larger data, or data that must be made accessible to shaders on a read-write basis, consider +/// [`StorageBuffer`](crate::render_resource::StorageBuffer). /// -/// Uniform buffers must conform to [std140 alignment/padding requirements], which this helper structure takes care of enforcing. -/// Per the WGPU spec, uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. +/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::UniformBuffer::write_buffer) queues +/// copying of the data from system RAM to VRAM. Data in uniform buffers must follow [std140 alignment/padding requirements], +/// which is automatically enforced by this structure. Per the WGPU spec, uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. /// If this is required, consider [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer). /// -/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::UniformBuffer::write_buffer) queues -/// copying of the data from system RAM to VRAM. +/// If data does not need to be automatically padded or aligned, use [`BufferVec`](crate::render_resource::BufferVec). /// /// [std140 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-uniform pub struct UniformBuffer { @@ -97,17 +96,23 @@ impl UniformBuffer { } } -/// A helper structure for storing data that will be transferred to the GPU and made accessible -/// to shaders as a dynamic uniform buffer. +/// Stores data to be transferred to the GPU and made accessible to shaders as a dynamic uniform buffer. /// /// Dynamic uniform buffers are available to shaders on a read-only basis. Dynamic uniform buffers are commonly used to make -/// available to shaders runtime-sized arrays of parameters that are otherwise constant during shader execution. +/// available to shaders runtime-sized arrays of parameters that are otherwise constant during shader execution, and are best +/// suited to data that is relatively small in size. For larger data, or data that must be made +/// accessible to shaders on a read-write basis, consider [`StorageBuffer`](crate::render_resource::StorageBuffer) or +/// [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer). If it is not necessary to store runtime-sized arrays, +/// consider [`UniformBuffer`](crate::render_resource::UniformBuffer) instead. /// -/// Dynamic uniform buffers must conform to std140 alignment/padding requirements, which this helper structure takes care of -/// enforcing. -/// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicUniformBuffer::write_buffer) queues -/// copying of the data from system RAM to VRAM. +/// copying of the data from system RAM to VRAM. Data in uniform buffers must follow [std140 alignment/padding requirements], +/// which is automatically enforced by this structure. Per the WGPU spec, uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. +/// If this is required, consider [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer). +/// +/// If data does not need to be automatically padded or aligned, use [`BufferVec`](crate::render_resource::BufferVec). +/// +/// [std140 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-uniform pub struct DynamicUniformBuffer { values: Vec, scratch: DynamicUniformBufferWrapper>, From d275294a3e3596222254694d1e81f30677769207 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Fri, 8 Jul 2022 14:07:02 -0700 Subject: [PATCH 11/20] say 'dynamic storage buffer', instead of only storage buffer, in dynamic storage buffer docs --- .../src/render_resource/storage_buffer.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index 260416249ae31..abdbf59ab0351 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -98,19 +98,19 @@ impl StorageBuffer { } } -/// Stores data to be transferred to the GPU and made accessible to shaders as a storage buffer. +/// Stores data to be transferred to the GPU and made accessible to shaders as a dynamic storage buffer. /// -/// Storage buffers can be made available to shaders as some combination of read/write, unlike -/// [`UniformBuffer`](crate::render_resource::UniformBuffer) which is read-only. Furthermore, storage buffers +/// Dynamic storage buffers can be made available to shaders as some combination of read/write, unlike +/// [`UniformBuffer`](crate::render_resource::UniformBuffer) which is read-only. Furthermore, dynamic storage buffers /// can store much larger data than uniform buffers, which are best suited to relatively small data. Dynamic storage buffers /// are particularly well-suited to storing like a Rust-vector (wgpu's "runtime-sized arrays") and have a /// [`push`](crate::render_resource::DynamicStorageBuffer::push) method, unlike /// [`StorageBuffer`](crate::render_resource::StorageBuffer). /// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicStorageBuffer::write_buffer) -/// queues copying of the data from system RAM to VRAM. Storage buffers must conform to [std430 alignment/padding requirements], which -/// is automatically enforced by this structure. If data does not need to be automatically padded or aligned, -/// consider using [`BufferVec`](crate::render_resource::BufferVec). +/// queues copying of the data from system RAM to VRAM. Dynamic storage buffers must conform to +/// [std430 alignment/padding requirements], which is automatically enforced by this structure. If data does not need to +/// be automatically padded or aligned, consider using [`BufferVec`](crate::render_resource::BufferVec). /// /// [std430 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-storage pub struct DynamicStorageBuffer { From d34311f59fb84f5bd377ab84ef8a6f830a7101a8 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Mon, 11 Jul 2022 14:00:53 -0700 Subject: [PATCH 12/20] addressing suggestions by @superdump (robswain) --- .../src/render_resource/storage_buffer.rs | 13 ++++++++++--- .../src/render_resource/uniform_buffer.rs | 11 +++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index abdbf59ab0351..e7061dfda282d 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -10,7 +10,10 @@ use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsa /// /// Storage buffers can be made available to shaders as some combination of read/write, unlike /// [`UniformBuffer`](crate::render_resource::UniformBuffer) which is read-only. Furthermore, storage buffers -/// can store much larger data than uniform buffers, which are best suited to relatively small data. +/// can store much larger data than uniform buffers, which are best suited to relatively small data. Note however that +/// WebGL2 does not support storage buffers, so other alternatives to consider are vertex/instance buffers (see +/// [`BufferVec`](crate::render_resource::BufferVec)), or data textures ([`Texture`](crate::render_resource::Texture)), +/// depending on what is most appropriate for the use case. /// /// Storage buffers can store runtime-sized arrays, but only if they are the last field in a structure. To store a /// runtime-sized array of data, use [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) instead. @@ -105,11 +108,15 @@ impl StorageBuffer { /// can store much larger data than uniform buffers, which are best suited to relatively small data. Dynamic storage buffers /// are particularly well-suited to storing like a Rust-vector (wgpu's "runtime-sized arrays") and have a /// [`push`](crate::render_resource::DynamicStorageBuffer::push) method, unlike -/// [`StorageBuffer`](crate::render_resource::StorageBuffer). +/// [`StorageBuffer`](crate::render_resource::StorageBuffer). Note however that +/// WebGL2 does not support dynamic storage buffers, so other alternatives to consider are vertex/instance buffers (see +/// [`BufferVec`](crate::render_resource::BufferVec)), or data textures ([`Texture`](crate::render_resource::Texture)), +/// depending on what is most appropriate for the use case. /// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicStorageBuffer::write_buffer) /// queues copying of the data from system RAM to VRAM. Dynamic storage buffers must conform to -/// [std430 alignment/padding requirements], which is automatically enforced by this structure. If data does not need to +/// [std430 alignment/padding requirements]; whenever data is [`push`](crate::render_resource::DynamicStorageBuffer::push)ed +/// into this structure, it is automatically aligned to these requirements. If data does not need to /// be automatically padded or aligned, consider using [`BufferVec`](crate::render_resource::BufferVec). /// /// [std430 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-storage diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index 228a253565f81..b9b7bc1d5be33 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -13,7 +13,11 @@ use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsa /// Uniform buffers are available to shaders on a read-only basis. Uniform buffers are commonly used to make available to shaders /// parameters that are constant during shader execution, and are best used for data that is relatively small in size. For /// larger data, or data that must be made accessible to shaders on a read-write basis, consider -/// [`StorageBuffer`](crate::render_resource::StorageBuffer). +/// [`StorageBuffer`](crate::render_resource::StorageBuffer) or +/// [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer). Note however that +/// WebGL2 does not support storage buffers, so other alternatives to consider are vertex/instance buffers (see +/// [`BufferVec`](crate::render_resource::BufferVec)), or data textures ([`Texture`](crate::render_resource::Texture)), +/// depending on what is most appropriate for the use case. /// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::UniformBuffer::write_buffer) queues /// copying of the data from system RAM to VRAM. Data in uniform buffers must follow [std140 alignment/padding requirements], @@ -102,7 +106,10 @@ impl UniformBuffer { /// available to shaders runtime-sized arrays of parameters that are otherwise constant during shader execution, and are best /// suited to data that is relatively small in size. For larger data, or data that must be made /// accessible to shaders on a read-write basis, consider [`StorageBuffer`](crate::render_resource::StorageBuffer) or -/// [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer). If it is not necessary to store runtime-sized arrays, +/// [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer). Note however that +/// WebGL2 does not support storage buffers, so other alternatives to consider are vertex/instance buffers (see +/// [`BufferVec`](crate::render_resource::BufferVec)), or data textures ([`Texture`](crate::render_resource::Texture)), +/// depending on what is most appropriate for the use case. If it is not necessary to store runtime-sized arrays, /// consider [`UniformBuffer`](crate::render_resource::UniformBuffer) instead. /// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicUniformBuffer::write_buffer) queues From e77771e03003def22beb58c00dce7bbea69b369c Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 19 Jul 2022 18:38:01 -0700 Subject: [PATCH 13/20] Update crates/bevy_render/src/render_resource/uniform_buffer.rs Co-authored-by: Robert Swain --- crates/bevy_render/src/render_resource/uniform_buffer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index b9b7bc1d5be33..a37e5f01c2a1b 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -104,7 +104,7 @@ impl UniformBuffer { /// /// Dynamic uniform buffers are available to shaders on a read-only basis. Dynamic uniform buffers are commonly used to make /// available to shaders runtime-sized arrays of parameters that are otherwise constant during shader execution, and are best -/// suited to data that is relatively small in size. For larger data, or data that must be made +/// suited to data that is relatively small in size as they are only guaranteed to support up to 16kB per binding. For larger data, or data that must be made /// accessible to shaders on a read-write basis, consider [`StorageBuffer`](crate::render_resource::StorageBuffer) or /// [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer). Note however that /// WebGL2 does not support storage buffers, so other alternatives to consider are vertex/instance buffers (see From 8cb0f0437d2c7dcd2ac4e95946a68f4c1128aa17 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 19 Jul 2022 18:38:18 -0700 Subject: [PATCH 14/20] Update crates/bevy_render/src/render_resource/uniform_buffer.rs Co-authored-by: Robert Swain --- crates/bevy_render/src/render_resource/uniform_buffer.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index a37e5f01c2a1b..47ecddae9a40b 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -22,7 +22,8 @@ use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsa /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::UniformBuffer::write_buffer) queues /// copying of the data from system RAM to VRAM. Data in uniform buffers must follow [std140 alignment/padding requirements], /// which is automatically enforced by this structure. Per the WGPU spec, uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. -/// If this is required, consider [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer). +/// If this is required within one draw command, consider `StorageBuffer`](crate::render_resource::StorageBuffer). +/// If this is required but could be across multiple draw commands, consider [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer). /// /// If data does not need to be automatically padded or aligned, use [`BufferVec`](crate::render_resource::BufferVec). /// From d4c1761416076f873d5d1c5b6d8225fc08d69fe9 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 19 Jul 2022 18:40:28 -0700 Subject: [PATCH 15/20] Update crates/bevy_render/src/render_resource/storage_buffer.rs Co-authored-by: Robert Swain --- crates/bevy_render/src/render_resource/storage_buffer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index e7061dfda282d..c7a099a0b7bf6 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -105,8 +105,8 @@ impl StorageBuffer { /// /// Dynamic storage buffers can be made available to shaders as some combination of read/write, unlike /// [`UniformBuffer`](crate::render_resource::UniformBuffer) which is read-only. Furthermore, dynamic storage buffers -/// can store much larger data than uniform buffers, which are best suited to relatively small data. Dynamic storage buffers -/// are particularly well-suited to storing like a Rust-vector (wgpu's "runtime-sized arrays") and have a +/// can store much larger data than uniform buffers, which are only guaranteed to be up to 16kB per binding. Dynamic storage buffers +/// support multiple separate bindings at dynamic byte offsets and so have a /// [`push`](crate::render_resource::DynamicStorageBuffer::push) method, unlike /// [`StorageBuffer`](crate::render_resource::StorageBuffer). Note however that /// WebGL2 does not support dynamic storage buffers, so other alternatives to consider are vertex/instance buffers (see From a109dadaa21fba05cc5127399c9268194bed8016 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 19 Jul 2022 18:41:05 -0700 Subject: [PATCH 16/20] Update crates/bevy_render/src/render_resource/storage_buffer.rs Co-authored-by: Robert Swain --- crates/bevy_render/src/render_resource/storage_buffer.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index c7a099a0b7bf6..bc8b2232dcf02 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -114,9 +114,9 @@ impl StorageBuffer { /// depending on what is most appropriate for the use case. /// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicStorageBuffer::write_buffer) -/// queues copying of the data from system RAM to VRAM. Dynamic storage buffers must conform to -/// [std430 alignment/padding requirements]; whenever data is [`push`](crate::render_resource::DynamicStorageBuffer::push)ed -/// into this structure, it is automatically aligned to these requirements. If data does not need to +/// queues copying of the data from system RAM to VRAM. The data within a storage buffer binding must conform to +/// [std430 alignment/padding requirements]. `DynamicStorageBuffer` takes care of serialising the inner type to conform to these requirements. Each item [`push`](crate::render_resource::DynamicStorageBuffer::push)ed +/// into this structure will additionally be aligned to meet dynamic offset alignment requirements. If data does not need to /// be automatically padded or aligned, consider using [`BufferVec`](crate::render_resource::BufferVec). /// /// [std430 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-storage From d5bf7967cfd9b36b4be8f4eb12faf8cafe347cf5 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 19 Jul 2022 18:41:17 -0700 Subject: [PATCH 17/20] Update crates/bevy_render/src/render_resource/storage_buffer.rs Co-authored-by: Robert Swain --- crates/bevy_render/src/render_resource/storage_buffer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index bc8b2232dcf02..8f9b0aff9d53d 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -10,7 +10,7 @@ use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsa /// /// Storage buffers can be made available to shaders as some combination of read/write, unlike /// [`UniformBuffer`](crate::render_resource::UniformBuffer) which is read-only. Furthermore, storage buffers -/// can store much larger data than uniform buffers, which are best suited to relatively small data. Note however that +/// can store much larger data than uniform buffers, which are only guaranteed to be up to 16kB per binding. Note however that /// WebGL2 does not support storage buffers, so other alternatives to consider are vertex/instance buffers (see /// [`BufferVec`](crate::render_resource::BufferVec)), or data textures ([`Texture`](crate::render_resource::Texture)), /// depending on what is most appropriate for the use case. From 4ff1a553a84c733664a32fcb1d28707b8750f551 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 19 Jul 2022 18:41:28 -0700 Subject: [PATCH 18/20] Update crates/bevy_render/src/render_resource/uniform_buffer.rs Co-authored-by: Robert Swain --- crates/bevy_render/src/render_resource/uniform_buffer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index 47ecddae9a40b..e3b8523338d52 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -11,7 +11,7 @@ use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsa /// Stores data to be transferred to the GPU and made accessible to shaders as a uniform buffer. /// /// Uniform buffers are available to shaders on a read-only basis. Uniform buffers are commonly used to make available to shaders -/// parameters that are constant during shader execution, and are best used for data that is relatively small in size. For +/// parameters that are constant during shader execution, and are best used for data that is relatively small in size as they are only guaranteed to support up to 16kB per binding. For /// larger data, or data that must be made accessible to shaders on a read-write basis, consider /// [`StorageBuffer`](crate::render_resource::StorageBuffer) or /// [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer). Note however that From fb5001ac6561cd48d1a955368fb0639f23ed78df Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Tue, 19 Jul 2022 19:10:13 -0700 Subject: [PATCH 19/20] strip down docs a bit, to avoid repetition, and provide a cohesive set of links to other data storage options at end of docstring fro each particular data storage option --- .../src/render_resource/buffer_vec.rs | 22 ++++----- .../src/render_resource/storage_buffer.rs | 47 ++++++++++--------- .../src/render_resource/uniform_buffer.rs | 40 ++++++++-------- 3 files changed, 54 insertions(+), 55 deletions(-) diff --git a/crates/bevy_render/src/render_resource/buffer_vec.rs b/crates/bevy_render/src/render_resource/buffer_vec.rs index 80b88c7ac8197..7ae137001ede4 100644 --- a/crates/bevy_render/src/render_resource/buffer_vec.rs +++ b/crates/bevy_render/src/render_resource/buffer_vec.rs @@ -10,25 +10,23 @@ use wgpu::BufferUsages; /// for use by the GPU. /// /// "Properly formatted" means that item data already meets the alignment and padding -/// requirements for how it will be used on the GPU. +/// requirements for how it will be used on the GPU. The item type must implement [`Pod`] +/// for its data representation to be directly copyable. /// /// Index, vertex, and instance-rate vertex buffers have no alignment nor padding requirements and -/// so this helper type is a good choice for them. Uniform buffers must adhere to std140 -/// alignment/padding requirements, and storage buffers to std430. There are helper types for such -/// buffers: -/// - Uniform buffers -/// - Plain: [`UniformBuffer`](crate::render_resource::UniformBuffer) -/// - Dynamic offsets: [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer) -/// - Storage buffers -/// - Plain: [`StorageBuffer`](crate::render_resource::StorageBuffer) -/// - Dynamic offsets: [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) -/// -/// The item type must implement [`Pod`] for its data representation to be directly copyable. +/// so this helper type is a good choice for them. /// /// The contained data is stored in system RAM. Calling [`reserve`](crate::render_resource::BufferVec::reserve) /// allocates VRAM from the [`RenderDevice`](crate::renderer::RenderDevice). /// [`write_buffer`](crate::render_resource::BufferVec::write_buffer) queues copying of the data /// from system RAM to VRAM. +/// +/// Other options for storing GPU-accessible data are: +/// * [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) +/// * [`UniformBuffer`](crate::render_resource::UniformBuffer) +/// * [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer) +/// * [`BufferVec`](crate::render_resource::BufferVec) +/// * [`Texture`](crate::render_resource::Texture) pub struct BufferVec { values: Vec, buffer: Option, diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index 8f9b0aff9d53d..ff3d3cb5a70d6 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -8,20 +8,21 @@ use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsa /// Stores data to be transferred to the GPU and made accessible to shaders as a storage buffer. /// -/// Storage buffers can be made available to shaders as some combination of read/write, unlike -/// [`UniformBuffer`](crate::render_resource::UniformBuffer) which is read-only. Furthermore, storage buffers -/// can store much larger data than uniform buffers, which are only guaranteed to be up to 16kB per binding. Note however that -/// WebGL2 does not support storage buffers, so other alternatives to consider are vertex/instance buffers (see -/// [`BufferVec`](crate::render_resource::BufferVec)), or data textures ([`Texture`](crate::render_resource::Texture)), -/// depending on what is most appropriate for the use case. +/// Storage buffers can be made available to shaders in some combination of read/write mode, and can store large amounts of data. +/// Note however that WebGL2 does not support storage buffers, so consider alternative options in this case. /// -/// Storage buffers can store runtime-sized arrays, but only if they are the last field in a structure. To store a -/// runtime-sized array of data, use [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) instead. +/// Storage buffers can store runtime-sized arrays, but only if they are the last field in a structure. /// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::StorageBuffer::write_buffer) queues /// copying of the data from system RAM to VRAM. Storage buffers must conform to [std430 alignment/padding requirements], which -/// is automatically enforced by this structure. If data does not need to be automatically padded or aligned, -/// consider using [`BufferVec`](crate::render_resource::BufferVec). +/// is automatically enforced by this structure. +/// +/// Other options for storing GPU-accessible data are: +/// * [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) +/// * [`UniformBuffer`](crate::render_resource::UniformBuffer) +/// * [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer) +/// * [`BufferVec`](crate::render_resource::BufferVec) +/// * [`Texture`](crate::render_resource::Texture) /// /// [std430 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-storage pub struct StorageBuffer { @@ -103,21 +104,23 @@ impl StorageBuffer { /// Stores data to be transferred to the GPU and made accessible to shaders as a dynamic storage buffer. /// -/// Dynamic storage buffers can be made available to shaders as some combination of read/write, unlike -/// [`UniformBuffer`](crate::render_resource::UniformBuffer) which is read-only. Furthermore, dynamic storage buffers -/// can store much larger data than uniform buffers, which are only guaranteed to be up to 16kB per binding. Dynamic storage buffers -/// support multiple separate bindings at dynamic byte offsets and so have a -/// [`push`](crate::render_resource::DynamicStorageBuffer::push) method, unlike -/// [`StorageBuffer`](crate::render_resource::StorageBuffer). Note however that -/// WebGL2 does not support dynamic storage buffers, so other alternatives to consider are vertex/instance buffers (see -/// [`BufferVec`](crate::render_resource::BufferVec)), or data textures ([`Texture`](crate::render_resource::Texture)), -/// depending on what is most appropriate for the use case. +/// Dynamic storage buffers can be made available to shaders in some combination of read/write mode, and can store large amounts +/// of data. Note however that WebGL2 does not support storage buffers, so consider alternative options in this case. Dynamic +/// storage buffers support multiple separate bindings at dynamic byte offsets and so have a +/// [`push`](crate::render_resource::DynamicStorageBuffer::push) method. /// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicStorageBuffer::write_buffer) /// queues copying of the data from system RAM to VRAM. The data within a storage buffer binding must conform to -/// [std430 alignment/padding requirements]. `DynamicStorageBuffer` takes care of serialising the inner type to conform to these requirements. Each item [`push`](crate::render_resource::DynamicStorageBuffer::push)ed -/// into this structure will additionally be aligned to meet dynamic offset alignment requirements. If data does not need to -/// be automatically padded or aligned, consider using [`BufferVec`](crate::render_resource::BufferVec). +/// [std430 alignment/padding requirements]. `DynamicStorageBuffer` takes care of serialising the inner type to conform to +/// these requirements. Each item [`push`](crate::render_resource::DynamicStorageBuffer::push)ed into this structure +/// will additionally be aligned to meet dynamic offset alignment requirements. +/// +/// Other options for storing GPU-accessible data are: +/// * [`StorageBuffer`](crate::render_resource::StorageBuffer) +/// * [`UniformBuffer`](crate::render_resource::UniformBuffer) +/// * [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer) +/// * [`BufferVec`](crate::render_resource::BufferVec) +/// * [`Texture`](crate::render_resource::Texture) /// /// [std430 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-storage pub struct DynamicStorageBuffer { diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index e3b8523338d52..c56294a2225a9 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -11,21 +11,20 @@ use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsa /// Stores data to be transferred to the GPU and made accessible to shaders as a uniform buffer. /// /// Uniform buffers are available to shaders on a read-only basis. Uniform buffers are commonly used to make available to shaders -/// parameters that are constant during shader execution, and are best used for data that is relatively small in size as they are only guaranteed to support up to 16kB per binding. For -/// larger data, or data that must be made accessible to shaders on a read-write basis, consider -/// [`StorageBuffer`](crate::render_resource::StorageBuffer) or -/// [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer). Note however that -/// WebGL2 does not support storage buffers, so other alternatives to consider are vertex/instance buffers (see -/// [`BufferVec`](crate::render_resource::BufferVec)), or data textures ([`Texture`](crate::render_resource::Texture)), -/// depending on what is most appropriate for the use case. +/// parameters that are constant during shader execution, and are best used for data that is relatively small in size as they are +/// only guaranteed to support up to 16kB per binding. /// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::UniformBuffer::write_buffer) queues /// copying of the data from system RAM to VRAM. Data in uniform buffers must follow [std140 alignment/padding requirements], -/// which is automatically enforced by this structure. Per the WGPU spec, uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. -/// If this is required within one draw command, consider `StorageBuffer`](crate::render_resource::StorageBuffer). -/// If this is required but could be across multiple draw commands, consider [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer). +/// which is automatically enforced by this structure. Per the WGPU spec, uniform buffers cannot store runtime-sized array +/// (vectors), or structures with fields that are vectors. /// -/// If data does not need to be automatically padded or aligned, use [`BufferVec`](crate::render_resource::BufferVec). +/// Other options for storing GPU-accessible data are: +/// * [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer) +/// * [`StorageBuffer`](crate::render_resource::StorageBuffer) +/// * [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) +/// * [`BufferVec`](crate::render_resource::BufferVec) +/// * [`Texture`](crate::render_resource::Texture) /// /// [std140 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-uniform pub struct UniformBuffer { @@ -105,20 +104,19 @@ impl UniformBuffer { /// /// Dynamic uniform buffers are available to shaders on a read-only basis. Dynamic uniform buffers are commonly used to make /// available to shaders runtime-sized arrays of parameters that are otherwise constant during shader execution, and are best -/// suited to data that is relatively small in size as they are only guaranteed to support up to 16kB per binding. For larger data, or data that must be made -/// accessible to shaders on a read-write basis, consider [`StorageBuffer`](crate::render_resource::StorageBuffer) or -/// [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer). Note however that -/// WebGL2 does not support storage buffers, so other alternatives to consider are vertex/instance buffers (see -/// [`BufferVec`](crate::render_resource::BufferVec)), or data textures ([`Texture`](crate::render_resource::Texture)), -/// depending on what is most appropriate for the use case. If it is not necessary to store runtime-sized arrays, -/// consider [`UniformBuffer`](crate::render_resource::UniformBuffer) instead. +/// suited to data that is relatively small in size as they are only guaranteed to support up to 16kB per binding. /// /// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicUniformBuffer::write_buffer) queues /// copying of the data from system RAM to VRAM. Data in uniform buffers must follow [std140 alignment/padding requirements], -/// which is automatically enforced by this structure. Per the WGPU spec, uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. -/// If this is required, consider [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer). +/// which is automatically enforced by this structure. Per the WGPU spec, uniform buffers cannot store runtime-sized array +/// (vectors), or structures with fields that are vectors. /// -/// If data does not need to be automatically padded or aligned, use [`BufferVec`](crate::render_resource::BufferVec). +/// Other options for storing GPU-accessible data are: +/// * [`StorageBuffer`](crate::render_resource::StorageBuffer) +/// * [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) +/// * [`UniformBuffer`](crate::render_resource::UniformBuffer) +/// * [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer) +/// * [`Texture`](crate::render_resource::Texture) /// /// [std140 alignment/padding requirements]: https://www.w3.org/TR/WGSL/#address-spaces-uniform pub struct DynamicUniformBuffer { From 15f70338202b682307b327da882797de1af5da69 Mon Sep 17 00:00:00 2001 From: Brian Merchant Date: Wed, 20 Jul 2022 09:58:53 -0700 Subject: [PATCH 20/20] allow doc_markdown clippy lint so that we can write WebGL2 without backticks --- crates/bevy_render/src/render_resource/storage_buffer.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index ff3d3cb5a70d6..4579cd2d06a43 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -1,3 +1,5 @@ +#![allow(clippy::doc_markdown)] + use super::Buffer; use crate::renderer::{RenderDevice, RenderQueue}; use encase::{