diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 1f90e1a21a..327b48e249 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -1,6 +1,7 @@ // FIXME(3492): remove once docs are ready #![allow(missing_docs)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![forbid(unsafe_code)] #![doc( html_logo_url = "https://bevyengine.org/assets/icon.png", html_favicon_url = "https://bevyengine.org/assets/icon.png" diff --git a/crates/bevy_pbr/src/meshlet/persistent_buffer.rs b/crates/bevy_pbr/src/meshlet/persistent_buffer.rs index fe67b18416..60e163a874 100644 --- a/crates/bevy_pbr/src/meshlet/persistent_buffer.rs +++ b/crates/bevy_pbr/src/meshlet/persistent_buffer.rs @@ -1,9 +1,7 @@ -#![allow(unsafe_code)] - use bevy_render::{ render_resource::{ BindingResource, Buffer, BufferAddress, BufferDescriptor, BufferUsages, - CommandEncoderDescriptor, + CommandEncoderDescriptor, COPY_BUFFER_ALIGNMENT, }, renderer::{RenderDevice, RenderQueue}, }; @@ -41,6 +39,7 @@ impl PersistentGpuBuffer { /// Queue an item of type T to be added to the buffer, returning the byte range within the buffer that it will be located at. pub fn queue_write(&mut self, data: T, metadata: T::Metadata) -> Range { let data_size = data.size_in_bytes() as u64; + debug_assert!(data_size % COPY_BUFFER_ALIGNMENT == 0); if let Ok(buffer_slice) = self.allocation_planner.allocate_range(data_size) { self.write_queue .push((data, metadata, buffer_slice.clone())); @@ -110,17 +109,18 @@ impl PersistentGpuBuffer { } /// A trait representing data that can be written to a [`PersistentGpuBuffer`]. -/// -/// # Safety -/// * All data must be a multiple of `wgpu::COPY_BUFFER_ALIGNMENT` bytes. -/// * The amount of bytes written to `buffer` in `write_bytes_le()` must match `size_in_bytes()`. -pub unsafe trait PersistentGpuBufferable { +pub trait PersistentGpuBufferable { /// Additional metadata associated with each item, made available during `write_bytes_le`. type Metadata; - /// The size in bytes of `self`. + /// The size in bytes of `self`. This will determine the size of the buffer passed into + /// `write_bytes_le`. + /// + /// All data written must be in a multiple of `wgpu::COPY_BUFFER_ALIGNMENT` bytes. Failure to do so will + /// result in a panic when using [`PersistentGpuBuffer`]. fn size_in_bytes(&self) -> usize; /// Convert `self` + `metadata` into bytes (little-endian), and write to the provided buffer slice. + /// Any bytes not written to in the slice will be zeroed out when uploaded to the GPU. fn write_bytes_le(&self, metadata: Self::Metadata, buffer_slice: &mut [u8]); } diff --git a/crates/bevy_pbr/src/meshlet/persistent_buffer_impls.rs b/crates/bevy_pbr/src/meshlet/persistent_buffer_impls.rs index b3e882dc43..e95aaa8d82 100644 --- a/crates/bevy_pbr/src/meshlet/persistent_buffer_impls.rs +++ b/crates/bevy_pbr/src/meshlet/persistent_buffer_impls.rs @@ -1,12 +1,9 @@ -#![allow(unsafe_code)] -#![allow(clippy::undocumented_unsafe_blocks)] - use super::{persistent_buffer::PersistentGpuBufferable, Meshlet, MeshletBoundingSphere}; use std::{mem::size_of, sync::Arc}; const MESHLET_VERTEX_SIZE_IN_BYTES: u32 = 48; -unsafe impl PersistentGpuBufferable for Arc<[u8]> { +impl PersistentGpuBufferable for Arc<[u8]> { type Metadata = (); fn size_in_bytes(&self) -> usize { @@ -18,7 +15,7 @@ unsafe impl PersistentGpuBufferable for Arc<[u8]> { } } -unsafe impl PersistentGpuBufferable for Arc<[u32]> { +impl PersistentGpuBufferable for Arc<[u32]> { type Metadata = u64; fn size_in_bytes(&self) -> usize { @@ -37,7 +34,7 @@ unsafe impl PersistentGpuBufferable for Arc<[u32]> { } } -unsafe impl PersistentGpuBufferable for Arc<[Meshlet]> { +impl PersistentGpuBufferable for Arc<[Meshlet]> { type Metadata = (u64, u64); fn size_in_bytes(&self) -> usize { @@ -65,7 +62,7 @@ unsafe impl PersistentGpuBufferable for Arc<[Meshlet]> { } } -unsafe impl PersistentGpuBufferable for Arc<[MeshletBoundingSphere]> { +impl PersistentGpuBufferable for Arc<[MeshletBoundingSphere]> { type Metadata = (); fn size_in_bytes(&self) -> usize { diff --git a/crates/bevy_render/src/render_resource/mod.rs b/crates/bevy_render/src/render_resource/mod.rs index f3b1af2f02..388bf0fb08 100644 --- a/crates/bevy_render/src/render_resource/mod.rs +++ b/crates/bevy_render/src/render_resource/mod.rs @@ -51,7 +51,7 @@ pub use wgpu::{ TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages, TextureViewDescriptor, TextureViewDimension, VertexAttribute, VertexBufferLayout as RawVertexBufferLayout, VertexFormat, VertexState as RawVertexState, - VertexStepMode, + VertexStepMode, COPY_BUFFER_ALIGNMENT, }; pub mod encase {