diff --git a/.gitattributes b/.gitattributes index 8bf01b73b0..975cb317ee 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,3 @@ -<<<<<<< HEAD -*.mtl binary -diff -*.obj binary -diff -======= *.mtl binary *.obj binary -wgpu/src/backend/webgpu/webgpu_sys/** linguist-generated=true ->>>>>>> trunk +wgpu/src/backend/webgpu/webgpu_sys/** linguist-generated=true \ No newline at end of file diff --git a/api_spec.rs b/api_spec.rs deleted file mode 100644 index dbf3979795..0000000000 --- a/api_spec.rs +++ /dev/null @@ -1,154 +0,0 @@ -// Ray tracing api proposal for wgpu (underlining Vulkan, Metal and DX12 implementations) - -// The general design goal is to come up with an simpler Api, which allows for validation. -// Since this validation would have high overhead in some cases, -// I decided to provide more limited functions and unsafe functions for the same action, to evade this tradeoff. - -// Error handling and traits like Debug are omitted. - -// Core structures with no public members -pub struct Blas {} -pub struct Tlas {} -pub struct BlasRequirements {} -pub struct TlasInstances{} - -// Size descriptors used to describe the size requirements of blas geometries. -// Also used internally for strict validation -pub struct BlasTriangleGeometrySizeDescriptor{ - pub vertex_format: wgt::VertexFormat, - pub vertex_count: u32, - pub index_format: Option, - pub index_count: Option, - pub flags: AccelerationStructureGeometryFlags, -} - -pub struct BlasProceduralGeometrySizeDescriptor{ - pub count: u32, - pub flags: AccelerationStructureGeometryFlags, -} - -// Procedural geometry contains AABBs -pub struct BlasProceduralGeometry{ - pub size: BlasTriangleGeometrySize, - pub bounding_box_buffer: Buffer, - pub bounding_box_buffer_offset: wgt::BufferAddress, - pub bounding_box_stride: wgt::BufferAddress, -} - -// Triangle Geometry contains vertices, optionally indices and transforms -pub struct BlasTriangleGeometry{ - pub size: BlasTriangleGeometrySize, - pub vertex_buffer: Buffer - pub first_vertex: u32, - pub vertex_stride: wgt::BufferAddress, - pub index_buffer: Option, - pub index_buffer_offset: Option, - pub transform_buffer: Option, - pub transform_buffer_offset: Option, -} - -// Build flags -pub struct AccelerationStructureFlags{ - // build_speed, small_size, ... -} - -// Geometry flags -pub struct AccelerationStructureGeometryFlags{ - // opaque, no_duplicate_any_hit, ... -} - -// Descriptors used to determine the memory requirements and validation of a acceleration structure -pub enum BlasGeometrySizeDescriptors{ - Triangles{desc: Vec}, - Procedural(desc: Vec) -} - -// With prefer update, we decide if an update is possible, else we rebuild. -// Maybe a force update option could be useful -pub enum UpdateMode{ - Build, - // Update, - PreferUpdate, -} - -// General descriptor for the size requirements, -// since the required size depends on the contents and build flags -pub struct GetBlasRequirementsDescriptor{ - pub flags: AccelerationStructureFlags, -} - -// Creation descriptors, we provide flags, and update_mode. -// We store it in the structure, so we don't need to pass it every build. -pub struct CreateBlasDescriptor<'a>{ - pub flags: AccelerationStructureFlags, - pub update_mode: UpdateMode, -} - -pub struct CreateTlasDescriptor{ - pub max_instances: u32, - pub flags: AccelerationStructureFlags, - pub update_mode: UpdateMode, -} - -// Secure instance entry for tlas -struct TlasInstance{ - transform: [f32; 12], - custom_index: u32, - mask: u8, - shader_binding_table_record_offset: u32, - flags: u8 //bitmap - blas: Blas -} - -impl Device { - // Creates a new bottom level accelerations structures and sets internal states for validation and builds (e.g update mode) - pub fn create_blas(&self, desc: &CreateBlasDescriptor, entries: BlasGeometrySizeDescriptors) -> Blas; - - // Creates a new top level accelerations structures and sets internal states for builds (e.g update mode) - pub fn create_tlas(&self, desc: &CreateTlasDescriptor) -> Tlas; -} - -// Enum for the different types of geometries inside a single blas build -// [Should we used nested iterators with dynamic dispatch instead] -enum BlasGeometries<'a>{ - TriangleGeometries(&'a [BlasTriangleGeometry]) - ProceduralGeometries(&'a [BlasProceduralGeometry]) -} - -impl CommandEncoder { - // Build acceleration structures. - // Elements of blas may be used in a tlas (internal synchronization). - // This function will allocate a single big scratch buffer, that is shared between internal builds. - // If there are to many acceleration structures for a single build (size constraint), - // we will automatically distribute them between multiple internal builds. (reducing the required size of the scratch buffer). - // This version will be implemented in wgpu::util not wgpu-core. - pub fn build_acceleration_structures<'a>(&self, - blas: impl IntoIterator)>, - tlas: impl IntoIterator)>, - ); - - // unsafe version without validation for tlas, directly using an instance buffer. - // u32 for the number of instances to build - pub fn build_acceleration_structures_unsafe_tlas<'a>(&self, - blas: impl IntoIterator)>, - tlas: impl IntoIterator, - ); - - // Creates a new blas and copies (in a compacting way) the contents of the provided blas - // into the new one (compaction flag must be set). - pub fn compact_blas(&self, blas: &Blas) -> Blas; -} - -// Safe Tlas Instance -impl TlasInstances{ - pub fn new(max_instances: u32) -> Self; - - // gets instances to read from - pub fn get(&self) -> &[TlasInstance]; - // gets instances to modify, we keep track of the range to determine what we need to validate and copy - pub fn get_mut_range(&mut self, range: Range) -> &mut [TlasInstance]; - // get the number of instances which will be build - pub fn active(&self) -> u32; - // set the number of instances which will be build - pub fn set_active(&mut self, active: u32); -} \ No newline at end of file diff --git a/examples/src/ray_cube_compute/mod.rs b/examples/src/ray_cube_compute/mod.rs index 126d202d9a..cd9bb9e645 100644 --- a/examples/src/ray_cube_compute/mod.rs +++ b/examples/src/ray_cube_compute/mod.rs @@ -369,7 +369,7 @@ impl crate::framework::Example for Example { update_mode: rt::AccelerationStructureUpdateMode::Build, }, rt::BlasGeometrySizeDescriptors::Triangles { - desc: vec![blas_geo_size_desc.clone()], + descriptors: vec![blas_geo_size_desc.clone()], }, ); diff --git a/examples/src/ray_cube_fragment/mod.rs b/examples/src/ray_cube_fragment/mod.rs index 6da273b455..d63c041d53 100644 --- a/examples/src/ray_cube_fragment/mod.rs +++ b/examples/src/ray_cube_fragment/mod.rs @@ -180,7 +180,7 @@ impl crate::framework::Example for Example { update_mode: rt::AccelerationStructureUpdateMode::Build, }, rt::BlasGeometrySizeDescriptors::Triangles { - desc: vec![blas_geo_size_desc.clone()], + descriptors: vec![blas_geo_size_desc.clone()], }, ); diff --git a/examples/src/ray_scene/mod.rs b/examples/src/ray_scene/mod.rs index 45304d765a..a735aed7c4 100644 --- a/examples/src/ray_scene/mod.rs +++ b/examples/src/ray_scene/mod.rs @@ -245,7 +245,7 @@ fn upload_scene_components( update_mode: rt::AccelerationStructureUpdateMode::Build, }, rt::BlasGeometrySizeDescriptors::Triangles { - desc: size_desc.clone(), + descriptors: size_desc.clone(), }, ); (size_desc, blas) diff --git a/examples/src/ray_shadows/mod.rs b/examples/src/ray_shadows/mod.rs index 250e26991d..998e55abb1 100644 --- a/examples/src/ray_shadows/mod.rs +++ b/examples/src/ray_shadows/mod.rs @@ -169,7 +169,7 @@ impl crate::framework::Example for Example { update_mode: rt::AccelerationStructureUpdateMode::Build, }, rt::BlasGeometrySizeDescriptors::Triangles { - desc: vec![blas_geo_size_desc.clone()], + descriptors: vec![blas_geo_size_desc.clone()], }, ); diff --git a/examples/src/ray_traced_triangle/mod.rs b/examples/src/ray_traced_triangle/mod.rs index 2bcaa89bd0..5fd06c43b1 100644 --- a/examples/src/ray_traced_triangle/mod.rs +++ b/examples/src/ray_traced_triangle/mod.rs @@ -146,7 +146,7 @@ impl crate::framework::Example for Example { update_mode: AccelerationStructureUpdateMode::Build, }, BlasGeometrySizeDescriptors::Triangles { - desc: vec![blas_size_desc.clone()], + descriptors: vec![blas_size_desc.clone()], }, ); diff --git a/tests/tests/ray_tracing_use_after_free/mod.rs b/tests/tests/ray_tracing_use_after_free/mod.rs index 93805e651c..56bc6cc239 100644 --- a/tests/tests/ray_tracing_use_after_free/mod.rs +++ b/tests/tests/ray_tracing_use_after_free/mod.rs @@ -35,7 +35,7 @@ fn execute(ctx: TestingContext) { update_mode: AccelerationStructureUpdateMode::Build, }, BlasGeometrySizeDescriptors::Triangles { - desc: vec![blas_size.clone()], + descriptors: vec![blas_size.clone()], }, ); let tlas = ctx.device.create_tlas(&CreateTlasDescriptor { diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index e74d010eba..8fbe7dad98 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1,3 +1,7 @@ +#[cfg(feature = "trace")] +use crate::device::trace; +#[cfg(feature = "trace")] +use crate::ray_tracing::TraceBlasGeometries; use crate::{ device::queue::TempResource, global::Global, @@ -114,12 +118,10 @@ impl Global { let trace_tlas: Vec = tlas_iter.collect(); #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf.data.lock().as_mut().unwrap().commands { - list.push( - crate::device::trace::Command::BuildAccelerationStructuresUnsafeTlas { - blas: trace_blas.clone(), - tlas: trace_tlas.clone(), - }, - ); + list.push(trace::Command::BuildAccelerationStructuresUnsafeTlas { + blas: trace_blas.clone(), + tlas: trace_tlas.clone(), + }); if !trace_tlas.is_empty() { log::warn!("a trace of command_encoder_build_acceleration_structures_unsafe_tlas containing a tlas build is not replayable!"); } @@ -128,9 +130,7 @@ impl Global { #[cfg(feature = "trace")] let blas_iter = trace_blas.iter().map(|x| { let geometries = match &x.geometries { - crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( - triangle_geometries, - ) => { + TraceBlasGeometries::TriangleGeometries(triangle_geometries) => { let iter = triangle_geometries.iter().map(|tg| BlasTriangleGeometry { size: &tg.size, vertex_buffer: tg.vertex_buffer, @@ -417,7 +417,7 @@ impl Global { #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf.data.lock().as_mut().unwrap().commands { - list.push(crate::device::trace::Command::BuildAccelerationStructures { + list.push(trace::Command::BuildAccelerationStructures { blas: trace_blas.clone(), tlas: trace_tlas.clone(), }); @@ -426,9 +426,7 @@ impl Global { #[cfg(feature = "trace")] let blas_iter = trace_blas.iter().map(|x| { let geometries = match &x.geometries { - crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( - triangle_geometries, - ) => { + TraceBlasGeometries::TriangleGeometries(triangle_geometries) => { let iter = triangle_geometries.iter().map(|tg| BlasTriangleGeometry { size: &tg.size, vertex_buffer: tg.vertex_buffer, @@ -813,7 +811,7 @@ fn iter_blas<'a>( BlasGeometries::TriangleGeometries(triangle_geometries) => { for (i, mesh) in triangle_geometries.enumerate() { let size_desc = match &blas.sizes { - wgt::BlasGeometrySizeDescriptors::Triangles { desc } => desc, + wgt::BlasGeometrySizeDescriptors::Triangles { descriptors } => descriptors, }; if i >= size_desc.len() { return Err(BuildAccelerationStructureError::IncompatibleBlasBuildSizes( @@ -947,7 +945,7 @@ fn iter_blas<'a>( Ok(()) } -/// Iterates over the buffers generated [iter_blas] and convert the barriers into hal barriers, and the triangles into [hal::AccelerationStructureEntries] (and also some validation). +/// Iterates over the buffers generated in [iter_blas], convert the barriers into hal barriers, and the triangles into [hal::AccelerationStructureEntries] (and also some validation). fn iter_buffers<'a, 'b>( buf_storage: &'a mut BufferStorage<'b>, snatch_guard: &'a SnatchGuard, diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index c2cfb854c7..6e7e7e7e93 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -23,21 +23,21 @@ impl Device { sizes: wgt::BlasGeometrySizeDescriptors, ) -> Result, CreateBlasError> { let size_info = match &sizes { - wgt::BlasGeometrySizeDescriptors::Triangles { desc } => { + wgt::BlasGeometrySizeDescriptors::Triangles { descriptors } => { let mut entries = Vec::>::with_capacity( - desc.len(), + descriptors.len(), ); - for x in desc { - if x.index_count.is_some() != x.index_format.is_some() { + for desc in descriptors { + if desc.index_count.is_some() != desc.index_format.is_some() { return Err(CreateBlasError::MissingIndexData); } let indices = - x.index_count + desc.index_count .map(|count| AccelerationStructureTriangleIndices::< dyn hal::DynBuffer, > { - format: x.index_format.unwrap(), + format: desc.index_format.unwrap(), buffer: None, offset: 0, count, @@ -45,22 +45,22 @@ impl Device { if !self .features .allowed_vertex_formats_for_blas() - .contains(&x.vertex_format) + .contains(&desc.vertex_format) { return Err(CreateBlasError::InvalidVertexFormat( - x.vertex_format, + desc.vertex_format, self.features.allowed_vertex_formats_for_blas(), )); } entries.push(hal::AccelerationStructureTriangles:: { vertex_buffer: None, - vertex_format: x.vertex_format, + vertex_format: desc.vertex_format, first_vertex: 0, - vertex_count: x.vertex_count, + vertex_count: desc.vertex_count, vertex_stride: 0, indices, transform: None, - flags: x.flags, + flags: desc.flags, }); } unsafe { diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 3a8273e15f..be7138257c 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -1,3 +1,12 @@ +// Ray tracing +// Major missing optimizations (no api surface changes needed): +// - use custom tracker to track build state +// - no forced rebuilt (build mode deduction) +// - lazy instance buffer allocation +// - maybe share scratch and instance staging buffer allocation +// - partial instance buffer uploads (api surface already designed with this in mind) +// - ([non performance] extract function in build (rust function extraction with guards is a pain)) + use crate::{ command::CommandEncoderError, device::DeviceError, @@ -5,14 +14,6 @@ use crate::{ resource::CreateBufferError, }; use std::sync::Arc; -/// Ray tracing -/// Major missing optimizations (no api surface changes needed): -/// - use custom tracker to track build state -/// - no forced rebuilt (build mode deduction) -/// - lazy instance buffer allocation -/// - maybe share scratch and instance staging buffer allocation -/// - partial instance buffer uploads (api surface already designed with this in mind) -/// - ([non performance] extract function in build (rust function extraction with guards is a pain)) use std::{num::NonZeroU64, slice}; use crate::resource::{Blas, ResourceErrorIdent, Tlas}; diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 86aa7f977c..4e54a4ca41 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -7464,7 +7464,7 @@ pub enum BlasGeometrySizeDescriptors { /// Triangle geometry version. Triangles { /// Descriptor for each triangle geometry. - desc: Vec, + descriptors: Vec, }, }