From 2089a28717192d588cb82796dfb60914ef057dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristoffer=20S=C3=B8holm?= Date: Fri, 3 May 2024 13:39:21 +0200 Subject: [PATCH] Add BufferVec, an higher-performance alternative to StorageBuffer, and make GpuArrayBuffer use it. (#13199) This is an adoption of #12670 plus some documentation fixes. See that PR for more details. --- ## Changelog * Renamed `BufferVec` to `RawBufferVec` and added a new `BufferVec` type. ## Migration Guide `BufferVec` has been renamed to `RawBufferVec` and a new similar type has taken the `BufferVec` name. --------- Co-authored-by: Patrick Walton Co-authored-by: Alice Cecile Co-authored-by: IceSentry --- crates/bevy_pbr/src/render/mesh.rs | 6 +- crates/bevy_pbr/src/render/morph.rs | 12 +- crates/bevy_pbr/src/render/skin.rs | 6 +- .../src/batching/gpu_preprocessing.rs | 10 +- .../src/render_resource/buffer_vec.rs | 185 ++++++++++++++++-- .../src/render_resource/gpu_array_buffer.rs | 26 +-- .../src/render_resource/storage_buffer.rs | 4 + .../src/render_resource/uniform_buffer.rs | 2 + crates/bevy_sprite/src/render/mod.rs | 8 +- crates/bevy_ui/src/render/mod.rs | 8 +- .../src/render/ui_material_pipeline.rs | 4 +- 11 files changed, 220 insertions(+), 51 deletions(-) diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 9433ac46c1..199f6752cf 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -331,7 +331,7 @@ pub struct MeshCullingData { /// To avoid wasting CPU time in the CPU culling case, this buffer will be empty /// if GPU culling isn't in use. #[derive(Resource, Deref, DerefMut)] -pub struct MeshCullingDataBuffer(BufferVec); +pub struct MeshCullingDataBuffer(RawBufferVec); impl MeshUniform { pub fn new(mesh_transforms: &MeshTransforms, maybe_lightmap_uv_rect: Option) -> Self { @@ -685,7 +685,7 @@ impl RenderMeshInstanceGpuBuilder { self, entity: Entity, render_mesh_instances: &mut EntityHashMap, - current_input_buffer: &mut BufferVec, + current_input_buffer: &mut RawBufferVec, ) -> usize { // Push the mesh input uniform. let current_uniform_index = current_input_buffer.push(MeshInputUniform { @@ -742,7 +742,7 @@ impl MeshCullingData { impl Default for MeshCullingDataBuffer { #[inline] fn default() -> Self { - Self(BufferVec::new(BufferUsages::STORAGE)) + Self(RawBufferVec::new(BufferUsages::STORAGE)) } } diff --git a/crates/bevy_pbr/src/render/morph.rs b/crates/bevy_pbr/src/render/morph.rs index b53cf62f2f..692af99621 100644 --- a/crates/bevy_pbr/src/render/morph.rs +++ b/crates/bevy_pbr/src/render/morph.rs @@ -6,7 +6,7 @@ use bevy_ecs::prelude::*; use bevy_render::{ batching::NoAutomaticBatching, mesh::morph::{MeshMorphWeights, MAX_MORPH_WEIGHTS}, - render_resource::{BufferUsages, BufferVec}, + render_resource::{BufferUsages, RawBufferVec}, renderer::{RenderDevice, RenderQueue}, view::ViewVisibility, Extract, @@ -23,13 +23,13 @@ pub struct MorphIndices(EntityHashMap); #[derive(Resource)] pub struct MorphUniform { - pub buffer: BufferVec, + pub buffer: RawBufferVec, } impl Default for MorphUniform { fn default() -> Self { Self { - buffer: BufferVec::new(BufferUsages::UNIFORM), + buffer: RawBufferVec::new(BufferUsages::UNIFORM), } } } @@ -53,14 +53,14 @@ const fn can_align(step: usize, target: usize) -> bool { const WGPU_MIN_ALIGN: usize = 256; -/// Align a [`BufferVec`] to `N` bytes by padding the end with `T::default()` values. -fn add_to_alignment(buffer: &mut BufferVec) { +/// Align a [`RawBufferVec`] to `N` bytes by padding the end with `T::default()` values. +fn add_to_alignment(buffer: &mut RawBufferVec) { let n = WGPU_MIN_ALIGN; let t_size = mem::size_of::(); if !can_align(n, t_size) { // This panic is stripped at compile time, due to n, t_size and can_align being const panic!( - "BufferVec should contain only types with a size multiple or divisible by {n}, \ + "RawBufferVec should contain only types with a size multiple or divisible by {n}, \ {} has a size of {t_size}, which is neither multiple or divisible by {n}", std::any::type_name::() ); diff --git a/crates/bevy_pbr/src/render/skin.rs b/crates/bevy_pbr/src/render/skin.rs index 6a725b546c..5d3e2ba2c9 100644 --- a/crates/bevy_pbr/src/render/skin.rs +++ b/crates/bevy_pbr/src/render/skin.rs @@ -6,7 +6,7 @@ use bevy_math::Mat4; use bevy_render::{ batching::NoAutomaticBatching, mesh::skinning::{SkinnedMesh, SkinnedMeshInverseBindposes}, - render_resource::{BufferUsages, BufferVec}, + render_resource::{BufferUsages, RawBufferVec}, renderer::{RenderDevice, RenderQueue}, view::ViewVisibility, Extract, @@ -36,13 +36,13 @@ pub struct SkinIndices(EntityHashMap); // Notes on implementation: see comment on top of the `extract_skins` system. #[derive(Resource)] pub struct SkinUniform { - pub buffer: BufferVec, + pub buffer: RawBufferVec, } impl Default for SkinUniform { fn default() -> Self { Self { - buffer: BufferVec::new(BufferUsages::UNIFORM), + buffer: RawBufferVec::new(BufferUsages::UNIFORM), } } } diff --git a/crates/bevy_render/src/batching/gpu_preprocessing.rs b/crates/bevy_render/src/batching/gpu_preprocessing.rs index bcbcf8b973..2430d6a2ab 100644 --- a/crates/bevy_render/src/batching/gpu_preprocessing.rs +++ b/crates/bevy_render/src/batching/gpu_preprocessing.rs @@ -21,7 +21,7 @@ use crate::{ BinnedPhaseItem, BinnedRenderPhase, BinnedRenderPhaseBatch, CachedRenderPipelinePhaseItem, PhaseItemExtraIndex, SortedPhaseItem, SortedRenderPhase, UnbatchableBinnedEntityIndices, }, - render_resource::{BufferVec, GpuArrayBufferable, UninitBufferVec}, + render_resource::{BufferVec, GpuArrayBufferable, RawBufferVec, UninitBufferVec}, renderer::{RenderAdapter, RenderDevice, RenderQueue}, view::{GpuCulling, ViewTarget}, Render, RenderApp, RenderSet, @@ -101,7 +101,7 @@ where /// The uniform data inputs for the current frame. /// /// These are uploaded during the extraction phase. - pub current_input_buffer: BufferVec, + pub current_input_buffer: RawBufferVec, /// The uniform data inputs for the previous frame. /// @@ -110,7 +110,7 @@ where /// can spawn or despawn between frames. Instead, each current buffer /// data input uniform is expected to contain the index of the /// corresponding buffer data input uniform in this list. - pub previous_input_buffer: BufferVec, + pub previous_input_buffer: RawBufferVec, } /// The buffer of GPU preprocessing work items for a single view. @@ -247,8 +247,8 @@ where BatchedInstanceBuffers { data_buffer: UninitBufferVec::new(BufferUsages::STORAGE), work_item_buffers: EntityHashMap::default(), - current_input_buffer: BufferVec::new(BufferUsages::STORAGE), - previous_input_buffer: BufferVec::new(BufferUsages::STORAGE), + current_input_buffer: RawBufferVec::new(BufferUsages::STORAGE), + previous_input_buffer: RawBufferVec::new(BufferUsages::STORAGE), } } diff --git a/crates/bevy_render/src/render_resource/buffer_vec.rs b/crates/bevy_render/src/render_resource/buffer_vec.rs index 7ff60c1f44..15874e4743 100644 --- a/crates/bevy_render/src/render_resource/buffer_vec.rs +++ b/crates/bevy_render/src/render_resource/buffer_vec.rs @@ -1,11 +1,15 @@ -use std::marker::PhantomData; +use std::{iter, marker::PhantomData}; use crate::{ render_resource::Buffer, renderer::{RenderDevice, RenderQueue}, }; use bytemuck::{must_cast_slice, NoUninit}; -use wgpu::BufferUsages; +use encase::{ + internal::{WriteInto, Writer}, + ShaderType, +}; +use wgpu::{BufferAddress, BufferUsages}; use super::GpuArrayBufferable; @@ -19,9 +23,9 @@ use super::GpuArrayBufferable; /// Index, vertex, and instance-rate vertex buffers have no alignment nor padding requirements and /// so this helper type is a good choice for them. /// -/// The contained data is stored in system RAM. Calling [`reserve`](BufferVec::reserve) +/// The contained data is stored in system RAM. Calling [`reserve`](RawBufferVec::reserve) /// allocates VRAM from the [`RenderDevice`]. -/// [`write_buffer`](BufferVec::write_buffer) queues copying of the data +/// [`write_buffer`](RawBufferVec::write_buffer) queues copying of the data /// from system RAM to VRAM. /// /// Other options for storing GPU-accessible data are: @@ -32,7 +36,7 @@ use super::GpuArrayBufferable; /// * [`GpuArrayBuffer`](crate::render_resource::GpuArrayBuffer) /// * [`BufferVec`] /// * [`Texture`](crate::render_resource::Texture) -pub struct BufferVec { +pub struct RawBufferVec { values: Vec, buffer: Option, capacity: usize, @@ -42,7 +46,7 @@ pub struct BufferVec { label_changed: bool, } -impl BufferVec { +impl RawBufferVec { pub const fn new(buffer_usage: BufferUsages) -> Self { Self { values: Vec::new(), @@ -81,7 +85,7 @@ impl BufferVec { index } - pub fn append(&mut self, other: &mut BufferVec) { + pub fn append(&mut self, other: &mut RawBufferVec) { self.values.append(&mut other.values); } @@ -108,7 +112,7 @@ impl BufferVec { /// once it is done using them (typically 1-2 frames). /// /// In addition to any [`BufferUsages`] provided when - /// the `BufferVec` was created, the buffer on the [`RenderDevice`] + /// the `RawBufferVec` was created, the buffer on the [`RenderDevice`] /// is marked as [`BufferUsages::COPY_DST`](BufferUsages). pub fn reserve(&mut self, capacity: usize, device: &RenderDevice) { if capacity > self.capacity || self.label_changed { @@ -116,7 +120,7 @@ impl BufferVec { let size = self.item_size * capacity; self.buffer = Some(device.create_buffer(&wgpu::BufferDescriptor { label: self.label.as_deref(), - size: size as wgpu::BufferAddress, + size: size as BufferAddress, usage: BufferUsages::COPY_DST | self.buffer_usage, mapped_at_creation: false, })); @@ -127,7 +131,7 @@ impl BufferVec { /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`] /// and the provided [`RenderQueue`]. /// - /// Before queuing the write, a [`reserve`](BufferVec::reserve) operation + /// Before queuing the write, a [`reserve`](RawBufferVec::reserve) operation /// is executed. pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { if self.values.is_empty() { @@ -158,20 +162,177 @@ impl BufferVec { } } -impl Extend for BufferVec { +impl Extend for RawBufferVec { #[inline] fn extend>(&mut self, iter: I) { self.values.extend(iter); } } +/// Like [`RawBufferVec`], but doesn't require that the data type `T` be +/// [`NoUninit`]. +/// +/// This is a high-performance data structure that you should use whenever +/// possible if your data is more complex than is suitable for [`RawBufferVec`]. +/// The [`ShaderType`] trait from the `encase` library is used to ensure that +/// the data is correctly aligned for use by the GPU. +/// +/// For performance reasons, unlike [`RawBufferVec`], this type doesn't allow +/// CPU access to the data after it's been added via [`BufferVec::push`]. If you +/// need CPU access to the data, consider another type, such as +/// [`StorageBuffer`]. +pub struct BufferVec +where + T: ShaderType + WriteInto, +{ + data: Vec, + buffer: Option, + capacity: usize, + buffer_usage: BufferUsages, + label: Option, + label_changed: bool, + phantom: PhantomData, +} + +impl BufferVec +where + T: ShaderType + WriteInto, +{ + /// Creates a new [`BufferVec`] with the given [`BufferUsages`]. + pub const fn new(buffer_usage: BufferUsages) -> Self { + Self { + data: vec![], + buffer: None, + capacity: 0, + buffer_usage, + label: None, + label_changed: false, + phantom: PhantomData, + } + } + + /// Returns a handle to the buffer, if the data has been uploaded. + #[inline] + pub fn buffer(&self) -> Option<&Buffer> { + self.buffer.as_ref() + } + + /// Returns the amount of space that the GPU will use before reallocating. + #[inline] + pub fn capacity(&self) -> usize { + self.capacity + } + + /// Returns the number of items that have been pushed to this buffer. + #[inline] + pub fn len(&self) -> usize { + self.data.len() / u64::from(T::min_size()) as usize + } + + /// Returns true if the buffer is empty. + #[inline] + pub fn is_empty(&self) -> bool { + self.data.is_empty() + } + + /// Adds a new value and returns its index. + pub fn push(&mut self, value: T) -> usize { + let element_size = u64::from(T::min_size()) as usize; + let offset = self.data.len(); + + // TODO: Consider using unsafe code to push uninitialized, to prevent + // the zeroing. It shows up in profiles. + self.data.extend(iter::repeat(0).take(element_size)); + + // Take a slice of the new data for `write_into` to use. This is + // important: it hoists the bounds check up here so that the compiler + // can eliminate all the bounds checks that `write_into` will emit. + let mut dest = &mut self.data[offset..(offset + element_size)]; + value.write_into(&mut Writer::new(&value, &mut dest, 0).unwrap()); + + offset / u64::from(T::min_size()) as usize + } + + /// Changes the debugging label of the buffer. + /// + /// The next time the buffer is updated (via [`reserve`]), Bevy will inform + /// the driver of the new label. + 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; + } + + /// Returns the label + pub fn get_label(&self) -> Option<&str> { + self.label.as_deref() + } + + /// Creates a [`Buffer`] on the [`RenderDevice`] with size + /// at least `std::mem::size_of::() * capacity`, unless such a buffer already exists. + /// + /// If a [`Buffer`] exists, but is too small, references to it will be discarded, + /// and a new [`Buffer`] will be created. Any previously created [`Buffer`]s + /// that are no longer referenced will be deleted by the [`RenderDevice`] + /// once it is done using them (typically 1-2 frames). + /// + /// In addition to any [`BufferUsages`] provided when + /// the `BufferVec` was created, the buffer on the [`RenderDevice`] + /// is marked as [`BufferUsages::COPY_DST`](BufferUsages). + pub fn reserve(&mut self, capacity: usize, device: &RenderDevice) { + if capacity <= self.capacity && !self.label_changed { + return; + } + + self.capacity = capacity; + let size = u64::from(T::min_size()) as usize * capacity; + self.buffer = Some(device.create_buffer(&wgpu::BufferDescriptor { + label: self.label.as_deref(), + size: size as BufferAddress, + usage: BufferUsages::COPY_DST | self.buffer_usage, + mapped_at_creation: false, + })); + self.label_changed = false; + } + + /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`] + /// and the provided [`RenderQueue`]. + /// + /// Before queuing the write, a [`reserve`](BufferVec::reserve) operation is + /// executed. + pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) { + if self.data.is_empty() { + return; + } + + self.reserve(self.data.len() / u64::from(T::min_size()) as usize, device); + + let Some(buffer) = &self.buffer else { return }; + queue.write_buffer(buffer, 0, &self.data); + } + + /// Reduces the length of the buffer. + pub fn truncate(&mut self, len: usize) { + self.data.truncate(u64::from(T::min_size()) as usize * len); + } + + /// Removes all elements from the buffer. + pub fn clear(&mut self) { + self.data.clear(); + } +} + /// Like a [`BufferVec`], but only reserves space on the GPU for elements /// instead of initializing them CPU-side. /// /// This type is useful when you're accumulating "output slots" for a GPU /// compute shader to write into. /// -/// The type `T` need not be [`NoUninit`], unlike [`BufferVec`]; it only has to +/// The type `T` need not be [`NoUninit`], unlike [`RawBufferVec`]; it only has to /// be [`GpuArrayBufferable`]. pub struct UninitBufferVec where diff --git a/crates/bevy_render/src/render_resource/gpu_array_buffer.rs b/crates/bevy_render/src/render_resource/gpu_array_buffer.rs index 60d8cc68e4..9765cfc627 100644 --- a/crates/bevy_render/src/render_resource/gpu_array_buffer.rs +++ b/crates/bevy_render/src/render_resource/gpu_array_buffer.rs @@ -1,6 +1,6 @@ use super::{ binding_types::{storage_buffer_read_only, uniform_buffer_sized}, - BindGroupLayoutEntryBuilder, StorageBuffer, + BindGroupLayoutEntryBuilder, BufferVec, }; use crate::{ render_resource::batched_uniform_buffer::BatchedUniformBuffer, @@ -10,7 +10,7 @@ use bevy_ecs::{prelude::Component, system::Resource}; use encase::{private::WriteInto, ShaderSize, ShaderType}; use nonmax::NonMaxU32; use std::marker::PhantomData; -use wgpu::BindingResource; +use wgpu::{BindingResource, BufferUsages}; /// Trait for types able to go in a [`GpuArrayBuffer`]. pub trait GpuArrayBufferable: ShaderType + ShaderSize + WriteInto + Clone {} @@ -18,21 +18,23 @@ impl GpuArrayBufferable for T {} /// Stores an array of elements to be transferred to the GPU and made accessible to shaders as a read-only array. /// -/// On platforms that support storage buffers, this is equivalent to [`StorageBuffer>`]. -/// Otherwise, this falls back to a dynamic offset uniform buffer with the largest -/// array of T that fits within a uniform buffer binding (within reasonable limits). +/// On platforms that support storage buffers, this is equivalent to +/// [`BufferVec`]. Otherwise, this falls back to a dynamic offset +/// uniform buffer with the largest array of T that fits within a uniform buffer +/// binding (within reasonable limits). /// /// Other options for storing GPU-accessible data are: /// * [`StorageBuffer`] /// * [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) /// * [`UniformBuffer`](crate::render_resource::UniformBuffer) /// * [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer) +/// * [`RawBufferVec`](crate::render_resource::RawBufferVec) /// * [`BufferVec`](crate::render_resource::BufferVec) /// * [`Texture`](crate::render_resource::Texture) #[derive(Resource)] pub enum GpuArrayBuffer { Uniform(BatchedUniformBuffer), - Storage(StorageBuffer>), + Storage(BufferVec), } impl GpuArrayBuffer { @@ -41,14 +43,14 @@ impl GpuArrayBuffer { if limits.max_storage_buffers_per_shader_stage == 0 { GpuArrayBuffer::Uniform(BatchedUniformBuffer::new(&limits)) } else { - GpuArrayBuffer::Storage(StorageBuffer::default()) + GpuArrayBuffer::Storage(BufferVec::new(BufferUsages::STORAGE)) } } pub fn clear(&mut self) { match self { GpuArrayBuffer::Uniform(buffer) => buffer.clear(), - GpuArrayBuffer::Storage(buffer) => buffer.get_mut().clear(), + GpuArrayBuffer::Storage(buffer) => buffer.clear(), } } @@ -56,9 +58,7 @@ impl GpuArrayBuffer { match self { GpuArrayBuffer::Uniform(buffer) => buffer.push(value), GpuArrayBuffer::Storage(buffer) => { - let buffer = buffer.get_mut(); - let index = buffer.len() as u32; - buffer.push(value); + let index = buffer.push(value) as u32; GpuArrayBufferIndex { index, dynamic_offset: None, @@ -91,7 +91,9 @@ impl GpuArrayBuffer { pub fn binding(&self) -> Option { match self { GpuArrayBuffer::Uniform(buffer) => buffer.binding(), - GpuArrayBuffer::Storage(buffer) => buffer.binding(), + GpuArrayBuffer::Storage(buffer) => { + buffer.buffer().map(|buffer| buffer.as_entire_binding()) + } } } diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index 418e35cfbc..d30a002c88 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -24,6 +24,8 @@ use wgpu::{util::BufferInitDescriptor, BindingResource, BufferBinding, BufferUsa /// * [`UniformBuffer`](crate::render_resource::UniformBuffer) /// * [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer) /// * [`GpuArrayBuffer`](crate::render_resource::GpuArrayBuffer) +/// * [`RawBufferVec`](crate::render_resource::RawBufferVec) +/// * [`BufferVec`](crate::render_resource::BufferVec) /// * [`BufferVec`](crate::render_resource::BufferVec) /// * [`Texture`](crate::render_resource::Texture) /// @@ -154,6 +156,8 @@ impl StorageBuffer { /// * [`UniformBuffer`](crate::render_resource::UniformBuffer) /// * [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer) /// * [`GpuArrayBuffer`](crate::render_resource::GpuArrayBuffer) +/// * [`RawBufferVec`](crate::render_resource::RawBufferVec) +/// * [`BufferVec`](crate::render_resource::BufferVec) /// * [`BufferVec`](crate::render_resource::BufferVec) /// * [`Texture`](crate::render_resource::Texture) /// diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index 6eaceeabbe..f71cdc1ceb 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -31,6 +31,7 @@ use super::IntoBinding; /// * [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) /// * [`DynamicUniformBuffer`] /// * [`GpuArrayBuffer`](crate::render_resource::GpuArrayBuffer) +/// * [`RawBufferVec`](crate::render_resource::RawBufferVec) /// * [`BufferVec`](crate::render_resource::BufferVec) /// * [`Texture`](crate::render_resource::Texture) /// @@ -168,6 +169,7 @@ impl<'a, T: ShaderType + WriteInto> IntoBinding<'a> for &'a UniformBuffer { /// * [`UniformBuffer`] /// * [`DynamicUniformBuffer`] /// * [`GpuArrayBuffer`](crate::render_resource::GpuArrayBuffer) +/// * [`RawBufferVec`](crate::render_resource::RawBufferVec) /// * [`BufferVec`](crate::render_resource::BufferVec) /// * [`Texture`](crate::render_resource::Texture) /// diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index f0f2b524a3..9f1ff76a20 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -413,16 +413,16 @@ impl SpriteInstance { #[derive(Resource)] pub struct SpriteMeta { view_bind_group: Option, - sprite_index_buffer: BufferVec, - sprite_instance_buffer: BufferVec, + sprite_index_buffer: RawBufferVec, + sprite_instance_buffer: RawBufferVec, } impl Default for SpriteMeta { fn default() -> Self { Self { view_bind_group: None, - sprite_index_buffer: BufferVec::::new(BufferUsages::INDEX), - sprite_instance_buffer: BufferVec::::new(BufferUsages::VERTEX), + sprite_index_buffer: RawBufferVec::::new(BufferUsages::INDEX), + sprite_instance_buffer: RawBufferVec::::new(BufferUsages::VERTEX), } } } diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 881e6918fd..4ff38dc4db 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -834,16 +834,16 @@ struct UiVertex { #[derive(Resource)] pub struct UiMeta { - vertices: BufferVec, - indices: BufferVec, + vertices: RawBufferVec, + indices: RawBufferVec, view_bind_group: Option, } impl Default for UiMeta { fn default() -> Self { Self { - vertices: BufferVec::new(BufferUsages::VERTEX), - indices: BufferVec::new(BufferUsages::INDEX), + vertices: RawBufferVec::new(BufferUsages::VERTEX), + indices: RawBufferVec::new(BufferUsages::INDEX), view_bind_group: None, } } diff --git a/crates/bevy_ui/src/render/ui_material_pipeline.rs b/crates/bevy_ui/src/render/ui_material_pipeline.rs index b1beaaa5d1..f1f2b00ba9 100644 --- a/crates/bevy_ui/src/render/ui_material_pipeline.rs +++ b/crates/bevy_ui/src/render/ui_material_pipeline.rs @@ -91,7 +91,7 @@ where #[derive(Resource)] pub struct UiMaterialMeta { - vertices: BufferVec, + vertices: RawBufferVec, view_bind_group: Option, marker: PhantomData, } @@ -99,7 +99,7 @@ pub struct UiMaterialMeta { impl Default for UiMaterialMeta { fn default() -> Self { Self { - vertices: BufferVec::new(BufferUsages::VERTEX), + vertices: RawBufferVec::new(BufferUsages::VERTEX), view_bind_group: Default::default(), marker: PhantomData, }