From cd16e71654ef7acf0979c113198a660a3d519f26 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Sat, 3 Sep 2022 15:28:00 +0200 Subject: [PATCH 001/146] Initial commit --- wgpu-hal/examples/halmark/main.rs | 8 ++++ wgpu-hal/src/empty.rs | 4 ++ wgpu-hal/src/gles/device.rs | 6 +++ wgpu-hal/src/gles/mod.rs | 1 + wgpu-hal/src/lib.rs | 18 ++++++++ wgpu-hal/src/vulkan/adapter.rs | 21 +++++++++ wgpu-hal/src/vulkan/device.rs | 71 +++++++++++++++++++++++++++++++ wgpu-hal/src/vulkan/mod.rs | 9 ++++ 8 files changed, 138 insertions(+) diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 383efcdc53..1fa19bfd07 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -345,6 +345,14 @@ impl Example { }; let sampler = unsafe { device.create_sampler(&sampler_desc).unwrap() }; + let accel = unsafe { + device.create_acceleration_structure(&hal::AccelerationStructureDescriptor { + label: Some("my as"), + size: 1024, + format: hal::AccelerationStructureFormat::BottomLevel, + }) + }; + let globals = Globals { // cgmath::ortho() projection mvp: [ diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 0c546469b2..59eae2dedf 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -28,6 +28,7 @@ impl crate::Api for Api { type Sampler = Resource; type QuerySet = Resource; type Fence = Resource; + type AccelerationStructure = Resource; type BindGroupLayout = Resource; type BindGroup = Resource; @@ -118,6 +119,9 @@ impl crate::Device for Context { unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult { Ok(Resource) } + unsafe fn create_acceleration_structure(&self, desc: &crate::AccelerationStructureDescriptor) -> DeviceResult { + Ok(Resource) + } unsafe fn destroy_buffer(&self, buffer: Resource) {} unsafe fn map_buffer( &self, diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 04ecdffe02..b8fd7d3842 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -455,6 +455,12 @@ impl crate::Device for super::Device { data, }) } + unsafe fn create_acceleration_structure( + &self, + _desc: &crate::AccelerationStructureDescriptor, + ) -> Result<(), crate::DeviceError> { + unimplemented!() + } unsafe fn destroy_buffer(&self, buffer: super::Buffer) { if let Some(raw) = buffer.raw { let gl = &self.shared.context.lock(); diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 717502f2c6..a688f230e7 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -112,6 +112,7 @@ impl crate::Api for Api { type Sampler = Sampler; type QuerySet = QuerySet; type Fence = Fence; + type AccelerationStructure = (); type BindGroupLayout = BindGroupLayout; type BindGroup = BindGroup; diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 02d3c13af1..88d0a848fc 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -172,6 +172,8 @@ pub trait Api: Clone + Sized { type ShaderModule: fmt::Debug + Send + Sync; type RenderPipeline: Send + Sync; type ComputePipeline: Send + Sync; + + type AccelerationStructure: fmt::Debug + Send + Sync + 'static; } pub trait Instance: Sized + Send + Sync { @@ -236,6 +238,9 @@ pub trait Device: Send + Sync { /// /// The initial usage is `BufferUses::empty()`. unsafe fn create_buffer(&self, desc: &BufferDescriptor) -> Result; + + unsafe fn create_acceleration_structure(&self, desc: &AccelerationStructureDescriptor) -> Result; + unsafe fn destroy_buffer(&self, buffer: A::Buffer); //TODO: clarify if zero-sized mapping is allowed unsafe fn map_buffer( @@ -810,6 +815,19 @@ pub struct BufferDescriptor<'a> { pub memory_flags: MemoryFlags, } +#[derive(Clone, Debug)] +pub struct AccelerationStructureDescriptor<'a> { + pub label: Label<'a>, + pub size: wgt::BufferAddress, + pub format: AccelerationStructureFormat, +} + +#[derive(Clone, Debug)] +pub enum AccelerationStructureFormat { + TopLevel, + BottomLevel, +} + #[derive(Clone, Debug)] pub struct TextureDescriptor<'a> { pub label: Label<'a>, diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 0a3afb690e..94ca7e0d13 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -27,6 +27,7 @@ pub struct PhysicalDeviceFeatures { vk::PhysicalDeviceShaderFloat16Int8Features, vk::PhysicalDevice16BitStorageFeatures, )>, + acceleration_structure: Option, } // This is safe because the structs have `p_next: *mut c_void`, which we null out/never read. @@ -65,6 +66,9 @@ impl PhysicalDeviceFeatures { info = info.push_next(f16_i8_feature); info = info.push_next(_16bit_feature); } + if let Some(ref mut feature) = self.acceleration_structure { + info = info.push_next(feature); + } info } @@ -295,6 +299,12 @@ impl PhysicalDeviceFeatures { } else { None }, + acceleration_structure: if true { + Some(vk::PhysicalDeviceAccelerationStructureFeaturesKHR::builder() + .acceleration_structure(true).build()) + } else { + None + } } } @@ -579,6 +589,11 @@ impl PhysicalDeviceCapabilities { extensions.push(vk::KhrDrawIndirectCountFn::name()); } + if true { + extensions.push(vk::KhrDeferredHostOperationsFn::name()); + extensions.push(vk::KhrAccelerationStructureFn::name()); + } + if requested_features.contains(wgt::Features::CONSERVATIVE_RASTERIZATION) { extensions.push(vk::ExtConservativeRasterizationFn::name()); } @@ -1098,6 +1113,11 @@ impl super::Adapter { } else { None }; + let acceleration_structure_fn = if enabled_extensions.contains(&khr::AccelerationStructure::name()) { + Some(khr::AccelerationStructure::new(&self.instance.raw, &raw_device)) + } else { + None + }; let naga_options = { use naga::back::spv; @@ -1190,6 +1210,7 @@ impl super::Adapter { extension_fns: super::DeviceExtensionFunctions { draw_indirect_count: indirect_count_fn, timeline_semaphore: timeline_semaphore_fn, + acceleration_structure: acceleration_structure_fn, }, vendor_id: self.phd_capabilities.properties.vendor_id, timestamp_period: self.phd_capabilities.properties.limits.timestamp_period, diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index b9d74e36e3..5f9a326608 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -808,6 +808,77 @@ impl crate::Device for super::Device { block: Mutex::new(block), }) } + + unsafe fn create_acceleration_structure(&self, desc: &crate::AccelerationStructureDescriptor) -> Result { + let functor = match self.shared.extension_fns.acceleration_structure { + Some(ref functor) => { + functor + } + None => panic!("Feature `RAY_TRACING` not enabled"), + }; + + let vk_buffer_info = vk::BufferCreateInfo::builder() + .size(desc.size) + .usage( + vk::BufferUsageFlags::ACCELERATION_STRUCTURE_STORAGE_KHR + | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS + ) + .sharing_mode(vk::SharingMode::EXCLUSIVE); + + let raw_buffer = self.shared.raw.create_buffer(&vk_buffer_info, None)?; + let req = self.shared.raw.get_buffer_memory_requirements(raw_buffer); + + dbg!(&req); + + let block = self.mem_allocator.lock().alloc( + &*self.shared, + gpu_alloc::Request { + size: req.size, + align_mask: req.alignment - 1, + usage: gpu_alloc::UsageFlags::FAST_DEVICE_ACCESS, + memory_types: req.memory_type_bits & self.valid_ash_memory_types, + }, + )?; + + self.shared + .raw + .bind_buffer_memory(raw_buffer, *block.memory(), block.offset())?; + + if let Some(label) = desc.label { + self.shared + .set_object_name(vk::ObjectType::BUFFER, raw_buffer, label); + } + + let ty = match desc.format { + crate::AccelerationStructureFormat::TopLevel => vk::AccelerationStructureTypeKHR::TOP_LEVEL, + crate::AccelerationStructureFormat::BottomLevel => vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL, + }; + + let vk_info = vk::AccelerationStructureCreateInfoKHR::builder() + .buffer(raw_buffer) + .offset(256) + .size(desc.size / 2) + .ty(ty).build(); + + dbg!(&vk_info); + + let raw_acceleration_structure = functor.create_acceleration_structure( + &vk_info, + None, + )?; + + if let Some(label) = desc.label { + self.shared + .set_object_name(vk::ObjectType::ACCELERATION_STRUCTURE_KHR, raw_acceleration_structure, label); + } + + Ok(super::AccelerationStructure { + raw: raw_acceleration_structure, + buffer: raw_buffer, + block: Mutex::new(block), + }) + } + unsafe fn destroy_buffer(&self, buffer: super::Buffer) { self.shared.raw.destroy_buffer(buffer.raw, None); self.mem_allocator diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index d3416a50ed..443d7f1422 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -65,6 +65,7 @@ impl crate::Api for Api { type Sampler = Sampler; type QuerySet = QuerySet; type Fence = Fence; + type AccelerationStructure = AccelerationStructure; type BindGroupLayout = BindGroupLayout; type BindGroup = BindGroup; @@ -147,6 +148,7 @@ enum ExtensionFn { struct DeviceExtensionFunctions { draw_indirect_count: Option, timeline_semaphore: Option>, + acceleration_structure: Option, } /// Set of internal capabilities, which don't show up in the exposed @@ -344,6 +346,13 @@ pub struct Buffer { block: Mutex>, } +#[derive(Debug)] +pub struct AccelerationStructure { + raw: vk::AccelerationStructureKHR, + buffer: vk::Buffer, + block: Mutex>, +} + #[derive(Debug)] pub struct Texture { raw: vk::Image, From ae4dcfed87df8e0b5fd21ffea0645c925c3201de Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Sun, 11 Sep 2022 20:53:15 +0200 Subject: [PATCH 002/146] Woo! building an AS works --- wgpu-hal/examples/halmark/main.rs | 131 +++++++++++++++++++++++++-- wgpu-hal/src/empty.rs | 28 +++++- wgpu-hal/src/lib.rs | 61 ++++++++++++- wgpu-hal/src/vulkan/adapter.rs | 89 ++++++++++++++++--- wgpu-hal/src/vulkan/command.rs | 51 +++++++++++ wgpu-hal/src/vulkan/conv.rs | 30 +++++++ wgpu-hal/src/vulkan/device.rs | 143 ++++++++++++++++++++++++------ wgpu-hal/src/vulkan/mod.rs | 1 + 8 files changed, 486 insertions(+), 48 deletions(-) diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 1fa19bfd07..ef92b30f7f 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -252,7 +252,9 @@ impl Example { let staging_buffer_desc = hal::BufferDescriptor { label: Some("stage"), size: texture_data.len() as wgt::BufferAddress, - usage: hal::BufferUses::MAP_WRITE | hal::BufferUses::COPY_SRC, + usage: hal::BufferUses::MAP_WRITE + | hal::BufferUses::COPY_SRC + | hal::BufferUses::BUFFER_DEVICE_ADDRESS, memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, }; let staging_buffer = unsafe { device.create_buffer(&staging_buffer_desc).unwrap() }; @@ -269,6 +271,110 @@ impl Example { assert!(mapping.is_coherent); } + let triangle: [f32; 9] = [0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0]; + + let triangle_size = std::mem::size_of::<[f32; 9]>(); + + dbg!(&triangle_size); + + let indices: [u32; 3] = [0, 1, 2]; + + let indices_size = std::mem::size_of::<[u32; 3]>(); + + let triangle_buffer = unsafe { + device + .create_buffer(&hal::BufferDescriptor { + label: Some("t buf"), + size: triangle_size as u64, + usage: hal::BufferUses::MAP_WRITE + | hal::BufferUses::BUFFER_DEVICE_ADDRESS + | hal::BufferUses::ACCELERATION_STRUCTURE_BUILD_INPUT, + memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, + }) + .unwrap() + }; + + let i_buf = unsafe { + device + .create_buffer(&hal::BufferDescriptor { + label: Some("i buf"), + size: indices_size as u64, + usage: hal::BufferUses::MAP_WRITE + | hal::BufferUses::BUFFER_DEVICE_ADDRESS + | hal::BufferUses::ACCELERATION_STRUCTURE_BUILD_INPUT, + memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, + }) + .unwrap() + }; + + unsafe { + let mapping = device + .map_buffer(&triangle_buffer, 0..triangle_size as u64) + .unwrap(); + ptr::copy_nonoverlapping( + triangle.as_ptr() as *const u8, + mapping.ptr.as_ptr(), + triangle_size, + ); + device.unmap_buffer(&staging_buffer).unwrap(); + assert!(mapping.is_coherent); + } + + unsafe { + let mapping = device.map_buffer(&i_buf, 0..indices_size as u64).unwrap(); + ptr::copy_nonoverlapping( + indices.as_ptr() as *const u8, + mapping.ptr.as_ptr(), + indices_size, + ); + device.unmap_buffer(&staging_buffer).unwrap(); + assert!(mapping.is_coherent); + } + + let geometry = hal::AccelerationStructureGeometry::Triangles { + vertex_buffer: &triangle_buffer, + vertex_format: wgt::VertexFormat::Float32x3, + max_vertex: 3, + vertex_stride: 3 * 4, + indices: Some(hal::AccelerationStructureGeometryIndices { + buffer: &i_buf, + format: wgt::IndexFormat::Uint32, + }), + }; + + let sizes = unsafe { + device.get_acceleration_structure_build_size( + &geometry, + hal::AccelerationStructureFormat::BottomLevel, + hal::AccelerationStructureBuildMode::Build, + (), + 1, + ) + }; + + dbg!(&sizes); + + let blas = unsafe { + device.create_acceleration_structure(&hal::AccelerationStructureDescriptor { + label: Some("my as"), + size: sizes.acceleration_structure_size, + format: hal::AccelerationStructureFormat::BottomLevel, + }) + } + .unwrap(); + + let scratch_buffer = unsafe { + device + .create_buffer(&hal::BufferDescriptor { + label: Some("scratch buffer"), + size: sizes.build_scratch_size, + usage: hal::BufferUses::BUFFER_DEVICE_ADDRESS + | hal::BufferUses::STORAGE_READ_WRITE, + memory_flags: hal::MemoryFlags::empty(), + }) + .unwrap() + }; + let texture_desc = hal::TextureDescriptor { label: None, size: wgt::Extent3d { @@ -291,6 +397,21 @@ impl Example { }; let mut cmd_encoder = unsafe { device.create_command_encoder(&cmd_encoder_desc).unwrap() }; unsafe { cmd_encoder.begin_encoding(Some("init")).unwrap() }; + + unsafe { + // todo: extract out bytes from transmission renderer example and try those. + cmd_encoder.build_acceleration_structures( + &geometry, + hal::AccelerationStructureFormat::BottomLevel, + hal::AccelerationStructureBuildMode::Build, + (), + 1, + 0, + &blas, + &scratch_buffer, + ); + } + { let buffer_barrier = hal::BufferBarrier { buffer: &staging_buffer, @@ -345,14 +466,6 @@ impl Example { }; let sampler = unsafe { device.create_sampler(&sampler_desc).unwrap() }; - let accel = unsafe { - device.create_acceleration_structure(&hal::AccelerationStructureDescriptor { - label: Some("my as"), - size: 1024, - format: hal::AccelerationStructureFormat::BottomLevel, - }) - }; - let globals = Globals { // cgmath::ortho() projection mvp: [ diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 59eae2dedf..8119af97c3 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -119,9 +119,22 @@ impl crate::Device for Context { unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult { Ok(Resource) } - unsafe fn create_acceleration_structure(&self, desc: &crate::AccelerationStructureDescriptor) -> DeviceResult { + unsafe fn create_acceleration_structure( + &self, + desc: &crate::AccelerationStructureDescriptor, + ) -> DeviceResult { Ok(Resource) } + unsafe fn get_acceleration_structure_build_size( + &self, + geometry: &crate::AccelerationStructureGeometry, + format: crate::AccelerationStructureFormat, + mode: crate::AccelerationStructureBuildMode, + flags: (), + primitive_count: u32, + ) -> crate::AccelerationStructureBuildSizes { + Default::default() + } unsafe fn destroy_buffer(&self, buffer: Resource) {} unsafe fn map_buffer( &self, @@ -395,4 +408,17 @@ impl crate::CommandEncoder for Encoder { unsafe fn dispatch(&mut self, count: [u32; 3]) {} unsafe fn dispatch_indirect(&mut self, buffer: &Resource, offset: wgt::BufferAddress) {} + + unsafe fn build_acceleration_structures( + &mut self, + geometry: &crate::AccelerationStructureGeometry, + format: crate::AccelerationStructureFormat, + mode: crate::AccelerationStructureBuildMode, + flags: (), + primitive_count: u32, + primitive_offset: u32, + destination_acceleration_structure: &Resource, + scratch_buffer: &Resource, + ) { + } } diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 88d0a848fc..e475c5748a 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -239,7 +239,19 @@ pub trait Device: Send + Sync { /// The initial usage is `BufferUses::empty()`. unsafe fn create_buffer(&self, desc: &BufferDescriptor) -> Result; - unsafe fn create_acceleration_structure(&self, desc: &AccelerationStructureDescriptor) -> Result; + unsafe fn create_acceleration_structure( + &self, + desc: &AccelerationStructureDescriptor, + ) -> Result; + + unsafe fn get_acceleration_structure_build_size( + &self, + geometry: &AccelerationStructureGeometry, + format: AccelerationStructureFormat, + mode: AccelerationStructureBuildMode, + flags: (), + primitive_count: u32, + ) -> AccelerationStructureBuildSizes; unsafe fn destroy_buffer(&self, buffer: A::Buffer); //TODO: clarify if zero-sized mapping is allowed @@ -528,6 +540,18 @@ pub trait CommandEncoder: Send + Sync { unsafe fn dispatch(&mut self, count: [u32; 3]); unsafe fn dispatch_indirect(&mut self, buffer: &A::Buffer, offset: wgt::BufferAddress); + + unsafe fn build_acceleration_structures( + &mut self, + geometry: &crate::AccelerationStructureGeometry, + format: crate::AccelerationStructureFormat, + mode: crate::AccelerationStructureBuildMode, + flags: (), + primitive_count: u32, + primitive_offset: u32, + destination_acceleration_structure: &A::AccelerationStructure, + scratch_buffer: &A::Buffer, + ); } bitflags!( @@ -664,6 +688,8 @@ bitflags::bitflags! { const STORAGE_READ_WRITE = 1 << 8; /// The indirect or count buffer in a indirect draw or dispatch. const INDIRECT = 1 << 9; + const BUFFER_DEVICE_ADDRESS = 1 << 10; + const ACCELERATION_STRUCTURE_BUILD_INPUT = 1 << 11; /// The combination of states that a buffer may be in _at the same time_. const INCLUSIVE = Self::MAP_READ.bits | Self::COPY_SRC.bits | Self::INDEX.bits | Self::VERTEX.bits | Self::UNIFORM.bits | @@ -822,12 +848,25 @@ pub struct AccelerationStructureDescriptor<'a> { pub format: AccelerationStructureFormat, } -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub enum AccelerationStructureFormat { TopLevel, BottomLevel, } +#[derive(Clone, Debug)] +pub enum AccelerationStructureBuildMode { + Build, + Update, +} + +#[derive(Clone, Debug, Default)] +pub struct AccelerationStructureBuildSizes { + pub acceleration_structure_size: wgt::BufferAddress, + pub update_scratch_size: wgt::BufferAddress, + pub build_scratch_size: wgt::BufferAddress, +} + #[derive(Clone, Debug)] pub struct TextureDescriptor<'a> { pub label: Label<'a>, @@ -1115,6 +1154,24 @@ pub struct BufferCopy { pub size: wgt::BufferSize, } +pub enum AccelerationStructureGeometry<'a, A: Api> { + Triangles { + vertex_buffer: &'a A::Buffer, + vertex_format: wgt::VertexFormat, + max_vertex: u32, + vertex_stride: wgt::BufferAddress, + indices: Option>, + }, + Instances { + buffer: &'a A::Buffer, + }, +} + +pub struct AccelerationStructureGeometryIndices<'a, A: Api> { + pub format: wgt::IndexFormat, + pub buffer: &'a A::Buffer, +} + #[derive(Clone, Debug)] pub struct TextureCopyBase { pub mip_level: u32, diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 94ca7e0d13..c5f75864a9 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -28,6 +28,8 @@ pub struct PhysicalDeviceFeatures { vk::PhysicalDevice16BitStorageFeatures, )>, acceleration_structure: Option, + buffer_device_address: Option, + ray_query: Option, } // This is safe because the structs have `p_next: *mut c_void`, which we null out/never read. @@ -69,6 +71,12 @@ impl PhysicalDeviceFeatures { if let Some(ref mut feature) = self.acceleration_structure { info = info.push_next(feature); } + if let Some(ref mut feature) = self.buffer_device_address { + info = info.push_next(feature); + } + if let Some(ref mut feature) = self.ray_query { + info = info.push_next(feature); + } info } @@ -299,12 +307,37 @@ impl PhysicalDeviceFeatures { } else { None }, - acceleration_structure: if true { - Some(vk::PhysicalDeviceAccelerationStructureFeaturesKHR::builder() - .acceleration_structure(true).build()) + acceleration_structure: if enabled_extensions + .contains(&vk::KhrAccelerationStructureFn::name()) + { + Some( + vk::PhysicalDeviceAccelerationStructureFeaturesKHR::builder() + .acceleration_structure(true) + .build(), + ) } else { None - } + }, + buffer_device_address: if enabled_extensions + .contains(&vk::KhrBufferDeviceAddressFn::name()) + { + Some( + vk::PhysicalDeviceBufferDeviceAddressFeaturesKHR::builder() + .buffer_device_address(true) + .build(), + ) + } else { + None + }, + ray_query: if enabled_extensions.contains(&vk::KhrRayQueryFn::name()) { + Some( + vk::PhysicalDeviceRayQueryFeaturesKHR::builder() + .ray_query(true) + .build(), + ) + } else { + None + }, } } @@ -516,11 +549,12 @@ impl PhysicalDeviceFeatures { } /// Information gathered about a physical device capabilities. -#[derive(Default)] +#[derive(Default, Debug)] pub struct PhysicalDeviceCapabilities { supported_extensions: Vec, properties: vk::PhysicalDeviceProperties, descriptor_indexing: Option, + acceleration_structure: Option, } // This is safe because the structs have `p_next: *mut c_void`, which we null out/never read. @@ -592,6 +626,8 @@ impl PhysicalDeviceCapabilities { if true { extensions.push(vk::KhrDeferredHostOperationsFn::name()); extensions.push(vk::KhrAccelerationStructureFn::name()); + extensions.push(vk::KhrBufferDeviceAddressFn::name()); + extensions.push(vk::KhrRayQueryFn::name()); } if requested_features.contains(wgt::Features::CONSERVATIVE_RASTERIZATION) { @@ -752,6 +788,9 @@ impl super::InstanceShared { let supports_descriptor_indexing = capabilities.supports_extension(vk::ExtDescriptorIndexingFn::name()); + let supports_acceleration_structure = + capabilities.supports_extension(vk::KhrAccelerationStructureFn::name()); + let mut builder = vk::PhysicalDeviceProperties2::builder(); if supports_descriptor_indexing { @@ -761,6 +800,13 @@ impl super::InstanceShared { builder = builder.push_next(next); } + if supports_acceleration_structure { + let next = capabilities + .acceleration_structure + .insert(vk::PhysicalDeviceAccelerationStructurePropertiesKHR::default()); + builder = builder.push_next(next); + } + let mut properties2 = builder.build(); unsafe { get_device_properties.get_physical_device_properties2(phd, &mut properties2); @@ -846,6 +892,12 @@ impl super::InstanceShared { builder = builder.push_next(&mut next.0); builder = builder.push_next(&mut next.1); } + if capabilities.supports_extension(vk::KhrAccelerationStructureFn::name()) { + let next = features + .acceleration_structure + .insert(vk::PhysicalDeviceAccelerationStructureFeaturesKHR::default()); + builder = builder.push_next(next); + } let mut features2 = builder.build(); unsafe { @@ -1113,11 +1165,24 @@ impl super::Adapter { } else { None }; - let acceleration_structure_fn = if enabled_extensions.contains(&khr::AccelerationStructure::name()) { - Some(khr::AccelerationStructure::new(&self.instance.raw, &raw_device)) - } else { - None - }; + let acceleration_structure_fn = + if enabled_extensions.contains(&khr::AccelerationStructure::name()) { + Some(khr::AccelerationStructure::new( + &self.instance.raw, + &raw_device, + )) + } else { + None + }; + let buffer_device_address_fn = + if enabled_extensions.contains(&khr::BufferDeviceAddress::name()) { + Some(khr::BufferDeviceAddress::new( + &self.instance.raw, + &raw_device, + )) + } else { + None + }; let naga_options = { use naga::back::spv; @@ -1211,6 +1276,7 @@ impl super::Adapter { draw_indirect_count: indirect_count_fn, timeline_semaphore: timeline_semaphore_fn, acceleration_structure: acceleration_structure_fn, + buffer_device_address: buffer_device_address_fn, }, vendor_id: self.phd_capabilities.properties.vendor_id, timestamp_period: self.phd_capabilities.properties.limits.timestamp_period, @@ -1259,7 +1325,8 @@ impl super::Adapter { size: memory_heap.size, }) .collect(), - buffer_device_address: false, + buffer_device_address: enabled_extensions + .contains(&khr::BufferDeviceAddress::name()), }; gpu_alloc::GpuAllocator::new(config, properties) }; diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index e225ca8356..641145dc94 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -341,6 +341,57 @@ impl crate::CommandEncoder for super::CommandEncoder { ); } + unsafe fn build_acceleration_structures( + &mut self, + geometry: &crate::AccelerationStructureGeometry, + format: crate::AccelerationStructureFormat, + mode: crate::AccelerationStructureBuildMode, + flags: (), + primitive_count: u32, + primitive_offset: u32, + destination_acceleration_structure: &super::AccelerationStructure, + scratch_buffer: &super::Buffer, + ) { + let extension = match self.device.extension_fns.acceleration_structure { + Some(ref extension) => extension, + None => panic!("Feature `RAY_TRACING` not enabled"), + }; + + let bda_extension = match self.device.extension_fns.buffer_device_address { + Some(ref extension) => extension, + None => panic!("Feature `BDA` not enabled"), + }; + + let geometry = + super::device::map_acceleration_structure_geometry(geometry, &bda_extension).build(); + + let geometries = &[geometry]; + + let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() + .primitive_count(primitive_count) + .primitive_offset(primitive_offset) + .build(); + + let mut geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() + .ty(conv::map_acceleration_structure_format(format)) + .mode(conv::map_acceleration_structure_build_mode(mode)) + .flags(vk::BuildAccelerationStructureFlagsKHR::PREFER_FAST_TRACE) + .geometries(geometries) + .dst_acceleration_structure(destination_acceleration_structure.raw) + .scratch_data(vk::DeviceOrHostAddressKHR { + device_address: bda_extension.get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(scratch_buffer.raw), + ), + }) + .build(); + + let range = &[range][..]; + let range = &[range][..]; + let geometry_info = &[geometry_info]; + + extension.cmd_build_acceleration_structures(self.active, geometry_info, range); + } + // render unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor) { diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index dc5b915970..95ff907f83 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -491,6 +491,12 @@ pub fn map_buffer_usage(usage: crate::BufferUses) -> vk::BufferUsageFlags { if usage.contains(crate::BufferUses::INDIRECT) { flags |= vk::BufferUsageFlags::INDIRECT_BUFFER; } + if usage.contains(crate::BufferUses::BUFFER_DEVICE_ADDRESS) { + flags |= vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS; + } + if usage.contains(crate::BufferUses::ACCELERATION_STRUCTURE_BUILD_INPUT) { + flags |= vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR; + } flags } @@ -823,3 +829,27 @@ pub fn map_pipeline_statistics( } flags } + +pub fn map_acceleration_structure_format( + format: crate::AccelerationStructureFormat, +) -> vk::AccelerationStructureTypeKHR { + match format { + crate::AccelerationStructureFormat::TopLevel => vk::AccelerationStructureTypeKHR::TOP_LEVEL, + crate::AccelerationStructureFormat::BottomLevel => { + vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL + } + } +} + +pub fn map_acceleration_structure_build_mode( + format: crate::AccelerationStructureBuildMode, +) -> vk::BuildAccelerationStructureModeKHR { + match format { + crate::AccelerationStructureBuildMode::Build => { + vk::BuildAccelerationStructureModeKHR::BUILD + } + crate::AccelerationStructureBuildMode::Update => { + vk::BuildAccelerationStructureModeKHR::UPDATE + } + } +} diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 5f9a326608..79a12e689b 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -809,11 +809,53 @@ impl crate::Device for super::Device { }) } - unsafe fn create_acceleration_structure(&self, desc: &crate::AccelerationStructureDescriptor) -> Result { - let functor = match self.shared.extension_fns.acceleration_structure { - Some(ref functor) => { - functor - } + unsafe fn get_acceleration_structure_build_size( + &self, + geometry: &crate::AccelerationStructureGeometry, + format: crate::AccelerationStructureFormat, + mode: crate::AccelerationStructureBuildMode, + flags: (), + primitive_count: u32, + ) -> crate::AccelerationStructureBuildSizes { + let extension = match self.shared.extension_fns.acceleration_structure { + Some(ref extension) => extension, + None => panic!("Feature `RAY_TRACING` not enabled"), + }; + + let bda_extension = match self.shared.extension_fns.buffer_device_address { + Some(ref extension) => extension, + None => panic!("Feature `BDA` not enabled"), + }; + + let geometry = map_acceleration_structure_geometry(geometry, &bda_extension); + + let geometries = &[*geometry]; + + let geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() + .ty(conv::map_acceleration_structure_format(format)) + .mode(conv::map_acceleration_structure_build_mode(mode)) + .flags(vk::BuildAccelerationStructureFlagsKHR::PREFER_FAST_TRACE) + .geometries(geometries); + + let raw = extension.get_acceleration_structure_build_sizes( + vk::AccelerationStructureBuildTypeKHR::DEVICE, + &geometry_info, + &[primitive_count], + ); + + crate::AccelerationStructureBuildSizes { + acceleration_structure_size: raw.acceleration_structure_size, + update_scratch_size: raw.update_scratch_size, + build_scratch_size: raw.build_scratch_size, + } + } + + unsafe fn create_acceleration_structure( + &self, + desc: &crate::AccelerationStructureDescriptor, + ) -> Result { + let extension = match self.shared.extension_fns.acceleration_structure { + Some(ref extension) => extension, None => panic!("Feature `RAY_TRACING` not enabled"), }; @@ -821,14 +863,12 @@ impl crate::Device for super::Device { .size(desc.size) .usage( vk::BufferUsageFlags::ACCELERATION_STRUCTURE_STORAGE_KHR - | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS + | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, ) .sharing_mode(vk::SharingMode::EXCLUSIVE); let raw_buffer = self.shared.raw.create_buffer(&vk_buffer_info, None)?; let req = self.shared.raw.get_buffer_memory_requirements(raw_buffer); - - dbg!(&req); let block = self.mem_allocator.lock().alloc( &*self.shared, @@ -849,27 +889,20 @@ impl crate::Device for super::Device { .set_object_name(vk::ObjectType::BUFFER, raw_buffer, label); } - let ty = match desc.format { - crate::AccelerationStructureFormat::TopLevel => vk::AccelerationStructureTypeKHR::TOP_LEVEL, - crate::AccelerationStructureFormat::BottomLevel => vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL, - }; - let vk_info = vk::AccelerationStructureCreateInfoKHR::builder() - .buffer(raw_buffer) - .offset(256) - .size(desc.size / 2) - .ty(ty).build(); - - dbg!(&vk_info); + .buffer(raw_buffer) + .offset(0) + .size(desc.size) + .ty(conv::map_acceleration_structure_format(desc.format)); - let raw_acceleration_structure = functor.create_acceleration_structure( - &vk_info, - None, - )?; + let raw_acceleration_structure = extension.create_acceleration_structure(&vk_info, None)?; if let Some(label) = desc.label { - self.shared - .set_object_name(vk::ObjectType::ACCELERATION_STRUCTURE_KHR, raw_acceleration_structure, label); + self.shared.set_object_name( + vk::ObjectType::ACCELERATION_STRUCTURE_KHR, + raw_acceleration_structure, + label, + ); } Ok(super::AccelerationStructure { @@ -2006,3 +2039,63 @@ impl From for crate::DeviceError { Self::OutOfMemory } } + +pub unsafe fn map_acceleration_structure_geometry<'a>( + geometry: &crate::AccelerationStructureGeometry, + buffer_device_address: &ash::extensions::khr::BufferDeviceAddress, +) -> vk::AccelerationStructureGeometryKHRBuilder<'a> { + match geometry { + crate::AccelerationStructureGeometry::Instances { buffer } => { + let instances = vk::AccelerationStructureGeometryInstancesDataKHR::builder().data( + vk::DeviceOrHostAddressConstKHR { + device_address: buffer_device_address.get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), + ), + }, + ); + + vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::INSTANCES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + instances: *instances, + }) + .flags(vk::GeometryFlagsKHR::empty()) + } + &crate::AccelerationStructureGeometry::Triangles { + vertex_buffer, + vertex_format, + max_vertex, + vertex_stride, + ref indices, + } => { + let mut triangles_data = vk::AccelerationStructureGeometryTrianglesDataKHR::builder() + .vertex_data(vk::DeviceOrHostAddressConstKHR { + device_address: buffer_device_address.get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(vertex_buffer.raw), + ), + }) + .vertex_format(conv::map_vertex_format(vertex_format)) + .vertex_stride(vertex_stride) + .max_vertex(max_vertex); + + if let Some(indices) = indices { + triangles_data = triangles_data + .index_type(conv::map_index_format(indices.format)) + .index_data(vk::DeviceOrHostAddressConstKHR { + device_address: buffer_device_address.get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(indices.buffer.raw), + ), + }) + } + + let triangles_data = triangles_data.build(); + + vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::TRIANGLES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + triangles: triangles_data, + }) + .flags(vk::GeometryFlagsKHR::empty()) + } + } +} diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 443d7f1422..5732fbfb60 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -149,6 +149,7 @@ struct DeviceExtensionFunctions { draw_indirect_count: Option, timeline_semaphore: Option>, acceleration_structure: Option, + buffer_device_address: Option, } /// Set of internal capabilities, which don't show up in the exposed From 98cf75b594f378ef6b186c27f955e60469234a73 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Sun, 11 Sep 2022 23:29:49 +0200 Subject: [PATCH 003/146] Fix alignment for amdpro driver --- wgpu-hal/examples/halmark/main.rs | 179 +++++++++++++++++++++++++++++- wgpu-hal/src/empty.rs | 7 ++ wgpu-hal/src/lib.rs | 10 +- wgpu-hal/src/vulkan/conv.rs | 13 ++- wgpu-hal/src/vulkan/device.rs | 47 +++++++- 5 files changed, 245 insertions(+), 11 deletions(-) diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index ef92b30f7f..eeb3838533 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -78,6 +78,8 @@ struct Example { context_index: usize, extent: [u32; 2], start: Instant, + buffers: Vec, + acceleration_structures: Vec, } impl Example { @@ -288,7 +290,7 @@ impl Example { size: triangle_size as u64, usage: hal::BufferUses::MAP_WRITE | hal::BufferUses::BUFFER_DEVICE_ADDRESS - | hal::BufferUses::ACCELERATION_STRUCTURE_BUILD_INPUT, + | hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, }) .unwrap() @@ -301,7 +303,7 @@ impl Example { size: indices_size as u64, usage: hal::BufferUses::MAP_WRITE | hal::BufferUses::BUFFER_DEVICE_ADDRESS - | hal::BufferUses::ACCELERATION_STRUCTURE_BUILD_INPUT, + | hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, }) .unwrap() @@ -316,7 +318,7 @@ impl Example { mapping.ptr.as_ptr(), triangle_size, ); - device.unmap_buffer(&staging_buffer).unwrap(); + device.unmap_buffer(&triangle_buffer).unwrap(); assert!(mapping.is_coherent); } @@ -327,7 +329,7 @@ impl Example { mapping.ptr.as_ptr(), indices_size, ); - device.unmap_buffer(&staging_buffer).unwrap(); + device.unmap_buffer(&i_buf).unwrap(); assert!(mapping.is_coherent); } @@ -375,6 +377,146 @@ impl Example { .unwrap() }; + #[derive(Clone, Copy)] + struct Vec4 { + x: f32, + y: f32, + z: f32, + w: f32, + } + + struct Mat4 { + rows: [Vec4; 4], + } + + impl Mat4 { + const fn from_translation(x: f32, y: f32, z: f32) -> Self { + Mat4 { + rows: [ + Vec4 { + x: 1.0, + y: 0.0, + z: 0.0, + w: 0.0, + }, + Vec4 { + x: 0.0, + y: 1.0, + z: 0.0, + w: 0.0, + }, + Vec4 { + x: 0.0, + y: 0.0, + z: 1.0, + w: 0.0, + }, + Vec4 { x, y, z, w: 1.0 }, + ], + } + } + } + + fn transpose_matrix_for_acceleration_structure_instance(matrix: Mat4) -> [f32; 12] { + let row_0 = matrix.rows[0]; + let row_1 = matrix.rows[1]; + let row_2 = matrix.rows[2]; + [ + row_0.x, row_0.y, row_0.z, row_0.w, row_1.x, row_1.y, row_1.z, row_1.w, row_2.x, + row_2.y, row_2.z, row_2.w, + ] + } + + fn pack_24_8(low_24: u32, high_8: u8) -> u32 { + (low_24 & 0x00ff_ffff) | (u32::from(high_8) << 24) + } + + #[derive(Debug)] + #[repr(C)] + struct Instance { + transform: [f32; 12], + instance_custom_index_and_mask: u32, + instance_shader_binding_table_record_offset_and_flags: u32, + acceleration_structure_reference: u64, + } + + let instances = unsafe { + [ + Instance { + transform: transpose_matrix_for_acceleration_structure_instance( + Mat4::from_translation(0.0, 0.0, 0.0), + ), + instance_custom_index_and_mask: pack_24_8(0, 0xff), + instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), + acceleration_structure_reference: device + .get_acceleration_structure_device_address(&blas), + }, + Instance { + transform: transpose_matrix_for_acceleration_structure_instance( + Mat4::from_translation(1.0, 1.0, 1.0), + ), + instance_custom_index_and_mask: pack_24_8(0, 0xff), + instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), + acceleration_structure_reference: device + .get_acceleration_structure_device_address(&blas), + }, + ] + }; + + let instances_buffer_size = instances.len() * std::mem::size_of::(); + + dbg!(&instances_buffer_size); + + let instances_buffer = unsafe { + device + .create_buffer(&hal::BufferDescriptor { + label: Some("instances_buffer"), + size: instances_buffer_size as u64, + usage: hal::BufferUses::MAP_WRITE + | hal::BufferUses::BUFFER_DEVICE_ADDRESS + | hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, + }) + .unwrap() + }; + + unsafe { + let mapping = device + .map_buffer(&instances_buffer, 0..instances_buffer_size as u64) + .unwrap(); + ptr::copy_nonoverlapping( + instances.as_ptr() as *const u8, + mapping.ptr.as_ptr(), + instances_buffer_size, + ); + device.unmap_buffer(&instances_buffer).unwrap(); + assert!(mapping.is_coherent); + } + + let instance_geometry: hal::AccelerationStructureGeometry = + hal::AccelerationStructureGeometry::Instances { + buffer: &instances_buffer, + }; + + let instance_sizes = unsafe { + device.get_acceleration_structure_build_size( + &instance_geometry, + hal::AccelerationStructureFormat::TopLevel, + hal::AccelerationStructureBuildMode::Build, + (), + 2, + ) + }; + + let tlas = unsafe { + device.create_acceleration_structure(&hal::AccelerationStructureDescriptor { + label: Some("my tlas"), + size: instance_sizes.acceleration_structure_size, + format: hal::AccelerationStructureFormat::TopLevel, + }) + } + .unwrap(); + let texture_desc = hal::TextureDescriptor { label: None, size: wgt::Extent3d { @@ -410,6 +552,24 @@ impl Example { &blas, &scratch_buffer, ); + + let as_barrier = hal::BufferBarrier { + buffer: &staging_buffer, + usage: hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT + ..hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + }; + cmd_encoder.transition_buffers(iter::once(as_barrier)); + + cmd_encoder.build_acceleration_structures( + &instance_geometry, + hal::AccelerationStructureFormat::TopLevel, + hal::AccelerationStructureBuildMode::Build, + (), + 2, + 0, + &tlas, + &scratch_buffer, + ); } { @@ -623,6 +783,8 @@ impl Example { context_index: 0, extent: [window_size.0, window_size.1], start: Instant::now(), + buffers: vec![triangle_buffer, i_buf, scratch_buffer, instances_buffer], + acceleration_structures: vec![blas, tlas], }) } @@ -651,6 +813,15 @@ impl Example { self.device.destroy_buffer(self.global_buffer); self.device.destroy_texture_view(self.texture_view); self.device.destroy_texture(self.texture); + + for buffer in self.buffers.drain(..) { + self.device.destroy_buffer(buffer); + } + + for a_s in self.acceleration_structures.drain(..) { + self.device.destroy_acceleration_structure(a_s); + } + self.device.destroy_sampler(self.sampler); self.device.destroy_shader_module(self.shader); self.device.destroy_render_pipeline(self.pipeline); diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 8119af97c3..904f4d119b 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -135,6 +135,13 @@ impl crate::Device for Context { ) -> crate::AccelerationStructureBuildSizes { Default::default() } + unsafe fn get_acceleration_structure_device_address( + &self, + _acceleration_structure: &Resource, + ) -> wgt::BufferAddress { + Default::default() + } + unsafe fn destroy_acceleration_structure(&self, buffer: Resource) {} unsafe fn destroy_buffer(&self, buffer: Resource) {} unsafe fn map_buffer( &self, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index e475c5748a..212a31d848 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -253,6 +253,13 @@ pub trait Device: Send + Sync { primitive_count: u32, ) -> AccelerationStructureBuildSizes; + unsafe fn get_acceleration_structure_device_address( + &self, + acceleration_structure: &A::AccelerationStructure, + ) -> wgt::BufferAddress; + + unsafe fn destroy_acceleration_structure(&self, buffer: A::AccelerationStructure); + unsafe fn destroy_buffer(&self, buffer: A::Buffer); //TODO: clarify if zero-sized mapping is allowed unsafe fn map_buffer( @@ -689,7 +696,8 @@ bitflags::bitflags! { /// The indirect or count buffer in a indirect draw or dispatch. const INDIRECT = 1 << 9; const BUFFER_DEVICE_ADDRESS = 1 << 10; - const ACCELERATION_STRUCTURE_BUILD_INPUT = 1 << 11; + const BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT = 1 << 11; + const TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT = 1 << 12; /// The combination of states that a buffer may be in _at the same time_. const INCLUSIVE = Self::MAP_READ.bits | Self::COPY_SRC.bits | Self::INDEX.bits | Self::VERTEX.bits | Self::UNIFORM.bits | diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index 95ff907f83..f8d6e68f1f 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -494,7 +494,10 @@ pub fn map_buffer_usage(usage: crate::BufferUses) -> vk::BufferUsageFlags { if usage.contains(crate::BufferUses::BUFFER_DEVICE_ADDRESS) { flags |= vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS; } - if usage.contains(crate::BufferUses::ACCELERATION_STRUCTURE_BUILD_INPUT) { + if usage.intersects( + crate::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT + | crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) { flags |= vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR; } flags @@ -549,6 +552,14 @@ pub fn map_buffer_usage_to_barrier( stages |= vk::PipelineStageFlags::DRAW_INDIRECT; access |= vk::AccessFlags::INDIRECT_COMMAND_READ; } + if usage.intersects( + crate::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT + | crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) { + stages |= vk::PipelineStageFlags::ACCELERATION_STRUCTURE_BUILD_KHR; + access |= vk::AccessFlags::ACCELERATION_STRUCTURE_READ_KHR + | vk::AccessFlags::ACCELERATION_STRUCTURE_WRITE_KHR; + } (stages, access) } diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 79a12e689b..a0cfe725d9 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -788,7 +788,14 @@ impl crate::Device for super::Device { &*self.shared, gpu_alloc::Request { size: req.size, - align_mask: req.alignment - 1, + align_mask: if desc + .usage + .contains(crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT) + { + 16 + } else { + req.alignment + } - 1, usage: alloc_usage, memory_types: req.memory_type_bits & self.valid_ash_memory_types, }, @@ -850,6 +857,21 @@ impl crate::Device for super::Device { } } + unsafe fn get_acceleration_structure_device_address( + &self, + acceleration_structure: &super::AccelerationStructure, + ) -> wgt::BufferAddress { + let extension = match self.shared.extension_fns.acceleration_structure { + Some(ref extension) => extension, + None => panic!("Feature `RAY_TRACING` not enabled"), + }; + + extension.get_acceleration_structure_device_address( + &vk::AccelerationStructureDeviceAddressInfoKHR::builder() + .acceleration_structure(acceleration_structure.raw), + ) + } + unsafe fn create_acceleration_structure( &self, desc: &crate::AccelerationStructureDescriptor, @@ -861,10 +883,7 @@ impl crate::Device for super::Device { let vk_buffer_info = vk::BufferCreateInfo::builder() .size(desc.size) - .usage( - vk::BufferUsageFlags::ACCELERATION_STRUCTURE_STORAGE_KHR - | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, - ) + .usage(vk::BufferUsageFlags::ACCELERATION_STRUCTURE_STORAGE_KHR) .sharing_mode(vk::SharingMode::EXCLUSIVE); let raw_buffer = self.shared.raw.create_buffer(&vk_buffer_info, None)?; @@ -919,6 +938,24 @@ impl crate::Device for super::Device { .dealloc(&*self.shared, buffer.block.into_inner()); } + unsafe fn destroy_acceleration_structure( + &self, + acceleration_structure: super::AccelerationStructure, + ) { + let extension = match self.shared.extension_fns.acceleration_structure { + Some(ref extension) => extension, + None => panic!("Feature `RAY_TRACING` not enabled"), + }; + + extension.destroy_acceleration_structure(acceleration_structure.raw, None); + self.shared + .raw + .destroy_buffer(acceleration_structure.buffer, None); + self.mem_allocator + .lock() + .dealloc(&*self.shared, acceleration_structure.block.into_inner()); + } + unsafe fn map_buffer( &self, buffer: &super::Buffer, From 6655d2380495302a460e20692b6f91c80c1ffdb0 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Mon, 12 Sep 2022 23:26:26 +0200 Subject: [PATCH 004/146] Ray tracing works in shaders! --- Cargo.lock | 9 +- wgpu-hal/Cargo.toml | 1 + wgpu-hal/examples/halmark/main.rs | 296 +------ wgpu-hal/examples/ray-traced-triangle/main.rs | 829 ++++++++++++++++++ .../examples/ray-traced-triangle/shader.comp | 44 + .../ray-traced-triangle/shader.comp.spv | Bin 0 -> 3520 bytes wgpu-hal/src/empty.rs | 4 +- wgpu-hal/src/lib.rs | 20 +- wgpu-hal/src/vulkan/command.rs | 61 +- wgpu-hal/src/vulkan/conv.rs | 1 + wgpu-hal/src/vulkan/device.rs | 141 +-- wgpu-types/src/lib.rs | 2 + 12 files changed, 1035 insertions(+), 373 deletions(-) create mode 100644 wgpu-hal/examples/ray-traced-triangle/main.rs create mode 100644 wgpu-hal/examples/ray-traced-triangle/shader.comp create mode 100644 wgpu-hal/examples/ray-traced-triangle/shader.comp.spv diff --git a/Cargo.lock b/Cargo.lock index 7b48ee4aad..7fea60ce6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -814,6 +814,12 @@ version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f43e957e744be03f5801a55472f593d43fabdebf25a4585db250f04d86b1675f" +[[package]] +name = "glam" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "518faa5064866338b013ff9b2350dc318e14cc4fcd6cb8206d7e7c9886c98815" + [[package]] name = "glow" version = "0.11.2" @@ -2352,7 +2358,7 @@ dependencies = [ "ddsfile", "env_logger", "futures-intrusive", - "glam", + "glam 0.20.5", "js-sys", "log", "naga", @@ -2414,6 +2420,7 @@ dependencies = [ "env_logger", "foreign-types 0.3.2", "fxhash", + "glam 0.21.3", "glow", "glutin", "gpu-alloc", diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index b89f400537..9fcc70e8b6 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -109,6 +109,7 @@ features = ["wgsl-in"] [dev-dependencies] env_logger = "0.9" winit = "0.27.1" # for "halmark" example +glam = "0.21.3" # for ray-traced-triangle example [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] glutin = "0.28.0" # for "gles" example diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index eeb3838533..bd8196d8dc 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -78,8 +78,6 @@ struct Example { context_index: usize, extent: [u32; 2], start: Instant, - buffers: Vec, - acceleration_structures: Vec, } impl Example { @@ -254,9 +252,7 @@ impl Example { let staging_buffer_desc = hal::BufferDescriptor { label: Some("stage"), size: texture_data.len() as wgt::BufferAddress, - usage: hal::BufferUses::MAP_WRITE - | hal::BufferUses::COPY_SRC - | hal::BufferUses::BUFFER_DEVICE_ADDRESS, + usage: hal::BufferUses::MAP_WRITE | hal::BufferUses::COPY_SRC, memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, }; let staging_buffer = unsafe { device.create_buffer(&staging_buffer_desc).unwrap() }; @@ -273,250 +269,6 @@ impl Example { assert!(mapping.is_coherent); } - let triangle: [f32; 9] = [0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0]; - - let triangle_size = std::mem::size_of::<[f32; 9]>(); - - dbg!(&triangle_size); - - let indices: [u32; 3] = [0, 1, 2]; - - let indices_size = std::mem::size_of::<[u32; 3]>(); - - let triangle_buffer = unsafe { - device - .create_buffer(&hal::BufferDescriptor { - label: Some("t buf"), - size: triangle_size as u64, - usage: hal::BufferUses::MAP_WRITE - | hal::BufferUses::BUFFER_DEVICE_ADDRESS - | hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, - memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, - }) - .unwrap() - }; - - let i_buf = unsafe { - device - .create_buffer(&hal::BufferDescriptor { - label: Some("i buf"), - size: indices_size as u64, - usage: hal::BufferUses::MAP_WRITE - | hal::BufferUses::BUFFER_DEVICE_ADDRESS - | hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, - memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, - }) - .unwrap() - }; - - unsafe { - let mapping = device - .map_buffer(&triangle_buffer, 0..triangle_size as u64) - .unwrap(); - ptr::copy_nonoverlapping( - triangle.as_ptr() as *const u8, - mapping.ptr.as_ptr(), - triangle_size, - ); - device.unmap_buffer(&triangle_buffer).unwrap(); - assert!(mapping.is_coherent); - } - - unsafe { - let mapping = device.map_buffer(&i_buf, 0..indices_size as u64).unwrap(); - ptr::copy_nonoverlapping( - indices.as_ptr() as *const u8, - mapping.ptr.as_ptr(), - indices_size, - ); - device.unmap_buffer(&i_buf).unwrap(); - assert!(mapping.is_coherent); - } - - let geometry = hal::AccelerationStructureGeometry::Triangles { - vertex_buffer: &triangle_buffer, - vertex_format: wgt::VertexFormat::Float32x3, - max_vertex: 3, - vertex_stride: 3 * 4, - indices: Some(hal::AccelerationStructureGeometryIndices { - buffer: &i_buf, - format: wgt::IndexFormat::Uint32, - }), - }; - - let sizes = unsafe { - device.get_acceleration_structure_build_size( - &geometry, - hal::AccelerationStructureFormat::BottomLevel, - hal::AccelerationStructureBuildMode::Build, - (), - 1, - ) - }; - - dbg!(&sizes); - - let blas = unsafe { - device.create_acceleration_structure(&hal::AccelerationStructureDescriptor { - label: Some("my as"), - size: sizes.acceleration_structure_size, - format: hal::AccelerationStructureFormat::BottomLevel, - }) - } - .unwrap(); - - let scratch_buffer = unsafe { - device - .create_buffer(&hal::BufferDescriptor { - label: Some("scratch buffer"), - size: sizes.build_scratch_size, - usage: hal::BufferUses::BUFFER_DEVICE_ADDRESS - | hal::BufferUses::STORAGE_READ_WRITE, - memory_flags: hal::MemoryFlags::empty(), - }) - .unwrap() - }; - - #[derive(Clone, Copy)] - struct Vec4 { - x: f32, - y: f32, - z: f32, - w: f32, - } - - struct Mat4 { - rows: [Vec4; 4], - } - - impl Mat4 { - const fn from_translation(x: f32, y: f32, z: f32) -> Self { - Mat4 { - rows: [ - Vec4 { - x: 1.0, - y: 0.0, - z: 0.0, - w: 0.0, - }, - Vec4 { - x: 0.0, - y: 1.0, - z: 0.0, - w: 0.0, - }, - Vec4 { - x: 0.0, - y: 0.0, - z: 1.0, - w: 0.0, - }, - Vec4 { x, y, z, w: 1.0 }, - ], - } - } - } - - fn transpose_matrix_for_acceleration_structure_instance(matrix: Mat4) -> [f32; 12] { - let row_0 = matrix.rows[0]; - let row_1 = matrix.rows[1]; - let row_2 = matrix.rows[2]; - [ - row_0.x, row_0.y, row_0.z, row_0.w, row_1.x, row_1.y, row_1.z, row_1.w, row_2.x, - row_2.y, row_2.z, row_2.w, - ] - } - - fn pack_24_8(low_24: u32, high_8: u8) -> u32 { - (low_24 & 0x00ff_ffff) | (u32::from(high_8) << 24) - } - - #[derive(Debug)] - #[repr(C)] - struct Instance { - transform: [f32; 12], - instance_custom_index_and_mask: u32, - instance_shader_binding_table_record_offset_and_flags: u32, - acceleration_structure_reference: u64, - } - - let instances = unsafe { - [ - Instance { - transform: transpose_matrix_for_acceleration_structure_instance( - Mat4::from_translation(0.0, 0.0, 0.0), - ), - instance_custom_index_and_mask: pack_24_8(0, 0xff), - instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), - acceleration_structure_reference: device - .get_acceleration_structure_device_address(&blas), - }, - Instance { - transform: transpose_matrix_for_acceleration_structure_instance( - Mat4::from_translation(1.0, 1.0, 1.0), - ), - instance_custom_index_and_mask: pack_24_8(0, 0xff), - instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), - acceleration_structure_reference: device - .get_acceleration_structure_device_address(&blas), - }, - ] - }; - - let instances_buffer_size = instances.len() * std::mem::size_of::(); - - dbg!(&instances_buffer_size); - - let instances_buffer = unsafe { - device - .create_buffer(&hal::BufferDescriptor { - label: Some("instances_buffer"), - size: instances_buffer_size as u64, - usage: hal::BufferUses::MAP_WRITE - | hal::BufferUses::BUFFER_DEVICE_ADDRESS - | hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, - memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, - }) - .unwrap() - }; - - unsafe { - let mapping = device - .map_buffer(&instances_buffer, 0..instances_buffer_size as u64) - .unwrap(); - ptr::copy_nonoverlapping( - instances.as_ptr() as *const u8, - mapping.ptr.as_ptr(), - instances_buffer_size, - ); - device.unmap_buffer(&instances_buffer).unwrap(); - assert!(mapping.is_coherent); - } - - let instance_geometry: hal::AccelerationStructureGeometry = - hal::AccelerationStructureGeometry::Instances { - buffer: &instances_buffer, - }; - - let instance_sizes = unsafe { - device.get_acceleration_structure_build_size( - &instance_geometry, - hal::AccelerationStructureFormat::TopLevel, - hal::AccelerationStructureBuildMode::Build, - (), - 2, - ) - }; - - let tlas = unsafe { - device.create_acceleration_structure(&hal::AccelerationStructureDescriptor { - label: Some("my tlas"), - size: instance_sizes.acceleration_structure_size, - format: hal::AccelerationStructureFormat::TopLevel, - }) - } - .unwrap(); - let texture_desc = hal::TextureDescriptor { label: None, size: wgt::Extent3d { @@ -539,39 +291,6 @@ impl Example { }; let mut cmd_encoder = unsafe { device.create_command_encoder(&cmd_encoder_desc).unwrap() }; unsafe { cmd_encoder.begin_encoding(Some("init")).unwrap() }; - - unsafe { - // todo: extract out bytes from transmission renderer example and try those. - cmd_encoder.build_acceleration_structures( - &geometry, - hal::AccelerationStructureFormat::BottomLevel, - hal::AccelerationStructureBuildMode::Build, - (), - 1, - 0, - &blas, - &scratch_buffer, - ); - - let as_barrier = hal::BufferBarrier { - buffer: &staging_buffer, - usage: hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT - ..hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, - }; - cmd_encoder.transition_buffers(iter::once(as_barrier)); - - cmd_encoder.build_acceleration_structures( - &instance_geometry, - hal::AccelerationStructureFormat::TopLevel, - hal::AccelerationStructureBuildMode::Build, - (), - 2, - 0, - &tlas, - &scratch_buffer, - ); - } - { let buffer_barrier = hal::BufferBarrier { buffer: &staging_buffer, @@ -696,6 +415,7 @@ impl Example { buffers: &[global_buffer_binding], samplers: &[&sampler], textures: &[texture_binding], + acceleration_structures: &[], entries: &[ hal::BindGroupEntry { binding: 0, @@ -729,6 +449,7 @@ impl Example { buffers: &[local_buffer_binding], samplers: &[], textures: &[], + acceleration_structures: &[], entries: &[hal::BindGroupEntry { binding: 0, resource_index: 0, @@ -783,8 +504,6 @@ impl Example { context_index: 0, extent: [window_size.0, window_size.1], start: Instant::now(), - buffers: vec![triangle_buffer, i_buf, scratch_buffer, instances_buffer], - acceleration_structures: vec![blas, tlas], }) } @@ -813,15 +532,6 @@ impl Example { self.device.destroy_buffer(self.global_buffer); self.device.destroy_texture_view(self.texture_view); self.device.destroy_texture(self.texture); - - for buffer in self.buffers.drain(..) { - self.device.destroy_buffer(buffer); - } - - for a_s in self.acceleration_structures.drain(..) { - self.device.destroy_acceleration_structure(a_s); - } - self.device.destroy_sampler(self.sampler); self.device.destroy_shader_module(self.shader); self.device.destroy_render_pipeline(self.pipeline); diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs new file mode 100644 index 0000000000..93f62eac04 --- /dev/null +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -0,0 +1,829 @@ +extern crate wgpu_hal as hal; + +use hal::{ + Adapter as _, CommandEncoder as _, Device as _, Instance as _, Queue as _, Surface as _, +}; + +use glam::{Mat4, Vec3}; +use std::{ + borrow::{Borrow, Cow}, + iter, mem, + mem::{align_of, size_of}, + ptr::{self, copy_nonoverlapping}, + time::Instant, +}; + +const COMMAND_BUFFER_PER_CONTEXT: usize = 100; +const DESIRED_FRAMES: u32 = 3; + +struct ExecutionContext { + encoder: A::CommandEncoder, + fence: A::Fence, + fence_value: hal::FenceValue, + used_views: Vec, + used_cmd_bufs: Vec, + frames_recorded: usize, +} + +impl ExecutionContext { + unsafe fn wait_and_clear(&mut self, device: &A::Device) { + device.wait(&self.fence, self.fence_value, !0).unwrap(); + self.encoder.reset_all(self.used_cmd_bufs.drain(..)); + for view in self.used_views.drain(..) { + device.destroy_texture_view(view); + } + self.frames_recorded = 0; + } +} + +#[allow(dead_code)] +struct Example { + instance: A::Instance, + adapter: A::Adapter, + surface: A::Surface, + surface_format: wgt::TextureFormat, + device: A::Device, + queue: A::Queue, + + contexts: Vec>, + context_index: usize, + extent: [u32; 2], + start: Instant, + pipeline: A::ComputePipeline, + bind_group: A::BindGroup, + //local_group: A::BindGroup, + //global_group_layout: A::BindGroupLayout, + //local_group_layout: A::BindGroupLayout, + pipeline_layout: A::PipelineLayout, + /*shader: A::ShaderModule, + pipeline: A::RenderPipeline, + bunnies: Vec, + local_buffer: A::Buffer, + local_alignment: u32, + global_buffer: A::Buffer, + sampler: A::Sampler, + */ + texture: A::Texture, + /*texture_view: A::TextureView, + contexts: Vec>, + context_index: usize, + extent: [u32; 2], + start: Instant, + buffers: Vec, + acceleration_structures: Vec,*/ +} + +impl Example { + fn init(window: &winit::window::Window) -> Result { + let instance_desc = hal::InstanceDescriptor { + name: "example", + flags: if cfg!(debug_assertions) { + hal::InstanceFlags::all() + } else { + hal::InstanceFlags::empty() + }, + }; + let instance = unsafe { A::Instance::init(&instance_desc)? }; + let mut surface = unsafe { instance.create_surface(window).unwrap() }; + + let (adapter, _capabilities) = unsafe { + let mut adapters = instance.enumerate_adapters(); + if adapters.is_empty() { + return Err(hal::InstanceError); + } + let exposed = adapters.swap_remove(0); + (exposed.adapter, exposed.capabilities) + }; + let surface_caps = + unsafe { adapter.surface_capabilities(&surface) }.ok_or(hal::InstanceError)?; + log::info!("Surface caps: {:#?}", surface_caps); + + let hal::OpenDevice { device, mut queue } = unsafe { + adapter + .open(wgt::Features::empty(), &wgt::Limits::default()) + .unwrap() + }; + + let window_size: (u32, u32) = window.inner_size().into(); + let surface_config = hal::SurfaceConfiguration { + swap_chain_size: DESIRED_FRAMES + .max(*surface_caps.swap_chain_sizes.start()) + .min(*surface_caps.swap_chain_sizes.end()), + present_mode: wgt::PresentMode::Fifo, + composite_alpha_mode: hal::CompositeAlphaMode::Opaque, + format: wgt::TextureFormat::Rgba8Unorm, + extent: wgt::Extent3d { + width: window_size.0, + height: window_size.1, + depth_or_array_layers: 1, + }, + usage: hal::TextureUses::COLOR_TARGET | hal::TextureUses::COPY_DST, + }; + unsafe { + surface.configure(&device, &surface_config).unwrap(); + }; + + #[allow(dead_code)] + struct Uniforms { + view_inverse: glam::Mat4, + proj_inverse: glam::Mat4, + } + + let bgl_desc = hal::BindGroupLayoutDescriptor { + label: None, + flags: hal::BindGroupLayoutFlags::empty(), + entries: &[ + wgt::BindGroupLayoutEntry { + binding: 0, + visibility: wgt::ShaderStages::COMPUTE, + ty: wgt::BindingType::Buffer { + ty: wgt::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: wgt::BufferSize::new(mem::size_of::() as _), + }, + count: None, + }, + wgt::BindGroupLayoutEntry { + binding: 1, + visibility: wgt::ShaderStages::COMPUTE, + ty: wgt::BindingType::StorageTexture { + access: wgt::StorageTextureAccess::WriteOnly, + format: wgt::TextureFormat::Rgba8Unorm, + view_dimension: wgt::TextureViewDimension::D2, + }, + count: None, + }, + wgt::BindGroupLayoutEntry { + binding: 2, + visibility: wgt::ShaderStages::COMPUTE, + ty: wgt::BindingType::AccelerationStructure, + count: None, + }, + ], + }; + + let bgl = unsafe { device.create_bind_group_layout(&bgl_desc).unwrap() }; + + pub fn make_spirv_raw(data: &[u8]) -> Cow<[u32]> { + const MAGIC_NUMBER: u32 = 0x0723_0203; + assert_eq!( + data.len() % size_of::(), + 0, + "data size is not a multiple of 4" + ); + + //If the data happens to be aligned, directly use the byte array, + // otherwise copy the byte array in an owned vector and use that instead. + let words = if data.as_ptr().align_offset(align_of::()) == 0 { + let (pre, words, post) = unsafe { data.align_to::() }; + debug_assert!(pre.is_empty()); + debug_assert!(post.is_empty()); + Cow::from(words) + } else { + let mut words = vec![0u32; data.len() / size_of::()]; + unsafe { + copy_nonoverlapping(data.as_ptr(), words.as_mut_ptr() as *mut u8, data.len()); + } + Cow::from(words) + }; + + assert_eq!( + words[0], MAGIC_NUMBER, + "wrong magic word {:x}. Make sure you are using a binary SPIRV file.", + words[0] + ); + + words + } + + let shader = unsafe { + device + .create_shader_module( + &hal::ShaderModuleDescriptor { + label: None, + runtime_checks: false, + }, + hal::ShaderInput::SpirV(&make_spirv_raw(include_bytes!("shader.comp.spv"))), + ) + .unwrap() + }; + + let pipeline_layout_desc = hal::PipelineLayoutDescriptor { + label: None, + flags: hal::PipelineLayoutFlags::empty(), + bind_group_layouts: &[&bgl], + push_constant_ranges: &[], + }; + let pipeline_layout = unsafe { + device + .create_pipeline_layout(&pipeline_layout_desc) + .unwrap() + }; + + let pipeline = unsafe { + device.create_compute_pipeline(&hal::ComputePipelineDescriptor { + label: Some("pipeline"), + layout: &pipeline_layout, + stage: hal::ProgrammableStage { + module: &shader, + entry_point: "main", + }, + }) + } + .unwrap(); + + let vertices: [f32; 9] = [1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, -1.0, 0.0]; + + let vertices_size_in_bytes = vertices.len() * 4; + + let indices: [u32; 3] = [0, 1, 2]; + + let indices_size_in_bytes = indices.len() * 4; + + let transform_matrix = [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0]; + + let vertices_buffer = unsafe { + let vertices_buffer = device + .create_buffer(&hal::BufferDescriptor { + label: Some("vertices buffer"), + size: vertices_size_in_bytes as u64, + usage: hal::BufferUses::MAP_WRITE + | hal::BufferUses::BUFFER_DEVICE_ADDRESS + | hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, + }) + .unwrap(); + + let mapping = device + .map_buffer(&vertices_buffer, 0..vertices_size_in_bytes as u64) + .unwrap(); + ptr::copy_nonoverlapping( + vertices.as_ptr() as *const u8, + mapping.ptr.as_ptr(), + vertices_size_in_bytes, + ); + device.unmap_buffer(&vertices_buffer).unwrap(); + assert!(mapping.is_coherent); + + vertices_buffer + }; + + let indices_buffer = unsafe { + let indices_buffer = device + .create_buffer(&hal::BufferDescriptor { + label: Some("indices buffer"), + size: indices_size_in_bytes as u64, + usage: hal::BufferUses::MAP_WRITE + | hal::BufferUses::BUFFER_DEVICE_ADDRESS + | hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, + }) + .unwrap(); + + let mapping = device + .map_buffer(&indices_buffer, 0..indices_size_in_bytes as u64) + .unwrap(); + ptr::copy_nonoverlapping( + indices.as_ptr() as *const u8, + mapping.ptr.as_ptr(), + indices_size_in_bytes, + ); + device.unmap_buffer(&indices_buffer).unwrap(); + assert!(mapping.is_coherent); + + indices_buffer + }; + + let blas_sizes = unsafe { + device.get_acceleration_structure_build_sizes( + &hal::AccelerationStructureGeometryInfo::Triangles { + vertex_format: wgt::VertexFormat::Float32x3, + max_vertex: 3, + index_format: Some(wgt::IndexFormat::Uint32), + }, + hal::AccelerationStructureFormat::BottomLevel, + hal::AccelerationStructureBuildMode::Build, + (), + 1, + ) + }; + + let tlas_sizes = unsafe { + device.get_acceleration_structure_build_sizes( + &hal::AccelerationStructureGeometryInfo::Instances, + hal::AccelerationStructureFormat::TopLevel, + hal::AccelerationStructureBuildMode::Build, + (), + 1, + ) + }; + + let blas = unsafe { + device.create_acceleration_structure(&hal::AccelerationStructureDescriptor { + label: Some("blas"), + size: blas_sizes.acceleration_structure_size, + format: hal::AccelerationStructureFormat::BottomLevel, + }) + } + .unwrap(); + + let tlas = unsafe { + device.create_acceleration_structure(&hal::AccelerationStructureDescriptor { + label: Some("tlas"), + size: tlas_sizes.acceleration_structure_size, + format: hal::AccelerationStructureFormat::TopLevel, + }) + } + .unwrap(); + + let uniforms = { + let view = Mat4::look_at_rh(Vec3::new(0.0, 0.0, 2.5), Vec3::ZERO, Vec3::Y); + let proj = Mat4::perspective_rh(59.0_f32.to_radians(), 1.0, 0.001, 1000.0); + + Uniforms { + view_inverse: view.inverse(), + proj_inverse: proj.inverse(), + } + }; + + let uniforms_size = std::mem::size_of::(); + + let uniform_buffer = unsafe { + let uniform_buffer = device + .create_buffer(&hal::BufferDescriptor { + label: Some("uniform buffer"), + size: uniforms_size as u64, + usage: hal::BufferUses::MAP_WRITE | hal::BufferUses::UNIFORM, + memory_flags: hal::MemoryFlags::PREFER_COHERENT, + }) + .unwrap(); + + let mapping = device + .map_buffer(&uniform_buffer, 0..uniforms_size as u64) + .unwrap(); + ptr::copy_nonoverlapping( + &uniforms as *const Uniforms as *const u8, + mapping.ptr.as_ptr(), + uniforms_size, + ); + device.unmap_buffer(&uniform_buffer).unwrap(); + assert!(mapping.is_coherent); + uniform_buffer + }; + + let texture_desc = hal::TextureDescriptor { + label: None, + size: wgt::Extent3d { + width: 512, + height: 512, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgt::TextureDimension::D2, + format: wgt::TextureFormat::Rgba8Unorm, + usage: hal::TextureUses::STORAGE_READ_WRITE | hal::TextureUses::COPY_SRC, + memory_flags: hal::MemoryFlags::empty(), + }; + let texture = unsafe { device.create_texture(&texture_desc).unwrap() }; + + let view_desc = hal::TextureViewDescriptor { + label: None, + format: texture_desc.format, + dimension: wgt::TextureViewDimension::D2, + usage: hal::TextureUses::STORAGE_READ_WRITE | hal::TextureUses::COPY_SRC, + range: wgt::ImageSubresourceRange::default(), + }; + let texture_view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() }; + + let bind_group = { + let buffer_binding = hal::BufferBinding { + buffer: &uniform_buffer, + offset: 0, + size: None, + }; + let texture_binding = hal::TextureBinding { + view: &texture_view, + usage: hal::TextureUses::STORAGE_READ_WRITE, + }; + let group_desc = hal::BindGroupDescriptor { + label: Some("bind group"), + layout: &bgl, + buffers: &[buffer_binding], + samplers: &[], + textures: &[texture_binding], + acceleration_structures: &[&tlas], + entries: &[ + hal::BindGroupEntry { + binding: 0, + resource_index: 0, + count: 1, + }, + hal::BindGroupEntry { + binding: 1, + resource_index: 0, + count: 1, + }, + hal::BindGroupEntry { + binding: 2, + resource_index: 0, + count: 1, + }, + ], + }; + unsafe { device.create_bind_group(&group_desc).unwrap() } + }; + + let scratch_buffer = unsafe { + device + .create_buffer(&hal::BufferDescriptor { + label: Some("scratch buffer"), + size: blas_sizes + .build_scratch_size + .max(tlas_sizes.build_scratch_size), + usage: hal::BufferUses::BUFFER_DEVICE_ADDRESS + | hal::BufferUses::STORAGE_READ_WRITE, + memory_flags: hal::MemoryFlags::empty(), + }) + .unwrap() + }; + + fn pack_24_8(low_24: u32, high_8: u8) -> u32 { + (low_24 & 0x00ff_ffff) | (u32::from(high_8) << 24) + } + + #[derive(Debug)] + #[repr(C)] + struct Instance { + transform: [f32; 12], + instance_custom_index_and_mask: u32, + instance_shader_binding_table_record_offset_and_flags: u32, + acceleration_structure_reference: u64, + } + + fn transpose_matrix_for_acceleration_structure_instance(matrix: Mat4) -> [f32; 12] { + let row_0 = matrix.row(0); + let row_1 = matrix.row(1); + let row_2 = matrix.row(2); + [ + row_0.x, row_0.y, row_0.z, row_0.w, row_1.x, row_1.y, row_1.z, row_1.w, row_2.x, + row_2.y, row_2.z, row_2.w, + ] + } + + let instances = [ + Instance { + transform: transform_matrix, + instance_custom_index_and_mask: pack_24_8(0, 0xff), + instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), + acceleration_structure_reference: unsafe { + device.get_acceleration_structure_device_address(&blas) + }, + }, + Instance { + transform: transpose_matrix_for_acceleration_structure_instance( + Mat4::from_rotation_y(1.0), + ), + instance_custom_index_and_mask: pack_24_8(0, 0xff), + instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), + acceleration_structure_reference: unsafe { + device.get_acceleration_structure_device_address(&blas) + }, + }, + Instance { + transform: transpose_matrix_for_acceleration_structure_instance( + Mat4::from_rotation_y(-1.0), + ), + instance_custom_index_and_mask: pack_24_8(0, 0xff), + instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), + acceleration_structure_reference: unsafe { + device.get_acceleration_structure_device_address(&blas) + }, + }, + ]; + + let instances_buffer_size = instances.len() * std::mem::size_of::(); + + let instances_buffer = unsafe { + let instances_buffer = device + .create_buffer(&hal::BufferDescriptor { + label: Some("instances_buffer"), + size: instances_buffer_size as u64, + usage: hal::BufferUses::MAP_WRITE + | hal::BufferUses::BUFFER_DEVICE_ADDRESS + | hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, + }) + .unwrap(); + + let mapping = device + .map_buffer(&instances_buffer, 0..instances_buffer_size as u64) + .unwrap(); + ptr::copy_nonoverlapping( + instances.as_ptr() as *const u8, + mapping.ptr.as_ptr(), + instances_buffer_size, + ); + device.unmap_buffer(&instances_buffer).unwrap(); + assert!(mapping.is_coherent); + + instances_buffer + }; + + let cmd_encoder_desc = hal::CommandEncoderDescriptor { + label: None, + queue: &queue, + }; + let mut cmd_encoder = unsafe { device.create_command_encoder(&cmd_encoder_desc).unwrap() }; + + unsafe { cmd_encoder.begin_encoding(Some("init")).unwrap() }; + + unsafe { + cmd_encoder.build_acceleration_structures( + &hal::AccelerationStructureGeometry::Triangles { + vertex_buffer: &vertices_buffer, + vertex_format: wgt::VertexFormat::Float32x3, + max_vertex: vertices.len() as u32, + vertex_stride: 3 * 4, + indices: Some(hal::AccelerationStructureGeometryIndices { + buffer: &indices_buffer, + format: wgt::IndexFormat::Uint32, + }), + }, + hal::AccelerationStructureFormat::BottomLevel, + hal::AccelerationStructureBuildMode::Build, + (), + indices.len() as u32 / 3, + 0, + &blas, + &scratch_buffer, + ); + + let as_barrier = hal::BufferBarrier { + buffer: &scratch_buffer, + usage: hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT + ..hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + }; + cmd_encoder.transition_buffers(iter::once(as_barrier)); + + cmd_encoder.build_acceleration_structures( + &hal::AccelerationStructureGeometry::Instances { + buffer: &instances_buffer, + }, + hal::AccelerationStructureFormat::TopLevel, + hal::AccelerationStructureBuildMode::Build, + (), + instances.len() as u32, + 0, + &tlas, + &scratch_buffer, + ); + + let texture_barrier = hal::TextureBarrier { + texture: &texture, + range: wgt::ImageSubresourceRange::default(), + usage: hal::TextureUses::UNINITIALIZED..hal::TextureUses::STORAGE_READ_WRITE, + }; + + cmd_encoder.transition_textures(iter::once(texture_barrier)); + } + + let init_fence_value = 1; + let fence = unsafe { + let mut fence = device.create_fence().unwrap(); + let init_cmd = cmd_encoder.end_encoding().unwrap(); + queue + .submit(&[&init_cmd], Some((&mut fence, init_fence_value))) + .unwrap(); + device.wait(&fence, init_fence_value, !0).unwrap(); + cmd_encoder.reset_all(iter::once(init_cmd)); + fence + }; + + Ok(Self { + instance, + adapter, + surface, + surface_format: surface_config.format, + device, + queue, + pipeline, + contexts: vec![ExecutionContext { + encoder: cmd_encoder, + fence, + fence_value: init_fence_value + 1, + used_views: Vec::new(), + used_cmd_bufs: Vec::new(), + frames_recorded: 0, + }], + context_index: 0, + extent: [window_size.0, window_size.1], + start: Instant::now(), + pipeline_layout, + bind_group, + texture, + }) + } + + fn update(&mut self, _event: winit::event::WindowEvent) {} + + fn render(&mut self) { + let ctx = &mut self.contexts[self.context_index]; + + let surface_tex = unsafe { self.surface.acquire_texture(None).unwrap().unwrap().texture }; + + let target_barrier0 = hal::TextureBarrier { + texture: surface_tex.borrow(), + range: wgt::ImageSubresourceRange::default(), + usage: hal::TextureUses::UNINITIALIZED..hal::TextureUses::COPY_DST, + }; + unsafe { + ctx.encoder.begin_encoding(Some("frame")).unwrap(); + ctx.encoder.transition_textures(iter::once(target_barrier0)); + } + + let surface_view_desc = hal::TextureViewDescriptor { + label: None, + format: self.surface_format, + dimension: wgt::TextureViewDimension::D2, + usage: hal::TextureUses::COPY_DST, + range: wgt::ImageSubresourceRange::default(), + }; + let surface_tex_view = unsafe { + self.device + .create_texture_view(surface_tex.borrow(), &surface_view_desc) + .unwrap() + }; + unsafe { + ctx.encoder + .begin_compute_pass(&hal::ComputePassDescriptor { label: None }); + ctx.encoder.set_compute_pipeline(&self.pipeline); + ctx.encoder + .set_bind_group(&self.pipeline_layout, 0, &self.bind_group, &[]); + ctx.encoder.dispatch([512 / 8, 512 / 8, 1]); + } + + ctx.frames_recorded += 1; + let do_fence = ctx.frames_recorded > COMMAND_BUFFER_PER_CONTEXT; + + let target_barrier1 = hal::TextureBarrier { + texture: surface_tex.borrow(), + range: wgt::ImageSubresourceRange::default(), + usage: hal::TextureUses::COPY_DST..hal::TextureUses::PRESENT, + }; + let target_barrier2 = hal::TextureBarrier { + texture: &self.texture, + range: wgt::ImageSubresourceRange::default(), + usage: hal::TextureUses::STORAGE_READ_WRITE..hal::TextureUses::COPY_SRC, + }; + let target_barrier3 = hal::TextureBarrier { + texture: &self.texture, + range: wgt::ImageSubresourceRange::default(), + usage: hal::TextureUses::COPY_SRC..hal::TextureUses::STORAGE_READ_WRITE, + }; + unsafe { + ctx.encoder.end_compute_pass(); + ctx.encoder.transition_textures(iter::once(target_barrier2)); + ctx.encoder.copy_texture_to_texture( + &self.texture, + hal::TextureUses::COPY_SRC, + &surface_tex.borrow(), + std::iter::once(hal::TextureCopy { + src_base: hal::TextureCopyBase { + mip_level: 0, + array_layer: 0, + origin: wgt::Origin3d::ZERO, + aspect: hal::FormatAspects::COLOR, + }, + dst_base: hal::TextureCopyBase { + mip_level: 0, + array_layer: 0, + origin: wgt::Origin3d::ZERO, + aspect: hal::FormatAspects::COLOR, + }, + size: hal::CopyExtent { + width: 512, + height: 512, + depth: 1, + }, + }), + ); + ctx.encoder.transition_textures(iter::once(target_barrier1)); + ctx.encoder.transition_textures(iter::once(target_barrier3)); + } + + unsafe { + let cmd_buf = ctx.encoder.end_encoding().unwrap(); + let fence_param = if do_fence { + Some((&mut ctx.fence, ctx.fence_value)) + } else { + None + }; + self.queue.submit(&[&cmd_buf], fence_param).unwrap(); + self.queue.present(&mut self.surface, surface_tex).unwrap(); + ctx.used_cmd_bufs.push(cmd_buf); + ctx.used_views.push(surface_tex_view); + }; + + if do_fence { + log::info!("Context switch from {}", self.context_index); + let old_fence_value = ctx.fence_value; + if self.contexts.len() == 1 { + let hal_desc = hal::CommandEncoderDescriptor { + label: None, + queue: &self.queue, + }; + self.contexts.push(unsafe { + ExecutionContext { + encoder: self.device.create_command_encoder(&hal_desc).unwrap(), + fence: self.device.create_fence().unwrap(), + fence_value: 0, + used_views: Vec::new(), + used_cmd_bufs: Vec::new(), + frames_recorded: 0, + } + }); + } + self.context_index = (self.context_index + 1) % self.contexts.len(); + let next = &mut self.contexts[self.context_index]; + unsafe { + next.wait_and_clear(&self.device); + } + next.fence_value = old_fence_value + 1; + } + } +} + +#[cfg(all(feature = "metal"))] +type Api = hal::api::Metal; +#[cfg(all(feature = "vulkan", not(feature = "metal")))] +type Api = hal::api::Vulkan; +#[cfg(all(feature = "gles", not(feature = "metal"), not(feature = "vulkan")))] +type Api = hal::api::Gles; +#[cfg(all( + feature = "dx12", + not(feature = "metal"), + not(feature = "vulkan"), + not(feature = "gles") +))] +type Api = hal::api::Dx12; +#[cfg(not(any( + feature = "metal", + feature = "vulkan", + feature = "gles", + feature = "dx12" +)))] +type Api = hal::api::Empty; + +fn main() { + env_logger::init(); + + let event_loop = winit::event_loop::EventLoop::new(); + let window = winit::window::WindowBuilder::new() + .with_title("hal-bunnymark") + .with_inner_size(winit::dpi::PhysicalSize { + width: 512, + height: 512, + }) + .build(&event_loop) + .unwrap(); + + let example_result = Example::::init(&window); + let mut example = Some(example_result.expect("Selected backend is not supported")); + + event_loop.run(move |event, _, control_flow| { + let _ = &window; // force ownership by the closure + *control_flow = winit::event_loop::ControlFlow::Poll; + match event { + winit::event::Event::RedrawEventsCleared => { + window.request_redraw(); + } + winit::event::Event::WindowEvent { event, .. } => match event { + winit::event::WindowEvent::KeyboardInput { + input: + winit::event::KeyboardInput { + virtual_keycode: Some(winit::event::VirtualKeyCode::Escape), + state: winit::event::ElementState::Pressed, + .. + }, + .. + } + | winit::event::WindowEvent::CloseRequested => { + *control_flow = winit::event_loop::ControlFlow::Exit; + } + _ => { + example.as_mut().unwrap().update(event); + } + }, + winit::event::Event::RedrawRequested(_) => { + let ex = example.as_mut().unwrap(); + + ex.render(); + } + winit::event::Event::LoopDestroyed => { + //example.take().unwrap().exit(); + } + _ => {} + } + }); +} diff --git a/wgpu-hal/examples/ray-traced-triangle/shader.comp b/wgpu-hal/examples/ray-traced-triangle/shader.comp new file mode 100644 index 0000000000..d31f29115f --- /dev/null +++ b/wgpu-hal/examples/ray-traced-triangle/shader.comp @@ -0,0 +1,44 @@ +#version 460 +#extension GL_EXT_ray_query : enable + +layout(set = 0, binding = 0) uniform Uniforms +{ + mat4 viewInverse; + mat4 projInverse; +} cam; +layout(set = 0, binding = 1, rgba8) uniform image2D image; +layout(set = 0, binding = 2) uniform accelerationStructureEXT tlas; + +layout(local_size_x = 8, local_size_y = 8) in; + +void main() +{ + uvec2 launch_id = gl_GlobalInvocationID.xy; + uvec2 launch_size = gl_NumWorkGroups.xy * 8; + + const vec2 pixelCenter = vec2(launch_id) + vec2(0.5); + const vec2 inUV = pixelCenter/vec2(launch_size); + vec2 d = inUV * 2.0 - 1.0; + + vec4 origin = cam.viewInverse * vec4(0,0,0,1); + vec4 target = cam.projInverse * vec4(d.x, d.y, 1, 1) ; + vec4 direction = cam.viewInverse*vec4(normalize(target.xyz), 0) ; + + float tmin = 0.001; + float tmax = 10000.0; + + rayQueryEXT rayQuery; + rayQueryInitializeEXT(rayQuery, tlas, gl_RayFlagsOpaqueEXT, 0xff, origin.xyz, tmin, direction.xyz, tmax); + + rayQueryProceedEXT(rayQuery); + + vec3 out_colour = vec3(0.0, 0.0, 0.0); + + if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT ) { + vec2 barycentrics = rayQueryGetIntersectionBarycentricsEXT(rayQuery, true); + + out_colour = vec3(barycentrics.x, barycentrics.y, 1.0 - barycentrics.x - barycentrics.y); + } + + imageStore(image, ivec2(launch_id), vec4(out_colour, 1.0)); +} \ No newline at end of file diff --git a/wgpu-hal/examples/ray-traced-triangle/shader.comp.spv b/wgpu-hal/examples/ray-traced-triangle/shader.comp.spv new file mode 100644 index 0000000000000000000000000000000000000000..345085c948d1fab7ad065d6d92437f40c1c57440 GIT binary patch literal 3520 zcmZ9O`F0dV6o)&>B#}ihYym|KizpHiWfcU%IsqaCLc$_443i-lm`sOG0tvDNL5=@- zj<4af_zFIU%Q+tXzV0p1UGiqyz7DsPIKS$ZbckJG?(+bO?Hbv@N9(6|T=mjuQ zt~KPBf_GAMq&!nFdj{*Z@z;v{9izY;#evevE0JY9<$r%$B*_GtO5oT=KwDmk6$+Q>OKGjTai?iQ1HW^#%! zeC^RXz%ldnb^#DgVwriC$wg=m9Lr&;ljMVQ}rr-L`Cx0-v?YUgA?V0v={N}C%)?GuDHOL-d z?e3I&HMeJ!&70*K>p3!x^wN3b-v@HS`o?SpjJ{xhoSO4ToMSt>F$LiIdy&o|zZQE( zuIt}`?Rm)w<98zMjlBEQ_8jHx=NHHx&;p!adlzt+zZ+?6Hcz(ReL5Mvti*Nf2XXfd;&mi@AcA+Poppru+(7>itfC8kqvnkvUAOD&rK++9!v2-p zShewYz&c*rM@aYL-kOKK4QKl}cNpt>wEadL_Tw4S^D)PH7b6#d_fy!rz1*`<6Ep4I zUod|6*7P3x_PhRIFK@EF!+w9kukD-NY;S3@y^p@z!LRK*+iVw`Y|nh?4cj+1#E+qm zH`&e~=k_7i@1EZVezWJvGH+SV$vf=vVRr65^@TitJN>pp-U@U%;V^HIPFZsm2z`B# zbF1OZ(Pw@8CTD$f-UZG%iQSESFXx_-ue~AXd;`q4&vNGL?*Ve5-bQri2=z9h%Pr*f ze7k#qy!AXMxlr#zbh%&h_>a)#wgUI*oZEokt9YJspP(D7&$^zs+)@0#2YY~T$S&Yq zz72bU{IA6LCVZK5`;pf0j>v@?U!hyW_aW3cgf4H4_oNRv_hDd+-_KFdm&z>WIJz;% zK!`bkE;?Ag-p&Dij=-Hq5AlH;%sFd@JzhXJ-+2A|K-l9&bk}T*dn_X5 z)cqEHQ`Lu&Bfx!KLw*ac=eGMS0nah)^JdP;JHkH0Ih5h7ANq6)-MK@41zk=!-pn6` zb4_zyi_-Vo^&A5?z)fI%YZ&*qtB}68x6!Wx_cM;Hfu~*m2Np$lfj;ltZ}hy1tOI%L z{z*;)>G+2p=$im?zM<+1-Pw0Di5_Y>SBxze?(RKwx#qi@V9SS?sXWHHL(its~LuEg$k8qMIu}nBUFs&|RnN&>#9J|2I7dy->Pl zf2*E?C%N5;oCk}*BmB>h--CHzyx+%j;Ms)x{37QNFS#Fb&N~s}e$2U6WVrV~p_^~K Te)~{i9@pf&`v2u-?Fat@FKh for Context { ) -> DeviceResult { Ok(Resource) } - unsafe fn get_acceleration_structure_build_size( + unsafe fn get_acceleration_structure_build_sizes( &self, - geometry: &crate::AccelerationStructureGeometry, + geometry_info: &crate::AccelerationStructureGeometryInfo, format: crate::AccelerationStructureFormat, mode: crate::AccelerationStructureBuildMode, flags: (), diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 212a31d848..44d7860e10 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -244,9 +244,9 @@ pub trait Device: Send + Sync { desc: &AccelerationStructureDescriptor, ) -> Result; - unsafe fn get_acceleration_structure_build_size( + unsafe fn get_acceleration_structure_build_sizes( &self, - geometry: &AccelerationStructureGeometry, + geometry_info: &AccelerationStructureGeometryInfo, format: AccelerationStructureFormat, mode: AccelerationStructureBuildMode, flags: (), @@ -550,9 +550,9 @@ pub trait CommandEncoder: Send + Sync { unsafe fn build_acceleration_structures( &mut self, - geometry: &crate::AccelerationStructureGeometry, - format: crate::AccelerationStructureFormat, - mode: crate::AccelerationStructureBuildMode, + geometry: &AccelerationStructureGeometry, + format: AccelerationStructureFormat, + mode: AccelerationStructureBuildMode, flags: (), primitive_count: u32, primitive_offset: u32, @@ -993,6 +993,7 @@ pub struct BindGroupDescriptor<'a, A: Api> { pub samplers: &'a [&'a A::Sampler], pub textures: &'a [TextureBinding<'a, A>], pub entries: &'a [BindGroupEntry], + pub acceleration_structures: &'a [&'a A::AccelerationStructure], } #[derive(Clone, Debug)] @@ -1162,6 +1163,15 @@ pub struct BufferCopy { pub size: wgt::BufferSize, } +pub enum AccelerationStructureGeometryInfo { + Triangles { + vertex_format: wgt::VertexFormat, + max_vertex: u32, + index_format: Option, + }, + Instances, +} + pub enum AccelerationStructureGeometry<'a, A: Api> { Triangles { vertex_buffer: &'a A::Buffer, diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 641145dc94..e3073b0643 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -362,17 +362,70 @@ impl crate::CommandEncoder for super::CommandEncoder { None => panic!("Feature `BDA` not enabled"), }; - let geometry = - super::device::map_acceleration_structure_geometry(geometry, &bda_extension).build(); + let geometry = match geometry { + crate::AccelerationStructureGeometry::Instances { buffer } => { + let instances = vk::AccelerationStructureGeometryInstancesDataKHR::builder().data( + vk::DeviceOrHostAddressConstKHR { + device_address: bda_extension.get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), + ), + }, + ); + + vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::INSTANCES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + instances: *instances, + }) + .flags(vk::GeometryFlagsKHR::empty()) + } + &crate::AccelerationStructureGeometry::Triangles { + vertex_buffer, + vertex_format, + max_vertex, + vertex_stride, + ref indices, + } => { + let mut triangles_data = + vk::AccelerationStructureGeometryTrianglesDataKHR::builder() + .vertex_data(vk::DeviceOrHostAddressConstKHR { + device_address: bda_extension.get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(vertex_buffer.raw), + ), + }) + .vertex_format(conv::map_vertex_format(vertex_format)) + .vertex_stride(vertex_stride) + .max_vertex(max_vertex); + + if let Some(indices) = indices { + triangles_data = triangles_data + .index_type(conv::map_index_format(indices.format)) + .index_data(vk::DeviceOrHostAddressConstKHR { + device_address: bda_extension.get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(indices.buffer.raw), + ), + }) + } + + let triangles_data = triangles_data.build(); + + vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::TRIANGLES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + triangles: triangles_data, + }) + .flags(vk::GeometryFlagsKHR::empty()) + } + }; - let geometries = &[geometry]; + let geometries = &[*geometry]; let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() .primitive_count(primitive_count) .primitive_offset(primitive_offset) .build(); - let mut geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() + let geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() .ty(conv::map_acceleration_structure_format(format)) .mode(conv::map_acceleration_structure_build_mode(mode)) .flags(vk::BuildAccelerationStructureFlagsKHR::PREFER_FAST_TRACE) diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index f8d6e68f1f..e169b4ad29 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -713,6 +713,7 @@ pub fn map_binding_type(ty: wgt::BindingType) -> vk::DescriptorType { wgt::BindingType::Sampler { .. } => vk::DescriptorType::SAMPLER, wgt::BindingType::Texture { .. } => vk::DescriptorType::SAMPLED_IMAGE, wgt::BindingType::StorageTexture { .. } => vk::DescriptorType::STORAGE_IMAGE, + wgt::BindingType::AccelerationStructure => vk::DescriptorType::ACCELERATION_STRUCTURE_KHR, } } diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index a0cfe725d9..47c20726fc 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -816,9 +816,9 @@ impl crate::Device for super::Device { }) } - unsafe fn get_acceleration_structure_build_size( + unsafe fn get_acceleration_structure_build_sizes( &self, - geometry: &crate::AccelerationStructureGeometry, + geometry_info: &crate::AccelerationStructureGeometryInfo, format: crate::AccelerationStructureFormat, mode: crate::AccelerationStructureBuildMode, flags: (), @@ -829,12 +829,40 @@ impl crate::Device for super::Device { None => panic!("Feature `RAY_TRACING` not enabled"), }; - let bda_extension = match self.shared.extension_fns.buffer_device_address { - Some(ref extension) => extension, - None => panic!("Feature `BDA` not enabled"), - }; + let geometry = match geometry_info { + crate::AccelerationStructureGeometryInfo::Instances => { + let instances_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder(); - let geometry = map_acceleration_structure_geometry(geometry, &bda_extension); + vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::INSTANCES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + instances: *instances_data, + }) + .flags(vk::GeometryFlagsKHR::empty()) + } + &crate::AccelerationStructureGeometryInfo::Triangles { + vertex_format, + max_vertex, + index_format, + } => { + let mut triangles_data = + vk::AccelerationStructureGeometryTrianglesDataKHR::builder() + .vertex_format(conv::map_vertex_format(vertex_format)) + .max_vertex(max_vertex); + + if let Some(index_format) = index_format { + triangles_data = + triangles_data.index_type(conv::map_index_format(index_format)); + } + + vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::TRIANGLES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + triangles: *triangles_data, + }) + .flags(vk::GeometryFlagsKHR::empty()) + } + }; let geometries = &[*geometry]; @@ -1277,6 +1305,9 @@ impl crate::Device for super::Device { wgt::BindingType::StorageTexture { .. } => { desc_count.storage_image += count; } + wgt::BindingType::AccelerationStructure => { + desc_count.acceleration_structure += count; + } } } @@ -1475,6 +1506,10 @@ impl crate::Device for super::Device { let mut buffer_infos = Vec::with_capacity(desc.buffers.len()); let mut sampler_infos = Vec::with_capacity(desc.samplers.len()); let mut image_infos = Vec::with_capacity(desc.textures.len()); + let mut acceleration_structure_infos = + Vec::with_capacity(desc.acceleration_structures.len()); + let mut raw_acceleration_structures = + Vec::with_capacity(desc.acceleration_structures.len()); for entry in desc.entries { let (ty, size) = desc.layout.types[entry.binding as usize]; if size == 0 { @@ -1484,6 +1519,9 @@ impl crate::Device for super::Device { .dst_set(*set.raw()) .dst_binding(entry.binding) .descriptor_type(ty); + + let mut extra_descriptor_count = 0; + write = match ty { vk::DescriptorType::SAMPLER => { let index = sampler_infos.len(); @@ -1532,9 +1570,36 @@ impl crate::Device for super::Device { )); write.buffer_info(&buffer_infos[index..]) } + vk::DescriptorType::ACCELERATION_STRUCTURE_KHR => { + let index = acceleration_structure_infos.len(); + let start = entry.resource_index; + let end = start + entry.count; + + let raw_start = raw_acceleration_structures.len(); + + raw_acceleration_structures.extend( + desc.acceleration_structures[start as usize..end as usize] + .iter() + .map(|acceleration_structure| acceleration_structure.raw), + ); + + acceleration_structure_infos.push( + // todo: this dereference to build the struct is a hack to get around lifetime issues. + *vk::WriteDescriptorSetAccelerationStructureKHR::builder() + .acceleration_structures(&raw_acceleration_structures[raw_start..]), + ); + + extra_descriptor_count += 1; + + write.push_next(&mut acceleration_structure_infos[index]) + } _ => unreachable!(), }; - writes.push(write.build()); + + let mut write = write.build(); + write.descriptor_count += extra_descriptor_count; + + writes.push(write); } self.shared.raw.update_descriptor_sets(&writes, &[]); @@ -2076,63 +2141,3 @@ impl From for crate::DeviceError { Self::OutOfMemory } } - -pub unsafe fn map_acceleration_structure_geometry<'a>( - geometry: &crate::AccelerationStructureGeometry, - buffer_device_address: &ash::extensions::khr::BufferDeviceAddress, -) -> vk::AccelerationStructureGeometryKHRBuilder<'a> { - match geometry { - crate::AccelerationStructureGeometry::Instances { buffer } => { - let instances = vk::AccelerationStructureGeometryInstancesDataKHR::builder().data( - vk::DeviceOrHostAddressConstKHR { - device_address: buffer_device_address.get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), - ), - }, - ); - - vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::INSTANCES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - instances: *instances, - }) - .flags(vk::GeometryFlagsKHR::empty()) - } - &crate::AccelerationStructureGeometry::Triangles { - vertex_buffer, - vertex_format, - max_vertex, - vertex_stride, - ref indices, - } => { - let mut triangles_data = vk::AccelerationStructureGeometryTrianglesDataKHR::builder() - .vertex_data(vk::DeviceOrHostAddressConstKHR { - device_address: buffer_device_address.get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(vertex_buffer.raw), - ), - }) - .vertex_format(conv::map_vertex_format(vertex_format)) - .vertex_stride(vertex_stride) - .max_vertex(max_vertex); - - if let Some(indices) = indices { - triangles_data = triangles_data - .index_type(conv::map_index_format(indices.format)) - .index_data(vk::DeviceOrHostAddressConstKHR { - device_address: buffer_device_address.get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(indices.buffer.raw), - ), - }) - } - - let triangles_data = triangles_data.build(); - - vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::TRIANGLES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - triangles: triangles_data, - }) - .flags(vk::GeometryFlagsKHR::empty()) - } - } -} diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 8718d79794..ab6e9a944d 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -4040,6 +4040,8 @@ pub enum BindingType { /// Dimension of the texture view that is going to be sampled. view_dimension: TextureViewDimension, }, + + AccelerationStructure, } impl BindingType { From 2cc43852d4ed64a3412c55a7c5260a14381176da Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Thu, 15 Sep 2022 11:59:05 +0200 Subject: [PATCH 005/146] Major clean up, allow for acceleration structure updates --- wgpu-hal/examples/ray-traced-triangle/main.rs | 219 +++++++++++++----- wgpu-hal/src/empty.rs | 4 +- wgpu-hal/src/lib.rs | 19 +- wgpu-hal/src/vulkan/adapter.rs | 39 ++-- wgpu-hal/src/vulkan/command.rs | 62 +++-- wgpu-hal/src/vulkan/conv.rs | 34 ++- wgpu-hal/src/vulkan/device.rs | 64 ++--- wgpu-hal/src/vulkan/mod.rs | 8 +- wgpu-types/src/lib.rs | 15 ++ 9 files changed, 321 insertions(+), 143 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 93f62eac04..a4ae25e41c 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -16,6 +16,29 @@ use std::{ const COMMAND_BUFFER_PER_CONTEXT: usize = 100; const DESIRED_FRAMES: u32 = 3; +fn pack_24_8(low_24: u32, high_8: u8) -> u32 { + (low_24 & 0x00ff_ffff) | (u32::from(high_8) << 24) +} + +#[derive(Debug)] +#[repr(C)] +struct Instance { + transform: [f32; 12], + instance_custom_index_and_mask: u32, + instance_shader_binding_table_record_offset_and_flags: u32, + acceleration_structure_reference: u64, +} + +fn transpose_matrix_for_acceleration_structure_instance(matrix: Mat4) -> [f32; 12] { + let row_0 = matrix.row(0); + let row_1 = matrix.row(1); + let row_2 = matrix.row(2); + [ + row_0.x, row_0.y, row_0.z, row_0.w, row_1.x, row_1.y, row_1.z, row_1.w, row_2.x, row_2.y, + row_2.z, row_2.w, + ] +} + struct ExecutionContext { encoder: A::CommandEncoder, fence: A::Fence, @@ -51,26 +74,20 @@ struct Example { start: Instant, pipeline: A::ComputePipeline, bind_group: A::BindGroup, - //local_group: A::BindGroup, - //global_group_layout: A::BindGroupLayout, - //local_group_layout: A::BindGroupLayout, + bgl: A::BindGroupLayout, + shader_module: A::ShaderModule, + texture_view: A::TextureView, + uniform_buffer: A::Buffer, pipeline_layout: A::PipelineLayout, - /*shader: A::ShaderModule, - pipeline: A::RenderPipeline, - bunnies: Vec, - local_buffer: A::Buffer, - local_alignment: u32, - global_buffer: A::Buffer, - sampler: A::Sampler, - */ + vertices_buffer: A::Buffer, + indices_buffer: A::Buffer, texture: A::Texture, - /*texture_view: A::TextureView, - contexts: Vec>, - context_index: usize, - extent: [u32; 2], - start: Instant, - buffers: Vec, - acceleration_structures: Vec,*/ + instances: [Instance; 1], + instances_buffer: A::Buffer, + blas: A::AccelerationStructure, + tlas: A::AccelerationStructure, + scratch_buffer: A::Buffer, + time: f32, } impl Example { @@ -86,23 +103,21 @@ impl Example { let instance = unsafe { A::Instance::init(&instance_desc)? }; let mut surface = unsafe { instance.create_surface(window).unwrap() }; - let (adapter, _capabilities) = unsafe { + let (adapter, features) = unsafe { let mut adapters = instance.enumerate_adapters(); if adapters.is_empty() { return Err(hal::InstanceError); } let exposed = adapters.swap_remove(0); - (exposed.adapter, exposed.capabilities) + dbg!(exposed.features); + (exposed.adapter, exposed.features) }; let surface_caps = unsafe { adapter.surface_capabilities(&surface) }.ok_or(hal::InstanceError)?; log::info!("Surface caps: {:#?}", surface_caps); - let hal::OpenDevice { device, mut queue } = unsafe { - adapter - .open(wgt::Features::empty(), &wgt::Limits::default()) - .unwrap() - }; + let hal::OpenDevice { device, mut queue } = + unsafe { adapter.open(features, &wgt::Limits::default()).unwrap() }; let window_size: (u32, u32) = window.inner_size().into(); let surface_config = hal::SurfaceConfiguration { @@ -196,7 +211,7 @@ impl Example { words } - let shader = unsafe { + let shader_module = unsafe { device .create_shader_module( &hal::ShaderModuleDescriptor { @@ -225,7 +240,7 @@ impl Example { label: Some("pipeline"), layout: &pipeline_layout, stage: hal::ProgrammableStage { - module: &shader, + module: &shader_module, entry_point: "main", }, }) @@ -248,7 +263,6 @@ impl Example { label: Some("vertices buffer"), size: vertices_size_in_bytes as u64, usage: hal::BufferUses::MAP_WRITE - | hal::BufferUses::BUFFER_DEVICE_ADDRESS | hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, }) @@ -274,7 +288,6 @@ impl Example { label: Some("indices buffer"), size: indices_size_in_bytes as u64, usage: hal::BufferUses::MAP_WRITE - | hal::BufferUses::BUFFER_DEVICE_ADDRESS | hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, }) @@ -303,17 +316,20 @@ impl Example { }, hal::AccelerationStructureFormat::BottomLevel, hal::AccelerationStructureBuildMode::Build, - (), + hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, 1, ) }; + let tlas_flags = hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE + | hal::AccelerationStructureBuildFlags::ALLOW_UPDATE; + let tlas_sizes = unsafe { device.get_acceleration_structure_build_sizes( &hal::AccelerationStructureGeometryInfo::Instances, hal::AccelerationStructureFormat::TopLevel, hal::AccelerationStructureBuildMode::Build, - (), + tlas_flags, 1, ) }; @@ -441,36 +457,12 @@ impl Example { size: blas_sizes .build_scratch_size .max(tlas_sizes.build_scratch_size), - usage: hal::BufferUses::BUFFER_DEVICE_ADDRESS - | hal::BufferUses::STORAGE_READ_WRITE, + usage: hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, memory_flags: hal::MemoryFlags::empty(), }) .unwrap() }; - fn pack_24_8(low_24: u32, high_8: u8) -> u32 { - (low_24 & 0x00ff_ffff) | (u32::from(high_8) << 24) - } - - #[derive(Debug)] - #[repr(C)] - struct Instance { - transform: [f32; 12], - instance_custom_index_and_mask: u32, - instance_shader_binding_table_record_offset_and_flags: u32, - acceleration_structure_reference: u64, - } - - fn transpose_matrix_for_acceleration_structure_instance(matrix: Mat4) -> [f32; 12] { - let row_0 = matrix.row(0); - let row_1 = matrix.row(1); - let row_2 = matrix.row(2); - [ - row_0.x, row_0.y, row_0.z, row_0.w, row_1.x, row_1.y, row_1.z, row_1.w, row_2.x, - row_2.y, row_2.z, row_2.w, - ] - } - let instances = [ Instance { transform: transform_matrix, @@ -480,7 +472,7 @@ impl Example { device.get_acceleration_structure_device_address(&blas) }, }, - Instance { + /*Instance { transform: transpose_matrix_for_acceleration_structure_instance( Mat4::from_rotation_y(1.0), ), @@ -499,7 +491,7 @@ impl Example { acceleration_structure_reference: unsafe { device.get_acceleration_structure_device_address(&blas) }, - }, + },*/ ]; let instances_buffer_size = instances.len() * std::mem::size_of::(); @@ -510,7 +502,6 @@ impl Example { label: Some("instances_buffer"), size: instances_buffer_size as u64, usage: hal::BufferUses::MAP_WRITE - | hal::BufferUses::BUFFER_DEVICE_ADDRESS | hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, }) @@ -552,7 +543,7 @@ impl Example { }, hal::AccelerationStructureFormat::BottomLevel, hal::AccelerationStructureBuildMode::Build, - (), + hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, indices.len() as u32 / 3, 0, &blas, @@ -572,7 +563,7 @@ impl Example { }, hal::AccelerationStructureFormat::TopLevel, hal::AccelerationStructureBuildMode::Build, - (), + tlas_flags, instances.len() as u32, 0, &tlas, @@ -622,6 +613,18 @@ impl Example { pipeline_layout, bind_group, texture, + instances, + instances_buffer, + blas, + tlas, + scratch_buffer, + time: 0.0, + indices_buffer, + vertices_buffer, + uniform_buffer, + texture_view, + bgl, + shader_module, }) } @@ -637,8 +640,63 @@ impl Example { range: wgt::ImageSubresourceRange::default(), usage: hal::TextureUses::UNINITIALIZED..hal::TextureUses::COPY_DST, }; + + let instances_buffer_size = self.instances.len() * std::mem::size_of::(); + + let tlas_flags = hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE + | hal::AccelerationStructureBuildFlags::ALLOW_UPDATE; + + self.time += 1.0 / 60.0; + + self.instances[0] = Instance { + transform: transpose_matrix_for_acceleration_structure_instance(Mat4::from_rotation_y( + self.time, + )), + instance_custom_index_and_mask: pack_24_8(0, 0xff), + instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), + acceleration_structure_reference: unsafe { + self.device + .get_acceleration_structure_device_address(&self.blas) + }, + }; + + unsafe { + let mapping = self + .device + .map_buffer(&self.instances_buffer, 0..instances_buffer_size as u64) + .unwrap(); + ptr::copy_nonoverlapping( + self.instances.as_ptr() as *const u8, + mapping.ptr.as_ptr(), + instances_buffer_size, + ); + self.device.unmap_buffer(&self.instances_buffer).unwrap(); + assert!(mapping.is_coherent); + } + unsafe { ctx.encoder.begin_encoding(Some("frame")).unwrap(); + + ctx.encoder.build_acceleration_structures( + &hal::AccelerationStructureGeometry::Instances { + buffer: &self.instances_buffer, + }, + hal::AccelerationStructureFormat::TopLevel, + hal::AccelerationStructureBuildMode::Build, + tlas_flags, + self.instances.len() as u32, + 0, + &self.tlas, + &self.scratch_buffer, + ); + + let as_barrier = hal::BufferBarrier { + buffer: &self.scratch_buffer, + usage: hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT + ..hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + }; + ctx.encoder.transition_buffers(iter::once(as_barrier)); + ctx.encoder.transition_textures(iter::once(target_barrier0)); } @@ -752,6 +810,43 @@ impl Example { next.fence_value = old_fence_value + 1; } } + + fn exit(mut self) { + unsafe { + { + let ctx = &mut self.contexts[self.context_index]; + self.queue + .submit(&[], Some((&mut ctx.fence, ctx.fence_value))) + .unwrap(); + } + + for mut ctx in self.contexts { + ctx.wait_and_clear(&self.device); + self.device.destroy_command_encoder(ctx.encoder); + self.device.destroy_fence(ctx.fence); + } + + self.device.destroy_bind_group(self.bind_group); + self.device.destroy_buffer(self.scratch_buffer); + self.device.destroy_buffer(self.instances_buffer); + self.device.destroy_buffer(self.indices_buffer); + self.device.destroy_buffer(self.vertices_buffer); + self.device.destroy_buffer(self.uniform_buffer); + self.device.destroy_acceleration_structure(self.tlas); + self.device.destroy_acceleration_structure(self.blas); + self.device.destroy_texture_view(self.texture_view); + self.device.destroy_texture(self.texture); + self.device.destroy_compute_pipeline(self.pipeline); + self.device.destroy_pipeline_layout(self.pipeline_layout); + self.device.destroy_bind_group_layout(self.bgl); + self.device.destroy_shader_module(self.shader_module); + + self.surface.unconfigure(&self.device); + self.device.exit(self.queue); + self.instance.destroy_surface(self.surface); + drop(self.adapter); + } + } } #[cfg(all(feature = "metal"))] @@ -821,7 +916,7 @@ fn main() { ex.render(); } winit::event::Event::LoopDestroyed => { - //example.take().unwrap().exit(); + example.take().unwrap().exit(); } _ => {} } diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 5d5fa43d22..6448157a18 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -130,7 +130,7 @@ impl crate::Device for Context { geometry_info: &crate::AccelerationStructureGeometryInfo, format: crate::AccelerationStructureFormat, mode: crate::AccelerationStructureBuildMode, - flags: (), + flags: crate::AccelerationStructureBuildFlags, primitive_count: u32, ) -> crate::AccelerationStructureBuildSizes { Default::default() @@ -421,7 +421,7 @@ impl crate::CommandEncoder for Encoder { geometry: &crate::AccelerationStructureGeometry, format: crate::AccelerationStructureFormat, mode: crate::AccelerationStructureBuildMode, - flags: (), + flags: crate::AccelerationStructureBuildFlags, primitive_count: u32, primitive_offset: u32, destination_acceleration_structure: &Resource, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 44d7860e10..a0c4597254 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -249,7 +249,7 @@ pub trait Device: Send + Sync { geometry_info: &AccelerationStructureGeometryInfo, format: AccelerationStructureFormat, mode: AccelerationStructureBuildMode, - flags: (), + flags: crate::AccelerationStructureBuildFlags, primitive_count: u32, ) -> AccelerationStructureBuildSizes; @@ -553,7 +553,7 @@ pub trait CommandEncoder: Send + Sync { geometry: &AccelerationStructureGeometry, format: AccelerationStructureFormat, mode: AccelerationStructureBuildMode, - flags: (), + flags: crate::AccelerationStructureBuildFlags, primitive_count: u32, primitive_offset: u32, destination_acceleration_structure: &A::AccelerationStructure, @@ -695,7 +695,7 @@ bitflags::bitflags! { const STORAGE_READ_WRITE = 1 << 8; /// The indirect or count buffer in a indirect draw or dispatch. const INDIRECT = 1 << 9; - const BUFFER_DEVICE_ADDRESS = 1 << 10; + const ACCELERATION_STRUCTURE_SCRATCH = 1 << 10; const BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT = 1 << 11; const TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT = 1 << 12; /// The combination of states that a buffer may be in _at the same time_. @@ -856,13 +856,13 @@ pub struct AccelerationStructureDescriptor<'a> { pub format: AccelerationStructureFormat, } -#[derive(Clone, Copy, Debug)] +#[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum AccelerationStructureFormat { TopLevel, BottomLevel, } -#[derive(Clone, Debug)] +#[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum AccelerationStructureBuildMode { Build, Update, @@ -1190,6 +1190,15 @@ pub struct AccelerationStructureGeometryIndices<'a, A: Api> { pub buffer: &'a A::Buffer, } +bitflags!( + pub struct AccelerationStructureBuildFlags: u32 { + const PREFER_FAST_TRACE = 1 << 0; + const PREFER_FAST_BUILD = 1 << 1; + const ALLOW_UPDATE = 1 << 2; + const LOW_MEMORY = 1 << 3; + } +); + #[derive(Clone, Debug)] pub struct TextureCopyBase { pub mip_level: u32, diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index c5f75864a9..025eb4cb4b 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -535,6 +535,14 @@ impl PhysicalDeviceFeatures { ), ); + features.set( + F::RAY_TRACING, + caps.supports_extension(vk::KhrDeferredHostOperationsFn::name()) + && caps.supports_extension(vk::KhrAccelerationStructureFn::name()) + && caps.supports_extension(vk::KhrBufferDeviceAddressFn::name()) + && caps.supports_extension(vk::KhrRayQueryFn::name()), + ); + (features, dl_flags) } @@ -623,7 +631,7 @@ impl PhysicalDeviceCapabilities { extensions.push(vk::KhrDrawIndirectCountFn::name()); } - if true { + if requested_features.contains(wgt::Features::RAY_TRACING) { extensions.push(vk::KhrDeferredHostOperationsFn::name()); extensions.push(vk::KhrAccelerationStructureFn::name()); extensions.push(vk::KhrBufferDeviceAddressFn::name()); @@ -1165,24 +1173,22 @@ impl super::Adapter { } else { None }; - let acceleration_structure_fn = - if enabled_extensions.contains(&khr::AccelerationStructure::name()) { - Some(khr::AccelerationStructure::new( + let ray_tracing_fns = if enabled_extensions.contains(&khr::AccelerationStructure::name()) + && enabled_extensions.contains(&khr::BufferDeviceAddress::name()) + { + Some(super::RayTracingDeviceExtensionFunctions { + acceleration_structure: khr::AccelerationStructure::new( &self.instance.raw, &raw_device, - )) - } else { - None - }; - let buffer_device_address_fn = - if enabled_extensions.contains(&khr::BufferDeviceAddress::name()) { - Some(khr::BufferDeviceAddress::new( + ), + buffer_device_address: khr::BufferDeviceAddress::new( &self.instance.raw, &raw_device, - )) - } else { - None - }; + ), + }) + } else { + None + }; let naga_options = { use naga::back::spv; @@ -1275,8 +1281,7 @@ impl super::Adapter { extension_fns: super::DeviceExtensionFunctions { draw_indirect_count: indirect_count_fn, timeline_semaphore: timeline_semaphore_fn, - acceleration_structure: acceleration_structure_fn, - buffer_device_address: buffer_device_address_fn, + ray_tracing: ray_tracing_fns, }, vendor_id: self.phd_capabilities.properties.vendor_id, timestamp_period: self.phd_capabilities.properties.limits.timestamp_period, diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index e3073b0643..a5b35f765e 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -346,29 +346,26 @@ impl crate::CommandEncoder for super::CommandEncoder { geometry: &crate::AccelerationStructureGeometry, format: crate::AccelerationStructureFormat, mode: crate::AccelerationStructureBuildMode, - flags: (), + flags: crate::AccelerationStructureBuildFlags, primitive_count: u32, primitive_offset: u32, destination_acceleration_structure: &super::AccelerationStructure, scratch_buffer: &super::Buffer, ) { - let extension = match self.device.extension_fns.acceleration_structure { - Some(ref extension) => extension, + let ray_tracing_functions = match self.device.extension_fns.ray_tracing { + Some(ref functions) => functions, None => panic!("Feature `RAY_TRACING` not enabled"), }; - let bda_extension = match self.device.extension_fns.buffer_device_address { - Some(ref extension) => extension, - None => panic!("Feature `BDA` not enabled"), - }; - let geometry = match geometry { crate::AccelerationStructureGeometry::Instances { buffer } => { let instances = vk::AccelerationStructureGeometryInstancesDataKHR::builder().data( vk::DeviceOrHostAddressConstKHR { - device_address: bda_extension.get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), - ), + device_address: ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), + ), }, ); @@ -389,9 +386,12 @@ impl crate::CommandEncoder for super::CommandEncoder { let mut triangles_data = vk::AccelerationStructureGeometryTrianglesDataKHR::builder() .vertex_data(vk::DeviceOrHostAddressConstKHR { - device_address: bda_extension.get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(vertex_buffer.raw), - ), + device_address: ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder() + .buffer(vertex_buffer.raw), + ), }) .vertex_format(conv::map_vertex_format(vertex_format)) .vertex_stride(vertex_stride) @@ -401,9 +401,12 @@ impl crate::CommandEncoder for super::CommandEncoder { triangles_data = triangles_data .index_type(conv::map_index_format(indices.format)) .index_data(vk::DeviceOrHostAddressConstKHR { - device_address: bda_extension.get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(indices.buffer.raw), - ), + device_address: ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder() + .buffer(indices.buffer.raw), + ), }) } @@ -425,24 +428,33 @@ impl crate::CommandEncoder for super::CommandEncoder { .primitive_offset(primitive_offset) .build(); - let geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() + let mut geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() .ty(conv::map_acceleration_structure_format(format)) .mode(conv::map_acceleration_structure_build_mode(mode)) - .flags(vk::BuildAccelerationStructureFlagsKHR::PREFER_FAST_TRACE) + .flags(conv::map_acceleration_structure_flags(flags)) .geometries(geometries) .dst_acceleration_structure(destination_acceleration_structure.raw) .scratch_data(vk::DeviceOrHostAddressKHR { - device_address: bda_extension.get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(scratch_buffer.raw), - ), - }) - .build(); + device_address: ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(scratch_buffer.raw), + ), + }); + + if mode == crate::AccelerationStructureBuildMode::Update { + geometry_info.src_acceleration_structure = destination_acceleration_structure.raw; + } + + let geometry_info = geometry_info.build(); let range = &[range][..]; let range = &[range][..]; let geometry_info = &[geometry_info]; - extension.cmd_build_acceleration_structures(self.active, geometry_info, range); + ray_tracing_functions + .acceleration_structure + .cmd_build_acceleration_structures(self.active, geometry_info, range); } // render diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index e169b4ad29..7677a2ab56 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -491,14 +491,15 @@ pub fn map_buffer_usage(usage: crate::BufferUses) -> vk::BufferUsageFlags { if usage.contains(crate::BufferUses::INDIRECT) { flags |= vk::BufferUsageFlags::INDIRECT_BUFFER; } - if usage.contains(crate::BufferUses::BUFFER_DEVICE_ADDRESS) { - flags |= vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS; + if usage.contains(crate::BufferUses::ACCELERATION_STRUCTURE_SCRATCH) { + flags |= vk::BufferUsageFlags::STORAGE_BUFFER | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS; } if usage.intersects( crate::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT | crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) { - flags |= vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR; + flags |= vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR + | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS; } flags } @@ -554,7 +555,8 @@ pub fn map_buffer_usage_to_barrier( } if usage.intersects( crate::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT - | crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + | crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT + | crate::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, ) { stages |= vk::PipelineStageFlags::ACCELERATION_STRUCTURE_BUILD_KHR; access |= vk::AccessFlags::ACCELERATION_STRUCTURE_READ_KHR @@ -865,3 +867,27 @@ pub fn map_acceleration_structure_build_mode( } } } + +pub fn map_acceleration_structure_flags( + flags: crate::AccelerationStructureBuildFlags, +) -> vk::BuildAccelerationStructureFlagsKHR { + let mut vk_flags = vk::BuildAccelerationStructureFlagsKHR::empty(); + + if flags.contains(crate::AccelerationStructureBuildFlags::PREFER_FAST_TRACE) { + vk_flags |= vk::BuildAccelerationStructureFlagsKHR::PREFER_FAST_TRACE; + } + + if flags.contains(crate::AccelerationStructureBuildFlags::PREFER_FAST_BUILD) { + vk_flags |= vk::BuildAccelerationStructureFlagsKHR::PREFER_FAST_BUILD; + } + + if flags.contains(crate::AccelerationStructureBuildFlags::ALLOW_UPDATE) { + vk_flags |= vk::BuildAccelerationStructureFlagsKHR::ALLOW_UPDATE; + } + + if flags.contains(crate::AccelerationStructureBuildFlags::LOW_MEMORY) { + vk_flags |= vk::BuildAccelerationStructureFlagsKHR::LOW_MEMORY; + } + + vk_flags +} diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 47c20726fc..42b2257c24 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -821,11 +821,11 @@ impl crate::Device for super::Device { geometry_info: &crate::AccelerationStructureGeometryInfo, format: crate::AccelerationStructureFormat, mode: crate::AccelerationStructureBuildMode, - flags: (), + flags: crate::AccelerationStructureBuildFlags, primitive_count: u32, ) -> crate::AccelerationStructureBuildSizes { - let extension = match self.shared.extension_fns.acceleration_structure { - Some(ref extension) => extension, + let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { + Some(ref functions) => functions, None => panic!("Feature `RAY_TRACING` not enabled"), }; @@ -869,14 +869,16 @@ impl crate::Device for super::Device { let geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() .ty(conv::map_acceleration_structure_format(format)) .mode(conv::map_acceleration_structure_build_mode(mode)) - .flags(vk::BuildAccelerationStructureFlagsKHR::PREFER_FAST_TRACE) + .flags(conv::map_acceleration_structure_flags(flags)) .geometries(geometries); - let raw = extension.get_acceleration_structure_build_sizes( - vk::AccelerationStructureBuildTypeKHR::DEVICE, - &geometry_info, - &[primitive_count], - ); + let raw = ray_tracing_functions + .acceleration_structure + .get_acceleration_structure_build_sizes( + vk::AccelerationStructureBuildTypeKHR::DEVICE, + &geometry_info, + &[primitive_count], + ); crate::AccelerationStructureBuildSizes { acceleration_structure_size: raw.acceleration_structure_size, @@ -889,23 +891,25 @@ impl crate::Device for super::Device { &self, acceleration_structure: &super::AccelerationStructure, ) -> wgt::BufferAddress { - let extension = match self.shared.extension_fns.acceleration_structure { - Some(ref extension) => extension, + let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { + Some(ref functions) => functions, None => panic!("Feature `RAY_TRACING` not enabled"), }; - extension.get_acceleration_structure_device_address( - &vk::AccelerationStructureDeviceAddressInfoKHR::builder() - .acceleration_structure(acceleration_structure.raw), - ) + ray_tracing_functions + .acceleration_structure + .get_acceleration_structure_device_address( + &vk::AccelerationStructureDeviceAddressInfoKHR::builder() + .acceleration_structure(acceleration_structure.raw), + ) } unsafe fn create_acceleration_structure( &self, desc: &crate::AccelerationStructureDescriptor, ) -> Result { - let extension = match self.shared.extension_fns.acceleration_structure { - Some(ref extension) => extension, + let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { + Some(ref functions) => functions, None => panic!("Feature `RAY_TRACING` not enabled"), }; @@ -942,7 +946,9 @@ impl crate::Device for super::Device { .size(desc.size) .ty(conv::map_acceleration_structure_format(desc.format)); - let raw_acceleration_structure = extension.create_acceleration_structure(&vk_info, None)?; + let raw_acceleration_structure = ray_tracing_functions + .acceleration_structure + .create_acceleration_structure(&vk_info, None)?; if let Some(label) = desc.label { self.shared.set_object_name( @@ -970,12 +976,14 @@ impl crate::Device for super::Device { &self, acceleration_structure: super::AccelerationStructure, ) { - let extension = match self.shared.extension_fns.acceleration_structure { - Some(ref extension) => extension, + let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { + Some(ref functions) => functions, None => panic!("Feature `RAY_TRACING` not enabled"), }; - extension.destroy_acceleration_structure(acceleration_structure.raw, None); + ray_tracing_functions + .acceleration_structure + .destroy_acceleration_structure(acceleration_structure.raw, None); self.shared .raw .destroy_buffer(acceleration_structure.buffer, None); @@ -1583,11 +1591,15 @@ impl crate::Device for super::Device { .map(|acceleration_structure| acceleration_structure.raw), ); - acceleration_structure_infos.push( - // todo: this dereference to build the struct is a hack to get around lifetime issues. - *vk::WriteDescriptorSetAccelerationStructureKHR::builder() - .acceleration_structures(&raw_acceleration_structures[raw_start..]), - ); + let acceleration_structure_info = + vk::WriteDescriptorSetAccelerationStructureKHR::builder() + .acceleration_structures(&raw_acceleration_structures[raw_start..]); + + // todo: Dereference the struct to get around lifetime issues. Safe as long as we never resize + // `raw_acceleration_structures`. + let acceleration_structure_info: vk::WriteDescriptorSetAccelerationStructureKHR = *acceleration_structure_info; + + acceleration_structure_infos.push(acceleration_structure_info); extra_descriptor_count += 1; diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 5732fbfb60..c552a6179b 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -148,8 +148,12 @@ enum ExtensionFn { struct DeviceExtensionFunctions { draw_indirect_count: Option, timeline_semaphore: Option>, - acceleration_structure: Option, - buffer_device_address: Option, + ray_tracing: Option, +} + +struct RayTracingDeviceExtensionFunctions { + acceleration_structure: khr::AccelerationStructure, + buffer_device_address: khr::BufferDeviceAddress, } /// Set of internal capabilities, which don't show up in the exposed diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index ab6e9a944d..b33702e6ec 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -638,6 +638,14 @@ bitflags::bitflags! { /// - DX12 /// - Metal (Intel and AMD GPUs) const WRITE_TIMESTAMP_INSIDE_PASSES = 1 << 41; + + /// Allows for the creation of ray-tracing acceleration structures and ray queries within shaders. + /// + /// Supported platforms: + /// - Vulkan + /// + /// This is a native-only feature. + const RAY_TRACING = 1 << 42; } } @@ -4041,6 +4049,13 @@ pub enum BindingType { view_dimension: TextureViewDimension, }, + /// A ray-tracing acceleration structure binding. + /// + /// Example GLSL syntax: + /// ```cpp,ignore + /// layout(binding = 0) + /// uniform accelerationStructureEXT as; + /// ``` AccelerationStructure, } From cd7c80755b259ea201166bf7915b247192071c5a Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Thu, 15 Sep 2022 12:09:55 +0200 Subject: [PATCH 006/146] Fix trait implementaiton on gles --- wgpu-hal/src/empty.rs | 46 ++++++++++++++++++------------------ wgpu-hal/src/gles/command.rs | 14 +++++++++++ wgpu-hal/src/gles/device.rs | 31 +++++++++++++++++++----- wgpu-hal/src/lib.rs | 4 ++-- 4 files changed, 64 insertions(+), 31 deletions(-) diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 6448157a18..54e791b680 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -119,29 +119,6 @@ impl crate::Device for Context { unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult { Ok(Resource) } - unsafe fn create_acceleration_structure( - &self, - desc: &crate::AccelerationStructureDescriptor, - ) -> DeviceResult { - Ok(Resource) - } - unsafe fn get_acceleration_structure_build_sizes( - &self, - geometry_info: &crate::AccelerationStructureGeometryInfo, - format: crate::AccelerationStructureFormat, - mode: crate::AccelerationStructureBuildMode, - flags: crate::AccelerationStructureBuildFlags, - primitive_count: u32, - ) -> crate::AccelerationStructureBuildSizes { - Default::default() - } - unsafe fn get_acceleration_structure_device_address( - &self, - _acceleration_structure: &Resource, - ) -> wgt::BufferAddress { - Default::default() - } - unsafe fn destroy_acceleration_structure(&self, buffer: Resource) {} unsafe fn destroy_buffer(&self, buffer: Resource) {} unsafe fn map_buffer( &self, @@ -253,6 +230,29 @@ impl crate::Device for Context { false } unsafe fn stop_capture(&self) {} + unsafe fn create_acceleration_structure( + &self, + desc: &crate::AccelerationStructureDescriptor, + ) -> DeviceResult { + Ok(Resource) + } + unsafe fn get_acceleration_structure_build_sizes( + &self, + geometry_info: &crate::AccelerationStructureGeometryInfo, + format: crate::AccelerationStructureFormat, + mode: crate::AccelerationStructureBuildMode, + flags: crate::AccelerationStructureBuildFlags, + primitive_count: u32, + ) -> crate::AccelerationStructureBuildSizes { + Default::default() + } + unsafe fn get_acceleration_structure_device_address( + &self, + _acceleration_structure: &Resource, + ) -> wgt::BufferAddress { + Default::default() + } + unsafe fn destroy_acceleration_structure(&self, _acceleration_structure: Resource) {} } impl crate::CommandEncoder for Encoder { diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index beaf600e6e..a7ab8bef04 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -1000,4 +1000,18 @@ impl crate::CommandEncoder for super::CommandEncoder { indirect_offset: offset, }); } + + unsafe fn build_acceleration_structures( + &mut self, + _geometry: &crate::AccelerationStructureGeometry, + _format: crate::AccelerationStructureFormat, + _mode: crate::AccelerationStructureBuildMode, + _flags: crate::AccelerationStructureBuildFlags, + _primitive_count: u32, + _primitive_offset: u32, + _destination_acceleration_structure: &(), + _scratch_buffer: &super::Buffer, + ) { + unimplemented!() + } } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index b8fd7d3842..c765d95cca 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -455,12 +455,6 @@ impl crate::Device for super::Device { data, }) } - unsafe fn create_acceleration_structure( - &self, - _desc: &crate::AccelerationStructureDescriptor, - ) -> Result<(), crate::DeviceError> { - unimplemented!() - } unsafe fn destroy_buffer(&self, buffer: super::Buffer) { if let Some(raw) = buffer.raw { let gl = &self.shared.context.lock(); @@ -867,6 +861,7 @@ impl crate::Device for super::Device { ty: wgt::BufferBindingType::Storage { .. }, .. } => &mut num_storage_buffers, + wgt::BindingType::AccelerationStructure => unimplemented!(), }; binding_to_slot[entry.binding as usize] = *counter; @@ -947,6 +942,7 @@ impl crate::Device for super::Device { format: format_desc.internal, }) } + wgt::BindingType::AccelerationStructure => unimplemented!(), }; contents.push(binding); } @@ -1167,6 +1163,29 @@ impl crate::Device for super::Device { self.render_doc .end_frame_capture(ptr::null_mut(), ptr::null_mut()) } + unsafe fn create_acceleration_structure( + &self, + _desc: &crate::AccelerationStructureDescriptor, + ) -> Result<(), crate::DeviceError> { + unimplemented!() + } + unsafe fn get_acceleration_structure_build_sizes( + &self, + _geometry_info: &crate::AccelerationStructureGeometryInfo, + _format: crate::AccelerationStructureFormat, + _mode: crate::AccelerationStructureBuildMode, + _flags: crate::AccelerationStructureBuildFlags, + _primitive_count: u32, + ) -> crate::AccelerationStructureBuildSizes { + unimplemented!() + } + unsafe fn get_acceleration_structure_device_address( + &self, + _acceleration_structure: &(), + ) -> wgt::BufferAddress { + unimplemented!() + } + unsafe fn destroy_acceleration_structure(&self, _acceleration_structure: ()) {} } // SAFE: WASM doesn't have threads diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index a0c4597254..ea953cefb2 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -249,7 +249,7 @@ pub trait Device: Send + Sync { geometry_info: &AccelerationStructureGeometryInfo, format: AccelerationStructureFormat, mode: AccelerationStructureBuildMode, - flags: crate::AccelerationStructureBuildFlags, + flags: AccelerationStructureBuildFlags, primitive_count: u32, ) -> AccelerationStructureBuildSizes; @@ -553,7 +553,7 @@ pub trait CommandEncoder: Send + Sync { geometry: &AccelerationStructureGeometry, format: AccelerationStructureFormat, mode: AccelerationStructureBuildMode, - flags: crate::AccelerationStructureBuildFlags, + flags: AccelerationStructureBuildFlags, primitive_count: u32, primitive_offset: u32, destination_acceleration_structure: &A::AccelerationStructure, From 4ef32a4dce94151fbe6a2aab27b46e82f123aac3 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Thu, 15 Sep 2022 19:47:39 +0200 Subject: [PATCH 007/146] Put larger function call param lists into descriptors for easier dummy implementation, run cargo clippy, fix wgpu/wgpu build --- wgpu-core/src/binding_model.rs | 1 + wgpu-core/src/device/mod.rs | 2 + wgpu-hal/examples/ray-traced-triangle/main.rs | 95 ++++++----- wgpu-hal/src/empty.rs | 15 +- wgpu-hal/src/gles/command.rs | 9 +- wgpu-hal/src/gles/device.rs | 6 +- wgpu-hal/src/lib.rs | 159 +++++++++--------- wgpu-hal/src/vulkan/command.rs | 33 ++-- wgpu-hal/src/vulkan/device.rs | 18 +- 9 files changed, 161 insertions(+), 177 deletions(-) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 71f95a723d..7ef9acac2a 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -328,6 +328,7 @@ impl BindingTypeMaxCountValidator { wgt::BindingType::StorageTexture { .. } => { self.storage_textures.add(binding.visibility, count); } + wgt::BindingType::AccelerationStructure => todo!(), } } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index a5c5cbe51c..68d8b8fa59 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -1504,6 +1504,7 @@ impl Device { }, ) } + Bt::AccelerationStructure => todo!(), }; // Validate the count parameter @@ -1977,6 +1978,7 @@ impl Device { buffers: &hal_buffers, samplers: &hal_samplers, textures: &hal_textures, + acceleration_structures: &[], }; let raw = unsafe { self.raw diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index a4ae25e41c..fa749de870 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -309,15 +309,17 @@ impl Example { let blas_sizes = unsafe { device.get_acceleration_structure_build_sizes( - &hal::AccelerationStructureGeometryInfo::Triangles { - vertex_format: wgt::VertexFormat::Float32x3, - max_vertex: 3, - index_format: Some(wgt::IndexFormat::Uint32), + &hal::GetAccelerationStructureBuildSizesDescriptor { + geometry_info: hal::AccelerationStructureGeometryInfo::Triangles { + vertex_format: wgt::VertexFormat::Float32x3, + max_vertex: 3, + index_format: Some(wgt::IndexFormat::Uint32), + }, + format: hal::AccelerationStructureFormat::BottomLevel, + mode: hal::AccelerationStructureBuildMode::Build, + flags: hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, + primitive_count: 1, }, - hal::AccelerationStructureFormat::BottomLevel, - hal::AccelerationStructureBuildMode::Build, - hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, - 1, ) }; @@ -326,11 +328,13 @@ impl Example { let tlas_sizes = unsafe { device.get_acceleration_structure_build_sizes( - &hal::AccelerationStructureGeometryInfo::Instances, - hal::AccelerationStructureFormat::TopLevel, - hal::AccelerationStructureBuildMode::Build, - tlas_flags, - 1, + &hal::GetAccelerationStructureBuildSizesDescriptor { + geometry_info: hal::AccelerationStructureGeometryInfo::Instances, + format: hal::AccelerationStructureFormat::TopLevel, + mode: hal::AccelerationStructureBuildMode::Build, + flags: tlas_flags, + primitive_count: 1, + }, ) }; @@ -530,8 +534,8 @@ impl Example { unsafe { cmd_encoder.begin_encoding(Some("init")).unwrap() }; unsafe { - cmd_encoder.build_acceleration_structures( - &hal::AccelerationStructureGeometry::Triangles { + cmd_encoder.build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { + geometry: &hal::AccelerationStructureGeometry::Triangles { vertex_buffer: &vertices_buffer, vertex_format: wgt::VertexFormat::Float32x3, max_vertex: vertices.len() as u32, @@ -541,14 +545,14 @@ impl Example { format: wgt::IndexFormat::Uint32, }), }, - hal::AccelerationStructureFormat::BottomLevel, - hal::AccelerationStructureBuildMode::Build, - hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, - indices.len() as u32 / 3, - 0, - &blas, - &scratch_buffer, - ); + format: hal::AccelerationStructureFormat::BottomLevel, + mode: hal::AccelerationStructureBuildMode::Build, + flags: hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, + primitive_count: indices.len() as u32 / 3, + primitive_offset: 0, + destination_acceleration_structure: &blas, + scratch_buffer: &scratch_buffer, + }); let as_barrier = hal::BufferBarrier { buffer: &scratch_buffer, @@ -557,18 +561,18 @@ impl Example { }; cmd_encoder.transition_buffers(iter::once(as_barrier)); - cmd_encoder.build_acceleration_structures( - &hal::AccelerationStructureGeometry::Instances { + cmd_encoder.build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { + geometry: &hal::AccelerationStructureGeometry::Instances { buffer: &instances_buffer, }, - hal::AccelerationStructureFormat::TopLevel, - hal::AccelerationStructureBuildMode::Build, - tlas_flags, - instances.len() as u32, - 0, - &tlas, - &scratch_buffer, - ); + format: hal::AccelerationStructureFormat::TopLevel, + mode: hal::AccelerationStructureBuildMode::Build, + flags: tlas_flags, + primitive_count: instances.len() as u32, + primitive_offset: 0, + destination_acceleration_structure: &tlas, + scratch_buffer: &scratch_buffer, + }); let texture_barrier = hal::TextureBarrier { texture: &texture, @@ -677,18 +681,19 @@ impl Example { unsafe { ctx.encoder.begin_encoding(Some("frame")).unwrap(); - ctx.encoder.build_acceleration_structures( - &hal::AccelerationStructureGeometry::Instances { - buffer: &self.instances_buffer, - }, - hal::AccelerationStructureFormat::TopLevel, - hal::AccelerationStructureBuildMode::Build, - tlas_flags, - self.instances.len() as u32, - 0, - &self.tlas, - &self.scratch_buffer, - ); + ctx.encoder + .build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { + geometry: &hal::AccelerationStructureGeometry::Instances { + buffer: &self.instances_buffer, + }, + format: hal::AccelerationStructureFormat::TopLevel, + mode: hal::AccelerationStructureBuildMode::Update, + flags: tlas_flags, + primitive_count: self.instances.len() as u32, + primitive_offset: 0, + destination_acceleration_structure: &self.tlas, + scratch_buffer: &self.scratch_buffer, + }); let as_barrier = hal::BufferBarrier { buffer: &self.scratch_buffer, diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 54e791b680..aff9640a79 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -238,11 +238,7 @@ impl crate::Device for Context { } unsafe fn get_acceleration_structure_build_sizes( &self, - geometry_info: &crate::AccelerationStructureGeometryInfo, - format: crate::AccelerationStructureFormat, - mode: crate::AccelerationStructureBuildMode, - flags: crate::AccelerationStructureBuildFlags, - primitive_count: u32, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, ) -> crate::AccelerationStructureBuildSizes { Default::default() } @@ -418,14 +414,7 @@ impl crate::CommandEncoder for Encoder { unsafe fn build_acceleration_structures( &mut self, - geometry: &crate::AccelerationStructureGeometry, - format: crate::AccelerationStructureFormat, - mode: crate::AccelerationStructureBuildMode, - flags: crate::AccelerationStructureBuildFlags, - primitive_count: u32, - primitive_offset: u32, - destination_acceleration_structure: &Resource, - scratch_buffer: &Resource, + _desc: &crate::BuildAccelerationStructureDescriptor, ) { } } diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index a7ab8bef04..e61e70357b 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -1003,14 +1003,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn build_acceleration_structures( &mut self, - _geometry: &crate::AccelerationStructureGeometry, - _format: crate::AccelerationStructureFormat, - _mode: crate::AccelerationStructureBuildMode, - _flags: crate::AccelerationStructureBuildFlags, - _primitive_count: u32, - _primitive_offset: u32, - _destination_acceleration_structure: &(), - _scratch_buffer: &super::Buffer, + _desc: &crate::BuildAccelerationStructureDescriptor, ) { unimplemented!() } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index c765d95cca..1858825463 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -1171,11 +1171,7 @@ impl crate::Device for super::Device { } unsafe fn get_acceleration_structure_build_sizes( &self, - _geometry_info: &crate::AccelerationStructureGeometryInfo, - _format: crate::AccelerationStructureFormat, - _mode: crate::AccelerationStructureBuildMode, - _flags: crate::AccelerationStructureBuildFlags, - _primitive_count: u32, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, ) -> crate::AccelerationStructureBuildSizes { unimplemented!() } diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index ea953cefb2..019c6b4b9f 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -246,11 +246,7 @@ pub trait Device: Send + Sync { unsafe fn get_acceleration_structure_build_sizes( &self, - geometry_info: &AccelerationStructureGeometryInfo, - format: AccelerationStructureFormat, - mode: AccelerationStructureBuildMode, - flags: AccelerationStructureBuildFlags, - primitive_count: u32, + desc: &GetAccelerationStructureBuildSizesDescriptor, ) -> AccelerationStructureBuildSizes; unsafe fn get_acceleration_structure_device_address( @@ -550,14 +546,7 @@ pub trait CommandEncoder: Send + Sync { unsafe fn build_acceleration_structures( &mut self, - geometry: &AccelerationStructureGeometry, - format: AccelerationStructureFormat, - mode: AccelerationStructureBuildMode, - flags: AccelerationStructureBuildFlags, - primitive_count: u32, - primitive_offset: u32, - destination_acceleration_structure: &A::AccelerationStructure, - scratch_buffer: &A::Buffer, + desc: &BuildAccelerationStructureDescriptor, ); } @@ -849,32 +838,6 @@ pub struct BufferDescriptor<'a> { pub memory_flags: MemoryFlags, } -#[derive(Clone, Debug)] -pub struct AccelerationStructureDescriptor<'a> { - pub label: Label<'a>, - pub size: wgt::BufferAddress, - pub format: AccelerationStructureFormat, -} - -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub enum AccelerationStructureFormat { - TopLevel, - BottomLevel, -} - -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub enum AccelerationStructureBuildMode { - Build, - Update, -} - -#[derive(Clone, Debug, Default)] -pub struct AccelerationStructureBuildSizes { - pub acceleration_structure_size: wgt::BufferAddress, - pub update_scratch_size: wgt::BufferAddress, - pub build_scratch_size: wgt::BufferAddress, -} - #[derive(Clone, Debug)] pub struct TextureDescriptor<'a> { pub label: Label<'a>, @@ -1163,42 +1126,6 @@ pub struct BufferCopy { pub size: wgt::BufferSize, } -pub enum AccelerationStructureGeometryInfo { - Triangles { - vertex_format: wgt::VertexFormat, - max_vertex: u32, - index_format: Option, - }, - Instances, -} - -pub enum AccelerationStructureGeometry<'a, A: Api> { - Triangles { - vertex_buffer: &'a A::Buffer, - vertex_format: wgt::VertexFormat, - max_vertex: u32, - vertex_stride: wgt::BufferAddress, - indices: Option>, - }, - Instances { - buffer: &'a A::Buffer, - }, -} - -pub struct AccelerationStructureGeometryIndices<'a, A: Api> { - pub format: wgt::IndexFormat, - pub buffer: &'a A::Buffer, -} - -bitflags!( - pub struct AccelerationStructureBuildFlags: u32 { - const PREFER_FAST_TRACE = 1 << 0; - const PREFER_FAST_BUILD = 1 << 1; - const ALLOW_UPDATE = 1 << 2; - const LOW_MEMORY = 1 << 3; - } -); - #[derive(Clone, Debug)] pub struct TextureCopyBase { pub mip_level: u32, @@ -1329,3 +1256,85 @@ fn test_default_limits() { let limits = wgt::Limits::default(); assert!(limits.max_bind_groups <= MAX_BIND_GROUPS as u32); } + +#[derive(Clone, Debug)] +pub struct AccelerationStructureDescriptor<'a> { + pub label: Label<'a>, + pub size: wgt::BufferAddress, + pub format: AccelerationStructureFormat, +} + +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub enum AccelerationStructureFormat { + TopLevel, + BottomLevel, +} + +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub enum AccelerationStructureBuildMode { + Build, + Update, +} + +#[derive(Clone, Debug, Default)] +pub struct AccelerationStructureBuildSizes { + pub acceleration_structure_size: wgt::BufferAddress, + pub update_scratch_size: wgt::BufferAddress, + pub build_scratch_size: wgt::BufferAddress, +} + +pub struct GetAccelerationStructureBuildSizesDescriptor { + pub geometry_info: AccelerationStructureGeometryInfo, + pub format: AccelerationStructureFormat, + pub mode: AccelerationStructureBuildMode, + pub flags: AccelerationStructureBuildFlags, + pub primitive_count: u32, +} + +#[derive(Clone, Copy)] +pub enum AccelerationStructureGeometryInfo { + Triangles { + vertex_format: wgt::VertexFormat, + max_vertex: u32, + index_format: Option, + }, + Instances, +} + +pub struct BuildAccelerationStructureDescriptor<'a, A: Api> { + pub geometry: &'a AccelerationStructureGeometry<'a, A>, + pub format: AccelerationStructureFormat, + pub mode: AccelerationStructureBuildMode, + pub flags: AccelerationStructureBuildFlags, + pub primitive_count: u32, + pub primitive_offset: u32, + pub destination_acceleration_structure: &'a A::AccelerationStructure, + pub scratch_buffer: &'a A::Buffer, +} + +pub enum AccelerationStructureGeometry<'a, A: Api> { + Triangles { + vertex_buffer: &'a A::Buffer, + vertex_format: wgt::VertexFormat, + max_vertex: u32, + vertex_stride: wgt::BufferAddress, + indices: Option>, + }, + Instances { + buffer: &'a A::Buffer, + }, +} + +pub struct AccelerationStructureGeometryIndices<'a, A: Api> { + pub format: wgt::IndexFormat, + pub buffer: &'a A::Buffer, +} + +bitflags!( + pub struct AccelerationStructureBuildFlags: u32 { + const PREFER_FAST_TRACE = 1 << 0; + const PREFER_FAST_BUILD = 1 << 1; + const ALLOW_UPDATE = 1 << 2; + const LOW_MEMORY = 1 << 3; + } +); diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index a5b35f765e..02768f3c74 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -343,21 +343,14 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn build_acceleration_structures( &mut self, - geometry: &crate::AccelerationStructureGeometry, - format: crate::AccelerationStructureFormat, - mode: crate::AccelerationStructureBuildMode, - flags: crate::AccelerationStructureBuildFlags, - primitive_count: u32, - primitive_offset: u32, - destination_acceleration_structure: &super::AccelerationStructure, - scratch_buffer: &super::Buffer, + desc: &crate::BuildAccelerationStructureDescriptor, ) { let ray_tracing_functions = match self.device.extension_fns.ray_tracing { Some(ref functions) => functions, None => panic!("Feature `RAY_TRACING` not enabled"), }; - let geometry = match geometry { + let geometry = match *desc.geometry { crate::AccelerationStructureGeometry::Instances { buffer } => { let instances = vk::AccelerationStructureGeometryInstancesDataKHR::builder().data( vk::DeviceOrHostAddressConstKHR { @@ -376,7 +369,7 @@ impl crate::CommandEncoder for super::CommandEncoder { }) .flags(vk::GeometryFlagsKHR::empty()) } - &crate::AccelerationStructureGeometry::Triangles { + crate::AccelerationStructureGeometry::Triangles { vertex_buffer, vertex_format, max_vertex, @@ -397,7 +390,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .vertex_stride(vertex_stride) .max_vertex(max_vertex); - if let Some(indices) = indices { + if let Some(ref indices) = *indices { triangles_data = triangles_data .index_type(conv::map_index_format(indices.format)) .index_data(vk::DeviceOrHostAddressConstKHR { @@ -424,26 +417,26 @@ impl crate::CommandEncoder for super::CommandEncoder { let geometries = &[*geometry]; let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() - .primitive_count(primitive_count) - .primitive_offset(primitive_offset) + .primitive_count(desc.primitive_count) + .primitive_offset(desc.primitive_offset) .build(); let mut geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() - .ty(conv::map_acceleration_structure_format(format)) - .mode(conv::map_acceleration_structure_build_mode(mode)) - .flags(conv::map_acceleration_structure_flags(flags)) + .ty(conv::map_acceleration_structure_format(desc.format)) + .mode(conv::map_acceleration_structure_build_mode(desc.mode)) + .flags(conv::map_acceleration_structure_flags(desc.flags)) .geometries(geometries) - .dst_acceleration_structure(destination_acceleration_structure.raw) + .dst_acceleration_structure(desc.destination_acceleration_structure.raw) .scratch_data(vk::DeviceOrHostAddressKHR { device_address: ray_tracing_functions .buffer_device_address .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(scratch_buffer.raw), + &vk::BufferDeviceAddressInfo::builder().buffer(desc.scratch_buffer.raw), ), }); - if mode == crate::AccelerationStructureBuildMode::Update { - geometry_info.src_acceleration_structure = destination_acceleration_structure.raw; + if desc.mode == crate::AccelerationStructureBuildMode::Update { + geometry_info.src_acceleration_structure = desc.destination_acceleration_structure.raw; } let geometry_info = geometry_info.build(); diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 42b2257c24..83c9e6ac58 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -818,18 +818,14 @@ impl crate::Device for super::Device { unsafe fn get_acceleration_structure_build_sizes( &self, - geometry_info: &crate::AccelerationStructureGeometryInfo, - format: crate::AccelerationStructureFormat, - mode: crate::AccelerationStructureBuildMode, - flags: crate::AccelerationStructureBuildFlags, - primitive_count: u32, + desc: &crate::GetAccelerationStructureBuildSizesDescriptor, ) -> crate::AccelerationStructureBuildSizes { let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { Some(ref functions) => functions, None => panic!("Feature `RAY_TRACING` not enabled"), }; - let geometry = match geometry_info { + let geometry = match desc.geometry_info { crate::AccelerationStructureGeometryInfo::Instances => { let instances_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder(); @@ -840,7 +836,7 @@ impl crate::Device for super::Device { }) .flags(vk::GeometryFlagsKHR::empty()) } - &crate::AccelerationStructureGeometryInfo::Triangles { + crate::AccelerationStructureGeometryInfo::Triangles { vertex_format, max_vertex, index_format, @@ -867,9 +863,9 @@ impl crate::Device for super::Device { let geometries = &[*geometry]; let geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() - .ty(conv::map_acceleration_structure_format(format)) - .mode(conv::map_acceleration_structure_build_mode(mode)) - .flags(conv::map_acceleration_structure_flags(flags)) + .ty(conv::map_acceleration_structure_format(desc.format)) + .mode(conv::map_acceleration_structure_build_mode(desc.mode)) + .flags(conv::map_acceleration_structure_flags(desc.flags)) .geometries(geometries); let raw = ray_tracing_functions @@ -877,7 +873,7 @@ impl crate::Device for super::Device { .get_acceleration_structure_build_sizes( vk::AccelerationStructureBuildTypeKHR::DEVICE, &geometry_info, - &[primitive_count], + &[desc.primitive_count], ); crate::AccelerationStructureBuildSizes { From 8318b5f77a538d6db692b2e1f760ad154b6f37bf Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Thu, 15 Sep 2022 19:55:53 +0200 Subject: [PATCH 008/146] Fix wasm build --- wgpu/src/backend/web.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index f816125148..6b1a8cfd37 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1443,7 +1443,8 @@ impl crate::Context for Context { storage_texture.access(mapped_access); storage_texture.view_dimension(map_texture_view_dimension(view_dimension)); mapped_entry.storage_texture(&storage_texture); - } + }, + wgt::BindingType::AccelerationStructure => todo!(), } mapped_entry From fecb5382e7e50e451f1b4e10459992d436d4324f Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Thu, 15 Sep 2022 20:48:43 +0200 Subject: [PATCH 009/146] Shuffle some code around, add a dummy implementation for DX12 with some links to implementation resources. --- wgpu-hal/src/dx11/command.rs | 7 + wgpu-hal/src/dx11/device.rs | 25 +++ wgpu-hal/src/dx11/mod.rs | 4 + wgpu-hal/src/dx12/command.rs | 9 + wgpu-hal/src/dx12/conv.rs | 1 + wgpu-hal/src/dx12/device.rs | 36 ++++ wgpu-hal/src/dx12/mod.rs | 5 + wgpu-hal/src/lib.rs | 35 ++-- wgpu-hal/src/vulkan/device.rs | 331 +++++++++++++++++----------------- wgpu/src/backend/web.rs | 2 +- 10 files changed, 270 insertions(+), 185 deletions(-) diff --git a/wgpu-hal/src/dx11/command.rs b/wgpu-hal/src/dx11/command.rs index 1c73f3c325..3ec95d0c33 100644 --- a/wgpu-hal/src/dx11/command.rs +++ b/wgpu-hal/src/dx11/command.rs @@ -265,4 +265,11 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn dispatch_indirect(&mut self, buffer: &super::Buffer, offset: wgt::BufferAddress) { todo!() } + + unsafe fn build_acceleration_structures( + &mut self, + desc: &crate::BuildAccelerationStructureDescriptor, + ) { + todo!() + } } diff --git a/wgpu-hal/src/dx11/device.rs b/wgpu-hal/src/dx11/device.rs index 7b095ba1df..ee73329412 100644 --- a/wgpu-hal/src/dx11/device.rs +++ b/wgpu-hal/src/dx11/device.rs @@ -200,6 +200,31 @@ impl crate::Device for super::Device { unsafe fn stop_capture(&self) { todo!() } + + unsafe fn create_acceleration_structure( + &self, + desc: &crate::AccelerationStructureDescriptor, + ) -> Result { + todo!() + } + unsafe fn get_acceleration_structure_build_sizes( + &self, + desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + ) -> crate::AccelerationStructureBuildSizes { + todo!() + } + unsafe fn get_acceleration_structure_device_address( + &self, + acceleration_structure: &super::AccelerationStructure, + ) -> wgt::BufferAddress { + todo!() + } + unsafe fn destroy_acceleration_structure( + &self, + acceleration_structure: super::AccelerationStructure, + ) { + todo!() + } } impl crate::Queue for super::Queue { diff --git a/wgpu-hal/src/dx11/mod.rs b/wgpu-hal/src/dx11/mod.rs index a77bb95919..e67feb3fad 100644 --- a/wgpu-hal/src/dx11/mod.rs +++ b/wgpu-hal/src/dx11/mod.rs @@ -36,6 +36,8 @@ impl crate::Api for Api { type ShaderModule = ShaderModule; type RenderPipeline = RenderPipeline; type ComputePipeline = ComputePipeline; + + type AccelerationStructure = AccelerationStructure; } pub struct Instance { @@ -106,6 +108,8 @@ pub struct BindGroup {} pub struct PipelineLayout {} #[derive(Debug)] pub struct ShaderModule {} +#[derive(Debug)] +pub struct AccelerationStructure {} pub struct RenderPipeline {} pub struct ComputePipeline {} diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index ca2f036430..4f843146f8 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1019,4 +1019,13 @@ impl crate::CommandEncoder for super::CommandEncoder { 0, ); } + + unsafe fn build_acceleration_structures( + &mut self, + _desc: &crate::BuildAccelerationStructureDescriptor, + ) { + // Implement using `BuildRaytracingAccelerationStructure`: + // https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#buildraytracingaccelerationstructure + todo!() + } } diff --git a/wgpu-hal/src/dx12/conv.rs b/wgpu-hal/src/dx12/conv.rs index 4114fba002..bbe14cefff 100644 --- a/wgpu-hal/src/dx12/conv.rs +++ b/wgpu-hal/src/dx12/conv.rs @@ -107,6 +107,7 @@ pub fn map_binding_type(ty: &wgt::BindingType) -> native::DescriptorRangeType { .. } | Bt::StorageTexture { .. } => native::DescriptorRangeType::UAV, + Bt::AccelerationStructure => todo!(), } } diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index de81b4e1bd..106f815711 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -706,6 +706,7 @@ impl crate::Device for super::Device { num_texture_views += count } wgt::BindingType::Sampler { .. } => num_samplers += count, + wgt::BindingType::AccelerationStructure => todo!(), } } @@ -1189,6 +1190,7 @@ impl crate::Device for super::Device { cpu_samplers.as_mut().unwrap().stage.push(data.handle.raw); } } + wgt::BindingType::AccelerationStructure => todo!(), } } @@ -1567,4 +1569,38 @@ impl crate::Device for super::Device { self.render_doc .end_frame_capture(self.raw.as_mut_ptr() as *mut _, ptr::null_mut()) } + + unsafe fn get_acceleration_structure_build_sizes( + &self, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + ) -> crate::AccelerationStructureBuildSizes { + // Implement using `GetRaytracingAccelerationStructurePrebuildInfo`: + // https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#getraytracingaccelerationstructureprebuildinfo + todo!() + } + + unsafe fn get_acceleration_structure_device_address( + &self, + _acceleration_structure: &super::AccelerationStructure, + ) -> wgt::BufferAddress { + // Implement using `GetGPUVirtualAddress`: + // https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12resource-getgpuvirtualaddress + todo!() + } + + unsafe fn create_acceleration_structure( + &self, + _desc: &crate::AccelerationStructureDescriptor, + ) -> Result { + // Create a D3D12 resource as per-usual. + todo!() + } + + unsafe fn destroy_acceleration_structure( + &self, + _acceleration_structure: super::AccelerationStructure, + ) { + // Destroy a D3D12 resource as per-usual. + todo!() + } } diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 61d2ad9576..195fd429fe 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -79,6 +79,8 @@ impl crate::Api for Api { type ShaderModule = ShaderModule; type RenderPipeline = RenderPipeline; type ComputePipeline = ComputePipeline; + + type AccelerationStructure = AccelerationStructure; } // Limited by D3D12's root signature size of 64. Each element takes 1 or 2 entries. @@ -524,6 +526,9 @@ pub struct ComputePipeline { unsafe impl Send for ComputePipeline {} unsafe impl Sync for ComputePipeline {} +#[derive(Debug)] +pub struct AccelerationStructure {} + impl SwapChain { unsafe fn release_resources(self) -> native::WeakPtr { for resource in self.resources { diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 019c6b4b9f..c91560cca9 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -238,24 +238,6 @@ pub trait Device: Send + Sync { /// /// The initial usage is `BufferUses::empty()`. unsafe fn create_buffer(&self, desc: &BufferDescriptor) -> Result; - - unsafe fn create_acceleration_structure( - &self, - desc: &AccelerationStructureDescriptor, - ) -> Result; - - unsafe fn get_acceleration_structure_build_sizes( - &self, - desc: &GetAccelerationStructureBuildSizesDescriptor, - ) -> AccelerationStructureBuildSizes; - - unsafe fn get_acceleration_structure_device_address( - &self, - acceleration_structure: &A::AccelerationStructure, - ) -> wgt::BufferAddress; - - unsafe fn destroy_acceleration_structure(&self, buffer: A::AccelerationStructure); - unsafe fn destroy_buffer(&self, buffer: A::Buffer); //TODO: clarify if zero-sized mapping is allowed unsafe fn map_buffer( @@ -343,6 +325,23 @@ pub trait Device: Send + Sync { unsafe fn start_capture(&self) -> bool; unsafe fn stop_capture(&self); + + unsafe fn create_acceleration_structure( + &self, + desc: &AccelerationStructureDescriptor, + ) -> Result; + unsafe fn get_acceleration_structure_build_sizes( + &self, + desc: &GetAccelerationStructureBuildSizesDescriptor, + ) -> AccelerationStructureBuildSizes; + unsafe fn get_acceleration_structure_device_address( + &self, + acceleration_structure: &A::AccelerationStructure, + ) -> wgt::BufferAddress; + unsafe fn destroy_acceleration_structure( + &self, + acceleration_structure: A::AccelerationStructure, + ); } pub trait Queue: Send + Sync { diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 83c9e6ac58..afff881b18 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -815,152 +815,6 @@ impl crate::Device for super::Device { block: Mutex::new(block), }) } - - unsafe fn get_acceleration_structure_build_sizes( - &self, - desc: &crate::GetAccelerationStructureBuildSizesDescriptor, - ) -> crate::AccelerationStructureBuildSizes { - let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { - Some(ref functions) => functions, - None => panic!("Feature `RAY_TRACING` not enabled"), - }; - - let geometry = match desc.geometry_info { - crate::AccelerationStructureGeometryInfo::Instances => { - let instances_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder(); - - vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::INSTANCES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - instances: *instances_data, - }) - .flags(vk::GeometryFlagsKHR::empty()) - } - crate::AccelerationStructureGeometryInfo::Triangles { - vertex_format, - max_vertex, - index_format, - } => { - let mut triangles_data = - vk::AccelerationStructureGeometryTrianglesDataKHR::builder() - .vertex_format(conv::map_vertex_format(vertex_format)) - .max_vertex(max_vertex); - - if let Some(index_format) = index_format { - triangles_data = - triangles_data.index_type(conv::map_index_format(index_format)); - } - - vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::TRIANGLES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - triangles: *triangles_data, - }) - .flags(vk::GeometryFlagsKHR::empty()) - } - }; - - let geometries = &[*geometry]; - - let geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() - .ty(conv::map_acceleration_structure_format(desc.format)) - .mode(conv::map_acceleration_structure_build_mode(desc.mode)) - .flags(conv::map_acceleration_structure_flags(desc.flags)) - .geometries(geometries); - - let raw = ray_tracing_functions - .acceleration_structure - .get_acceleration_structure_build_sizes( - vk::AccelerationStructureBuildTypeKHR::DEVICE, - &geometry_info, - &[desc.primitive_count], - ); - - crate::AccelerationStructureBuildSizes { - acceleration_structure_size: raw.acceleration_structure_size, - update_scratch_size: raw.update_scratch_size, - build_scratch_size: raw.build_scratch_size, - } - } - - unsafe fn get_acceleration_structure_device_address( - &self, - acceleration_structure: &super::AccelerationStructure, - ) -> wgt::BufferAddress { - let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { - Some(ref functions) => functions, - None => panic!("Feature `RAY_TRACING` not enabled"), - }; - - ray_tracing_functions - .acceleration_structure - .get_acceleration_structure_device_address( - &vk::AccelerationStructureDeviceAddressInfoKHR::builder() - .acceleration_structure(acceleration_structure.raw), - ) - } - - unsafe fn create_acceleration_structure( - &self, - desc: &crate::AccelerationStructureDescriptor, - ) -> Result { - let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { - Some(ref functions) => functions, - None => panic!("Feature `RAY_TRACING` not enabled"), - }; - - let vk_buffer_info = vk::BufferCreateInfo::builder() - .size(desc.size) - .usage(vk::BufferUsageFlags::ACCELERATION_STRUCTURE_STORAGE_KHR) - .sharing_mode(vk::SharingMode::EXCLUSIVE); - - let raw_buffer = self.shared.raw.create_buffer(&vk_buffer_info, None)?; - let req = self.shared.raw.get_buffer_memory_requirements(raw_buffer); - - let block = self.mem_allocator.lock().alloc( - &*self.shared, - gpu_alloc::Request { - size: req.size, - align_mask: req.alignment - 1, - usage: gpu_alloc::UsageFlags::FAST_DEVICE_ACCESS, - memory_types: req.memory_type_bits & self.valid_ash_memory_types, - }, - )?; - - self.shared - .raw - .bind_buffer_memory(raw_buffer, *block.memory(), block.offset())?; - - if let Some(label) = desc.label { - self.shared - .set_object_name(vk::ObjectType::BUFFER, raw_buffer, label); - } - - let vk_info = vk::AccelerationStructureCreateInfoKHR::builder() - .buffer(raw_buffer) - .offset(0) - .size(desc.size) - .ty(conv::map_acceleration_structure_format(desc.format)); - - let raw_acceleration_structure = ray_tracing_functions - .acceleration_structure - .create_acceleration_structure(&vk_info, None)?; - - if let Some(label) = desc.label { - self.shared.set_object_name( - vk::ObjectType::ACCELERATION_STRUCTURE_KHR, - raw_acceleration_structure, - label, - ); - } - - Ok(super::AccelerationStructure { - raw: raw_acceleration_structure, - buffer: raw_buffer, - block: Mutex::new(block), - }) - } - unsafe fn destroy_buffer(&self, buffer: super::Buffer) { self.shared.raw.destroy_buffer(buffer.raw, None); self.mem_allocator @@ -968,26 +822,6 @@ impl crate::Device for super::Device { .dealloc(&*self.shared, buffer.block.into_inner()); } - unsafe fn destroy_acceleration_structure( - &self, - acceleration_structure: super::AccelerationStructure, - ) { - let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { - Some(ref functions) => functions, - None => panic!("Feature `RAY_TRACING` not enabled"), - }; - - ray_tracing_functions - .acceleration_structure - .destroy_acceleration_structure(acceleration_structure.raw, None); - self.shared - .raw - .destroy_buffer(acceleration_structure.buffer, None); - self.mem_allocator - .lock() - .dealloc(&*self.shared, acceleration_structure.block.into_inner()); - } - unsafe fn map_buffer( &self, buffer: &super::Buffer, @@ -2117,6 +1951,171 @@ impl crate::Device for super::Device { .end_frame_capture(raw_vk_instance_dispatch_table, ptr::null_mut()) } } + + unsafe fn get_acceleration_structure_build_sizes( + &self, + desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + ) -> crate::AccelerationStructureBuildSizes { + let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { + Some(ref functions) => functions, + None => panic!("Feature `RAY_TRACING` not enabled"), + }; + + let geometry = match desc.geometry_info { + crate::AccelerationStructureGeometryInfo::Instances => { + let instances_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder(); + + vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::INSTANCES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + instances: *instances_data, + }) + .flags(vk::GeometryFlagsKHR::empty()) + } + crate::AccelerationStructureGeometryInfo::Triangles { + vertex_format, + max_vertex, + index_format, + } => { + let mut triangles_data = + vk::AccelerationStructureGeometryTrianglesDataKHR::builder() + .vertex_format(conv::map_vertex_format(vertex_format)) + .max_vertex(max_vertex); + + if let Some(index_format) = index_format { + triangles_data = + triangles_data.index_type(conv::map_index_format(index_format)); + } + + vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::TRIANGLES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + triangles: *triangles_data, + }) + .flags(vk::GeometryFlagsKHR::empty()) + } + }; + + let geometries = &[*geometry]; + + let geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() + .ty(conv::map_acceleration_structure_format(desc.format)) + .mode(conv::map_acceleration_structure_build_mode(desc.mode)) + .flags(conv::map_acceleration_structure_flags(desc.flags)) + .geometries(geometries); + + let raw = ray_tracing_functions + .acceleration_structure + .get_acceleration_structure_build_sizes( + vk::AccelerationStructureBuildTypeKHR::DEVICE, + &geometry_info, + &[desc.primitive_count], + ); + + crate::AccelerationStructureBuildSizes { + acceleration_structure_size: raw.acceleration_structure_size, + update_scratch_size: raw.update_scratch_size, + build_scratch_size: raw.build_scratch_size, + } + } + + unsafe fn get_acceleration_structure_device_address( + &self, + acceleration_structure: &super::AccelerationStructure, + ) -> wgt::BufferAddress { + let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { + Some(ref functions) => functions, + None => panic!("Feature `RAY_TRACING` not enabled"), + }; + + ray_tracing_functions + .acceleration_structure + .get_acceleration_structure_device_address( + &vk::AccelerationStructureDeviceAddressInfoKHR::builder() + .acceleration_structure(acceleration_structure.raw), + ) + } + + unsafe fn create_acceleration_structure( + &self, + desc: &crate::AccelerationStructureDescriptor, + ) -> Result { + let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { + Some(ref functions) => functions, + None => panic!("Feature `RAY_TRACING` not enabled"), + }; + + let vk_buffer_info = vk::BufferCreateInfo::builder() + .size(desc.size) + .usage(vk::BufferUsageFlags::ACCELERATION_STRUCTURE_STORAGE_KHR) + .sharing_mode(vk::SharingMode::EXCLUSIVE); + + let raw_buffer = self.shared.raw.create_buffer(&vk_buffer_info, None)?; + let req = self.shared.raw.get_buffer_memory_requirements(raw_buffer); + + let block = self.mem_allocator.lock().alloc( + &*self.shared, + gpu_alloc::Request { + size: req.size, + align_mask: req.alignment - 1, + usage: gpu_alloc::UsageFlags::FAST_DEVICE_ACCESS, + memory_types: req.memory_type_bits & self.valid_ash_memory_types, + }, + )?; + + self.shared + .raw + .bind_buffer_memory(raw_buffer, *block.memory(), block.offset())?; + + if let Some(label) = desc.label { + self.shared + .set_object_name(vk::ObjectType::BUFFER, raw_buffer, label); + } + + let vk_info = vk::AccelerationStructureCreateInfoKHR::builder() + .buffer(raw_buffer) + .offset(0) + .size(desc.size) + .ty(conv::map_acceleration_structure_format(desc.format)); + + let raw_acceleration_structure = ray_tracing_functions + .acceleration_structure + .create_acceleration_structure(&vk_info, None)?; + + if let Some(label) = desc.label { + self.shared.set_object_name( + vk::ObjectType::ACCELERATION_STRUCTURE_KHR, + raw_acceleration_structure, + label, + ); + } + + Ok(super::AccelerationStructure { + raw: raw_acceleration_structure, + buffer: raw_buffer, + block: Mutex::new(block), + }) + } + + unsafe fn destroy_acceleration_structure( + &self, + acceleration_structure: super::AccelerationStructure, + ) { + let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { + Some(ref functions) => functions, + None => panic!("Feature `RAY_TRACING` not enabled"), + }; + + ray_tracing_functions + .acceleration_structure + .destroy_acceleration_structure(acceleration_structure.raw, None); + self.shared + .raw + .destroy_buffer(acceleration_structure.buffer, None); + self.mem_allocator + .lock() + .dealloc(&*self.shared, acceleration_structure.block.into_inner()); + } } impl From for crate::DeviceError { diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 6b1a8cfd37..5cb9057208 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1443,7 +1443,7 @@ impl crate::Context for Context { storage_texture.access(mapped_access); storage_texture.view_dimension(map_texture_view_dimension(view_dimension)); mapped_entry.storage_texture(&storage_texture); - }, + } wgt::BindingType::AccelerationStructure => todo!(), } From 7905dc582f90ece798f069fe481cfa581411cf93 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Fri, 16 Sep 2022 22:28:09 +0200 Subject: [PATCH 010/146] Add dummy implementation for metal --- wgpu-hal/src/metal/command.rs | 7 +++++++ wgpu-hal/src/metal/device.rs | 28 ++++++++++++++++++++++++++++ wgpu-hal/src/metal/mod.rs | 5 +++++ 3 files changed, 40 insertions(+) diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 49337ee7ea..6048aca0f4 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -962,4 +962,11 @@ impl crate::CommandEncoder for super::CommandEncoder { let encoder = self.state.compute.as_ref().unwrap(); encoder.dispatch_thread_groups_indirect(&buffer.raw, offset, self.state.raw_wg_size); } + + unsafe fn build_acceleration_structures( + &mut self, + _desc: &crate::BuildAccelerationStructureDescriptor, + ) { + unimplemented!() + } } diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 81b9461f87..7064068acb 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -1123,4 +1123,32 @@ impl crate::Device for super::Device { } shared_capture_manager.stop_capture(); } + + unsafe fn get_acceleration_structure_build_sizes( + &self, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + ) -> crate::AccelerationStructureBuildSizes { + unimplemented!() + } + + unsafe fn get_acceleration_structure_device_address( + &self, + _acceleration_structure: &super::AccelerationStructure, + ) -> wgt::BufferAddress { + unimplemented!() + } + + unsafe fn create_acceleration_structure( + &self, + _desc: &crate::AccelerationStructureDescriptor, + ) -> Result { + unimplemented!() + } + + unsafe fn destroy_acceleration_structure( + &self, + _acceleration_structure: super::AccelerationStructure, + ) { + unimplemented!() + } } diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index dee9467e74..42466fc3c8 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -59,6 +59,8 @@ impl crate::Api for Api { type ShaderModule = ShaderModule; type RenderPipeline = RenderPipeline; type ComputePipeline = ComputePipeline; + + type AccelerationStructure = AccelerationStructure; } pub struct Instance { @@ -733,3 +735,6 @@ pub struct CommandBuffer { unsafe impl Send for CommandBuffer {} unsafe impl Sync for CommandBuffer {} + +#[derive(Debug)] +pub struct AccelerationStructure; From 6f2b07a00c3e462da85a6c15fe88adcc45b30ae4 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Sun, 18 Sep 2022 15:08:19 +0200 Subject: [PATCH 011/146] Fix example, hopefully have fixed metal code --- wgpu-hal/examples/ray-traced-triangle/main.rs | 7 ++++++- wgpu-hal/src/metal/device.rs | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index fa749de870..49fb58686b 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -3,6 +3,7 @@ extern crate wgpu_hal as hal; use hal::{ Adapter as _, CommandEncoder as _, Device as _, Instance as _, Queue as _, Surface as _, }; +use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; use glam::{Mat4, Vec3}; use std::{ @@ -101,7 +102,11 @@ impl Example { }, }; let instance = unsafe { A::Instance::init(&instance_desc)? }; - let mut surface = unsafe { instance.create_surface(window).unwrap() }; + let mut surface = unsafe { + instance + .create_surface(window.raw_display_handle(), window.raw_window_handle()) + .unwrap() + }; let (adapter, features) = unsafe { let mut adapters = instance.enumerate_adapters(); diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 81b9461f87..da7ecd4830 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -595,6 +595,7 @@ impl crate::Device for super::Device { wgt::StorageTextureAccess::ReadWrite => true, }; } + wgt::BindingType::AccelerationStructure => unimplemented!(), } let br = naga::ResourceBinding { @@ -755,6 +756,7 @@ impl crate::Device for super::Device { ); counter.textures += size; } + wgt::BindingType::AccelerationStructure => unimplemented!(), } } } From 3828af7765f42f288befe9ec7a354e6f97f5af1b Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Fri, 3 Feb 2023 04:42:34 +0100 Subject: [PATCH 012/146] Changed surface_format in example. --- wgpu-hal/examples/ray-traced-triangle/main.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 49fb58686b..dacd484eaa 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -125,13 +125,19 @@ impl Example { unsafe { adapter.open(features, &wgt::Limits::default()).unwrap() }; let window_size: (u32, u32) = window.inner_size().into(); + dbg!(&surface_caps.formats); + let surface_format = if surface_caps.formats.contains(&wgt::TextureFormat::Rgba8Snorm) { + wgt::TextureFormat::Rgba8Unorm + }else{ + *surface_caps.formats.first().unwrap() + }; let surface_config = hal::SurfaceConfiguration { swap_chain_size: DESIRED_FRAMES .max(*surface_caps.swap_chain_sizes.start()) .min(*surface_caps.swap_chain_sizes.end()), present_mode: wgt::PresentMode::Fifo, composite_alpha_mode: hal::CompositeAlphaMode::Opaque, - format: wgt::TextureFormat::Rgba8Unorm, + format: surface_format, extent: wgt::Extent3d { width: window_size.0, height: window_size.1, From e2de5a3f0c26eb6bec485e13099386d1f0dd4371 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Fri, 3 Feb 2023 04:45:08 +0100 Subject: [PATCH 013/146] Changed based on PR 3020#pullrequestreview-1139691697 feedback. --- wgpu-hal/src/lib.rs | 6 ++++-- wgpu-hal/src/vulkan/command.rs | 8 ++++---- wgpu-hal/src/vulkan/device.rs | 17 +++++++++-------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 321d8664ee..8888508d4e 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -690,9 +690,11 @@ bitflags::bitflags! { /// The combination of states that a buffer may be in _at the same time_. const INCLUSIVE = Self::MAP_READ.bits | Self::COPY_SRC.bits | Self::INDEX.bits | Self::VERTEX.bits | Self::UNIFORM.bits | - Self::STORAGE_READ.bits | Self::INDIRECT.bits; + Self::STORAGE_READ.bits | Self::INDIRECT.bits | + Self::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT.bits | Self::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT.bits; /// The combination of states that a buffer must exclusively be in. - const EXCLUSIVE = Self::MAP_WRITE.bits | Self::COPY_DST.bits | Self::STORAGE_READ_WRITE.bits; + const EXCLUSIVE = Self::MAP_WRITE.bits | Self::COPY_DST.bits | + Self::STORAGE_READ_WRITE.bits | Self::ACCELERATION_STRUCTURE_SCRATCH.bits; /// The combination of all usages that the are guaranteed to be be ordered by the hardware. /// If a usage is ordered, then if the buffer state doesn't change between draw calls, there /// are no barriers needed for synchronization. diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 02768f3c74..2f5e1ea59e 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -441,13 +441,13 @@ impl crate::CommandEncoder for super::CommandEncoder { let geometry_info = geometry_info.build(); - let range = &[range][..]; - let range = &[range][..]; - let geometry_info = &[geometry_info]; + //each geometry has multiple ranges; building requires a vector of geometry_infos and a vector of vectors of ranges + let ranges : &[&[vk::AccelerationStructureBuildRangeInfoKHR]] = &[&[range]]; + let geometry_infos = &[geometry_info]; ray_tracing_functions .acceleration_structure - .cmd_build_acceleration_structures(self.active, geometry_info, range); + .cmd_build_acceleration_structures(self.active, geometry_infos, ranges); } // render diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index afff881b18..428554ecbc 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -784,18 +784,18 @@ impl crate::Device for super::Device { desc.memory_flags.contains(crate::MemoryFlags::TRANSIENT), ); + let alignment_mask = if desc.usage + .contains(crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT){ + 16 + } else { + req.alignment + } - 1; + let block = self.mem_allocator.lock().alloc( &*self.shared, gpu_alloc::Request { size: req.size, - align_mask: if desc - .usage - .contains(crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT) - { - 16 - } else { - req.alignment - } - 1, + align_mask: alignment_mask, usage: alloc_usage, memory_types: req.memory_type_bits & self.valid_ash_memory_types, }, @@ -1429,6 +1429,7 @@ impl crate::Device for super::Device { // `raw_acceleration_structures`. let acceleration_structure_info: vk::WriteDescriptorSetAccelerationStructureKHR = *acceleration_structure_info; + assert!(index < desc.acceleration_structures.len(), "Encountered more acceleration structures then expected"); acceleration_structure_infos.push(acceleration_structure_info); extra_descriptor_count += 1; From 074ebe560d2f0ea2cf2e1b6ab5e0d502fa222b06 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 21 Feb 2023 23:01:44 +0100 Subject: [PATCH 014/146] unsafe blocks in unsafe functions --- wgpu-hal/src/vulkan/command.rs | 60 ++++++++++------- wgpu-hal/src/vulkan/device.rs | 118 ++++++++++++++++++--------------- 2 files changed, 101 insertions(+), 77 deletions(-) diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 1bb4c0c16a..9e72f00653 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -377,13 +377,16 @@ impl crate::CommandEncoder for super::CommandEncoder { let geometry = match *desc.geometry { crate::AccelerationStructureGeometry::Instances { buffer } => { + let device_address = unsafe { + ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), + ) + }; let instances = vk::AccelerationStructureGeometryInstancesDataKHR::builder().data( vk::DeviceOrHostAddressConstKHR { - device_address: ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), - ), + device_address }, ); @@ -401,30 +404,36 @@ impl crate::CommandEncoder for super::CommandEncoder { vertex_stride, ref indices, } => { + let device_address = unsafe { + ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder() + .buffer(vertex_buffer.raw), + ) + }; let mut triangles_data = vk::AccelerationStructureGeometryTrianglesDataKHR::builder() .vertex_data(vk::DeviceOrHostAddressConstKHR { - device_address: ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder() - .buffer(vertex_buffer.raw), - ), + device_address }) .vertex_format(conv::map_vertex_format(vertex_format)) .vertex_stride(vertex_stride) .max_vertex(max_vertex); if let Some(ref indices) = *indices { + let device_address = unsafe { + ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder() + .buffer(indices.buffer.raw), + ) + }; triangles_data = triangles_data .index_type(conv::map_index_format(indices.format)) .index_data(vk::DeviceOrHostAddressConstKHR { - device_address: ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder() - .buffer(indices.buffer.raw), - ), + device_address }) } @@ -446,6 +455,13 @@ impl crate::CommandEncoder for super::CommandEncoder { .primitive_offset(desc.primitive_offset) .build(); + let device_address = unsafe { + ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(desc.scratch_buffer.raw), + ) + }; let mut geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() .ty(conv::map_acceleration_structure_format(desc.format)) .mode(conv::map_acceleration_structure_build_mode(desc.mode)) @@ -453,11 +469,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .geometries(geometries) .dst_acceleration_structure(desc.destination_acceleration_structure.raw) .scratch_data(vk::DeviceOrHostAddressKHR { - device_address: ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(desc.scratch_buffer.raw), - ), + device_address }); if desc.mode == crate::AccelerationStructureBuildMode::Update { @@ -470,9 +482,11 @@ impl crate::CommandEncoder for super::CommandEncoder { let ranges : &[&[vk::AccelerationStructureBuildRangeInfoKHR]] = &[&[range]]; let geometry_infos = &[geometry_info]; - ray_tracing_functions + unsafe { + ray_tracing_functions .acceleration_structure .cmd_build_acceleration_structures(self.active, geometry_infos, ranges); + } } // render diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index d80ef1e90c..2fa1e34fa3 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -2106,13 +2106,15 @@ impl crate::Device for super::Device { .flags(conv::map_acceleration_structure_flags(desc.flags)) .geometries(geometries); - let raw = ray_tracing_functions - .acceleration_structure - .get_acceleration_structure_build_sizes( - vk::AccelerationStructureBuildTypeKHR::DEVICE, - &geometry_info, - &[desc.primitive_count], - ); + let raw = unsafe { + ray_tracing_functions + .acceleration_structure + .get_acceleration_structure_build_sizes( + vk::AccelerationStructureBuildTypeKHR::DEVICE, + &geometry_info, + &[desc.primitive_count], + ) + }; crate::AccelerationStructureBuildSizes { acceleration_structure_size: raw.acceleration_structure_size, @@ -2130,12 +2132,14 @@ impl crate::Device for super::Device { None => panic!("Feature `RAY_TRACING` not enabled"), }; - ray_tracing_functions + unsafe { + ray_tracing_functions .acceleration_structure .get_acceleration_structure_device_address( &vk::AccelerationStructureDeviceAddressInfoKHR::builder() .acceleration_structure(acceleration_structure.raw), ) + } } unsafe fn create_acceleration_structure( @@ -2152,51 +2156,55 @@ impl crate::Device for super::Device { .usage(vk::BufferUsageFlags::ACCELERATION_STRUCTURE_STORAGE_KHR) .sharing_mode(vk::SharingMode::EXCLUSIVE); - let raw_buffer = self.shared.raw.create_buffer(&vk_buffer_info, None)?; - let req = self.shared.raw.get_buffer_memory_requirements(raw_buffer); + unsafe { - let block = self.mem_allocator.lock().alloc( - &*self.shared, - gpu_alloc::Request { - size: req.size, - align_mask: req.alignment - 1, - usage: gpu_alloc::UsageFlags::FAST_DEVICE_ACCESS, - memory_types: req.memory_type_bits & self.valid_ash_memory_types, - }, - )?; + let raw_buffer = self.shared.raw.create_buffer(&vk_buffer_info, None)?; + let req = self.shared.raw.get_buffer_memory_requirements(raw_buffer); - self.shared - .raw - .bind_buffer_memory(raw_buffer, *block.memory(), block.offset())?; + let block = self.mem_allocator.lock().alloc( + &*self.shared, + gpu_alloc::Request { + size: req.size, + align_mask: req.alignment - 1, + usage: gpu_alloc::UsageFlags::FAST_DEVICE_ACCESS, + memory_types: req.memory_type_bits & self.valid_ash_memory_types, + }, + )?; - if let Some(label) = desc.label { self.shared - .set_object_name(vk::ObjectType::BUFFER, raw_buffer, label); - } + .raw + .bind_buffer_memory(raw_buffer, *block.memory(), block.offset())?; - let vk_info = vk::AccelerationStructureCreateInfoKHR::builder() - .buffer(raw_buffer) - .offset(0) - .size(desc.size) - .ty(conv::map_acceleration_structure_format(desc.format)); + if let Some(label) = desc.label { + self.shared + .set_object_name(vk::ObjectType::BUFFER, raw_buffer, label); + } - let raw_acceleration_structure = ray_tracing_functions - .acceleration_structure - .create_acceleration_structure(&vk_info, None)?; + let vk_info = vk::AccelerationStructureCreateInfoKHR::builder() + .buffer(raw_buffer) + .offset(0) + .size(desc.size) + .ty(conv::map_acceleration_structure_format(desc.format)); + + let raw_acceleration_structure = ray_tracing_functions + .acceleration_structure + .create_acceleration_structure(&vk_info, None)?; + + if let Some(label) = desc.label { + self.shared.set_object_name( + vk::ObjectType::ACCELERATION_STRUCTURE_KHR, + raw_acceleration_structure, + label, + ); + } - if let Some(label) = desc.label { - self.shared.set_object_name( - vk::ObjectType::ACCELERATION_STRUCTURE_KHR, - raw_acceleration_structure, - label, - ); - } + Ok(super::AccelerationStructure { + raw: raw_acceleration_structure, + buffer: raw_buffer, + block: Mutex::new(block), + }) - Ok(super::AccelerationStructure { - raw: raw_acceleration_structure, - buffer: raw_buffer, - block: Mutex::new(block), - }) + } } unsafe fn destroy_acceleration_structure( @@ -2208,15 +2216,17 @@ impl crate::Device for super::Device { None => panic!("Feature `RAY_TRACING` not enabled"), }; - ray_tracing_functions - .acceleration_structure - .destroy_acceleration_structure(acceleration_structure.raw, None); - self.shared - .raw - .destroy_buffer(acceleration_structure.buffer, None); - self.mem_allocator - .lock() - .dealloc(&*self.shared, acceleration_structure.block.into_inner()); + unsafe{ + ray_tracing_functions + .acceleration_structure + .destroy_acceleration_structure(acceleration_structure.raw, None); + self.shared + .raw + .destroy_buffer(acceleration_structure.buffer, None); + self.mem_allocator + .lock() + .dealloc(&*self.shared, acceleration_structure.block.into_inner()); + } } } From 8ce204bc59543a4e19db1e284ef8908a52064fc1 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 21 Feb 2023 23:14:49 +0100 Subject: [PATCH 015/146] formatted code --- wgpu-hal/examples/ray-traced-triangle/main.rs | 11 ++++--- wgpu-hal/src/vulkan/adapter.rs | 2 +- wgpu-hal/src/vulkan/command.rs | 31 ++++++------------- wgpu-hal/src/vulkan/device.rs | 25 ++++++++------- 4 files changed, 32 insertions(+), 37 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index dd120868df..b9de4a01ae 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -100,7 +100,7 @@ impl Example { } else { hal::InstanceFlags::empty() }, - dx12_shader_compiler: wgt::Dx12Compiler::Fxc + dx12_shader_compiler: wgt::Dx12Compiler::Fxc, }; let instance = unsafe { A::Instance::init(&instance_desc)? }; let mut surface = unsafe { @@ -127,9 +127,12 @@ impl Example { let window_size: (u32, u32) = window.inner_size().into(); dbg!(&surface_caps.formats); - let surface_format = if surface_caps.formats.contains(&wgt::TextureFormat::Rgba8Snorm) { + let surface_format = if surface_caps + .formats + .contains(&wgt::TextureFormat::Rgba8Snorm) + { wgt::TextureFormat::Rgba8Unorm - }else{ + } else { *surface_caps.formats.first().unwrap() }; let surface_config = hal::SurfaceConfiguration { @@ -417,7 +420,7 @@ impl Example { format: wgt::TextureFormat::Rgba8Unorm, usage: hal::TextureUses::STORAGE_READ_WRITE | hal::TextureUses::COPY_SRC, memory_flags: hal::MemoryFlags::empty(), - view_formats: vec![wgt::TextureFormat::Rgba8Unorm] + view_formats: vec![wgt::TextureFormat::Rgba8Unorm], }; let texture = unsafe { device.create_texture(&texture_desc).unwrap() }; diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 39faf4ca28..b024e1388d 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -874,7 +874,7 @@ impl super::InstanceShared { .insert(vk::PhysicalDeviceAccelerationStructurePropertiesKHR::default()); builder = builder.push_next(next); } - + if supports_driver_properties { let next = capabilities .driver diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 9e72f00653..27727b6070 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -384,11 +384,8 @@ impl crate::CommandEncoder for super::CommandEncoder { &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), ) }; - let instances = vk::AccelerationStructureGeometryInstancesDataKHR::builder().data( - vk::DeviceOrHostAddressConstKHR { - device_address - }, - ); + let instances = vk::AccelerationStructureGeometryInstancesDataKHR::builder() + .data(vk::DeviceOrHostAddressConstKHR { device_address }); vk::AccelerationStructureGeometryKHR::builder() .geometry_type(vk::GeometryTypeKHR::INSTANCES) @@ -408,15 +405,12 @@ impl crate::CommandEncoder for super::CommandEncoder { ray_tracing_functions .buffer_device_address .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder() - .buffer(vertex_buffer.raw), + &vk::BufferDeviceAddressInfo::builder().buffer(vertex_buffer.raw), ) }; let mut triangles_data = vk::AccelerationStructureGeometryTrianglesDataKHR::builder() - .vertex_data(vk::DeviceOrHostAddressConstKHR { - device_address - }) + .vertex_data(vk::DeviceOrHostAddressConstKHR { device_address }) .vertex_format(conv::map_vertex_format(vertex_format)) .vertex_stride(vertex_stride) .max_vertex(max_vertex); @@ -426,15 +420,12 @@ impl crate::CommandEncoder for super::CommandEncoder { ray_tracing_functions .buffer_device_address .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder() - .buffer(indices.buffer.raw), + &vk::BufferDeviceAddressInfo::builder().buffer(indices.buffer.raw), ) }; triangles_data = triangles_data .index_type(conv::map_index_format(indices.format)) - .index_data(vk::DeviceOrHostAddressConstKHR { - device_address - }) + .index_data(vk::DeviceOrHostAddressConstKHR { device_address }) } let triangles_data = triangles_data.build(); @@ -468,9 +459,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .flags(conv::map_acceleration_structure_flags(desc.flags)) .geometries(geometries) .dst_acceleration_structure(desc.destination_acceleration_structure.raw) - .scratch_data(vk::DeviceOrHostAddressKHR { - device_address - }); + .scratch_data(vk::DeviceOrHostAddressKHR { device_address }); if desc.mode == crate::AccelerationStructureBuildMode::Update { geometry_info.src_acceleration_structure = desc.destination_acceleration_structure.raw; @@ -479,13 +468,13 @@ impl crate::CommandEncoder for super::CommandEncoder { let geometry_info = geometry_info.build(); //each geometry has multiple ranges; building requires a vector of geometry_infos and a vector of vectors of ranges - let ranges : &[&[vk::AccelerationStructureBuildRangeInfoKHR]] = &[&[range]]; + let ranges: &[&[vk::AccelerationStructureBuildRangeInfoKHR]] = &[&[range]]; let geometry_infos = &[geometry_info]; unsafe { ray_tracing_functions - .acceleration_structure - .cmd_build_acceleration_structures(self.active, geometry_infos, ranges); + .acceleration_structure + .cmd_build_acceleration_structures(self.active, geometry_infos, ranges); } } diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 2fa1e34fa3..434110aefe 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -841,8 +841,10 @@ impl crate::Device for super::Device { desc.memory_flags.contains(crate::MemoryFlags::TRANSIENT), ); - let alignment_mask = if desc.usage - .contains(crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT){ + let alignment_mask = if desc + .usage + .contains(crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT) + { 16 } else { req.alignment @@ -1510,7 +1512,10 @@ impl crate::Device for super::Device { // `raw_acceleration_structures`. let acceleration_structure_info: vk::WriteDescriptorSetAccelerationStructureKHR = *acceleration_structure_info; - assert!(index < desc.acceleration_structures.len(), "Encountered more acceleration structures then expected"); + assert!( + index < desc.acceleration_structures.len(), + "Encountered more acceleration structures then expected" + ); acceleration_structure_infos.push(acceleration_structure_info); extra_descriptor_count += 1; @@ -2134,11 +2139,11 @@ impl crate::Device for super::Device { unsafe { ray_tracing_functions - .acceleration_structure - .get_acceleration_structure_device_address( - &vk::AccelerationStructureDeviceAddressInfoKHR::builder() - .acceleration_structure(acceleration_structure.raw), - ) + .acceleration_structure + .get_acceleration_structure_device_address( + &vk::AccelerationStructureDeviceAddressInfoKHR::builder() + .acceleration_structure(acceleration_structure.raw), + ) } } @@ -2157,7 +2162,6 @@ impl crate::Device for super::Device { .sharing_mode(vk::SharingMode::EXCLUSIVE); unsafe { - let raw_buffer = self.shared.raw.create_buffer(&vk_buffer_info, None)?; let req = self.shared.raw.get_buffer_memory_requirements(raw_buffer); @@ -2203,7 +2207,6 @@ impl crate::Device for super::Device { buffer: raw_buffer, block: Mutex::new(block), }) - } } @@ -2216,7 +2219,7 @@ impl crate::Device for super::Device { None => panic!("Feature `RAY_TRACING` not enabled"), }; - unsafe{ + unsafe { ray_tracing_functions .acceleration_structure .destroy_acceleration_structure(acceleration_structure.raw, None); From f52a70b59c558a2ea0ab5533926c7e28f74e3999 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 22 Feb 2023 06:22:23 +0100 Subject: [PATCH 016/146] added utility functions to AccelerationStructureInstance (bit packing) --- wgpu-hal/examples/ray-traced-triangle/main.rs | 248 +++++++++++++----- 1 file changed, 187 insertions(+), 61 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index b9de4a01ae..29bfa391dd 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -5,7 +5,7 @@ use hal::{ }; use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; -use glam::{Mat4, Vec3}; +use glam::{Affine3A, Mat4, Vec3}; use std::{ borrow::{Borrow, Cow}, iter, mem, @@ -17,27 +17,152 @@ use std::{ const COMMAND_BUFFER_PER_CONTEXT: usize = 100; const DESIRED_FRAMES: u32 = 3; -fn pack_24_8(low_24: u32, high_8: u8) -> u32 { - (low_24 & 0x00ff_ffff) | (u32::from(high_8) << 24) -} - -#[derive(Debug)] +/// [D3D12_RAYTRACING_INSTANCE_DESC](https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#d3d12_raytracing_instance_desc) +/// [VkAccelerationStructureInstanceKHR](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkAccelerationStructureInstanceKHR.html) +#[derive(Clone)] #[repr(C)] -struct Instance { +struct AccelerationStructureInstance { transform: [f32; 12], - instance_custom_index_and_mask: u32, - instance_shader_binding_table_record_offset_and_flags: u32, + custom_index_and_mask: u32, + shader_binding_table_record_offset_and_flags: u32, acceleration_structure_reference: u64, } -fn transpose_matrix_for_acceleration_structure_instance(matrix: Mat4) -> [f32; 12] { - let row_0 = matrix.row(0); - let row_1 = matrix.row(1); - let row_2 = matrix.row(2); - [ - row_0.x, row_0.y, row_0.z, row_0.w, row_1.x, row_1.y, row_1.z, row_1.w, row_2.x, row_2.y, - row_2.z, row_2.w, - ] +impl std::fmt::Debug for AccelerationStructureInstance { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Instance") + .field("transform", &self.transform) + .field("custom_index()", &self.custom_index()) + .field("mask()", &self.mask()) + .field( + "shader_binding_table_record_offset()", + &self.shader_binding_table_record_offset(), + ) + .field("flags()", &self.flags()) + .field( + "acceleration_structure_reference", + &self.acceleration_structure_reference, + ) + .finish() + } +} + +#[allow(dead_code)] +impl AccelerationStructureInstance { + const LOW_24_MASK: u32 = 0x00ff_ffff; + const MAX_U24: u32 = (1u32 << 24u32) - 1u32; + + #[inline] + fn affine_to_rows(mat: &Affine3A) -> [f32; 12] { + let row_0 = mat.matrix3.row(0); + let row_1 = mat.matrix3.row(1); + let row_2 = mat.matrix3.row(2); + let translation = mat.translation; + [ + row_0.x, + row_0.y, + row_0.z, + translation.x, + row_1.x, + row_1.y, + row_1.z, + translation.y, + row_2.x, + row_2.y, + row_2.z, + translation.z, + ] + } + + #[inline] + fn rows_to_affine(rows: &[f32; 12]) -> Affine3A { + Affine3A::from_cols_array(&[ + rows[0], rows[3], rows[6], rows[9], rows[1], rows[4], rows[7], rows[10], rows[2], + rows[5], rows[8], rows[11], + ]) + } + + pub fn transform_as_affine(&self) -> Affine3A { + Self::rows_to_affine(&self.transform) + } + pub fn set_transform(&mut self, transform: &Affine3A) { + self.transform = Self::affine_to_rows(&transform); + } + + pub fn custom_index(&self) -> u32 { + self.custom_index_and_mask & Self::LOW_24_MASK + } + + pub fn mask(&self) -> u8 { + (self.custom_index_and_mask >> 24) as u8 + } + + pub fn shader_binding_table_record_offset(&self) -> u32 { + self.shader_binding_table_record_offset_and_flags & Self::LOW_24_MASK + } + + pub fn flags(&self) -> u8 { + (self.shader_binding_table_record_offset_and_flags >> 24) as u8 + } + + pub fn set_custom_index(&mut self, custom_index: u32) { + debug_assert!( + custom_index <= Self::MAX_U24, + "custom_index uses more than 24 bits! {custom_index} > {}", + Self::MAX_U24 + ); + self.custom_index_and_mask = + (custom_index & Self::LOW_24_MASK) | (self.custom_index_and_mask & !Self::LOW_24_MASK) + } + + pub fn set_mask(&mut self, mask: u8) { + self.custom_index_and_mask = + (self.custom_index_and_mask & Self::LOW_24_MASK) | (u32::from(mask) << 24) + } + + pub fn set_shader_binding_table_record_offset( + &mut self, + shader_binding_table_record_offset: u32, + ) { + debug_assert!(shader_binding_table_record_offset <= Self::MAX_U24, "shader_binding_table_record_offset uses more than 24 bits! {shader_binding_table_record_offset} > {}", Self::MAX_U24); + self.shader_binding_table_record_offset_and_flags = (shader_binding_table_record_offset + & Self::LOW_24_MASK) + | (self.shader_binding_table_record_offset_and_flags & !Self::LOW_24_MASK) + } + + pub fn set_flags(&mut self, flags: u8) { + self.shader_binding_table_record_offset_and_flags = + (self.shader_binding_table_record_offset_and_flags & Self::LOW_24_MASK) + | (u32::from(flags) << 24) + } + + pub fn new( + transform: &Affine3A, + custom_index: u32, + mask: u8, + shader_binding_table_record_offset: u32, + flags: u8, + acceleration_structure_reference: u64, + ) -> Self { + dbg!(transform); + debug_assert!( + custom_index <= Self::MAX_U24, + "custom_index uses more than 24 bits! {custom_index} > {}", + Self::MAX_U24 + ); + debug_assert!( + shader_binding_table_record_offset <= Self::MAX_U24, + "shader_binding_table_record_offset uses more than 24 bits! {shader_binding_table_record_offset} > {}", Self::MAX_U24 + ); + AccelerationStructureInstance { + transform: Self::affine_to_rows(transform), + custom_index_and_mask: (custom_index & Self::MAX_U24) | (u32::from(mask) << 24), + shader_binding_table_record_offset_and_flags: (shader_binding_table_record_offset + & Self::MAX_U24) + | (u32::from(flags) << 24), + acceleration_structure_reference, + } + } } struct ExecutionContext { @@ -83,7 +208,7 @@ struct Example { vertices_buffer: A::Buffer, indices_buffer: A::Buffer, texture: A::Texture, - instances: [Instance; 1], + instances: [AccelerationStructureInstance; 3], instances_buffer: A::Buffer, blas: A::AccelerationStructure, tlas: A::AccelerationStructure, @@ -271,8 +396,6 @@ impl Example { let indices_size_in_bytes = indices.len() * 4; - let transform_matrix = [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0]; - let vertices_buffer = unsafe { let vertices_buffer = device .create_buffer(&hal::BufferDescriptor { @@ -485,37 +608,48 @@ impl Example { }; let instances = [ - Instance { - transform: transform_matrix, - instance_custom_index_and_mask: pack_24_8(0, 0xff), - instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), - acceleration_structure_reference: unsafe { - device.get_acceleration_structure_device_address(&blas) - }, - }, - /*Instance { - transform: transpose_matrix_for_acceleration_structure_instance( - Mat4::from_rotation_y(1.0), - ), - instance_custom_index_and_mask: pack_24_8(0, 0xff), - instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), - acceleration_structure_reference: unsafe { - device.get_acceleration_structure_device_address(&blas) - }, - }, - Instance { - transform: transpose_matrix_for_acceleration_structure_instance( - Mat4::from_rotation_y(-1.0), - ), - instance_custom_index_and_mask: pack_24_8(0, 0xff), - instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), - acceleration_structure_reference: unsafe { - device.get_acceleration_structure_device_address(&blas) - }, - },*/ + AccelerationStructureInstance::new( + &Affine3A::from_translation(Vec3 { + x: 0.0, + y: 0.0, + z: 0.0, + }), + 0, + 0xff, + 0, + 0, + unsafe { device.get_acceleration_structure_device_address(&blas) }, + ), + AccelerationStructureInstance::new( + &Affine3A::from_translation(Vec3 { + x: -1.0, + y: -1.0, + z: -2.0, + }), + 0, + 0xff, + 0, + 0, + unsafe { device.get_acceleration_structure_device_address(&blas) }, + ), + AccelerationStructureInstance::new( + &Affine3A::from_translation(Vec3 { + x: 1.0, + y: -1.0, + z: -2.0, + }), + 0, + 0xff, + 0, + 0, + unsafe { device.get_acceleration_structure_device_address(&blas) }, + ), ]; - let instances_buffer_size = instances.len() * std::mem::size_of::(); + dbg!(&instances[0]); + + let instances_buffer_size = + instances.len() * std::mem::size_of::(); let instances_buffer = unsafe { let instances_buffer = device @@ -662,24 +796,15 @@ impl Example { usage: hal::TextureUses::UNINITIALIZED..hal::TextureUses::COPY_DST, }; - let instances_buffer_size = self.instances.len() * std::mem::size_of::(); + let instances_buffer_size = + self.instances.len() * std::mem::size_of::(); let tlas_flags = hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE | hal::AccelerationStructureBuildFlags::ALLOW_UPDATE; self.time += 1.0 / 60.0; - self.instances[0] = Instance { - transform: transpose_matrix_for_acceleration_structure_instance(Mat4::from_rotation_y( - self.time, - )), - instance_custom_index_and_mask: pack_24_8(0, 0xff), - instance_shader_binding_table_record_offset_and_flags: pack_24_8(0, 0), - acceleration_structure_reference: unsafe { - self.device - .get_acceleration_structure_device_address(&self.blas) - }, - }; + self.instances[0].set_transform(&Affine3A::from_rotation_y(self.time)); unsafe { let mapping = self @@ -902,6 +1027,7 @@ fn main() { width: 512, height: 512, }) + .with_resizable(false) .build(&event_loop) .unwrap(); From f15e865801cd119aaf1ec74a8f853c163a36cef9 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 27 Feb 2023 14:32:38 +0100 Subject: [PATCH 017/146] WIP api change build_acceleration_structures --- wgpu-hal/examples/ray-traced-triangle/main.rs | 56 +++--- wgpu-hal/src/lib.rs | 52 ++++-- wgpu-hal/src/vulkan/command.rs | 162 +++++++++++------- 3 files changed, 166 insertions(+), 104 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 29bfa391dd..dc0b09810f 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -144,7 +144,6 @@ impl AccelerationStructureInstance { flags: u8, acceleration_structure_reference: u64, ) -> Self { - dbg!(transform); debug_assert!( custom_index <= Self::MAX_U24, "custom_index uses more than 24 bits! {custom_index} > {}", @@ -646,8 +645,6 @@ impl Example { ), ]; - dbg!(&instances[0]); - let instances_buffer_size = instances.len() * std::mem::size_of::(); @@ -685,24 +682,27 @@ impl Example { unsafe { cmd_encoder.begin_encoding(Some("init")).unwrap() }; unsafe { + let geometry = hal::AccelerationStructureTriangles { + vertex_buffer: &vertices_buffer, + first_vertex: 0, + vertex_format: wgt::VertexFormat::Float32x3, + vertex_count: vertices.len() as u32, + vertex_stride: 3 * 4, + indices: Some(hal::AccelerationStructureTriangleIndices { + buffer: &indices_buffer, + format: wgt::IndexFormat::Uint32, + offset: 0, + count: indices.len() as u32, + }), + transforms: None, + }; cmd_encoder.build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { - geometry: &hal::AccelerationStructureGeometry::Triangles { - vertex_buffer: &vertices_buffer, - vertex_format: wgt::VertexFormat::Float32x3, - max_vertex: vertices.len() as u32, - vertex_stride: 3 * 4, - indices: Some(hal::AccelerationStructureGeometryIndices { - buffer: &indices_buffer, - format: wgt::IndexFormat::Uint32, - }), - }, - format: hal::AccelerationStructureFormat::BottomLevel, mode: hal::AccelerationStructureBuildMode::Build, flags: hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, - primitive_count: indices.len() as u32 / 3, - primitive_offset: 0, destination_acceleration_structure: &blas, scratch_buffer: &scratch_buffer, + entries: &hal::AccelerationStructureEntries::Triangles(&vec![geometry]), + source_acceleration_structure: None, }); let as_barrier = hal::BufferBarrier { @@ -712,17 +712,17 @@ impl Example { }; cmd_encoder.transition_buffers(iter::once(as_barrier)); + let instances = hal::AccelerationStructureInstances { + buffer: &instances_buffer, + count: instances.len() as u32, + }; cmd_encoder.build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { - geometry: &hal::AccelerationStructureGeometry::Instances { - buffer: &instances_buffer, - }, - format: hal::AccelerationStructureFormat::TopLevel, mode: hal::AccelerationStructureBuildMode::Build, flags: tlas_flags, - primitive_count: instances.len() as u32, - primitive_offset: 0, destination_acceleration_structure: &tlas, scratch_buffer: &scratch_buffer, + entries: &hal::AccelerationStructureEntries::Instances(&instances), + source_acceleration_structure: None, }); let texture_barrier = hal::TextureBarrier { @@ -823,18 +823,18 @@ impl Example { unsafe { ctx.encoder.begin_encoding(Some("frame")).unwrap(); + let instances = hal::AccelerationStructureInstances { + buffer: &self.instances_buffer, + count: self.instances.len() as u32, + }; ctx.encoder .build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { - geometry: &hal::AccelerationStructureGeometry::Instances { - buffer: &self.instances_buffer, - }, - format: hal::AccelerationStructureFormat::TopLevel, mode: hal::AccelerationStructureBuildMode::Update, flags: tlas_flags, - primitive_count: self.instances.len() as u32, - primitive_offset: 0, destination_acceleration_structure: &self.tlas, scratch_buffer: &self.scratch_buffer, + entries: &hal::AccelerationStructureEntries::Instances(&instances), + source_acceleration_structure: Some(&self.tlas), }); let as_barrier = hal::BufferBarrier { diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 63d0a689f6..4d0dca7533 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -1392,32 +1392,52 @@ pub enum AccelerationStructureGeometryInfo { } pub struct BuildAccelerationStructureDescriptor<'a, A: Api> { - pub geometry: &'a AccelerationStructureGeometry<'a, A>, - pub format: AccelerationStructureFormat, + pub entries: &'a AccelerationStructureEntries<'a, A>, pub mode: AccelerationStructureBuildMode, pub flags: AccelerationStructureBuildFlags, - pub primitive_count: u32, - pub primitive_offset: u32, + pub source_acceleration_structure: Option<&'a A::AccelerationStructure>, pub destination_acceleration_structure: &'a A::AccelerationStructure, pub scratch_buffer: &'a A::Buffer, } -pub enum AccelerationStructureGeometry<'a, A: Api> { - Triangles { - vertex_buffer: &'a A::Buffer, - vertex_format: wgt::VertexFormat, - max_vertex: u32, - vertex_stride: wgt::BufferAddress, - indices: Option>, - }, - Instances { - buffer: &'a A::Buffer, - }, +pub enum AccelerationStructureEntries<'a, A: Api> { + Instances(&'a AccelerationStructureInstances<'a, A>), + Triangles(&'a [AccelerationStructureTriangles<'a, A>]), + AABBs(&'a [AccelerationStructureAABBs]), } -pub struct AccelerationStructureGeometryIndices<'a, A: Api> { +// TODO: flags +pub struct AccelerationStructureTriangles<'a, A: Api> { + pub vertex_buffer: &'a A::Buffer, + pub first_vertex: u32, + pub vertex_format: wgt::VertexFormat, + pub vertex_count: u32, + pub vertex_stride: wgt::BufferAddress, + pub indices: Option>, + pub transforms: Option>, +} + +// TODO: * +pub struct AccelerationStructureAABBs { + pub count: u32, //TODO +} + +// TODO: offset +pub struct AccelerationStructureInstances<'a, A: Api> { + pub buffer: &'a A::Buffer, + pub count: u32, +} + +pub struct AccelerationStructureTriangleIndices<'a, A: Api> { pub format: wgt::IndexFormat, pub buffer: &'a A::Buffer, + pub offset: u32, + pub count: u32, +} + +pub struct AccelerationStructureTriangleTransforms<'a, A: Api> { + pub buffer: &'a A::Buffer, + pub offset: u32, } bitflags!( diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 27727b6070..2e12eea09f 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -375,106 +375,148 @@ impl crate::CommandEncoder for super::CommandEncoder { None => panic!("Feature `RAY_TRACING` not enabled"), }; - let geometry = match *desc.geometry { - crate::AccelerationStructureGeometry::Instances { buffer } => { + let (geometries, ranges) = match *desc.entries { + crate::AccelerationStructureEntries::Instances(instances) => { let device_address = unsafe { ray_tracing_functions .buffer_device_address .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), + &vk::BufferDeviceAddressInfo::builder().buffer(instances.buffer.raw), ) }; - let instances = vk::AccelerationStructureGeometryInstancesDataKHR::builder() + let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder() .data(vk::DeviceOrHostAddressConstKHR { device_address }); - vk::AccelerationStructureGeometryKHR::builder() + let geometry = vk::AccelerationStructureGeometryKHR::builder() .geometry_type(vk::GeometryTypeKHR::INSTANCES) .geometry(vk::AccelerationStructureGeometryDataKHR { - instances: *instances, + instances: *instance_data, }) - .flags(vk::GeometryFlagsKHR::empty()) + .flags(vk::GeometryFlagsKHR::empty()); + + let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() + .primitive_count(instances.count); + + (vec![*geometry], vec![*range]) } - crate::AccelerationStructureGeometry::Triangles { - vertex_buffer, - vertex_format, - max_vertex, - vertex_stride, - ref indices, - } => { - let device_address = unsafe { - ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(vertex_buffer.raw), - ) - }; - let mut triangles_data = - vk::AccelerationStructureGeometryTrianglesDataKHR::builder() - .vertex_data(vk::DeviceOrHostAddressConstKHR { device_address }) - .vertex_format(conv::map_vertex_format(vertex_format)) - .vertex_stride(vertex_stride) - .max_vertex(max_vertex); - - if let Some(ref indices) = *indices { - let device_address = unsafe { + crate::AccelerationStructureEntries::Triangles(in_geometries) => { + let mut ranges = Vec::::with_capacity( + in_geometries.len(), + ); + let mut geometries = + Vec::::with_capacity(in_geometries.len()); + for triangles in in_geometries { + let vertex_device_address = unsafe { ray_tracing_functions .buffer_device_address .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(indices.buffer.raw), + &vk::BufferDeviceAddressInfo::builder() + .buffer(triangles.vertex_buffer.raw), ) }; - triangles_data = triangles_data - .index_type(conv::map_index_format(indices.format)) - .index_data(vk::DeviceOrHostAddressConstKHR { device_address }) - } - - let triangles_data = triangles_data.build(); + let mut triangle_data = + vk::AccelerationStructureGeometryTrianglesDataKHR::builder() + .vertex_data(vk::DeviceOrHostAddressConstKHR { + device_address: vertex_device_address, + }) + .vertex_format(conv::map_vertex_format(triangles.vertex_format)) + .max_vertex(triangles.vertex_count) + .vertex_stride(triangles.vertex_stride); + + let mut range = vk::AccelerationStructureBuildRangeInfoKHR::builder(); + + if let Some(indices) = &triangles.indices { + let index_device_address = unsafe { + ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder() + .buffer(indices.buffer.raw), + ) + }; + triangle_data = triangle_data + .index_data(vk::DeviceOrHostAddressConstKHR { + device_address: index_device_address, + }) + .index_type(conv::map_index_format(indices.format)); + + range = range + .primitive_count(indices.count / 3) + .primitive_offset(indices.offset) + .first_vertex(triangles.first_vertex); + } else { + range = range + .primitive_count(triangles.vertex_count) + .first_vertex(triangles.first_vertex); + } + if let Some(transform) = &triangles.transforms { + let transform_device_address = unsafe { + ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder() + .buffer(transform.buffer.raw), + ) + }; + triangle_data = + triangle_data.transform_data(vk::DeviceOrHostAddressConstKHR { + device_address: transform_device_address, + }); + + range = range.transform_offset(transform.offset); + } - vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::TRIANGLES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - triangles: triangles_data, - }) - .flags(vk::GeometryFlagsKHR::empty()) + let geometry = vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::TRIANGLES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + triangles: *triangle_data, + }) + .flags(vk::GeometryFlagsKHR::empty()) + .build(); + geometries.push(geometry); + ranges.push(*range); + } + (geometries, ranges) } + crate::AccelerationStructureEntries::AABBs(_) => todo!(), }; - let geometries = &[*geometry]; - - let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() - .primitive_count(desc.primitive_count) - .primitive_offset(desc.primitive_offset) - .build(); - - let device_address = unsafe { + let scratch_device_address = unsafe { ray_tracing_functions .buffer_device_address .get_buffer_device_address( &vk::BufferDeviceAddressInfo::builder().buffer(desc.scratch_buffer.raw), ) }; + let ty = match desc.entries { + crate::AccelerationStructureEntries::Instances(_) => { + vk::AccelerationStructureTypeKHR::TOP_LEVEL + } + _ => vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL, + }; let mut geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() - .ty(conv::map_acceleration_structure_format(desc.format)) + .ty(ty) .mode(conv::map_acceleration_structure_build_mode(desc.mode)) .flags(conv::map_acceleration_structure_flags(desc.flags)) - .geometries(geometries) + .geometries(&geometries) .dst_acceleration_structure(desc.destination_acceleration_structure.raw) - .scratch_data(vk::DeviceOrHostAddressKHR { device_address }); + .scratch_data(vk::DeviceOrHostAddressKHR { + device_address: scratch_device_address, + }); if desc.mode == crate::AccelerationStructureBuildMode::Update { - geometry_info.src_acceleration_structure = desc.destination_acceleration_structure.raw; + geometry_info.src_acceleration_structure = desc + .source_acceleration_structure + .expect("Acceleration tructure update: source structure required") + .raw; } let geometry_info = geometry_info.build(); - //each geometry has multiple ranges; building requires a vector of geometry_infos and a vector of vectors of ranges - let ranges: &[&[vk::AccelerationStructureBuildRangeInfoKHR]] = &[&[range]]; - let geometry_infos = &[geometry_info]; - unsafe { ray_tracing_functions .acceleration_structure - .cmd_build_acceleration_structures(self.active, geometry_infos, ranges); + .cmd_build_acceleration_structures(self.active, &[geometry_info], &[&ranges]); } } From a3c0ffb35f0f825e4999ac4bf2ebe4ffb4942e46 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 28 Feb 2023 08:33:27 +0100 Subject: [PATCH 018/146] preperation for changes in get_acceleration_structure_build_sizes --- wgpu-hal/examples/ray-traced-triangle/main.rs | 8 +- wgpu-hal/src/lib.rs | 11 +- wgpu-hal/src/vulkan/command.rs | 217 +++++++++--------- 3 files changed, 125 insertions(+), 111 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index dc0b09810f..da2e446d47 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -683,13 +683,13 @@ impl Example { unsafe { let geometry = hal::AccelerationStructureTriangles { - vertex_buffer: &vertices_buffer, + vertex_buffer: Some(&vertices_buffer), first_vertex: 0, vertex_format: wgt::VertexFormat::Float32x3, vertex_count: vertices.len() as u32, vertex_stride: 3 * 4, indices: Some(hal::AccelerationStructureTriangleIndices { - buffer: &indices_buffer, + buffer: Some(&indices_buffer), format: wgt::IndexFormat::Uint32, offset: 0, count: indices.len() as u32, @@ -713,7 +713,7 @@ impl Example { cmd_encoder.transition_buffers(iter::once(as_barrier)); let instances = hal::AccelerationStructureInstances { - buffer: &instances_buffer, + buffer: Some(&instances_buffer), count: instances.len() as u32, }; cmd_encoder.build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { @@ -824,7 +824,7 @@ impl Example { ctx.encoder.begin_encoding(Some("frame")).unwrap(); let instances = hal::AccelerationStructureInstances { - buffer: &self.instances_buffer, + buffer: Some(&self.instances_buffer), count: self.instances.len() as u32, }; ctx.encoder diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 4d0dca7533..a26cf87cd6 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -1400,6 +1400,11 @@ pub struct BuildAccelerationStructureDescriptor<'a, A: Api> { pub scratch_buffer: &'a A::Buffer, } +/// +/// Usage for buffer size requirements: +/// All Buffers, BufferAdresses and offsets will be ignored. +/// Reducing the amount of Instances, Triangle groups or AABB groups (or the number of Trinagles/AABBs in coresponding groups), +/// may result in reduced size requirements. pub enum AccelerationStructureEntries<'a, A: Api> { Instances(&'a AccelerationStructureInstances<'a, A>), Triangles(&'a [AccelerationStructureTriangles<'a, A>]), @@ -1408,7 +1413,7 @@ pub enum AccelerationStructureEntries<'a, A: Api> { // TODO: flags pub struct AccelerationStructureTriangles<'a, A: Api> { - pub vertex_buffer: &'a A::Buffer, + pub vertex_buffer: Option<&'a A::Buffer>, pub first_vertex: u32, pub vertex_format: wgt::VertexFormat, pub vertex_count: u32, @@ -1424,13 +1429,13 @@ pub struct AccelerationStructureAABBs { // TODO: offset pub struct AccelerationStructureInstances<'a, A: Api> { - pub buffer: &'a A::Buffer, + pub buffer: Option<&'a A::Buffer>, pub count: u32, } pub struct AccelerationStructureTriangleIndices<'a, A: Api> { pub format: wgt::IndexFormat, - pub buffer: &'a A::Buffer, + pub buffer: Option<&'a A::Buffer>, pub offset: u32, pub count: u32, } diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 2e12eea09f..b80b557ffb 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -375,110 +375,8 @@ impl crate::CommandEncoder for super::CommandEncoder { None => panic!("Feature `RAY_TRACING` not enabled"), }; - let (geometries, ranges) = match *desc.entries { - crate::AccelerationStructureEntries::Instances(instances) => { - let device_address = unsafe { - ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(instances.buffer.raw), - ) - }; - let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder() - .data(vk::DeviceOrHostAddressConstKHR { device_address }); - - let geometry = vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::INSTANCES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - instances: *instance_data, - }) - .flags(vk::GeometryFlagsKHR::empty()); - - let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() - .primitive_count(instances.count); - - (vec![*geometry], vec![*range]) - } - crate::AccelerationStructureEntries::Triangles(in_geometries) => { - let mut ranges = Vec::::with_capacity( - in_geometries.len(), - ); - let mut geometries = - Vec::::with_capacity(in_geometries.len()); - for triangles in in_geometries { - let vertex_device_address = unsafe { - ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder() - .buffer(triangles.vertex_buffer.raw), - ) - }; - let mut triangle_data = - vk::AccelerationStructureGeometryTrianglesDataKHR::builder() - .vertex_data(vk::DeviceOrHostAddressConstKHR { - device_address: vertex_device_address, - }) - .vertex_format(conv::map_vertex_format(triangles.vertex_format)) - .max_vertex(triangles.vertex_count) - .vertex_stride(triangles.vertex_stride); - - let mut range = vk::AccelerationStructureBuildRangeInfoKHR::builder(); - - if let Some(indices) = &triangles.indices { - let index_device_address = unsafe { - ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder() - .buffer(indices.buffer.raw), - ) - }; - triangle_data = triangle_data - .index_data(vk::DeviceOrHostAddressConstKHR { - device_address: index_device_address, - }) - .index_type(conv::map_index_format(indices.format)); - - range = range - .primitive_count(indices.count / 3) - .primitive_offset(indices.offset) - .first_vertex(triangles.first_vertex); - } else { - range = range - .primitive_count(triangles.vertex_count) - .first_vertex(triangles.first_vertex); - } - if let Some(transform) = &triangles.transforms { - let transform_device_address = unsafe { - ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder() - .buffer(transform.buffer.raw), - ) - }; - triangle_data = - triangle_data.transform_data(vk::DeviceOrHostAddressConstKHR { - device_address: transform_device_address, - }); - - range = range.transform_offset(transform.offset); - } - - let geometry = vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::TRIANGLES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - triangles: *triangle_data, - }) - .flags(vk::GeometryFlagsKHR::empty()) - .build(); - geometries.push(geometry); - ranges.push(*range); - } - (geometries, ranges) - } - crate::AccelerationStructureEntries::AABBs(_) => todo!(), + let (geometries, ranges) = unsafe { + to_raw_acceleration_structure_geometry_and_range_info(desc, ray_tracing_functions, true) }; let scratch_device_address = unsafe { @@ -971,6 +869,117 @@ impl crate::CommandEncoder for super::CommandEncoder { } } +unsafe fn to_raw_acceleration_structure_geometry_and_range_info( + desc: &crate::BuildAccelerationStructureDescriptor, + ray_tracing_functions: &super::RayTracingDeviceExtensionFunctions, + require_buffers: bool, +) -> ( + Vec, + Vec, +) { + let get_device_address = |buffer: Option<&super::Buffer>| { + if let Some(buffer) = buffer { + unsafe { + ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), + ) + } + } else { + if require_buffers { + panic!("Buffers are required to build acceleration structures"); + } + 0u64 + } + }; + let (geometries, ranges) = match *desc.entries { + crate::AccelerationStructureEntries::Instances(instances) => { + let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder().data( + vk::DeviceOrHostAddressConstKHR { + device_address: get_device_address(instances.buffer), + }, + ); + + let geometry = vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::INSTANCES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + instances: *instance_data, + }) + .flags(vk::GeometryFlagsKHR::empty()); + + let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() + .primitive_count(instances.count); + + (vec![*geometry], vec![*range]) + } + crate::AccelerationStructureEntries::Triangles(in_geometries) => { + let mut ranges = Vec::::with_capacity( + in_geometries.len(), + ); + let mut geometries = + Vec::::with_capacity(in_geometries.len()); + for triangles in in_geometries { + let mut triangle_data = + vk::AccelerationStructureGeometryTrianglesDataKHR::builder() + .vertex_data(vk::DeviceOrHostAddressConstKHR { + device_address: get_device_address(triangles.vertex_buffer), + }) + .vertex_format(conv::map_vertex_format(triangles.vertex_format)) + .max_vertex(triangles.vertex_count) + .vertex_stride(triangles.vertex_stride); + + let mut range = vk::AccelerationStructureBuildRangeInfoKHR::builder(); + + if let Some(indices) = &triangles.indices { + triangle_data = triangle_data + .index_data(vk::DeviceOrHostAddressConstKHR { + device_address: get_device_address(indices.buffer), + }) + .index_type(conv::map_index_format(indices.format)); + + range = range + .primitive_count(indices.count / 3) + .primitive_offset(indices.offset) + .first_vertex(triangles.first_vertex); + } else { + range = range + .primitive_count(triangles.vertex_count) + .first_vertex(triangles.first_vertex); + } + if let Some(transform) = &triangles.transforms { + let transform_device_address = unsafe { + ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder() + .buffer(transform.buffer.raw), + ) + }; + triangle_data = triangle_data.transform_data(vk::DeviceOrHostAddressConstKHR { + device_address: transform_device_address, + }); + + range = range.transform_offset(transform.offset); + } + + let geometry = vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::TRIANGLES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + triangles: *triangle_data, + }) + .flags(vk::GeometryFlagsKHR::empty()) + .build(); + geometries.push(geometry); + ranges.push(*range); + } + (geometries, ranges) + } + crate::AccelerationStructureEntries::AABBs(_) => todo!(), + }; + (geometries, ranges) +} + #[test] fn check_dst_image_layout() { assert_eq!( From a59d8882be2d59be1c4fa0737911a3f5608d6670 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 28 Feb 2023 11:51:48 +0100 Subject: [PATCH 019/146] WIP api change get_acceleration_structure_build_sizes --- wgpu-hal/examples/ray-traced-triangle/main.rs | 68 +++--- wgpu-hal/src/dx11/command.rs | 2 +- wgpu-hal/src/dx11/device.rs | 10 +- wgpu-hal/src/dx12/device.rs | 2 +- wgpu-hal/src/empty.rs | 2 +- wgpu-hal/src/gles/device.rs | 2 +- wgpu-hal/src/lib.rs | 29 +-- wgpu-hal/src/vulkan/command.rs | 209 ++++++++---------- wgpu-hal/src/vulkan/device.rs | 81 ++++--- 9 files changed, 197 insertions(+), 208 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index da2e446d47..1d41a74182 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -445,18 +445,33 @@ impl Example { indices_buffer }; + let blas_triangles = vec![hal::AccelerationStructureTriangles { + vertex_buffer: Some(&vertices_buffer), + first_vertex: 0, + vertex_format: wgt::VertexFormat::Float32x3, + vertex_count: vertices.len() as u32, + vertex_stride: 3 * 4, + indices: Some(hal::AccelerationStructureTriangleIndices { + buffer: Some(&indices_buffer), + format: wgt::IndexFormat::Uint32, + offset: 0, + count: indices.len() as u32, + }), + transforms: None, + }]; + let blas_entries = hal::AccelerationStructureEntries::Triangles(&blas_triangles); + + let mut tlas_entries = + hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { + buffer: None, + count: 3, + }); + let blas_sizes = unsafe { device.get_acceleration_structure_build_sizes( &hal::GetAccelerationStructureBuildSizesDescriptor { - geometry_info: hal::AccelerationStructureGeometryInfo::Triangles { - vertex_format: wgt::VertexFormat::Float32x3, - max_vertex: 3, - index_format: Some(wgt::IndexFormat::Uint32), - }, - format: hal::AccelerationStructureFormat::BottomLevel, - mode: hal::AccelerationStructureBuildMode::Build, + entries: &blas_entries, flags: hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, - primitive_count: 1, }, ) }; @@ -467,11 +482,8 @@ impl Example { let tlas_sizes = unsafe { device.get_acceleration_structure_build_sizes( &hal::GetAccelerationStructureBuildSizesDescriptor { - geometry_info: hal::AccelerationStructureGeometryInfo::Instances, - format: hal::AccelerationStructureFormat::TopLevel, - mode: hal::AccelerationStructureBuildMode::Build, + entries: &tlas_entries, flags: tlas_flags, - primitive_count: 1, }, ) }; @@ -673,6 +685,14 @@ impl Example { instances_buffer }; + if let hal::AccelerationStructureEntries::Instances(ref mut i) = tlas_entries { + i.buffer = Some(&instances_buffer); + assert!( + instances.len() <= i.count as usize, + "Tlas allocation to small" + ); + } + let cmd_encoder_desc = hal::CommandEncoderDescriptor { label: None, queue: &queue, @@ -682,26 +702,12 @@ impl Example { unsafe { cmd_encoder.begin_encoding(Some("init")).unwrap() }; unsafe { - let geometry = hal::AccelerationStructureTriangles { - vertex_buffer: Some(&vertices_buffer), - first_vertex: 0, - vertex_format: wgt::VertexFormat::Float32x3, - vertex_count: vertices.len() as u32, - vertex_stride: 3 * 4, - indices: Some(hal::AccelerationStructureTriangleIndices { - buffer: Some(&indices_buffer), - format: wgt::IndexFormat::Uint32, - offset: 0, - count: indices.len() as u32, - }), - transforms: None, - }; cmd_encoder.build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { mode: hal::AccelerationStructureBuildMode::Build, flags: hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, destination_acceleration_structure: &blas, scratch_buffer: &scratch_buffer, - entries: &hal::AccelerationStructureEntries::Triangles(&vec![geometry]), + entries: &blas_entries, source_acceleration_structure: None, }); @@ -712,16 +718,12 @@ impl Example { }; cmd_encoder.transition_buffers(iter::once(as_barrier)); - let instances = hal::AccelerationStructureInstances { - buffer: Some(&instances_buffer), - count: instances.len() as u32, - }; cmd_encoder.build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { mode: hal::AccelerationStructureBuildMode::Build, flags: tlas_flags, destination_acceleration_structure: &tlas, scratch_buffer: &scratch_buffer, - entries: &hal::AccelerationStructureEntries::Instances(&instances), + entries: &tlas_entries, source_acceleration_structure: None, }); @@ -833,7 +835,7 @@ impl Example { flags: tlas_flags, destination_acceleration_structure: &self.tlas, scratch_buffer: &self.scratch_buffer, - entries: &hal::AccelerationStructureEntries::Instances(&instances), + entries: &hal::AccelerationStructureEntries::Instances(instances), source_acceleration_structure: Some(&self.tlas), }); diff --git a/wgpu-hal/src/dx11/command.rs b/wgpu-hal/src/dx11/command.rs index 3ec95d0c33..20bf0cc9d0 100644 --- a/wgpu-hal/src/dx11/command.rs +++ b/wgpu-hal/src/dx11/command.rs @@ -270,6 +270,6 @@ impl crate::CommandEncoder for super::CommandEncoder { &mut self, desc: &crate::BuildAccelerationStructureDescriptor, ) { - todo!() + unimplemented!() } } diff --git a/wgpu-hal/src/dx11/device.rs b/wgpu-hal/src/dx11/device.rs index 847b002aa2..373ae7d0b0 100644 --- a/wgpu-hal/src/dx11/device.rs +++ b/wgpu-hal/src/dx11/device.rs @@ -205,25 +205,25 @@ impl crate::Device for super::Device { &self, desc: &crate::AccelerationStructureDescriptor, ) -> Result { - todo!() + unimplemented!() } unsafe fn get_acceleration_structure_build_sizes( &self, - desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + desc: &crate::GetAccelerationStructureBuildSizesDescriptor, ) -> crate::AccelerationStructureBuildSizes { - todo!() + unimplemented!() } unsafe fn get_acceleration_structure_device_address( &self, acceleration_structure: &super::AccelerationStructure, ) -> wgt::BufferAddress { - todo!() + unimplemented!() } unsafe fn destroy_acceleration_structure( &self, acceleration_structure: super::AccelerationStructure, ) { - todo!() + unimplemented!() } } diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index fd0922670f..9e74177fb3 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -1597,7 +1597,7 @@ impl crate::Device for super::Device { unsafe fn get_acceleration_structure_build_sizes( &self, - _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, ) -> crate::AccelerationStructureBuildSizes { // Implement using `GetRaytracingAccelerationStructurePrebuildInfo`: // https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#getraytracingaccelerationstructureprebuildinfo diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 049382e77e..670705c834 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -245,7 +245,7 @@ impl crate::Device for Context { } unsafe fn get_acceleration_structure_build_sizes( &self, - _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, ) -> crate::AccelerationStructureBuildSizes { Default::default() } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 1aed0a2232..b81c165749 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -1326,7 +1326,7 @@ impl crate::Device for super::Device { } unsafe fn get_acceleration_structure_build_sizes( &self, - _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, ) -> crate::AccelerationStructureBuildSizes { unimplemented!() } diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index a26cf87cd6..d5ea92a39a 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -357,7 +357,7 @@ pub trait Device: Send + Sync { ) -> Result; unsafe fn get_acceleration_structure_build_sizes( &self, - desc: &GetAccelerationStructureBuildSizesDescriptor, + desc: &GetAccelerationStructureBuildSizesDescriptor, ) -> AccelerationStructureBuildSizes; unsafe fn get_acceleration_structure_device_address( &self, @@ -1373,24 +1373,6 @@ pub struct AccelerationStructureBuildSizes { pub build_scratch_size: wgt::BufferAddress, } -pub struct GetAccelerationStructureBuildSizesDescriptor { - pub geometry_info: AccelerationStructureGeometryInfo, - pub format: AccelerationStructureFormat, - pub mode: AccelerationStructureBuildMode, - pub flags: AccelerationStructureBuildFlags, - pub primitive_count: u32, -} - -#[derive(Clone, Copy)] -pub enum AccelerationStructureGeometryInfo { - Triangles { - vertex_format: wgt::VertexFormat, - max_vertex: u32, - index_format: Option, - }, - Instances, -} - pub struct BuildAccelerationStructureDescriptor<'a, A: Api> { pub entries: &'a AccelerationStructureEntries<'a, A>, pub mode: AccelerationStructureBuildMode, @@ -1400,13 +1382,20 @@ pub struct BuildAccelerationStructureDescriptor<'a, A: Api> { pub scratch_buffer: &'a A::Buffer, } +pub struct GetAccelerationStructureBuildSizesDescriptor<'a, A: Api> { + pub entries: &'a AccelerationStructureEntries<'a, A>, + pub flags: AccelerationStructureBuildFlags, +} + /// /// Usage for buffer size requirements: /// All Buffers, BufferAdresses and offsets will be ignored. +/// The build mode will be ignored. /// Reducing the amount of Instances, Triangle groups or AABB groups (or the number of Trinagles/AABBs in coresponding groups), /// may result in reduced size requirements. +/// Any other change may result in a bigger or smaller size requirement. pub enum AccelerationStructureEntries<'a, A: Api> { - Instances(&'a AccelerationStructureInstances<'a, A>), + Instances(AccelerationStructureInstances<'a, A>), Triangles(&'a [AccelerationStructureTriangles<'a, A>]), AABBs(&'a [AccelerationStructureAABBs]), } diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index b80b557ffb..e5d36e4ad9 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -375,8 +375,100 @@ impl crate::CommandEncoder for super::CommandEncoder { None => panic!("Feature `RAY_TRACING` not enabled"), }; - let (geometries, ranges) = unsafe { - to_raw_acceleration_structure_geometry_and_range_info(desc, ray_tracing_functions, true) + let get_device_address = |buffer: Option<&super::Buffer>| unsafe { + match buffer { + Some(buffer) => ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), + ), + None => panic!("Buffers are required to build acceleration structures"), + } + }; + + let (geometries, ranges) = match *desc.entries { + crate::AccelerationStructureEntries::Instances(ref instances) => { + let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder() + .data(vk::DeviceOrHostAddressConstKHR { + device_address: get_device_address(instances.buffer), + }); + + let geometry = vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::INSTANCES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + instances: *instance_data, + }) + .flags(vk::GeometryFlagsKHR::empty()); + + let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() + .primitive_count(instances.count); + + (vec![*geometry], vec![*range]) + } + crate::AccelerationStructureEntries::Triangles(in_geometries) => { + let mut ranges = Vec::::with_capacity( + in_geometries.len(), + ); + let mut geometries = + Vec::::with_capacity(in_geometries.len()); + for triangles in in_geometries { + let mut triangle_data = + vk::AccelerationStructureGeometryTrianglesDataKHR::builder() + .vertex_data(vk::DeviceOrHostAddressConstKHR { + device_address: get_device_address(triangles.vertex_buffer), + }) + .vertex_format(conv::map_vertex_format(triangles.vertex_format)) + .max_vertex(triangles.vertex_count) + .vertex_stride(triangles.vertex_stride); + + let mut range = vk::AccelerationStructureBuildRangeInfoKHR::builder(); + + if let Some(ref indices) = triangles.indices { + triangle_data = triangle_data + .index_data(vk::DeviceOrHostAddressConstKHR { + device_address: get_device_address(indices.buffer), + }) + .index_type(conv::map_index_format(indices.format)); + + range = range + .primitive_count(indices.count / 3) + .primitive_offset(indices.offset) + .first_vertex(triangles.first_vertex); + } else { + range = range + .primitive_count(triangles.vertex_count) + .first_vertex(triangles.first_vertex); + } + if let Some(ref transform) = triangles.transforms { + let transform_device_address = unsafe { + ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder() + .buffer(transform.buffer.raw), + ) + }; + triangle_data = + triangle_data.transform_data(vk::DeviceOrHostAddressConstKHR { + device_address: transform_device_address, + }); + + range = range.transform_offset(transform.offset); + } + + let geometry = vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::TRIANGLES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + triangles: *triangle_data, + }) + .flags(vk::GeometryFlagsKHR::empty()) + .build(); + geometries.push(geometry); + ranges.push(*range); + } + (geometries, ranges) + } + crate::AccelerationStructureEntries::AABBs(_) => todo!(), }; let scratch_device_address = unsafe { @@ -386,7 +478,7 @@ impl crate::CommandEncoder for super::CommandEncoder { &vk::BufferDeviceAddressInfo::builder().buffer(desc.scratch_buffer.raw), ) }; - let ty = match desc.entries { + let ty = match *desc.entries { crate::AccelerationStructureEntries::Instances(_) => { vk::AccelerationStructureTypeKHR::TOP_LEVEL } @@ -869,117 +961,6 @@ impl crate::CommandEncoder for super::CommandEncoder { } } -unsafe fn to_raw_acceleration_structure_geometry_and_range_info( - desc: &crate::BuildAccelerationStructureDescriptor, - ray_tracing_functions: &super::RayTracingDeviceExtensionFunctions, - require_buffers: bool, -) -> ( - Vec, - Vec, -) { - let get_device_address = |buffer: Option<&super::Buffer>| { - if let Some(buffer) = buffer { - unsafe { - ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw), - ) - } - } else { - if require_buffers { - panic!("Buffers are required to build acceleration structures"); - } - 0u64 - } - }; - let (geometries, ranges) = match *desc.entries { - crate::AccelerationStructureEntries::Instances(instances) => { - let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder().data( - vk::DeviceOrHostAddressConstKHR { - device_address: get_device_address(instances.buffer), - }, - ); - - let geometry = vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::INSTANCES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - instances: *instance_data, - }) - .flags(vk::GeometryFlagsKHR::empty()); - - let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() - .primitive_count(instances.count); - - (vec![*geometry], vec![*range]) - } - crate::AccelerationStructureEntries::Triangles(in_geometries) => { - let mut ranges = Vec::::with_capacity( - in_geometries.len(), - ); - let mut geometries = - Vec::::with_capacity(in_geometries.len()); - for triangles in in_geometries { - let mut triangle_data = - vk::AccelerationStructureGeometryTrianglesDataKHR::builder() - .vertex_data(vk::DeviceOrHostAddressConstKHR { - device_address: get_device_address(triangles.vertex_buffer), - }) - .vertex_format(conv::map_vertex_format(triangles.vertex_format)) - .max_vertex(triangles.vertex_count) - .vertex_stride(triangles.vertex_stride); - - let mut range = vk::AccelerationStructureBuildRangeInfoKHR::builder(); - - if let Some(indices) = &triangles.indices { - triangle_data = triangle_data - .index_data(vk::DeviceOrHostAddressConstKHR { - device_address: get_device_address(indices.buffer), - }) - .index_type(conv::map_index_format(indices.format)); - - range = range - .primitive_count(indices.count / 3) - .primitive_offset(indices.offset) - .first_vertex(triangles.first_vertex); - } else { - range = range - .primitive_count(triangles.vertex_count) - .first_vertex(triangles.first_vertex); - } - if let Some(transform) = &triangles.transforms { - let transform_device_address = unsafe { - ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder() - .buffer(transform.buffer.raw), - ) - }; - triangle_data = triangle_data.transform_data(vk::DeviceOrHostAddressConstKHR { - device_address: transform_device_address, - }); - - range = range.transform_offset(transform.offset); - } - - let geometry = vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::TRIANGLES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - triangles: *triangle_data, - }) - .flags(vk::GeometryFlagsKHR::empty()) - .build(); - geometries.push(geometry); - ranges.push(*range); - } - (geometries, ranges) - } - crate::AccelerationStructureEntries::AABBs(_) => todo!(), - }; - (geometries, ranges) -} - #[test] fn check_dst_image_layout() { assert_eq!( diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 434110aefe..01c0358cec 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -2061,55 +2061,72 @@ impl crate::Device for super::Device { unsafe fn get_acceleration_structure_build_sizes( &self, - desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + desc: &crate::GetAccelerationStructureBuildSizesDescriptor, ) -> crate::AccelerationStructureBuildSizes { let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { Some(ref functions) => functions, None => panic!("Feature `RAY_TRACING` not enabled"), }; - let geometry = match desc.geometry_info { - crate::AccelerationStructureGeometryInfo::Instances => { - let instances_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder(); + let (geometries, primitive_counts) = match *desc.entries { + crate::AccelerationStructureEntries::Instances(ref instances) => { + let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder(); - vk::AccelerationStructureGeometryKHR::builder() + let geometry = vk::AccelerationStructureGeometryKHR::builder() .geometry_type(vk::GeometryTypeKHR::INSTANCES) .geometry(vk::AccelerationStructureGeometryDataKHR { - instances: *instances_data, + instances: *instance_data, }) - .flags(vk::GeometryFlagsKHR::empty()) + .flags(vk::GeometryFlagsKHR::empty()); + + (vec![*geometry], vec![instances.count]) } - crate::AccelerationStructureGeometryInfo::Triangles { - vertex_format, - max_vertex, - index_format, - } => { - let mut triangles_data = - vk::AccelerationStructureGeometryTrianglesDataKHR::builder() - .vertex_format(conv::map_vertex_format(vertex_format)) - .max_vertex(max_vertex); - - if let Some(index_format) = index_format { - triangles_data = - triangles_data.index_type(conv::map_index_format(index_format)); - } + crate::AccelerationStructureEntries::Triangles(in_geometries) => { + let mut primitive_counts = Vec::::with_capacity(in_geometries.len()); + let mut geometries = + Vec::::with_capacity(in_geometries.len()); + + for triangles in in_geometries { + let mut triangle_data = + vk::AccelerationStructureGeometryTrianglesDataKHR::builder() + .vertex_format(conv::map_vertex_format(triangles.vertex_format)) + .max_vertex(triangles.vertex_count) + .vertex_stride(triangles.vertex_stride); + + let pritive_count = if let Some(ref indices) = triangles.indices { + triangle_data = + triangle_data.index_type(conv::map_index_format(indices.format)); + indices.count / 3 + } else { + triangles.vertex_count + }; - vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::TRIANGLES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - triangles: *triangles_data, - }) - .flags(vk::GeometryFlagsKHR::empty()) + let geometry = vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::TRIANGLES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + triangles: *triangle_data, + }) + .flags(vk::GeometryFlagsKHR::empty()) + .build(); + geometries.push(geometry); + primitive_counts.push(pritive_count); + } + (geometries, primitive_counts) } + crate::AccelerationStructureEntries::AABBs(_) => todo!(), }; - let geometries = &[*geometry]; + let ty = match *desc.entries { + crate::AccelerationStructureEntries::Instances(_) => { + vk::AccelerationStructureTypeKHR::TOP_LEVEL + } + _ => vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL, + }; let geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() - .ty(conv::map_acceleration_structure_format(desc.format)) - .mode(conv::map_acceleration_structure_build_mode(desc.mode)) + .ty(ty) .flags(conv::map_acceleration_structure_flags(desc.flags)) - .geometries(geometries); + .geometries(&geometries); let raw = unsafe { ray_tracing_functions @@ -2117,7 +2134,7 @@ impl crate::Device for super::Device { .get_acceleration_structure_build_sizes( vk::AccelerationStructureBuildTypeKHR::DEVICE, &geometry_info, - &[desc.primitive_count], + &primitive_counts, ) }; From 93a347dfd94d80490ae0a0665db966a353b32ade Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 1 Mar 2023 06:48:54 +0100 Subject: [PATCH 020/146] added aabbs and geometry flag support --- wgpu-hal/examples/ray-traced-triangle/main.rs | 3 ++ wgpu-hal/src/lib.rs | 30 +++++++++---- wgpu-hal/src/vulkan/command.rs | 43 ++++++++++++++++--- wgpu-hal/src/vulkan/conv.rs | 20 +++++++++ wgpu-hal/src/vulkan/device.rs | 34 +++++++++++---- 5 files changed, 107 insertions(+), 23 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 1d41a74182..4eabf3e433 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -458,6 +458,7 @@ impl Example { count: indices.len() as u32, }), transforms: None, + flags: hal::AccelerationStructureGeometryFlags::OPAQUE, }]; let blas_entries = hal::AccelerationStructureEntries::Triangles(&blas_triangles); @@ -465,6 +466,7 @@ impl Example { hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { buffer: None, count: 3, + offset: 0, }); let blas_sizes = unsafe { @@ -828,6 +830,7 @@ impl Example { let instances = hal::AccelerationStructureInstances { buffer: Some(&self.instances_buffer), count: self.instances.len() as u32, + offset: 0, }; ctx.encoder .build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index d5ea92a39a..cbd8dc2d99 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -1397,28 +1397,34 @@ pub struct GetAccelerationStructureBuildSizesDescriptor<'a, A: Api> { pub enum AccelerationStructureEntries<'a, A: Api> { Instances(AccelerationStructureInstances<'a, A>), Triangles(&'a [AccelerationStructureTriangles<'a, A>]), - AABBs(&'a [AccelerationStructureAABBs]), + AABBs(&'a [AccelerationStructureAABBs<'a, A>]), } // TODO: flags pub struct AccelerationStructureTriangles<'a, A: Api> { pub vertex_buffer: Option<&'a A::Buffer>, - pub first_vertex: u32, pub vertex_format: wgt::VertexFormat, + pub first_vertex: u32, pub vertex_count: u32, pub vertex_stride: wgt::BufferAddress, pub indices: Option>, pub transforms: Option>, + pub flags: AccelerationStructureGeometryFlags, } // TODO: * -pub struct AccelerationStructureAABBs { - pub count: u32, //TODO +pub struct AccelerationStructureAABBs<'a, A: Api> { + pub buffer: Option<&'a A::Buffer>, + pub offset: u32, + pub count: u32, + pub stride: wgt::BufferAddress, + pub flags: AccelerationStructureGeometryFlags, } // TODO: offset pub struct AccelerationStructureInstances<'a, A: Api> { pub buffer: Option<&'a A::Buffer>, + pub offset: u32, pub count: u32, } @@ -1436,9 +1442,17 @@ pub struct AccelerationStructureTriangleTransforms<'a, A: Api> { bitflags!( pub struct AccelerationStructureBuildFlags: u32 { - const PREFER_FAST_TRACE = 1 << 0; - const PREFER_FAST_BUILD = 1 << 1; - const ALLOW_UPDATE = 1 << 2; - const LOW_MEMORY = 1 << 3; + const ALLOW_UPDATE = 1 << 0; + const ALLOW_COMPACTION = 1 << 1; + const PREFER_FAST_TRACE = 1 << 2; + const PREFER_FAST_BUILD = 1 << 3; + const LOW_MEMORY = 1 << 4; + } +); + +bitflags!( + pub struct AccelerationStructureGeometryFlags: u32 { + const OPAQUE = 1 << 0; + const NO_DUPLICATE_ANY_HIT_INVOCATION = 1 << 1; } ); diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index e5d36e4ad9..c1f7b8152a 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -397,11 +397,11 @@ impl crate::CommandEncoder for super::CommandEncoder { .geometry_type(vk::GeometryTypeKHR::INSTANCES) .geometry(vk::AccelerationStructureGeometryDataKHR { instances: *instance_data, - }) - .flags(vk::GeometryFlagsKHR::empty()); + }); let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() - .primitive_count(instances.count); + .primitive_count(instances.count) + .primitive_offset(instances.offset); (vec![*geometry], vec![*range]) } @@ -439,6 +439,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .primitive_count(triangles.vertex_count) .first_vertex(triangles.first_vertex); } + if let Some(ref transform) = triangles.transforms { let transform_device_address = unsafe { ray_tracing_functions @@ -461,14 +462,42 @@ impl crate::CommandEncoder for super::CommandEncoder { .geometry(vk::AccelerationStructureGeometryDataKHR { triangles: *triangle_data, }) - .flags(vk::GeometryFlagsKHR::empty()) - .build(); - geometries.push(geometry); + .flags(conv::map_acceleration_structure_geomety_flags( + triangles.flags, + )); + + geometries.push(*geometry); + ranges.push(*range); + } + (geometries, ranges) + } + crate::AccelerationStructureEntries::AABBs(in_geometries) => { + let mut ranges = Vec::::with_capacity( + in_geometries.len(), + ); + let mut geometries = + Vec::::with_capacity(in_geometries.len()); + for aabb in in_geometries { + let aabbs_data = vk::AccelerationStructureGeometryAabbsDataKHR::builder() + .data(vk::DeviceOrHostAddressConstKHR { + device_address: get_device_address(aabb.buffer), + }) + .stride(aabb.stride); + + let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() + .primitive_count(aabb.count) + .primitive_offset(aabb.offset); + + let geometry = vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::AABBS) + .geometry(vk::AccelerationStructureGeometryDataKHR { aabbs: *aabbs_data }) + .flags(conv::map_acceleration_structure_geomety_flags(aabb.flags)); + + geometries.push(*geometry); ranges.push(*range); } (geometries, ranges) } - crate::AccelerationStructureEntries::AABBs(_) => todo!(), }; let scratch_device_address = unsafe { diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index 2719a56924..2269eed978 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -889,5 +889,25 @@ pub fn map_acceleration_structure_flags( vk_flags |= vk::BuildAccelerationStructureFlagsKHR::LOW_MEMORY; } + if flags.contains(crate::AccelerationStructureBuildFlags::ALLOW_COMPACTION) { + vk_flags |= vk::BuildAccelerationStructureFlagsKHR::ALLOW_COMPACTION + } + + vk_flags +} + +pub fn map_acceleration_structure_geomety_flags( + flags: crate::AccelerationStructureGeometryFlags, +) -> vk::GeometryFlagsKHR { + let mut vk_flags = vk::GeometryFlagsKHR::empty(); + + if flags.contains(crate::AccelerationStructureGeometryFlags::OPAQUE) { + vk_flags |= vk::GeometryFlagsKHR::OPAQUE; + } + + if flags.contains(crate::AccelerationStructureGeometryFlags::NO_DUPLICATE_ANY_HIT_INVOCATION) { + vk_flags |= vk::GeometryFlagsKHR::NO_DUPLICATE_ANY_HIT_INVOCATION; + } + vk_flags } diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 01c0358cec..ddc5e4a1d1 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -2070,14 +2070,13 @@ impl crate::Device for super::Device { let (geometries, primitive_counts) = match *desc.entries { crate::AccelerationStructureEntries::Instances(ref instances) => { - let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder(); + let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::default(); let geometry = vk::AccelerationStructureGeometryKHR::builder() .geometry_type(vk::GeometryTypeKHR::INSTANCES) .geometry(vk::AccelerationStructureGeometryDataKHR { - instances: *instance_data, - }) - .flags(vk::GeometryFlagsKHR::empty()); + instances: instance_data, + }); (vec![*geometry], vec![instances.count]) } @@ -2106,14 +2105,33 @@ impl crate::Device for super::Device { .geometry(vk::AccelerationStructureGeometryDataKHR { triangles: *triangle_data, }) - .flags(vk::GeometryFlagsKHR::empty()) - .build(); - geometries.push(geometry); + .flags(conv::map_acceleration_structure_geomety_flags( + triangles.flags, + )); + + geometries.push(*geometry); primitive_counts.push(pritive_count); } (geometries, primitive_counts) } - crate::AccelerationStructureEntries::AABBs(_) => todo!(), + crate::AccelerationStructureEntries::AABBs(in_geometries) => { + let mut primitive_counts = Vec::::with_capacity(in_geometries.len()); + let mut geometries = + Vec::::with_capacity(in_geometries.len()); + for aabb in in_geometries { + let aabbs_data = vk::AccelerationStructureGeometryAabbsDataKHR::builder() + .stride(aabb.stride); + + let geometry = vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::AABBS) + .geometry(vk::AccelerationStructureGeometryDataKHR { aabbs: *aabbs_data }) + .flags(conv::map_acceleration_structure_geomety_flags(aabb.flags)); + + geometries.push(*geometry); + primitive_counts.push(aabb.count); + } + (geometries, primitive_counts) + } }; let ty = match *desc.entries { From 16cc4eb572a4fcd8b074ffa0229067877dc48c06 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 1 Mar 2023 07:23:10 +0100 Subject: [PATCH 021/146] fixed RAY_TRACING feature collision + seperated RAY_QUERY --- wgpu-hal/src/vulkan/adapter.rs | 13 +++++++++++-- wgpu-types/src/lib.rs | 21 ++++++++++++++------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index b024e1388d..2e5e40c2ba 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -573,8 +573,12 @@ impl PhysicalDeviceFeatures { F::RAY_TRACING, caps.supports_extension(vk::KhrDeferredHostOperationsFn::name()) && caps.supports_extension(vk::KhrAccelerationStructureFn::name()) - && caps.supports_extension(vk::KhrBufferDeviceAddressFn::name()) - && caps.supports_extension(vk::KhrRayQueryFn::name()), + && caps.supports_extension(vk::KhrBufferDeviceAddressFn::name()), + ); + + features.set( + F::RAY_QUERY, + caps.supports_extension(vk::KhrRayQueryFn::name()), ); (features, dl_flags) @@ -735,10 +739,15 @@ impl PhysicalDeviceCapabilities { extensions.push(vk::KhrDrawIndirectCountFn::name()); } + // Require `VK_KHR_deferred_host_operations`, `VK_KHR_acceleration_structure` and `VK_KHR_buffer_device_address` if the feature `RAY_TRACING` was requested if requested_features.contains(wgt::Features::RAY_TRACING) { extensions.push(vk::KhrDeferredHostOperationsFn::name()); extensions.push(vk::KhrAccelerationStructureFn::name()); extensions.push(vk::KhrBufferDeviceAddressFn::name()); + } + + // Require `VK_KHR_ray_query` if the associated feature was requested + if requested_features.contains(wgt::Features::RAY_QUERY) { extensions.push(vk::KhrRayQueryFn::name()); } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index c57e8b5d61..9692dfde6d 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -687,13 +687,6 @@ bitflags::bitflags! { /// This is currently unimplemented on Metal. /// When implemented, it will be supported on Metal on AMD and Intel GPUs, but not Apple GPUs. const WRITE_TIMESTAMP_INSIDE_PASSES = 1 << 41; - /// Allows for the creation of ray-tracing acceleration structures and ray queries within shaders. - /// - /// Supported platforms: - /// - Vulkan - /// - /// This is a native-only feature. - const RAY_TRACING = 1 << 42; /// Allows shaders to use i16. Not currently supported in naga, only available through `spirv-passthrough`. const SHADER_INT16 = 1 << 42; /// Allows shaders to use the `early_depth_test` attribute. @@ -703,6 +696,20 @@ bitflags::bitflags! { /// /// This is a native-only feature. const SHADER_EARLY_DEPTH_TEST = 1 << 43; + /// Allows for the creation of ray-tracing acceleration structures. + /// + /// Supported platforms: + /// - Vulkan + /// + /// This is a native-only feature. + const RAY_TRACING = 1 << 44; + /// Allows for the creation of ray-tracing queries within shaders. + /// + /// Supported platforms: + /// - Vulkan + /// + /// This is a native-only feature. + const RAY_QUERY = 1 << 45; } } From 5b8423892810754ac85bdde1b8fcfeca97656931 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 1 Mar 2023 07:27:27 +0100 Subject: [PATCH 022/146] renamed to build_acceleration_structure --- wgpu-hal/examples/ray-traced-triangle/main.rs | 6 +++--- wgpu-hal/src/dx11/command.rs | 2 +- wgpu-hal/src/dx12/command.rs | 2 +- wgpu-hal/src/empty.rs | 2 +- wgpu-hal/src/gles/command.rs | 2 +- wgpu-hal/src/lib.rs | 2 +- wgpu-hal/src/metal/command.rs | 2 +- wgpu-hal/src/vulkan/command.rs | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 4eabf3e433..bfb148cb8d 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -704,7 +704,7 @@ impl Example { unsafe { cmd_encoder.begin_encoding(Some("init")).unwrap() }; unsafe { - cmd_encoder.build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { + cmd_encoder.build_acceleration_structure(&hal::BuildAccelerationStructureDescriptor { mode: hal::AccelerationStructureBuildMode::Build, flags: hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, destination_acceleration_structure: &blas, @@ -720,7 +720,7 @@ impl Example { }; cmd_encoder.transition_buffers(iter::once(as_barrier)); - cmd_encoder.build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { + cmd_encoder.build_acceleration_structure(&hal::BuildAccelerationStructureDescriptor { mode: hal::AccelerationStructureBuildMode::Build, flags: tlas_flags, destination_acceleration_structure: &tlas, @@ -833,7 +833,7 @@ impl Example { offset: 0, }; ctx.encoder - .build_acceleration_structures(&hal::BuildAccelerationStructureDescriptor { + .build_acceleration_structure(&hal::BuildAccelerationStructureDescriptor { mode: hal::AccelerationStructureBuildMode::Update, flags: tlas_flags, destination_acceleration_structure: &self.tlas, diff --git a/wgpu-hal/src/dx11/command.rs b/wgpu-hal/src/dx11/command.rs index 20bf0cc9d0..5949b7ec8a 100644 --- a/wgpu-hal/src/dx11/command.rs +++ b/wgpu-hal/src/dx11/command.rs @@ -266,7 +266,7 @@ impl crate::CommandEncoder for super::CommandEncoder { todo!() } - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structure( &mut self, desc: &crate::BuildAccelerationStructureDescriptor, ) { diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index eeabe19587..9062ffc142 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1144,7 +1144,7 @@ impl crate::CommandEncoder for super::CommandEncoder { }; } - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structure( &mut self, _desc: &crate::BuildAccelerationStructureDescriptor, ) { diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 670705c834..2124c52f84 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -431,7 +431,7 @@ impl crate::CommandEncoder for Encoder { unsafe fn dispatch(&mut self, count: [u32; 3]) {} unsafe fn dispatch_indirect(&mut self, buffer: &Resource, offset: wgt::BufferAddress) {} - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structure( &mut self, _desc: &crate::BuildAccelerationStructureDescriptor, ) { diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index b529eea801..6a931756f6 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -1061,7 +1061,7 @@ impl crate::CommandEncoder for super::CommandEncoder { }); } - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structure( &mut self, _desc: &crate::BuildAccelerationStructureDescriptor, ) { diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index cbd8dc2d99..cd45d9474b 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -582,7 +582,7 @@ pub trait CommandEncoder: Send + Sync + fmt::Debug { unsafe fn dispatch(&mut self, count: [u32; 3]); unsafe fn dispatch_indirect(&mut self, buffer: &A::Buffer, offset: wgt::BufferAddress); - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structure( &mut self, desc: &BuildAccelerationStructureDescriptor, ); diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 16e8abbf4b..31ef925c7f 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -970,7 +970,7 @@ impl crate::CommandEncoder for super::CommandEncoder { encoder.dispatch_thread_groups_indirect(&buffer.raw, offset, self.state.raw_wg_size); } - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structure( &mut self, _desc: &crate::BuildAccelerationStructureDescriptor, ) { diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index c1f7b8152a..a1b349f36c 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -366,7 +366,7 @@ impl crate::CommandEncoder for super::CommandEncoder { }; } - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structure( &mut self, desc: &crate::BuildAccelerationStructureDescriptor, ) { From caa4ae7ab89ceb1192281435ff3aea3eeb1ac24a Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 1 Mar 2023 19:48:03 +0100 Subject: [PATCH 023/146] fixed missing type parameter for metal --- wgpu-hal/src/metal/device.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 55104f2e7c..f9259bec97 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -1158,7 +1158,7 @@ impl crate::Device for super::Device { unsafe fn get_acceleration_structure_build_sizes( &self, - _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, ) -> crate::AccelerationStructureBuildSizes { unimplemented!() } From bee8a36c5b71008d6abee5b7deed6800dd26548a Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sun, 19 Mar 2023 14:32:55 +0100 Subject: [PATCH 024/146] multiple AS builds at once (better allocation strategy required) --- wgpu-hal/examples/ray-traced-triangle/main.rs | 43 +-- wgpu-hal/src/dx11/command.rs | 4 +- wgpu-hal/src/dx12/command.rs | 4 +- wgpu-hal/src/empty.rs | 4 +- wgpu-hal/src/gles/command.rs | 4 +- wgpu-hal/src/lib.rs | 4 +- wgpu-hal/src/vulkan/command.rs | 313 +++++++++++------- 7 files changed, 220 insertions(+), 156 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index bfb148cb8d..d7d372c84a 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -704,14 +704,16 @@ impl Example { unsafe { cmd_encoder.begin_encoding(Some("init")).unwrap() }; unsafe { - cmd_encoder.build_acceleration_structure(&hal::BuildAccelerationStructureDescriptor { - mode: hal::AccelerationStructureBuildMode::Build, - flags: hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, - destination_acceleration_structure: &blas, - scratch_buffer: &scratch_buffer, - entries: &blas_entries, - source_acceleration_structure: None, - }); + cmd_encoder.build_acceleration_structures(&[ + &hal::BuildAccelerationStructureDescriptor { + mode: hal::AccelerationStructureBuildMode::Build, + flags: hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, + destination_acceleration_structure: &blas, + scratch_buffer: &scratch_buffer, + entries: &blas_entries, + source_acceleration_structure: None, + }, + ]); let as_barrier = hal::BufferBarrier { buffer: &scratch_buffer, @@ -720,14 +722,16 @@ impl Example { }; cmd_encoder.transition_buffers(iter::once(as_barrier)); - cmd_encoder.build_acceleration_structure(&hal::BuildAccelerationStructureDescriptor { - mode: hal::AccelerationStructureBuildMode::Build, - flags: tlas_flags, - destination_acceleration_structure: &tlas, - scratch_buffer: &scratch_buffer, - entries: &tlas_entries, - source_acceleration_structure: None, - }); + cmd_encoder.build_acceleration_structures(&[ + &hal::BuildAccelerationStructureDescriptor { + mode: hal::AccelerationStructureBuildMode::Build, + flags: tlas_flags, + destination_acceleration_structure: &tlas, + scratch_buffer: &scratch_buffer, + entries: &tlas_entries, + source_acceleration_structure: None, + }, + ]); let texture_barrier = hal::TextureBarrier { texture: &texture, @@ -832,15 +836,16 @@ impl Example { count: self.instances.len() as u32, offset: 0, }; - ctx.encoder - .build_acceleration_structure(&hal::BuildAccelerationStructureDescriptor { + ctx.encoder.build_acceleration_structures(&[ + &hal::BuildAccelerationStructureDescriptor { mode: hal::AccelerationStructureBuildMode::Update, flags: tlas_flags, destination_acceleration_structure: &self.tlas, scratch_buffer: &self.scratch_buffer, entries: &hal::AccelerationStructureEntries::Instances(instances), source_acceleration_structure: Some(&self.tlas), - }); + }, + ]); let as_barrier = hal::BufferBarrier { buffer: &self.scratch_buffer, diff --git a/wgpu-hal/src/dx11/command.rs b/wgpu-hal/src/dx11/command.rs index 5949b7ec8a..113a14e179 100644 --- a/wgpu-hal/src/dx11/command.rs +++ b/wgpu-hal/src/dx11/command.rs @@ -266,9 +266,9 @@ impl crate::CommandEncoder for super::CommandEncoder { todo!() } - unsafe fn build_acceleration_structure( + unsafe fn build_acceleration_structures( &mut self, - desc: &crate::BuildAccelerationStructureDescriptor, + desc: &[&crate::BuildAccelerationStructureDescriptor], ) { unimplemented!() } diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 2521db7a7d..0b2068323d 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1141,9 +1141,9 @@ impl crate::CommandEncoder for super::CommandEncoder { }; } - unsafe fn build_acceleration_structure( + unsafe fn build_acceleration_structures( &mut self, - _desc: &crate::BuildAccelerationStructureDescriptor, + _desc: &[&crate::BuildAccelerationStructureDescriptor], ) { // Implement using `BuildRaytracingAccelerationStructure`: // https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#buildraytracingaccelerationstructure diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 2124c52f84..b86d2f90a1 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -431,9 +431,9 @@ impl crate::CommandEncoder for Encoder { unsafe fn dispatch(&mut self, count: [u32; 3]) {} unsafe fn dispatch_indirect(&mut self, buffer: &Resource, offset: wgt::BufferAddress) {} - unsafe fn build_acceleration_structure( + unsafe fn build_acceleration_structures( &mut self, - _desc: &crate::BuildAccelerationStructureDescriptor, + _desc: &[&crate::BuildAccelerationStructureDescriptor], ) { } } diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index 6a931756f6..afff9c08b4 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -1061,9 +1061,9 @@ impl crate::CommandEncoder for super::CommandEncoder { }); } - unsafe fn build_acceleration_structure( + unsafe fn build_acceleration_structures( &mut self, - _desc: &crate::BuildAccelerationStructureDescriptor, + _desc: &[&crate::BuildAccelerationStructureDescriptor], ) { unimplemented!() } diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 1c1f71068c..3d721d81f8 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -568,9 +568,9 @@ pub trait CommandEncoder: Send + Sync + fmt::Debug { unsafe fn dispatch(&mut self, count: [u32; 3]); unsafe fn dispatch_indirect(&mut self, buffer: &A::Buffer, offset: wgt::BufferAddress); - unsafe fn build_acceleration_structure( + unsafe fn build_acceleration_structures( &mut self, - desc: &BuildAccelerationStructureDescriptor, + descriptors: &[&BuildAccelerationStructureDescriptor], ); } diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 136d1319c7..1c67ca4e9e 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -366,9 +366,9 @@ impl crate::CommandEncoder for super::CommandEncoder { }; } - unsafe fn build_acceleration_structure( + unsafe fn build_acceleration_structures( &mut self, - desc: &crate::BuildAccelerationStructureDescriptor, + descriptors: &[&crate::BuildAccelerationStructureDescriptor], ) { let ray_tracing_functions = match self.device.extension_fns.ray_tracing { Some(ref functions) => functions, @@ -386,157 +386,216 @@ impl crate::CommandEncoder for super::CommandEncoder { } }; - let (geometries, ranges) = match *desc.entries { - crate::AccelerationStructureEntries::Instances(ref instances) => { - let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder() + // storage to all the data required for cmd_build_acceleration_structures + let mut ranges_storage = + Vec::>::with_capacity( + descriptors.len(), + ); + let mut geometries_storage = + Vec::>::with_capacity(descriptors.len()); + + // pointers to all the data required for cmd_build_acceleration_structures + + let mut geometry_infos = + Vec::::with_capacity(descriptors.len()); + + let mut ranges_ptrs = + Vec::<&[vk::AccelerationStructureBuildRangeInfoKHR]>::with_capacity(descriptors.len()); + + for desc in descriptors { + let (geometries, ranges) = match *desc.entries { + crate::AccelerationStructureEntries::Instances(ref instances) => { + let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder( + ) .data(vk::DeviceOrHostAddressConstKHR { device_address: get_device_address(instances.buffer), }); - let geometry = vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::INSTANCES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - instances: *instance_data, - }); + let geometry = vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::INSTANCES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + instances: *instance_data, + }); - let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() - .primitive_count(instances.count) - .primitive_offset(instances.offset); + let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() + .primitive_count(instances.count) + .primitive_offset(instances.offset); - (vec![*geometry], vec![*range]) - } - crate::AccelerationStructureEntries::Triangles(in_geometries) => { - let mut ranges = Vec::::with_capacity( - in_geometries.len(), - ); - let mut geometries = - Vec::::with_capacity(in_geometries.len()); - for triangles in in_geometries { - let mut triangle_data = - vk::AccelerationStructureGeometryTrianglesDataKHR::builder() - .vertex_data(vk::DeviceOrHostAddressConstKHR { - device_address: get_device_address(triangles.vertex_buffer), + (vec![*geometry], vec![*range]) + } + crate::AccelerationStructureEntries::Triangles(in_geometries) => { + let mut ranges = + Vec::::with_capacity( + in_geometries.len(), + ); + let mut geometries = Vec::::with_capacity( + in_geometries.len(), + ); + for triangles in in_geometries { + let mut triangle_data = + vk::AccelerationStructureGeometryTrianglesDataKHR::builder() + .vertex_data(vk::DeviceOrHostAddressConstKHR { + device_address: get_device_address(triangles.vertex_buffer), + }) + .vertex_format(conv::map_vertex_format(triangles.vertex_format)) + .max_vertex(triangles.vertex_count) + .vertex_stride(triangles.vertex_stride); + + let mut range = vk::AccelerationStructureBuildRangeInfoKHR::builder(); + + if let Some(ref indices) = triangles.indices { + triangle_data = triangle_data + .index_data(vk::DeviceOrHostAddressConstKHR { + device_address: get_device_address(indices.buffer), + }) + .index_type(conv::map_index_format(indices.format)); + + range = range + .primitive_count(indices.count / 3) + .primitive_offset(indices.offset) + .first_vertex(triangles.first_vertex); + } else { + range = range + .primitive_count(triangles.vertex_count) + .first_vertex(triangles.first_vertex); + } + + if let Some(ref transform) = triangles.transforms { + let transform_device_address = unsafe { + ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder() + .buffer(transform.buffer.raw), + ) + }; + triangle_data = + triangle_data.transform_data(vk::DeviceOrHostAddressConstKHR { + device_address: transform_device_address, + }); + + range = range.transform_offset(transform.offset); + } + + let geometry = vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::TRIANGLES) + .geometry(vk::AccelerationStructureGeometryDataKHR { + triangles: *triangle_data, }) - .vertex_format(conv::map_vertex_format(triangles.vertex_format)) - .max_vertex(triangles.vertex_count) - .vertex_stride(triangles.vertex_stride); + .flags(conv::map_acceleration_structure_geomety_flags( + triangles.flags, + )); - let mut range = vk::AccelerationStructureBuildRangeInfoKHR::builder(); + geometries.push(*geometry); + ranges.push(*range); + } + (geometries, ranges) + } + crate::AccelerationStructureEntries::AABBs(in_geometries) => { + let mut ranges = + Vec::::with_capacity( + in_geometries.len(), + ); + let mut geometries = Vec::::with_capacity( + in_geometries.len(), + ); + for aabb in in_geometries { + let aabbs_data = vk::AccelerationStructureGeometryAabbsDataKHR::builder() + .data(vk::DeviceOrHostAddressConstKHR { + device_address: get_device_address(aabb.buffer), + }) + .stride(aabb.stride); - if let Some(ref indices) = triangles.indices { - triangle_data = triangle_data - .index_data(vk::DeviceOrHostAddressConstKHR { - device_address: get_device_address(indices.buffer), + let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() + .primitive_count(aabb.count) + .primitive_offset(aabb.offset); + + let geometry = vk::AccelerationStructureGeometryKHR::builder() + .geometry_type(vk::GeometryTypeKHR::AABBS) + .geometry(vk::AccelerationStructureGeometryDataKHR { + aabbs: *aabbs_data, }) - .index_type(conv::map_index_format(indices.format)); - - range = range - .primitive_count(indices.count / 3) - .primitive_offset(indices.offset) - .first_vertex(triangles.first_vertex); - } else { - range = range - .primitive_count(triangles.vertex_count) - .first_vertex(triangles.first_vertex); - } + .flags(conv::map_acceleration_structure_geomety_flags(aabb.flags)); - if let Some(ref transform) = triangles.transforms { - let transform_device_address = unsafe { - ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder() - .buffer(transform.buffer.raw), - ) - }; - triangle_data = - triangle_data.transform_data(vk::DeviceOrHostAddressConstKHR { - device_address: transform_device_address, - }); - - range = range.transform_offset(transform.offset); + geometries.push(*geometry); + ranges.push(*range); } - - let geometry = vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::TRIANGLES) - .geometry(vk::AccelerationStructureGeometryDataKHR { - triangles: *triangle_data, - }) - .flags(conv::map_acceleration_structure_geomety_flags( - triangles.flags, - )); - - geometries.push(*geometry); - ranges.push(*range); + (geometries, ranges) } - (geometries, ranges) - } - crate::AccelerationStructureEntries::AABBs(in_geometries) => { - let mut ranges = Vec::::with_capacity( - in_geometries.len(), - ); - let mut geometries = - Vec::::with_capacity(in_geometries.len()); - for aabb in in_geometries { - let aabbs_data = vk::AccelerationStructureGeometryAabbsDataKHR::builder() - .data(vk::DeviceOrHostAddressConstKHR { - device_address: get_device_address(aabb.buffer), - }) - .stride(aabb.stride); - - let range = vk::AccelerationStructureBuildRangeInfoKHR::builder() - .primitive_count(aabb.count) - .primitive_offset(aabb.offset); + }; - let geometry = vk::AccelerationStructureGeometryKHR::builder() - .geometry_type(vk::GeometryTypeKHR::AABBS) - .geometry(vk::AccelerationStructureGeometryDataKHR { aabbs: *aabbs_data }) - .flags(conv::map_acceleration_structure_geomety_flags(aabb.flags)); + ranges_storage.push(ranges); + geometries_storage.push(geometries); + } - geometries.push(*geometry); - ranges.push(*range); + for (i, desc) in descriptors.iter().enumerate() { + let scratch_device_address = unsafe { + ray_tracing_functions + .buffer_device_address + .get_buffer_device_address( + &vk::BufferDeviceAddressInfo::builder().buffer(desc.scratch_buffer.raw), + ) + }; + let ty = match *desc.entries { + crate::AccelerationStructureEntries::Instances(_) => { + vk::AccelerationStructureTypeKHR::TOP_LEVEL } - (geometries, ranges) - } - }; + _ => vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL, + }; + let mut geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() + .ty(ty) + .mode(conv::map_acceleration_structure_build_mode(desc.mode)) + .flags(conv::map_acceleration_structure_flags(desc.flags)) + .geometries(&geometries_storage[i]) // pointer must live + .dst_acceleration_structure(desc.destination_acceleration_structure.raw) + .scratch_data(vk::DeviceOrHostAddressKHR { + device_address: scratch_device_address, + }); - let scratch_device_address = unsafe { - ray_tracing_functions - .buffer_device_address - .get_buffer_device_address( - &vk::BufferDeviceAddressInfo::builder().buffer(desc.scratch_buffer.raw), - ) - }; - let ty = match *desc.entries { - crate::AccelerationStructureEntries::Instances(_) => { - vk::AccelerationStructureTypeKHR::TOP_LEVEL + if desc.mode == crate::AccelerationStructureBuildMode::Update { + geometry_info.src_acceleration_structure = desc + .source_acceleration_structure + .expect("Acceleration tructure update: source structure required") + .raw; } - _ => vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL, - }; - let mut geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder() - .ty(ty) - .mode(conv::map_acceleration_structure_build_mode(desc.mode)) - .flags(conv::map_acceleration_structure_flags(desc.flags)) - .geometries(&geometries) - .dst_acceleration_structure(desc.destination_acceleration_structure.raw) - .scratch_data(vk::DeviceOrHostAddressKHR { - device_address: scratch_device_address, - }); - if desc.mode == crate::AccelerationStructureBuildMode::Update { - geometry_info.src_acceleration_structure = desc - .source_acceleration_structure - .expect("Acceleration tructure update: source structure required") - .raw; + geometry_infos.push(*geometry_info); + ranges_ptrs.push(&ranges_storage[i]); } - let geometry_info = geometry_info.build(); + // let mut geometry_infos = + // Vec::::with_capacity(descriptors.len()); + + // let mut ranges_vec = + // Vec::<&[vk::AccelerationStructureBuildRangeInfoKHR]>::with_capacity(descriptors.len()); + + // let mut ranges_storage = + // Vec::>::with_capacity(descriptors.len()); + + // for desc in descriptors { + // let (ranges, geometry_info) = prepare_geometry_info_and_ranges(desc); + // geometry_infos.push(geometry_info); + // ranges_storage.push(ranges); + + // } + + // for i in 0..descriptors.len() { + // ranges_vec.push(&ranges_storage[i]); + // } + + // let (ranges, geometry_info) = prepare_geometry_info_and_ranges(descriptors[0]); unsafe { ray_tracing_functions .acceleration_structure - .cmd_build_acceleration_structures(self.active, &[geometry_info], &[&ranges]); + .cmd_build_acceleration_structures(self.active, &geometry_infos, &ranges_ptrs); } + + // unsafe { + // ray_tracing_functions + // .acceleration_structure + // .cmd_build_acceleration_structures(self.active, &geometry_infos, &ranges_vec); + // } } // render From a420b87d56af29282eaf7d4b786ad8bf06736698 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sun, 19 Mar 2023 15:49:38 +0100 Subject: [PATCH 025/146] switched to using smallvec --- wgpu-hal/src/vulkan/command.rs | 57 ++++++++++++++++++---------------- wgpu-hal/src/vulkan/device.rs | 12 ++++--- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 1c67ca4e9e..f269f5b0c0 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -370,6 +370,9 @@ impl crate::CommandEncoder for super::CommandEncoder { &mut self, descriptors: &[&crate::BuildAccelerationStructureDescriptor], ) { + const CAPACITY_OUTER: usize = 8; + const CAPACITY_INNER: usize = 1; + let ray_tracing_functions = match self.device.extension_fns.ray_tracing { Some(ref functions) => functions, None => panic!("Feature `RAY_TRACING` not enabled"), @@ -387,20 +390,22 @@ impl crate::CommandEncoder for super::CommandEncoder { }; // storage to all the data required for cmd_build_acceleration_structures - let mut ranges_storage = - Vec::>::with_capacity( - descriptors.len(), - ); - let mut geometries_storage = - Vec::>::with_capacity(descriptors.len()); + let mut ranges_storage = smallvec::SmallVec::< + [smallvec::SmallVec<[vk::AccelerationStructureBuildRangeInfoKHR; CAPACITY_INNER]>; + CAPACITY_OUTER], + >::with_capacity(descriptors.len()); + let mut geometries_storage = smallvec::SmallVec::< + [smallvec::SmallVec<[vk::AccelerationStructureGeometryKHR; CAPACITY_INNER]>; + CAPACITY_OUTER], + >::with_capacity(descriptors.len()); // pointers to all the data required for cmd_build_acceleration_structures - - let mut geometry_infos = - Vec::::with_capacity(descriptors.len()); - - let mut ranges_ptrs = - Vec::<&[vk::AccelerationStructureBuildRangeInfoKHR]>::with_capacity(descriptors.len()); + let mut geometry_infos = smallvec::SmallVec::< + [vk::AccelerationStructureBuildGeometryInfoKHR; CAPACITY_OUTER], + >::with_capacity(descriptors.len()); + let mut ranges_ptrs = smallvec::SmallVec::< + [&[vk::AccelerationStructureBuildRangeInfoKHR]; CAPACITY_OUTER], + >::with_capacity(descriptors.len()); for desc in descriptors { let (geometries, ranges) = match *desc.entries { @@ -421,16 +426,15 @@ impl crate::CommandEncoder for super::CommandEncoder { .primitive_count(instances.count) .primitive_offset(instances.offset); - (vec![*geometry], vec![*range]) + (smallvec::smallvec![*geometry], smallvec::smallvec![*range]) } crate::AccelerationStructureEntries::Triangles(in_geometries) => { - let mut ranges = - Vec::::with_capacity( - in_geometries.len(), - ); - let mut geometries = Vec::::with_capacity( - in_geometries.len(), - ); + let mut ranges = smallvec::SmallVec::< + [vk::AccelerationStructureBuildRangeInfoKHR; CAPACITY_INNER], + >::with_capacity(in_geometries.len()); + let mut geometries = smallvec::SmallVec::< + [vk::AccelerationStructureGeometryKHR; CAPACITY_INNER], + >::with_capacity(in_geometries.len()); for triangles in in_geometries { let mut triangle_data = vk::AccelerationStructureGeometryTrianglesDataKHR::builder() @@ -492,13 +496,12 @@ impl crate::CommandEncoder for super::CommandEncoder { (geometries, ranges) } crate::AccelerationStructureEntries::AABBs(in_geometries) => { - let mut ranges = - Vec::::with_capacity( - in_geometries.len(), - ); - let mut geometries = Vec::::with_capacity( - in_geometries.len(), - ); + let mut ranges = smallvec::SmallVec::< + [vk::AccelerationStructureBuildRangeInfoKHR; CAPACITY_INNER], + >::with_capacity(in_geometries.len()); + let mut geometries = smallvec::SmallVec::< + [vk::AccelerationStructureGeometryKHR; CAPACITY_INNER], + >::with_capacity(in_geometries.len()); for aabb in in_geometries { let aabbs_data = vk::AccelerationStructureGeometryAabbsDataKHR::builder() .data(vk::DeviceOrHostAddressConstKHR { diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index ddc5e4a1d1..6bd79e2f33 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -2063,6 +2063,8 @@ impl crate::Device for super::Device { &self, desc: &crate::GetAccelerationStructureBuildSizesDescriptor, ) -> crate::AccelerationStructureBuildSizes { + const CAPACITY: usize = 8; + let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { Some(ref functions) => functions, None => panic!("Feature `RAY_TRACING` not enabled"), @@ -2078,12 +2080,12 @@ impl crate::Device for super::Device { instances: instance_data, }); - (vec![*geometry], vec![instances.count]) + (smallvec::smallvec![*geometry], smallvec::smallvec![instances.count]) } crate::AccelerationStructureEntries::Triangles(in_geometries) => { - let mut primitive_counts = Vec::::with_capacity(in_geometries.len()); + let mut primitive_counts = smallvec::SmallVec::<[u32;CAPACITY]>::with_capacity(in_geometries.len()); let mut geometries = - Vec::::with_capacity(in_geometries.len()); + smallvec::SmallVec::<[vk::AccelerationStructureGeometryKHR;CAPACITY]>::with_capacity(in_geometries.len()); for triangles in in_geometries { let mut triangle_data = @@ -2115,9 +2117,9 @@ impl crate::Device for super::Device { (geometries, primitive_counts) } crate::AccelerationStructureEntries::AABBs(in_geometries) => { - let mut primitive_counts = Vec::::with_capacity(in_geometries.len()); + let mut primitive_counts = smallvec::SmallVec::<[u32;CAPACITY]>::with_capacity(in_geometries.len()); let mut geometries = - Vec::::with_capacity(in_geometries.len()); + smallvec::SmallVec::<[vk::AccelerationStructureGeometryKHR;CAPACITY]>::with_capacity(in_geometries.len()); for aabb in in_geometries { let aabbs_data = vk::AccelerationStructureGeometryAabbsDataKHR::builder() .stride(aabb.stride); From e48f7bd3cb088376d69fcf47426b6bb92ecf3c6d Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sun, 19 Mar 2023 17:25:21 +0100 Subject: [PATCH 026/146] small api change + documentation --- wgpu-hal/examples/ray-traced-triangle/main.rs | 2 +- wgpu-hal/src/lib.rs | 56 ++++++++++++++----- wgpu-hal/src/vulkan/command.rs | 4 +- wgpu-hal/src/vulkan/device.rs | 21 ++++--- 4 files changed, 60 insertions(+), 23 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index d7d372c84a..88c66c4bba 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -457,7 +457,7 @@ impl Example { offset: 0, count: indices.len() as u32, }), - transforms: None, + transform: None, flags: hal::AccelerationStructureGeometryFlags::OPAQUE, }]; let blas_entries = hal::AccelerationStructureEntries::Triangles(&blas_triangles); diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 3d721d81f8..785544b557 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -568,6 +568,13 @@ pub trait CommandEncoder: Send + Sync + fmt::Debug { unsafe fn dispatch(&mut self, count: [u32; 3]); unsafe fn dispatch_indirect(&mut self, buffer: &A::Buffer, offset: wgt::BufferAddress); + /// To get the required sizes for the buffer allocations use `get_acceleration_structure_build_sizes` per descriptor + /// All buffers must be synchronized externally + /// All buffer regions, which are written to may only be passed once per function call, + /// with the exertion of updates in the same descriptor. + /// Consequences of this limitation: + /// - scratch buffers need to be unique + /// - a tlas can't be build in the same call with a blas it contains unsafe fn build_acceleration_structures( &mut self, descriptors: &[&BuildAccelerationStructureDescriptor], @@ -1352,13 +1359,17 @@ pub enum AccelerationStructureBuildMode { Update, } -#[derive(Clone, Debug, Default)] +/// Information of the required size for a corresponding entries struct (+ flags) +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] pub struct AccelerationStructureBuildSizes { pub acceleration_structure_size: wgt::BufferAddress, pub update_scratch_size: wgt::BufferAddress, pub build_scratch_size: wgt::BufferAddress, } +/// Updates use source_acceleration_structure if present, else the update will be performed in place. +/// For updates, only the data is allowed to change (not the meta data or sizes). +#[derive(Clone, Debug)] pub struct BuildAccelerationStructureDescriptor<'a, A: Api> { pub entries: &'a AccelerationStructureEntries<'a, A>, pub mode: AccelerationStructureBuildMode, @@ -1368,25 +1379,32 @@ pub struct BuildAccelerationStructureDescriptor<'a, A: Api> { pub scratch_buffer: &'a A::Buffer, } +/// - All buffers, buffer addresses and offsets will be ignored. +/// - The build mode will be ignored. +/// - Reducing the amount of Instances, Triangle groups or AABB groups (or the number of Triangles/AABBs in corresponding groups), +/// may result in reduced size requirements. +/// - Any other change may result in a bigger or smaller size requirement. +#[derive(Clone, Debug)] pub struct GetAccelerationStructureBuildSizesDescriptor<'a, A: Api> { pub entries: &'a AccelerationStructureEntries<'a, A>, pub flags: AccelerationStructureBuildFlags, } -/// -/// Usage for buffer size requirements: -/// All Buffers, BufferAdresses and offsets will be ignored. -/// The build mode will be ignored. -/// Reducing the amount of Instances, Triangle groups or AABB groups (or the number of Trinagles/AABBs in coresponding groups), -/// may result in reduced size requirements. -/// Any other change may result in a bigger or smaller size requirement. +/// Entries for a single descriptor +/// * `Instances` - Multiple instances for a top level acceleration structure +/// * `Triangles` - Multiple triangle meshes for a bottom level acceleration structure +/// * `AABBs` - List of list of axis aligned bounding boxes for a bottom level acceleration structure +#[derive(Debug)] pub enum AccelerationStructureEntries<'a, A: Api> { Instances(AccelerationStructureInstances<'a, A>), Triangles(&'a [AccelerationStructureTriangles<'a, A>]), AABBs(&'a [AccelerationStructureAABBs<'a, A>]), } -// TODO: flags +/// * `first_vertex` - offset in the vertex buffer (as number of vertices) +/// * `indices` - optional index buffer with attributes +/// * `transform` - optional transform +#[derive(Clone, Debug)] pub struct AccelerationStructureTriangles<'a, A: Api> { pub vertex_buffer: Option<&'a A::Buffer>, pub vertex_format: wgt::VertexFormat, @@ -1394,11 +1412,12 @@ pub struct AccelerationStructureTriangles<'a, A: Api> { pub vertex_count: u32, pub vertex_stride: wgt::BufferAddress, pub indices: Option>, - pub transforms: Option>, + pub transform: Option>, pub flags: AccelerationStructureGeometryFlags, } -// TODO: * +/// * `offset` - offset in bytes +#[derive(Clone, Debug)] pub struct AccelerationStructureAABBs<'a, A: Api> { pub buffer: Option<&'a A::Buffer>, pub offset: u32, @@ -1407,13 +1426,16 @@ pub struct AccelerationStructureAABBs<'a, A: Api> { pub flags: AccelerationStructureGeometryFlags, } -// TODO: offset +/// * `offset` - offset in bytes +#[derive(Clone, Debug)] pub struct AccelerationStructureInstances<'a, A: Api> { pub buffer: Option<&'a A::Buffer>, pub offset: u32, pub count: u32, } +/// * `offset` - offset in bytes +#[derive(Clone, Debug)] pub struct AccelerationStructureTriangleIndices<'a, A: Api> { pub format: wgt::IndexFormat, pub buffer: Option<&'a A::Buffer>, @@ -1421,17 +1443,25 @@ pub struct AccelerationStructureTriangleIndices<'a, A: Api> { pub count: u32, } -pub struct AccelerationStructureTriangleTransforms<'a, A: Api> { +/// * `offset` - offset in bytes +#[derive(Clone, Debug)] +pub struct AccelerationStructureTriangleTransform<'a, A: Api> { pub buffer: &'a A::Buffer, pub offset: u32, } bitflags!( + /// Flags for acceleration structures pub struct AccelerationStructureBuildFlags: u32 { + /// Allow for incremental updates (no change in size) const ALLOW_UPDATE = 1 << 0; + /// Allow the acceleration structure to be compacted in a copy operation const ALLOW_COMPACTION = 1 << 1; + /// Optimize for fast ray tracing performance const PREFER_FAST_TRACE = 1 << 2; + /// Optimize for fast build time const PREFER_FAST_BUILD = 1 << 3; + /// Optimize for low memory footprint (scratch and output) const LOW_MEMORY = 1 << 4; } ); diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index f269f5b0c0..0c7833cb5a 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -464,7 +464,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .first_vertex(triangles.first_vertex); } - if let Some(ref transform) = triangles.transforms { + if let Some(ref transform) = triangles.transform { let transform_device_address = unsafe { ray_tracing_functions .buffer_device_address @@ -558,7 +558,7 @@ impl crate::CommandEncoder for super::CommandEncoder { if desc.mode == crate::AccelerationStructureBuildMode::Update { geometry_info.src_acceleration_structure = desc .source_acceleration_structure - .expect("Acceleration tructure update: source structure required") + .unwrap_or(desc.destination_acceleration_structure) .raw; } diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 6bd79e2f33..a54ac12f3e 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -2080,12 +2080,17 @@ impl crate::Device for super::Device { instances: instance_data, }); - (smallvec::smallvec![*geometry], smallvec::smallvec![instances.count]) + ( + smallvec::smallvec![*geometry], + smallvec::smallvec![instances.count], + ) } crate::AccelerationStructureEntries::Triangles(in_geometries) => { - let mut primitive_counts = smallvec::SmallVec::<[u32;CAPACITY]>::with_capacity(in_geometries.len()); - let mut geometries = - smallvec::SmallVec::<[vk::AccelerationStructureGeometryKHR;CAPACITY]>::with_capacity(in_geometries.len()); + let mut primitive_counts = + smallvec::SmallVec::<[u32; CAPACITY]>::with_capacity(in_geometries.len()); + let mut geometries = smallvec::SmallVec::< + [vk::AccelerationStructureGeometryKHR; CAPACITY], + >::with_capacity(in_geometries.len()); for triangles in in_geometries { let mut triangle_data = @@ -2117,9 +2122,11 @@ impl crate::Device for super::Device { (geometries, primitive_counts) } crate::AccelerationStructureEntries::AABBs(in_geometries) => { - let mut primitive_counts = smallvec::SmallVec::<[u32;CAPACITY]>::with_capacity(in_geometries.len()); - let mut geometries = - smallvec::SmallVec::<[vk::AccelerationStructureGeometryKHR;CAPACITY]>::with_capacity(in_geometries.len()); + let mut primitive_counts = + smallvec::SmallVec::<[u32; CAPACITY]>::with_capacity(in_geometries.len()); + let mut geometries = smallvec::SmallVec::< + [vk::AccelerationStructureGeometryKHR; CAPACITY], + >::with_capacity(in_geometries.len()); for aabb in in_geometries { let aabbs_data = vk::AccelerationStructureGeometryAabbsDataKHR::builder() .stride(aabb.stride); From c1dc803e29855a12d898d6dc4ec2c0758e4aa08a Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sun, 19 Mar 2023 17:53:21 +0100 Subject: [PATCH 027/146] added to changelog --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e209fc8541..45ba0ca539 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -88,6 +88,20 @@ By @teoxoy in [#3534](https://github.com/gfx-rs/wgpu/pull/3534) - All `fxhash` dependencies have been replaced with `rustc-hash`. By @james7132 in [#3502](https://github.com/gfx-rs/wgpu/pull/3502) - Change type of `bytes_per_row` and `rows_per_image` (members of `ImageDataLayout`) from `Option` to `Option`. By @teoxoy in [#3529](https://github.com/gfx-rs/wgpu/pull/3529) +### Added/New Features + +#### General +- Added feature flags for ray-tracing (currently only hal): `RAY_QUERY` and `RAY_TRACING` @daniel-keitel (started by @expenses) in [#3507](https://github.com/gfx-rs/wgpu/pull/3507) + +#### Vulkan + +- Implemented basic ray-tracing api for acceleration structures, and ray-queries @daniel-keitel (started by @expenses) in [#3507](https://github.com/gfx-rs/wgpu/pull/3507) + +#### Hal + +- Added basic ray-tracing api for acceleration structures, and ray-queries @daniel-keitel (started by @expenses) in [#3507](https://github.com/gfx-rs/wgpu/pull/3507) + + ### Changes #### General From 9c67400d3b0ce4ab71dadd75e51839fed5bf2509 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 20 Mar 2023 17:00:10 +0100 Subject: [PATCH 028/146] typo Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com> --- wgpu-hal/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 785544b557..092ab133bd 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -571,7 +571,7 @@ pub trait CommandEncoder: Send + Sync + fmt::Debug { /// To get the required sizes for the buffer allocations use `get_acceleration_structure_build_sizes` per descriptor /// All buffers must be synchronized externally /// All buffer regions, which are written to may only be passed once per function call, - /// with the exertion of updates in the same descriptor. + /// with the exception of updates in the same descriptor. /// Consequences of this limitation: /// - scratch buffers need to be unique /// - a tlas can't be build in the same call with a blas it contains From c931edf8c124cc7555f26095838d3f90fc1af2f3 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 27 Mar 2023 04:46:38 +0200 Subject: [PATCH 029/146] create_blas create_tlas --- wgpu-core/src/device/mod.rs | 122 ++++++++++++++++++++++++++++++++++++ wgpu-core/src/hub.rs | 16 ++++- wgpu-core/src/id.rs | 4 ++ wgpu-core/src/resource.rs | 51 +++++++++++++++ wgpu-types/src/lib.rs | 100 +++++++++++++++++++++++++++++ wgpu/src/backend/direct.rs | 79 +++++++++++++++++++++++ wgpu/src/context.rs | 70 ++++++++++++++++++--- wgpu/src/lib.rs | 74 ++++++++++++++++++++++ 8 files changed, 507 insertions(+), 9 deletions(-) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index c29dcc9639..c6f5c4aa82 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -3313,6 +3313,44 @@ impl Device { desc: desc.map_label(|_| ()), }) } + + fn create_blas( + &self, + self_id: id::DeviceId, + desc: &resource::BlasDescriptor, + ) -> Result, resource::CreateBlasError> { + debug_assert_eq!(self_id.backend(), A::VARIANT); + + // TODO + + Ok(resource::Blas { + raw: None, + device_id: Stored { + value: id::Valid(self_id), + ref_count: self.life_guard.add_ref(), + }, + life_guard: LifeGuard::new(desc.label.borrow_or_default()), + }) + } + + fn create_tlas( + &self, + self_id: id::DeviceId, + desc: &resource::TlasDescriptor, + ) -> Result, resource::CreateTlasError> { + debug_assert_eq!(self_id.backend(), A::VARIANT); + + // TODO + + Ok(resource::Tlas { + raw: None, + device_id: Stored { + value: id::Valid(self_id), + ref_count: self.life_guard.add_ref(), + }, + life_guard: LifeGuard::new(desc.label.borrow_or_default()), + }) + } } impl Device { @@ -6064,4 +6102,88 @@ impl Global { } Ok(()) } + + pub fn device_create_blas( + &self, + device_id: id::DeviceId, + desc: &resource::BlasDescriptor, + id_in: Input, + ) -> (id::BlasId, Option) { + profiling::scope!("Device::create_blas"); + + let hub = A::hub(self); + let mut token = Token::root(); + let fid = hub.blas_s.prepare(id_in); + + let (device_guard, mut token) = hub.devices.read(&mut token); + let error = loop { + let device = match device_guard.get(device_id) { + Ok(device) => device, + Err(_) => break DeviceError::Invalid.into(), + }; + // #[cfg(feature = "trace")] + // if let Some(ref trace) = device.trace { + // let mut desc = desc.clone(); + // trace + // .lock() + // .add(trace::Action::CreateBlas(fid.id(), desc)); + // } + + let mut blas = match device.create_blas(device_id, desc) { + Ok(blas) => blas, + Err(e) => break e, + }; + let ref_count = blas.life_guard.add_ref(); + + let id = fid.assign(blas, &mut token); + log::info!("Created blas {:?} with {:?}", id, desc); + + return (id.0, None); + }; + + let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); + (id, Some(error)) + } + + pub fn device_create_tlas( + &self, + device_id: id::DeviceId, + desc: &resource::TlasDescriptor, + id_in: Input, + ) -> (id::TlasId, Option) { + profiling::scope!("Device::create_tlas"); + + let hub = A::hub(self); + let mut token = Token::root(); + let fid = hub.tlas_s.prepare(id_in); + + let (device_guard, mut token) = hub.devices.read(&mut token); + let error = loop { + let device = match device_guard.get(device_id) { + Ok(device) => device, + Err(_) => break DeviceError::Invalid.into(), + }; + // #[cfg(feature = "trace")] + // if let Some(ref trace) = device.trace { + // let mut desc = desc.clone(); + // trace + // .lock() + // .add(trace::Action::CreateTlas(fid.id(), desc)); + // } + + let mut tlas = match device.create_tlas(device_id, desc) { + Ok(tlas) => tlas, + Err(e) => break e, + }; + let ref_count = tlas.life_guard.add_ref(); + + let id = fid.assign(tlas, &mut token); + log::info!("Created blas {:?} with {:?}", id, desc); + + return (id.0, None); + }; + + let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); + (id, Some(error)) + } } diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 655a47ad18..7af6ba45ff 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -156,7 +156,10 @@ use crate::{ id, instance::{Adapter, HalSurface, Instance, Surface}, pipeline::{ComputePipeline, RenderPipeline, ShaderModule}, - resource::{Buffer, QuerySet, Sampler, StagingBuffer, Texture, TextureClearMode, TextureView}, + resource::{ + Blas, Buffer, QuerySet, Sampler, StagingBuffer, Texture, TextureClearMode, TextureView, + Tlas, + }, Epoch, Index, }; @@ -538,6 +541,11 @@ impl Access> for Root {} impl Access> for Device {} impl Access> for TextureView {} +impl Access> for Root {} +impl Access> for Device {} +impl Access> for Root {} +impl Access> for Device {} + #[cfg(debug_assertions)] thread_local! { static ACTIVE_TOKEN: Cell = Cell::new(0); @@ -668,6 +676,8 @@ pub trait GlobalIdentityHandlerFactory: + IdentityHandlerFactory + IdentityHandlerFactory + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory { } @@ -855,6 +865,8 @@ pub struct Hub { pub textures: Registry, id::TextureId, F>, pub texture_views: Registry, id::TextureViewId, F>, pub samplers: Registry, id::SamplerId, F>, + pub blas_s: Registry, id::BlasId, F>, + pub tlas_s: Registry, id::TlasId, F>, } impl Hub { @@ -876,6 +888,8 @@ impl Hub { textures: Registry::new(A::VARIANT, factory), texture_views: Registry::new(A::VARIANT, factory), samplers: Registry::new(A::VARIANT, factory), + blas_s: Registry::new(A::VARIANT, factory), + tlas_s: Registry::new(A::VARIANT, factory), } } diff --git a/wgpu-core/src/id.rs b/wgpu-core/src/id.rs index 9c654e3ca9..3528a7460e 100644 --- a/wgpu-core/src/id.rs +++ b/wgpu-core/src/id.rs @@ -229,6 +229,10 @@ pub type RenderBundleEncoderId = *mut crate::command::RenderBundleEncoder; pub type RenderBundleId = Id>; pub type QuerySetId = Id>; +// Ray tracing +pub type BlasId = Id>; +pub type TlasId = Id>; + #[test] fn test_id_backend() { for &b in &[ diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 9dbf1b3357..b96611a47a 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -795,3 +795,54 @@ pub enum DestroyError { #[error("Resource is already destroyed")] AlreadyDestroyed, } + +pub type BlasDescriptor<'a> = wgt::CreateBlasDescriptor>; +pub type TlasDescriptor<'a> = wgt::CreateTlasDescriptor>; + +pub struct Blas { + pub(crate) raw: Option, + pub(crate) device_id: Stored, + pub(crate) life_guard: LifeGuard, +} + +impl Resource for Blas { + const TYPE: &'static str = "Blas"; + + fn life_guard(&self) -> &LifeGuard { + &self.life_guard + } +} + +pub struct Tlas { + pub(crate) raw: Option, + pub(crate) device_id: Stored, + pub(crate) life_guard: LifeGuard, +} + +impl Resource for Tlas { + const TYPE: &'static str = "Tlas"; + + fn life_guard(&self) -> &LifeGuard { + &self.life_guard + } +} + +#[derive(Clone, Debug, Error)] +pub enum CreateBlasError { + #[error(transparent)] + Device(#[from] DeviceError), + #[error(transparent)] + CreateBufferError(#[from] CreateBufferError), + #[error("Unimplemented Blas error: this error is not yet implemented")] + Unimplemented, +} + +#[derive(Clone, Debug, Error)] +pub enum CreateTlasError { + #[error(transparent)] + Device(#[from] DeviceError), + #[error(transparent)] + CreateBufferError(#[from] CreateBufferError), + #[error("Unimplemented Tlas error: this error is not yet implemented")] + Unimplemented, +} diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 9d6236766c..f1b0cf12b3 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6162,3 +6162,103 @@ impl Default for InstanceDescriptor { } } } + +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +pub struct BlasTriangleGeometrySizeDescriptor { + pub vertex_format: VertexFormat, + pub vertex_count: u32, + pub index_format: Option, + pub index_count: Option, + pub flags: AccelerationStructureGeometryFlags, +} + +#[derive(Clone, Debug)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +pub enum BlasGeometrySizeDescriptors { + Triangles { + desc: Vec, + }, +} + +#[repr(u8)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +pub enum AccelerationStructureUpdateMode { + Build, + PreferUpdate, +} + +#[repr(C)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "trace", derive(Serialize))] +#[cfg_attr(feature = "replay", derive(Deserialize))] +pub struct CreateBlasDescriptor { + pub label: L, + pub flags: AccelerationStructureFlags, + pub update_mode: AccelerationStructureUpdateMode, +} + +impl CreateBlasDescriptor { + /// Takes a closure and maps the label of the blas descriptor into another. + pub fn map_label(&self, fun: impl FnOnce(&L) -> K) -> CreateBlasDescriptor { + CreateBlasDescriptor { + label: fun(&self.label), + flags: self.flags, + update_mode: self.update_mode, + } + } +} + +#[repr(C)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "trace", derive(Serialize))] +#[cfg_attr(feature = "replay", derive(Deserialize))] +pub struct CreateTlasDescriptor { + pub label: L, + pub max_instances: u32, + pub flags: AccelerationStructureFlags, + pub update_mode: AccelerationStructureUpdateMode, +} + +impl CreateTlasDescriptor { + /// Takes a closure and maps the label of the blas descriptor into another. + pub fn map_label(&self, fun: impl FnOnce(&L) -> K) -> CreateTlasDescriptor { + CreateTlasDescriptor { + label: fun(&self.label), + flags: self.flags, + update_mode: self.update_mode, + max_instances: self.max_instances, + } + } +} + +// Todo let hal use these directly +bitflags::bitflags!( + /// Flags for acceleration structures + pub struct AccelerationStructureFlags: u8 { + /// Allow for incremental updates (no change in size) + const ALLOW_UPDATE = 1 << 0; + /// Allow the acceleration structure to be compacted in a copy operation + const ALLOW_COMPACTION = 1 << 1; + /// Optimize for fast ray tracing performance + const PREFER_FAST_TRACE = 1 << 2; + /// Optimize for fast build time + const PREFER_FAST_BUILD = 1 << 3; + /// Optimize for low memory footprint (scratch and output) + const LOW_MEMORY = 1 << 4; + } +); +impl_bitflags!(AccelerationStructureFlags); + +// Todo let hal use these directly +bitflags::bitflags!( + pub struct AccelerationStructureGeometryFlags: u8 { + const OPAQUE = 1 << 0; + const NO_DUPLICATE_ANY_HIT_INVOCATION = 1 << 1; + } +); +impl_bitflags!(AccelerationStructureGeometryFlags); diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 1b688b14a9..5d1c486da6 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -470,6 +470,16 @@ pub struct CommandEncoder { open: bool, } +#[derive(Debug)] +pub struct Blas { + error_sink: ErrorSink, +} + +#[derive(Debug)] +pub struct Tlas { + error_sink: ErrorSink, +} + impl crate::Context for Context { type AdapterId = wgc::id::AdapterId; type AdapterData = (); @@ -520,6 +530,11 @@ impl crate::Context for Context { type RequestAdapterFuture = Ready>; + type BlasId = wgc::id::BlasId; + type BlasData = Blas; + type TlasId = wgc::id::TlasId; + type TlasData = Tlas; + #[allow(clippy::type_complexity)] type RequestDeviceFuture = Ready< Result< @@ -2936,6 +2951,70 @@ impl crate::Context for Context { ) } } + + fn device_create_blas( + &self, + device: &Self::DeviceId, + device_data: &Self::DeviceData, + desc: &crate::CreateBlasDescriptor<'_>, + ) -> (Self::BlasId, Self::BlasData) { + let global = &self.0; + let (id, error) = wgc::gfx_select!(device => global.device_create_blas( + *device, + &desc.map_label(|l| l.map(Borrowed)), + () + )); + if let Some(cause) = error { + self.handle_error( + &device_data.error_sink, + cause, + LABEL, + desc.label, + "Device::create_blas", + ); + } + let x: Self::BufferData = Buffer { + error_sink: Arc::clone(&device_data.error_sink), + }; + let x: Self::BlasData = Blas { + error_sink: Arc::clone(&device_data.error_sink), + }; + ( + id, + Blas { + error_sink: Arc::clone(&device_data.error_sink), + }, + ) + } + + fn device_create_tlas( + &self, + device: &Self::DeviceId, + device_data: &Self::DeviceData, + desc: &crate::CreateTlasDescriptor<'_>, + ) -> (Self::TlasId, Self::TlasData) { + let global = &self.0; + let (id, error) = wgc::gfx_select!(device => global.device_create_tlas( + *device, + &desc.map_label(|l| l.map(Borrowed)), + () + )); + if let Some(cause) = error { + self.handle_error( + &device_data.error_sink, + cause, + LABEL, + desc.label, + "Device::create_blas", + ); + } + ( + id, + Tlas { + error_sink: Arc::clone(&device_data.error_sink), + }, + ) + } } impl From for wgc::id::Id { diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 92b85a9a04..0b4f32cd8c 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -8,14 +8,14 @@ use wgt::{ }; use crate::{ - BindGroupDescriptor, BindGroupLayoutDescriptor, Buffer, BufferAsyncError, BufferDescriptor, - CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, DeviceDescriptor, - Error, ErrorFilter, ImageCopyBuffer, ImageCopyTexture, Maintain, MapMode, - PipelineLayoutDescriptor, QuerySetDescriptor, RenderBundleDescriptor, - RenderBundleEncoderDescriptor, RenderPassDescriptor, RenderPipelineDescriptor, - RequestAdapterOptions, RequestDeviceError, SamplerDescriptor, ShaderModuleDescriptor, - ShaderModuleDescriptorSpirV, Texture, TextureDescriptor, TextureViewDescriptor, - UncapturedErrorHandler, + BindGroupDescriptor, BindGroupLayoutDescriptor, Blas, Buffer, BufferAsyncError, + BufferDescriptor, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, + CreateBlasDescriptor, CreateTlasDescriptor, DeviceDescriptor, Error, ErrorFilter, + ImageCopyBuffer, ImageCopyTexture, Maintain, MapMode, PipelineLayoutDescriptor, + QuerySetDescriptor, RenderBundleDescriptor, RenderBundleEncoderDescriptor, + RenderPassDescriptor, RenderPipelineDescriptor, RequestAdapterOptions, RequestDeviceError, + SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, Texture, + TextureDescriptor, TextureViewDescriptor, Tlas, UncapturedErrorHandler, }; /// Meta trait for an id tracked by a context. @@ -74,6 +74,11 @@ pub trait Context: Debug + Send + Sized + Sync { type SurfaceId: ContextId + Send + Sync; type SurfaceData: ContextData; + type BlasId: ContextId + Send + Sync; + type BlasData: ContextData; + type TlasId: ContextId + Send + Sync; + type TlasData: ContextData; + type SurfaceOutputDetail: Send + Sync + 'static; type SubmissionIndex: ContextId + Clone + Copy + Send + Sync; type SubmissionIndexData: ContextData + Copy; @@ -989,6 +994,19 @@ pub trait Context: Debug + Send + Sized + Sync { pass_data: &mut Self::RenderPassData, render_bundles: Box + 'a>, ); + + fn device_create_blas( + &self, + device: &Self::DeviceId, + device_data: &Self::DeviceData, + desc: &CreateBlasDescriptor, + ) -> (Self::BlasId, Self::BlasData); + fn device_create_tlas( + &self, + device: &Self::DeviceId, + device_data: &Self::DeviceData, + desc: &CreateTlasDescriptor, + ) -> (Self::TlasId, Self::TlasData); } /// Object id. @@ -1904,6 +1922,18 @@ pub(crate) trait DynContext: Debug + Send + Sync { pass_data: &mut crate::Data, render_bundles: Box + 'a>, ); + fn device_create_blas( + &self, + device: &ObjectId, + device_data: &crate::Data, + desc: &crate::CreateBlasDescriptor, + ) -> (ObjectId, Box); + fn device_create_tlas( + &self, + device: &ObjectId, + device_data: &crate::Data, + desc: &crate::CreateTlasDescriptor, + ) -> (ObjectId, Box); } // Blanket impl of DynContext for all types which implement Context. @@ -3854,6 +3884,30 @@ where ); Context::render_pass_execute_bundles(self, &mut pass, pass_data, render_bundles) } + + fn device_create_blas( + &self, + device: &ObjectId, + device_data: &crate::Data, + desc: &crate::CreateBlasDescriptor, + ) -> (ObjectId, Box) { + let device = ::from(*device); + let device_data = downcast_ref(device_data); + let (blas, data) = Context::device_create_blas(self, &device, device_data, desc); + (blas.into(), Box::new(data) as _) + } + + fn device_create_tlas( + &self, + device: &ObjectId, + device_data: &crate::Data, + desc: &crate::CreateTlasDescriptor, + ) -> (ObjectId, Box) { + let device = ::from(*device); + let device_data = downcast_ref(device_data); + let (tlas, data) = Context::device_create_tlas(self, &device, device_data, desc); + (tlas.into(), Box::new(data) as _) + } } pub trait QueueWriteBuffer: Send + Sync { diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index ee92091f01..731b299d1c 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -2243,6 +2243,30 @@ impl Device { DynContext::device_stop_capture(&*self.context, &self.id, self.data.as_ref()) } + /// Creates a [`Blas`]. + pub fn create_blas(&self, desc: &CreateBlasDescriptor) -> Blas { + let (id, data) = + DynContext::device_create_blas(&*self.context, &self.id, self.data.as_ref(), desc); + + Blas { + context: Arc::clone(&self.context), + id, + data, + } + } + + /// Creates a [`Blas`]. + pub fn create_tlas(&self, desc: &CreateTlasDescriptor) -> Blas { + let (id, data) = + DynContext::device_create_tlas(&*self.context, &self.id, self.data.as_ref(), desc); + + Blas { + context: Arc::clone(&self.context), + id, + data, + } + } + /// Apply a callback to this `Device`'s underlying backend device. /// /// If this `Device` is implemented by the backend API given by `A` (Vulkan, @@ -4477,3 +4501,53 @@ impl Display for Error { } } } + +pub type BlasTriangleGeometrySizeDescriptor = wgt::BlasTriangleGeometrySizeDescriptor; +static_assertions::assert_impl_all!(BlasTriangleGeometrySizeDescriptor: Send, Sync); + +pub type BlasGeometrySizeDescriptors = wgt::BlasGeometrySizeDescriptors; +static_assertions::assert_impl_all!(BlasGeometrySizeDescriptors: Send, Sync); + +pub type AccelerationStructureFlags = wgt::AccelerationStructureFlags; +static_assertions::assert_impl_all!(AccelerationStructureFlags: Send, Sync); + +pub type AccelerationStructureGeometryFlags = wgt::AccelerationStructureGeometryFlags; +static_assertions::assert_impl_all!(AccelerationStructureGeometryFlags: Send, Sync); + +pub type AccelerationStructureUpdateMode = wgt::AccelerationStructureUpdateMode; +static_assertions::assert_impl_all!(AccelerationStructureUpdateMode: Send, Sync); + +pub type CreateBlasDescriptor<'a> = wgt::CreateBlasDescriptor>; +static_assertions::assert_impl_all!(CreateBlasDescriptor: Send, Sync); + +pub type CreateTlasDescriptor<'a> = wgt::CreateTlasDescriptor>; +static_assertions::assert_impl_all!(CreateTlasDescriptor: Send, Sync); + +#[derive(Debug)] +pub struct BlasTriangleGeometry { + pub size: BlasTriangleGeometrySizeDescriptor, + 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, +} +static_assertions::assert_impl_all!(BlasTriangleGeometry: Send, Sync); + +#[derive(Debug)] +pub struct Blas { + context: Arc, + id: ObjectId, + data: Box, +} +static_assertions::assert_impl_all!(Blas: Send, Sync); + +#[derive(Debug)] +pub struct Tlas { + context: Arc, + id: ObjectId, + data: Box, +} +static_assertions::assert_impl_all!(Tlas: Send, Sync); From e3a7fc9a97d94acf7430bbab61ddc145c80e4422 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 27 Mar 2023 22:56:27 +0200 Subject: [PATCH 030/146] example skeleton --- api_spec.rs | 154 ++++++++++++ wgpu/examples/hello-ray-triangle/README.md | 9 + wgpu/examples/hello-ray-triangle/blit.wgsl | 52 ++++ wgpu/examples/hello-ray-triangle/main.rs | 247 +++++++++++++++++++ wgpu/examples/hello-ray-triangle/shader.wgsl | 23 ++ 5 files changed, 485 insertions(+) create mode 100644 api_spec.rs create mode 100644 wgpu/examples/hello-ray-triangle/README.md create mode 100644 wgpu/examples/hello-ray-triangle/blit.wgsl create mode 100644 wgpu/examples/hello-ray-triangle/main.rs create mode 100644 wgpu/examples/hello-ray-triangle/shader.wgsl diff --git a/api_spec.rs b/api_spec.rs new file mode 100644 index 0000000000..dbf3979795 --- /dev/null +++ b/api_spec.rs @@ -0,0 +1,154 @@ +// 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/wgpu/examples/hello-ray-triangle/README.md b/wgpu/examples/hello-ray-triangle/README.md new file mode 100644 index 0000000000..6efb0ebcec --- /dev/null +++ b/wgpu/examples/hello-ray-triangle/README.md @@ -0,0 +1,9 @@ +# hello-triangle + +This example renders a triangle to a window with a ray query. + +## To Run + +``` +cargo run --example hello-ray-triangle +``` \ No newline at end of file diff --git a/wgpu/examples/hello-ray-triangle/blit.wgsl b/wgpu/examples/hello-ray-triangle/blit.wgsl new file mode 100644 index 0000000000..69adbb3ccd --- /dev/null +++ b/wgpu/examples/hello-ray-triangle/blit.wgsl @@ -0,0 +1,52 @@ +struct VertexOutput { + @builtin(position) position: vec4, + @location(0) tex_coords: vec2, +}; + +// meant to be called with 3 vertex indices: 0, 1, 2 +// draws one large triangle over the clip space like this: +// (the asterisks represent the clip space bounds) +//-1,1 1,1 +// --------------------------------- +// | * . +// | * . +// | * . +// | * . +// | * . +// | * . +// |*************** +// | . 1,-1 +// | . +// | . +// | . +// | . +// |. +@vertex +fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput { + var result: VertexOutput; + let x = i32(vertex_index) / 2; + let y = i32(vertex_index) & 1; + let tc = vec2( + f32(x) * 2.0, + f32(y) * 2.0 + ); + result.position = vec4( + tc.x * 2.0 - 1.0, + 1.0 - tc.y * 2.0, + 0.0, 1.0 + ); + result.tex_coords = tc; + return result; +} + +@group(0) +@binding(0) +var r_color: texture_2d; +@group(0) +@binding(1) +var r_sampler: sampler; + +@fragment +fn fs_main(vertex: VertexOutput) -> @location(0) vec4 { + return textureSample(r_color, r_sampler, vertex.tex_coords); +} diff --git a/wgpu/examples/hello-ray-triangle/main.rs b/wgpu/examples/hello-ray-triangle/main.rs new file mode 100644 index 0000000000..175071b194 --- /dev/null +++ b/wgpu/examples/hello-ray-triangle/main.rs @@ -0,0 +1,247 @@ +use std::{borrow::Cow, num::NonZeroU32}; +use winit::{ + dpi::{LogicalSize, PhysicalPosition}, + event::{Event, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::Window, +}; + +async fn run(event_loop: EventLoop<()>, window: Window) { + let size = window.inner_size(); + + let instance = wgpu::Instance::default(); + + let surface = unsafe { instance.create_surface(&window) }.unwrap(); + let adapter = instance + .request_adapter(&wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::default(), + force_fallback_adapter: false, + // Request an adapter which can render to our surface + compatible_surface: Some(&surface), + }) + .await + .expect("Failed to find an appropriate adapter"); + + // Create the logical device and command queue + let (device, queue) = adapter + .request_device( + &wgpu::DeviceDescriptor { + label: None, + features: wgpu::Features::all_webgpu_mask() + | wgpu::Features::TEXTURE_BINDING_ARRAY + | wgpu::Features::STORAGE_RESOURCE_BINDING_ARRAY + | wgpu::Features::VERTEX_WRITABLE_STORAGE, + // Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain. + limits: wgpu::Limits::default(), + }, + None, + ) + .await + .expect("Failed to create device"); + + let swapchain_capabilities = surface.get_capabilities(&adapter); + let swapchain_format = swapchain_capabilities.formats[0]; + + let config = wgpu::SurfaceConfiguration { + usage: wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::RENDER_ATTACHMENT, + format: swapchain_format, + width: size.width, + height: size.height, + present_mode: wgpu::PresentMode::Fifo, + alpha_mode: swapchain_capabilities.alpha_modes[0], + view_formats: vec![], + }; + + surface.configure(&device, &config); + + let rt_target = device.create_texture(&wgpu::TextureDescriptor { + label: Some("rt_target"), + size: wgpu::Extent3d { + width: size.width, + height: size.height, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8Unorm, + usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::STORAGE_BINDING, + view_formats: &[wgpu::TextureFormat::Rgba8Unorm], + }); + + let rt_view = rt_target.create_view(&wgpu::TextureViewDescriptor { + label: None, + format: Some(wgpu::TextureFormat::Rgba8Unorm), + dimension: Some(wgpu::TextureViewDimension::D2), + aspect: wgpu::TextureAspect::All, + base_mip_level: 0, + mip_level_count: None, + base_array_layer: 0, + array_layer_count: None, + }); + + let sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("rt_sampler"), + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::FilterMode::Nearest, + ..Default::default() + }); + + // Load the shaders from disk + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("rt_computer"), + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), + }); + + let blit_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("blit"), + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("blit.wgsl"))), + }); + + let compute_pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: Some("rt"), + layout: None, + module: &shader, + entry_point: "main", + }); + + let compute_bind_group_layout = compute_pipeline.get_bind_group_layout(0); + + let compute_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &compute_bind_group_layout, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&rt_view), + }], + }); + + let blit_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("blit"), + layout: None, + vertex: wgpu::VertexState { + module: &blit_shader, + entry_point: "vs_main", + buffers: &[], + }, + fragment: Some(wgpu::FragmentState { + module: &blit_shader, + entry_point: "fs_main", + targets: &[Some(swapchain_format.into())], + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + ..Default::default() + }, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + multiview: None, + }); + + let blit_bind_group_layout = blit_pipeline.get_bind_group_layout(0); + + let blit_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &blit_bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&rt_view), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::Sampler(&sampler), + }, + ], + }); + + event_loop.run(move |event, _, control_flow| { + // Have the closure take ownership of the resources. + // `event_loop.run` never returns, therefore we must do this to ensure + // the resources are properly cleaned up. + let _ = ( + &instance, + &adapter, + &shader, + &blit_shader, + &compute_pipeline, + &blit_pipeline, + ); + + *control_flow = ControlFlow::Wait; + match event { + Event::WindowEvent { + event: WindowEvent::Resized(size), + .. + } => {} + Event::RedrawRequested(_) => { + let frame = surface + .get_current_texture() + .expect("Failed to acquire next swap chain texture"); + let view = frame + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut cpass = + encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None }); + cpass.set_pipeline(&compute_pipeline); + cpass.set_bind_group(0, &compute_bind_group, &[]); + cpass.dispatch_workgroups(rt_target.width() / 8, rt_target.height() / 8, 1); + } + + { + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), + store: true, + }, + })], + depth_stencil_attachment: None, + }); + rpass.set_pipeline(&blit_pipeline); + rpass.set_bind_group(0, &blit_bind_group, &[]); + rpass.draw(0..3, 0..1); + } + + queue.submit(Some(encoder.finish())); + frame.present(); + } + Event::WindowEvent { + event: WindowEvent::CloseRequested, + .. + } => *control_flow = ControlFlow::Exit, + _ => {} + } + }); +} + +fn main() { + let event_loop = EventLoop::new(); + let window = winit::window::Window::new(&event_loop).unwrap(); + window.set_inner_size(LogicalSize::new(600, 400)); + window.set_outer_position(PhysicalPosition::new(-1000, 0)); + window.set_resizable(false); + + #[cfg(not(target_arch = "wasm32"))] + { + env_logger::init(); + // Temporarily avoid srgb formats for the swapchain on the web + pollster::block_on(run(event_loop, window)); + } + #[cfg(target_arch = "wasm32")] + { + std::panic::set_hook(Box::new(console_error_panic_hook::hook)); + panic!("no wasm ray tracing support") + } +} diff --git a/wgpu/examples/hello-ray-triangle/shader.wgsl b/wgpu/examples/hello-ray-triangle/shader.wgsl new file mode 100644 index 0000000000..b3492eb981 --- /dev/null +++ b/wgpu/examples/hello-ray-triangle/shader.wgsl @@ -0,0 +1,23 @@ +// const MAX_BOUNCES: i32 = 3; + +// struct Parameters { +// cam_position: vec3, +// depth: f32, +// cam_orientation: vec4, +// fov: vec2, +// torus_radius: f32, +// rotation_angle: f32, +// }; + +// var parameters: Parameters; +// var acc_struct: acceleration_structure; +@group(0) @binding(0) +var output: texture_storage_2d; + + +@compute @workgroup_size(8, 8) +fn main(@builtin(global_invocation_id) global_id: vec3) { + let target_size = textureDimensions(output); + let color = vec4(vec2(global_id.xy) / vec2(target_size), 0.0, 0.0); + textureStore(output, global_id.xy, color); +} From e932040be07f252d110cf5a9146ee7b841c18ff9 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 27 Mar 2023 23:44:20 +0200 Subject: [PATCH 031/146] WIP --- wgpu-core/src/device/mod.rs | 4 +- wgpu-types/src/lib.rs | 5 +- wgpu/examples/hello-ray-triangle/main.rs | 108 ++++++++++++++++++++++- wgpu/src/backend/direct.rs | 2 + wgpu/src/context.rs | 5 +- wgpu/src/lib.rs | 15 +++- 6 files changed, 130 insertions(+), 9 deletions(-) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index c6f5c4aa82..547bde010a 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -3318,6 +3318,7 @@ impl Device { &self, self_id: id::DeviceId, desc: &resource::BlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, ) -> Result, resource::CreateBlasError> { debug_assert_eq!(self_id.backend(), A::VARIANT); @@ -6107,6 +6108,7 @@ impl Global { &self, device_id: id::DeviceId, desc: &resource::BlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, id_in: Input, ) -> (id::BlasId, Option) { profiling::scope!("Device::create_blas"); @@ -6129,7 +6131,7 @@ impl Global { // .add(trace::Action::CreateBlas(fid.id(), desc)); // } - let mut blas = match device.create_blas(device_id, desc) { + let mut blas = match device.create_blas(device_id, desc, sizes) { Ok(blas) => blas, Err(e) => break e, }; diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index f1b0cf12b3..dcf9d209d3 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6236,7 +6236,6 @@ impl CreateTlasDescriptor { } } -// Todo let hal use these directly bitflags::bitflags!( /// Flags for acceleration structures pub struct AccelerationStructureFlags: u8 { @@ -6254,10 +6253,12 @@ bitflags::bitflags!( ); impl_bitflags!(AccelerationStructureFlags); -// Todo let hal use these directly bitflags::bitflags!( + /// Flags for acceleration structure geometries pub struct AccelerationStructureGeometryFlags: u8 { + /// Is OPAQUE const OPAQUE = 1 << 0; + /// NO_DUPLICATE_ANY_HIT_INVOCATION const NO_DUPLICATE_ANY_HIT_INVOCATION = 1 << 1; } ); diff --git a/wgpu/examples/hello-ray-triangle/main.rs b/wgpu/examples/hello-ray-triangle/main.rs index 175071b194..6799ef8e08 100644 --- a/wgpu/examples/hello-ray-triangle/main.rs +++ b/wgpu/examples/hello-ray-triangle/main.rs @@ -1,4 +1,6 @@ -use std::{borrow::Cow, num::NonZeroU32}; +use bytemuck::{Pod, Zeroable}; +use std::{borrow::Cow, mem, num::NonZeroU32}; +use wgpu::util::DeviceExt; use winit::{ dpi::{LogicalSize, PhysicalPosition}, event::{Event, WindowEvent}, @@ -6,6 +8,67 @@ use winit::{ window::Window, }; +// from cube +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +struct Vertex { + _pos: [f32; 4], + _tex_coord: [f32; 2], +} + +fn vertex(pos: [i8; 3], tc: [i8; 2]) -> Vertex { + Vertex { + _pos: [pos[0] as f32, pos[1] as f32, pos[2] as f32, 1.0], + _tex_coord: [tc[0] as f32, tc[1] as f32], + } +} + +fn create_vertices() -> (Vec, Vec) { + let vertex_data = [ + // top (0, 0, 1) + vertex([-1, -1, 1], [0, 0]), + vertex([1, -1, 1], [1, 0]), + vertex([1, 1, 1], [1, 1]), + vertex([-1, 1, 1], [0, 1]), + // bottom (0, 0, -1) + vertex([-1, 1, -1], [1, 0]), + vertex([1, 1, -1], [0, 0]), + vertex([1, -1, -1], [0, 1]), + vertex([-1, -1, -1], [1, 1]), + // right (1, 0, 0) + vertex([1, -1, -1], [0, 0]), + vertex([1, 1, -1], [1, 0]), + vertex([1, 1, 1], [1, 1]), + vertex([1, -1, 1], [0, 1]), + // left (-1, 0, 0) + vertex([-1, -1, 1], [1, 0]), + vertex([-1, 1, 1], [0, 0]), + vertex([-1, 1, -1], [0, 1]), + vertex([-1, -1, -1], [1, 1]), + // front (0, 1, 0) + vertex([1, 1, -1], [1, 0]), + vertex([-1, 1, -1], [0, 0]), + vertex([-1, 1, 1], [0, 1]), + vertex([1, 1, 1], [1, 1]), + // back (0, -1, 0) + vertex([1, -1, 1], [0, 0]), + vertex([-1, -1, 1], [1, 0]), + vertex([-1, -1, -1], [1, 1]), + vertex([1, -1, -1], [0, 1]), + ]; + + let index_data: &[u16] = &[ + 0, 1, 2, 2, 3, 0, // top + 4, 5, 6, 6, 7, 4, // bottom + 8, 9, 10, 10, 11, 8, // right + 12, 13, 14, 14, 15, 12, // left + 16, 17, 18, 18, 19, 16, // front + 20, 21, 22, 22, 23, 20, // back + ]; + + (vertex_data.to_vec(), index_data.to_vec()) +} + async fn run(event_loop: EventLoop<()>, window: Window) { let size = window.inner_size(); @@ -91,7 +154,48 @@ async fn run(event_loop: EventLoop<()>, window: Window) { ..Default::default() }); - // Load the shaders from disk + // Create the vertex and index buffers + let vertex_size = mem::size_of::(); + let (vertex_data, index_data) = create_vertices(); + + let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(&vertex_data), + usage: wgpu::BufferUsages::VERTEX, + }); + + let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(&index_data), + usage: wgpu::BufferUsages::INDEX, + }); + + let blas_geo_size_desc = wgpu::BlasTriangleGeometrySizeDescriptor { + vertex_format: wgpu::VertexFormat::Float32x4, + vertex_count: vertex_data.size(), + index_format: Some(wgpu::IndexFormat::Uint16), + index_count: Some(index_data.size()), + flags: wgpu::AccelerationStructureGeometryFlags::OPAQUE, + }; + + let blas = device.create_blas( + &wgpu::CreateBlasDescriptor { + label: None, + flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: wgpu::AccelerationStructureUpdateMode::Build, + }, + wgpu::BlasGeometrySizeDescriptors::Triangles { + desc: [blas_geo_size_desc.clone()], + }, + ); + + let tlas = device.create_tlas(&wgpu::CreateTlasDescriptor { + label: None, + flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: wgpu::AccelerationStructureUpdateMode::Build, + max_instances: 1, + }); + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("rt_computer"), source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 5d1c486da6..33bbb5862a 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -2957,11 +2957,13 @@ impl crate::Context for Context { device: &Self::DeviceId, device_data: &Self::DeviceData, desc: &crate::CreateBlasDescriptor<'_>, + sizes: wgt::BlasGeometrySizeDescriptors, ) -> (Self::BlasId, Self::BlasData) { let global = &self.0; let (id, error) = wgc::gfx_select!(device => global.device_create_blas( *device, &desc.map_label(|l| l.map(Borrowed)), + sizes, () )); if let Some(cause) = error { diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 0b4f32cd8c..ed2805cdf9 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -1000,6 +1000,7 @@ pub trait Context: Debug + Send + Sized + Sync { device: &Self::DeviceId, device_data: &Self::DeviceData, desc: &CreateBlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, ) -> (Self::BlasId, Self::BlasData); fn device_create_tlas( &self, @@ -1927,6 +1928,7 @@ pub(crate) trait DynContext: Debug + Send + Sync { device: &ObjectId, device_data: &crate::Data, desc: &crate::CreateBlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, ) -> (ObjectId, Box); fn device_create_tlas( &self, @@ -3890,10 +3892,11 @@ where device: &ObjectId, device_data: &crate::Data, desc: &crate::CreateBlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, ) -> (ObjectId, Box) { let device = ::from(*device); let device_data = downcast_ref(device_data); - let (blas, data) = Context::device_create_blas(self, &device, device_data, desc); + let (blas, data) = Context::device_create_blas(self, &device, device_data, desc, sizes); (blas.into(), Box::new(data) as _) } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 731b299d1c..d62fc332be 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -2244,9 +2244,18 @@ impl Device { } /// Creates a [`Blas`]. - pub fn create_blas(&self, desc: &CreateBlasDescriptor) -> Blas { - let (id, data) = - DynContext::device_create_blas(&*self.context, &self.id, self.data.as_ref(), desc); + pub fn create_blas( + &self, + desc: &CreateBlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, + ) -> Blas { + let (id, data) = DynContext::device_create_blas( + &*self.context, + &self.id, + self.data.as_ref(), + desc, + sizes, + ); Blas { context: Arc::clone(&self.context), From f5e94e79d9b78ad3aa67df364c1b0e4652a6f555 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 27 Mar 2023 23:46:51 +0200 Subject: [PATCH 032/146] moved flags to wgt --- wgpu-hal/src/lib.rs | 24 ++---------------------- wgpu-types/src/lib.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index f8d6c33202..7d32ccf09d 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -1453,25 +1453,5 @@ pub struct AccelerationStructureTriangleTransform<'a, A: Api> { pub offset: u32, } -bitflags!( - /// Flags for acceleration structures - pub struct AccelerationStructureBuildFlags: u32 { - /// Allow for incremental updates (no change in size) - const ALLOW_UPDATE = 1 << 0; - /// Allow the acceleration structure to be compacted in a copy operation - const ALLOW_COMPACTION = 1 << 1; - /// Optimize for fast ray tracing performance - const PREFER_FAST_TRACE = 1 << 2; - /// Optimize for fast build time - const PREFER_FAST_BUILD = 1 << 3; - /// Optimize for low memory footprint (scratch and output) - const LOW_MEMORY = 1 << 4; - } -); - -bitflags!( - pub struct AccelerationStructureGeometryFlags: u32 { - const OPAQUE = 1 << 0; - const NO_DUPLICATE_ANY_HIT_INVOCATION = 1 << 1; - } -); +pub type AccelerationStructureBuildFlags = wgt::AccelerationStructureFlags; +pub type AccelerationStructureGeometryFlags = wgt::AccelerationStructureGeometryFlags; \ No newline at end of file diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 9d6236766c..29bee8e1ed 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6162,3 +6162,31 @@ impl Default for InstanceDescriptor { } } } + +bitflags::bitflags!( + /// Flags for acceleration structures + pub struct AccelerationStructureFlags: u8 { + /// Allow for incremental updates (no change in size) + const ALLOW_UPDATE = 1 << 0; + /// Allow the acceleration structure to be compacted in a copy operation + const ALLOW_COMPACTION = 1 << 1; + /// Optimize for fast ray tracing performance + const PREFER_FAST_TRACE = 1 << 2; + /// Optimize for fast build time + const PREFER_FAST_BUILD = 1 << 3; + /// Optimize for low memory footprint (scratch and output) + const LOW_MEMORY = 1 << 4; + } +); +impl_bitflags!(AccelerationStructureFlags); + +bitflags::bitflags!( + /// Flags for acceleration structure geometries + pub struct AccelerationStructureGeometryFlags: u8 { + /// Is OPAQUE + const OPAQUE = 1 << 0; + /// NO_DUPLICATE_ANY_HIT_INVOCATION + const NO_DUPLICATE_ANY_HIT_INVOCATION = 1 << 1; + } +); +impl_bitflags!(AccelerationStructureGeometryFlags); \ No newline at end of file From 0b7e728398572653e54dad667239a99faf966235 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 27 Mar 2023 23:49:40 +0200 Subject: [PATCH 033/146] renamed feature RAY_TRACING to RAY_TRACING_ACCELERATION_STRUCTURE --- wgpu-hal/src/vulkan/adapter.rs | 4 ++-- wgpu-types/src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 4b1a5b1388..d7252760e8 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -570,7 +570,7 @@ impl PhysicalDeviceFeatures { features.set(F::DEPTH32FLOAT_STENCIL8, texture_d32_s8); features.set( - F::RAY_TRACING, + F::RAY_TRACING_ACCELERATION_STRUCTURE, caps.supports_extension(vk::KhrDeferredHostOperationsFn::name()) && caps.supports_extension(vk::KhrAccelerationStructureFn::name()) && caps.supports_extension(vk::KhrBufferDeviceAddressFn::name()), @@ -741,7 +741,7 @@ impl PhysicalDeviceCapabilities { } // Require `VK_KHR_deferred_host_operations`, `VK_KHR_acceleration_structure` and `VK_KHR_buffer_device_address` if the feature `RAY_TRACING` was requested - if requested_features.contains(wgt::Features::RAY_TRACING) { + if requested_features.contains(wgt::Features::RAY_TRACING_ACCELERATION_STRUCTURE) { extensions.push(vk::KhrDeferredHostOperationsFn::name()); extensions.push(vk::KhrAccelerationStructureFn::name()); extensions.push(vk::KhrBufferDeviceAddressFn::name()); diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 29bee8e1ed..9407018fe3 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -708,7 +708,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native-only feature. - const RAY_TRACING = 1 << 54; + const RAY_TRACING_ACCELERATION_STRUCTURE = 1 << 54; // 55..59 available @@ -6189,4 +6189,4 @@ bitflags::bitflags!( const NO_DUPLICATE_ANY_HIT_INVOCATION = 1 << 1; } ); -impl_bitflags!(AccelerationStructureGeometryFlags); \ No newline at end of file +impl_bitflags!(AccelerationStructureGeometryFlags); From 079054e6da6c013196329de87728d4a04bffcc2a Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 28 Mar 2023 09:42:51 +0200 Subject: [PATCH 034/146] WIP build blas/tlas --- wgpu-core/src/command/mod.rs | 1 + wgpu-core/src/command/ray_tracing.rs | 86 ++++++++ wgpu-core/src/device/mod.rs | 126 +---------- wgpu-core/src/lib.rs | 1 + wgpu-core/src/ray_tracing.rs | 258 +++++++++++++++++++++++ wgpu-core/src/resource.rs | 6 +- wgpu/examples/hello-ray-triangle/main.rs | 5 +- wgpu/src/backend/direct.rs | 64 +++++- wgpu/src/context.rs | 95 ++++++++- wgpu/src/lib.rs | 146 ++++++++++++- 10 files changed, 647 insertions(+), 141 deletions(-) create mode 100644 wgpu-core/src/command/ray_tracing.rs create mode 100644 wgpu-core/src/ray_tracing.rs diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 899cf30d59..fcb56cc079 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -5,6 +5,7 @@ mod compute; mod draw; mod memory_init; mod query; +mod ray_tracing; mod render; mod transfer; diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs new file mode 100644 index 0000000000..eb36ff0cc0 --- /dev/null +++ b/wgpu-core/src/command/ray_tracing.rs @@ -0,0 +1,86 @@ +#[cfg(feature = "trace")] +use crate::device::trace::Command as TraceCommand; +use crate::{ + command::{clear_texture, CommandBuffer, CommandEncoderError}, + conv, + device::{Device, DeviceError, MissingDownlevelFlags}, + error::{ErrorFormatter, PrettyError}, + hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Storage, Token}, + id::{self, BlasId, BufferId, CommandEncoderId, TlasId}, + init_tracker::{ + has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, + TextureInitTrackerAction, + }, + ray_tracing::{BlasBuildEntry, BuildAccelerationStructureError, TlasBuildEntry}, + resource::{self, Texture, TextureErrorDimension}, + track::TextureSelector, + LabelHelpers, LifeGuard, Stored, +}; + +use arrayvec::ArrayVec; +use hal::{AccelerationStructureTriangleIndices, CommandEncoder as _, Device as _}; +use thiserror::Error; +use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages}; + +use std::iter; + +impl Global { + pub fn command_encoder_build_acceleration_structures_unsafe_tlas<'a, A: HalApi>( + &self, + command_encoder_id: CommandEncoderId, + blas_iter: impl Iterator>, + tlas_iter: impl Iterator, + ) -> Result<(), BuildAccelerationStructureError> { + profiling::scope!("CommandEncoder::build_acceleration_structures_unsafe_tlas"); + + let hub = A::hub(self); + let mut token = Token::root(); + + let (device_guard, mut token) = hub.devices.read(&mut token); + let (mut cmd_buf_guard, mut token) = hub.command_buffers.write(&mut token); + let cmd_buf = CommandBuffer::get_encoder_mut(&mut *cmd_buf_guard, command_encoder_id)?; + let (buffer_guard, _) = hub.buffers.read(&mut token); + + let device = &device_guard[cmd_buf.device_id.value]; + + let blas_build_descriptors = Vec::>::new(); + + let blas_build_entries = Vec::>::new(); + + // for blas in blas_iter.into_iter(){ + // match blas.geometries { + // crate::ray_tracing::BlasGeometries::TriangleGeometries(triangle_geometries) => { + + // }, + // } + // } + + todo!() + + // #[cfg(feature = "trace")] + // if let Some(ref mut list) = cmd_buf.commands { + // list.push(TraceCommand::CopyBufferToBuffer { + // src: source, + // src_offset: source_offset, + // dst: destination, + // dst_offset: destination_offset, + // size, + // }); + // } + + // let (src_buffer, src_pending) = cmd_buf + // .trackers + // .buffers + // .set_single(&*buffer_guard, source, hal::BufferUses::COPY_SRC) + // .ok_or(TransferError::InvalidBuffer(source))?; + // let src_raw = src_buffer + // .raw + // .as_ref() + // .ok_or(TransferError::InvalidBuffer(source))?; + // if !src_buffer.usage.contains(BufferUsages::COPY_SRC) { + // return Err(TransferError::MissingCopySrcUsageFlag.into()); + // } + // // expecting only a single barrier + // let src_barrier = src_pending.map(|pending| pending.into_hal(src_buffer)); + } +} diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 547bde010a..8733553542 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -18,7 +18,7 @@ use crate::{ }; use arrayvec::ArrayVec; -use hal::{CommandEncoder as _, Device as _}; +use hal::{AccelerationStructureTriangleIndices, CommandEncoder as _, Device as _}; use parking_lot::{Mutex, MutexGuard}; use smallvec::SmallVec; use thiserror::Error; @@ -3313,45 +3313,6 @@ impl Device { desc: desc.map_label(|_| ()), }) } - - fn create_blas( - &self, - self_id: id::DeviceId, - desc: &resource::BlasDescriptor, - sizes: wgt::BlasGeometrySizeDescriptors, - ) -> Result, resource::CreateBlasError> { - debug_assert_eq!(self_id.backend(), A::VARIANT); - - // TODO - - Ok(resource::Blas { - raw: None, - device_id: Stored { - value: id::Valid(self_id), - ref_count: self.life_guard.add_ref(), - }, - life_guard: LifeGuard::new(desc.label.borrow_or_default()), - }) - } - - fn create_tlas( - &self, - self_id: id::DeviceId, - desc: &resource::TlasDescriptor, - ) -> Result, resource::CreateTlasError> { - debug_assert_eq!(self_id.backend(), A::VARIANT); - - // TODO - - Ok(resource::Tlas { - raw: None, - device_id: Stored { - value: id::Valid(self_id), - ref_count: self.life_guard.add_ref(), - }, - life_guard: LifeGuard::new(desc.label.borrow_or_default()), - }) - } } impl Device { @@ -6103,89 +6064,4 @@ impl Global { } Ok(()) } - - pub fn device_create_blas( - &self, - device_id: id::DeviceId, - desc: &resource::BlasDescriptor, - sizes: wgt::BlasGeometrySizeDescriptors, - id_in: Input, - ) -> (id::BlasId, Option) { - profiling::scope!("Device::create_blas"); - - let hub = A::hub(self); - let mut token = Token::root(); - let fid = hub.blas_s.prepare(id_in); - - let (device_guard, mut token) = hub.devices.read(&mut token); - let error = loop { - let device = match device_guard.get(device_id) { - Ok(device) => device, - Err(_) => break DeviceError::Invalid.into(), - }; - // #[cfg(feature = "trace")] - // if let Some(ref trace) = device.trace { - // let mut desc = desc.clone(); - // trace - // .lock() - // .add(trace::Action::CreateBlas(fid.id(), desc)); - // } - - let mut blas = match device.create_blas(device_id, desc, sizes) { - Ok(blas) => blas, - Err(e) => break e, - }; - let ref_count = blas.life_guard.add_ref(); - - let id = fid.assign(blas, &mut token); - log::info!("Created blas {:?} with {:?}", id, desc); - - return (id.0, None); - }; - - let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); - (id, Some(error)) - } - - pub fn device_create_tlas( - &self, - device_id: id::DeviceId, - desc: &resource::TlasDescriptor, - id_in: Input, - ) -> (id::TlasId, Option) { - profiling::scope!("Device::create_tlas"); - - let hub = A::hub(self); - let mut token = Token::root(); - let fid = hub.tlas_s.prepare(id_in); - - let (device_guard, mut token) = hub.devices.read(&mut token); - let error = loop { - let device = match device_guard.get(device_id) { - Ok(device) => device, - Err(_) => break DeviceError::Invalid.into(), - }; - // #[cfg(feature = "trace")] - // if let Some(ref trace) = device.trace { - // let mut desc = desc.clone(); - // trace - // .lock() - // .add(trace::Action::CreateTlas(fid.id(), desc)); - // } - - let mut tlas = match device.create_tlas(device_id, desc) { - Ok(tlas) => tlas, - Err(e) => break e, - }; - let ref_count = tlas.life_guard.add_ref(); - - let id = fid.assign(tlas, &mut token); - log::info!("Created blas {:?} with {:?}", id, desc); - - return (id.0, None); - }; - - let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); - (id, Some(error)) - } } diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index fc80f0017d..21ddaf7e74 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -48,6 +48,7 @@ mod init_tracker; pub mod instance; pub mod pipeline; pub mod present; +pub mod ray_tracing; pub mod resource; mod track; mod validation; diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs new file mode 100644 index 0000000000..4a1cb71db0 --- /dev/null +++ b/wgpu-core/src/ray_tracing.rs @@ -0,0 +1,258 @@ +#[cfg(feature = "trace")] +use crate::device::trace::Command as TraceCommand; +use crate::{ + command::{clear_texture, CommandBuffer, CommandEncoderError}, + conv, + device::{Device, DeviceError, MissingDownlevelFlags}, + error::{ErrorFormatter, PrettyError}, + hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Storage, Token}, + id::{self, BlasId, BufferId, CommandEncoderId, TlasId}, + init_tracker::{ + has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, + TextureInitTrackerAction, + }, + resource::{self, Texture, TextureErrorDimension}, + track::TextureSelector, + LabelHelpers, LifeGuard, Stored, +}; + +use arrayvec::ArrayVec; +use hal::{AccelerationStructureTriangleIndices, CommandEncoder as _, Device as _}; +use thiserror::Error; +use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages}; + +use std::iter; + +/// Error encountered while attempting to do a copy on a command encoder. +#[derive(Clone, Debug, Error)] +pub enum BuildAccelerationStructureError { + #[error(transparent)] + Encoder(#[from] CommandEncoderError), +} + +impl Device { + fn create_blas( + &self, + self_id: id::DeviceId, + blas_desc: &resource::BlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, + ) -> Result, resource::CreateBlasError> { + debug_assert_eq!(self_id.backend(), A::VARIANT); + + let size_info = match &sizes { + wgt::BlasGeometrySizeDescriptors::Triangles { desc } => { + let mut entries = + Vec::>::with_capacity(desc.len()); + for x in desc { + if x.index_count.is_some() != x.index_format.is_some() { + return Err(resource::CreateBlasError::Unimplemented); + } + // TODO more validation + let indices = + x.index_count + .map(|count| AccelerationStructureTriangleIndices:: { + format: x.index_format.unwrap(), + buffer: None, + offset: 0, + count, + }); + entries.push(hal::AccelerationStructureTriangles:: { + vertex_buffer: None, + vertex_format: x.vertex_format, + first_vertex: 0, + vertex_count: x.vertex_count, + vertex_stride: 0, + indices: indices, + transform: None, + flags: x.flags, + }); + } + unsafe { + self.raw.get_acceleration_structure_build_sizes( + &hal::GetAccelerationStructureBuildSizesDescriptor { + entries: &hal::AccelerationStructureEntries::Triangles(&entries), + flags: blas_desc.flags, + }, + ) + } + } + }; + + let raw = unsafe { + self.raw + .create_acceleration_structure(&hal::AccelerationStructureDescriptor { + label: blas_desc.label.borrow_option(), + size: size_info.acceleration_structure_size, + format: hal::AccelerationStructureFormat::BottomLevel, + }) + } + .map_err(DeviceError::from)?; + + Ok(resource::Blas { + raw: Some(raw), + device_id: Stored { + value: id::Valid(self_id), + ref_count: self.life_guard.add_ref(), + }, + life_guard: LifeGuard::new(blas_desc.label.borrow_or_default()), + size_info, + }) + } + + fn create_tlas( + &self, + self_id: id::DeviceId, + desc: &resource::TlasDescriptor, + ) -> Result, resource::CreateTlasError> { + debug_assert_eq!(self_id.backend(), A::VARIANT); + + // TODO validate max_instances + let size_info = unsafe { + self.raw.get_acceleration_structure_build_sizes( + &hal::GetAccelerationStructureBuildSizesDescriptor { + entries: &hal::AccelerationStructureEntries::Instances( + hal::AccelerationStructureInstances { + buffer: None, + offset: 0, + count: desc.max_instances, + }, + ), + flags: desc.flags, + }, + ) + }; + + let raw = unsafe { + self.raw + .create_acceleration_structure(&hal::AccelerationStructureDescriptor { + label: desc.label.borrow_option(), + size: size_info.acceleration_structure_size, + format: hal::AccelerationStructureFormat::BottomLevel, + }) + } + .map_err(DeviceError::from)?; + + Ok(resource::Tlas { + raw: Some(raw), + device_id: Stored { + value: id::Valid(self_id), + ref_count: self.life_guard.add_ref(), + }, + life_guard: LifeGuard::new(desc.label.borrow_or_default()), + size_info, + }) + } +} + +impl Global { + pub fn device_create_blas( + &self, + device_id: id::DeviceId, + desc: &resource::BlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, + id_in: Input, + ) -> (BlasId, Option) { + profiling::scope!("Device::create_blas"); + + let hub = A::hub(self); + let mut token = Token::root(); + let fid = hub.blas_s.prepare(id_in); + + let (device_guard, mut token) = hub.devices.read(&mut token); + let error = loop { + let device = match device_guard.get(device_id) { + Ok(device) => device, + Err(_) => break DeviceError::Invalid.into(), + }; + // #[cfg(feature = "trace")] + // if let Some(ref trace) = device.trace { + // let mut desc = desc.clone(); + // trace + // .lock() + // .add(trace::Action::CreateBlas(fid.id(), desc)); + // } + + let blas = match device.create_blas(device_id, desc, sizes) { + Ok(blas) => blas, + Err(e) => break e, + }; + let ref_count = blas.life_guard.add_ref(); + + let id = fid.assign(blas, &mut token); + log::info!("Created blas {:?} with {:?}", id, desc); + + return (id.0, None); + }; + + let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); + (id, Some(error)) + } + + pub fn device_create_tlas( + &self, + device_id: id::DeviceId, + desc: &resource::TlasDescriptor, + id_in: Input, + ) -> (id::TlasId, Option) { + profiling::scope!("Device::create_tlas"); + + let hub = A::hub(self); + let mut token = Token::root(); + let fid = hub.tlas_s.prepare(id_in); + + let (device_guard, mut token) = hub.devices.read(&mut token); + let error = loop { + let device = match device_guard.get(device_id) { + Ok(device) => device, + Err(_) => break DeviceError::Invalid.into(), + }; + // #[cfg(feature = "trace")] + // if let Some(ref trace) = device.trace { + // let mut desc = desc.clone(); + // trace + // .lock() + // .add(trace::Action::CreateTlas(fid.id(), desc)); + // } + + let tlas = match device.create_tlas(device_id, desc) { + Ok(tlas) => tlas, + Err(e) => break e, + }; + let ref_count = tlas.life_guard.add_ref(); + + let id = fid.assign(tlas, &mut token); + log::info!("Created blas {:?} with {:?}", id, desc); + + return (id.0, None); + }; + + let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); + (id, Some(error)) + } +} + +pub struct BlasTriangleGeometry<'a> { + pub size: &'a wgt::BlasTriangleGeometrySizeDescriptor, + pub vertex_buffer: BufferId, + pub index_buffer: Option, + pub transform_buffer: Option, + pub first_vertex: u32, + pub vertex_stride: BufferAddress, + pub index_buffer_offset: Option, + pub transform_buffer_offset: Option, +} + +pub enum BlasGeometries<'a> { + TriangleGeometries(Box> + 'a>), +} + +pub struct BlasBuildEntry<'a> { + pub blas_id: BlasId, + pub geometries: BlasGeometries<'a>, +} + +pub struct TlasBuildEntry { + pub tlas_id: TlasId, + pub instance_buffer_id: BufferId, + pub instance_count: u32, +} diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index b96611a47a..c4af8296ec 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -800,9 +800,10 @@ pub type BlasDescriptor<'a> = wgt::CreateBlasDescriptor>; pub type TlasDescriptor<'a> = wgt::CreateTlasDescriptor>; pub struct Blas { - pub(crate) raw: Option, + pub(crate) raw: Option, pub(crate) device_id: Stored, pub(crate) life_guard: LifeGuard, + pub(crate) size_info: hal::AccelerationStructureBuildSizes, } impl Resource for Blas { @@ -814,9 +815,10 @@ impl Resource for Blas { } pub struct Tlas { - pub(crate) raw: Option, + pub(crate) raw: Option, pub(crate) device_id: Stored, pub(crate) life_guard: LifeGuard, + pub(crate) size_info: hal::AccelerationStructureBuildSizes, } impl Resource for Tlas { diff --git a/wgpu/examples/hello-ray-triangle/main.rs b/wgpu/examples/hello-ray-triangle/main.rs index d4d18cc747..0df828253e 100644 --- a/wgpu/examples/hello-ray-triangle/main.rs +++ b/wgpu/examples/hello-ray-triangle/main.rs @@ -93,7 +93,9 @@ async fn run(event_loop: EventLoop<()>, window: Window) { features: wgpu::Features::all_webgpu_mask() | wgpu::Features::TEXTURE_BINDING_ARRAY | wgpu::Features::STORAGE_RESOURCE_BINDING_ARRAY - | wgpu::Features::VERTEX_WRITABLE_STORAGE, + | wgpu::Features::VERTEX_WRITABLE_STORAGE + | wgpu::Features::RAY_QUERY + | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE, // Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain. limits: wgpu::Limits::default(), }, @@ -313,6 +315,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) { })], depth_stencil_attachment: None, }); + rpass.set_pipeline(&blit_pipeline); rpass.set_bind_group(0, &blit_bind_group, &[]); rpass.draw(0..3, 0..1); diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 33bbb5862a..285fc66d31 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -2,8 +2,8 @@ use crate::{ context::{ObjectId, Unused}, AdapterInfo, BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BufferBinding, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, - DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, Operations, - PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, + ContextBlasBuildEntry, DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, + Operations, PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, ShaderSource, SurfaceStatus, TextureDescriptor, TextureViewDescriptor, UncapturedErrorHandler, }; @@ -3017,6 +3017,66 @@ impl crate::Context for Context { }, ) } + + fn command_encoder_build_acceleration_structures_unsafe_tlas<'a>( + &'a self, + encoder: &Self::CommandEncoderId, + encoder_data: &Self::CommandEncoderData, + blas: impl Iterator>, + tlas: impl Iterator>, + ) { + let global = &self.0; + + let blas = blas.map(|e: crate::ContextBlasBuildEntry| { + let geometries = match e.geometries { + crate::ContextBlasGeometries::TriangleGeometries(triangle_geometries) => { + let iter = triangle_geometries.into_iter().map(|tg| { + wgc::ray_tracing::BlasTriangleGeometry { + vertex_buffer: tg.vertex_buffer.0, + index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.0), + transform_buffer: tg + .transform_buffer + .map(|transform_buffer| transform_buffer.0), + size: tg.size, + transform_buffer_offset: tg.transform_buffer_offset, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + } + }); + wgc::ray_tracing::BlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + wgc::ray_tracing::BlasBuildEntry { + blas_id: e.blas_id, + geometries: geometries, + } + }); + + let tlas = tlas + .into_iter() + .map( + |e: crate::ContextTlasBuildEntry| wgc::ray_tracing::TlasBuildEntry { + tlas_id: e.tlas_id, + instance_buffer_id: e.instance_buffer_id, + instance_count: e.instance_count, + }, + ); + + if let Err(cause) = wgc::gfx_select!(encoder => global.command_encoder_build_acceleration_structures_unsafe_tlas( + *encoder, + { + blas + }, + {tlas} + )) { + self.handle_error_nolabel( + &encoder_data.error_sink, + cause, + "CommandEncoder::build_acceleration_structures_unsafe_tlas", + ); + } + } } impl From for wgc::id::Id { diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index ed2805cdf9..b9020cda0a 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -10,12 +10,13 @@ use wgt::{ use crate::{ BindGroupDescriptor, BindGroupLayoutDescriptor, Blas, Buffer, BufferAsyncError, BufferDescriptor, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, - CreateBlasDescriptor, CreateTlasDescriptor, DeviceDescriptor, Error, ErrorFilter, - ImageCopyBuffer, ImageCopyTexture, Maintain, MapMode, PipelineLayoutDescriptor, - QuerySetDescriptor, RenderBundleDescriptor, RenderBundleEncoderDescriptor, - RenderPassDescriptor, RenderPipelineDescriptor, RequestAdapterOptions, RequestDeviceError, - SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, Texture, - TextureDescriptor, TextureViewDescriptor, Tlas, UncapturedErrorHandler, + ContextBlasBuildEntry, ContextBlasTriangleGeometry, CreateBlasDescriptor, CreateTlasDescriptor, + DeviceDescriptor, Error, ErrorFilter, ImageCopyBuffer, ImageCopyTexture, Maintain, MapMode, + PipelineLayoutDescriptor, QuerySetDescriptor, RenderBundleDescriptor, + RenderBundleEncoderDescriptor, RenderPassDescriptor, RenderPipelineDescriptor, + RequestAdapterOptions, RequestDeviceError, SamplerDescriptor, ShaderModuleDescriptor, + ShaderModuleDescriptorSpirV, Texture, TextureDescriptor, TextureViewDescriptor, Tlas, + UncapturedErrorHandler, }; /// Meta trait for an id tracked by a context. @@ -1008,6 +1009,13 @@ pub trait Context: Debug + Send + Sized + Sync { device_data: &Self::DeviceData, desc: &CreateTlasDescriptor, ) -> (Self::TlasId, Self::TlasData); + fn command_encoder_build_acceleration_structures_unsafe_tlas<'a>( + &'a self, + encoder: &Self::CommandEncoderId, + encoder_data: &Self::CommandEncoderData, + blas: impl Iterator>, + tlas: impl Iterator>, + ); } /// Object id. @@ -1936,6 +1944,13 @@ pub(crate) trait DynContext: Debug + Send + Sync { device_data: &crate::Data, desc: &crate::CreateTlasDescriptor, ) -> (ObjectId, Box); + fn command_encoder_build_acceleration_structures_unsafe_tlas<'a>( + &self, + encoder: &ObjectId, + encoder_data: &crate::Data, + blas: &mut dyn Iterator>, + tlas: &mut dyn Iterator>, + ); } // Blanket impl of DynContext for all types which implement Context. @@ -3911,6 +3926,74 @@ where let (tlas, data) = Context::device_create_tlas(self, &device, device_data, desc); (tlas.into(), Box::new(data) as _) } + + fn command_encoder_build_acceleration_structures_unsafe_tlas<'a>( + &self, + encoder: &ObjectId, + encoder_data: &crate::Data, + blas: &mut dyn Iterator>, + tlas: &mut dyn Iterator>, + ) { + let encoder = ::from(*encoder); + let encoder_data = downcast_ref(encoder_data); + + let blas = blas.into_iter().map(|e| { + let geometries = match e.geometries { + crate::DynContextBlasGeometries::TriangleGeometries(triangle_geometries) => { + let iter = + triangle_geometries + .into_iter() + .map(|tg| ContextBlasTriangleGeometry { + vertex_buffer: ( + ::from(tg.vertex_buffer.0), + downcast_ref(tg.vertex_buffer.1), + ), + index_buffer: tg.index_buffer.map(|index_buffer| { + ( + ::from(index_buffer.0), + downcast_ref(index_buffer.1), + ) + }), + transform_buffer: tg.transform_buffer.map(|transform_buffer| { + ( + ::from(transform_buffer.0), + downcast_ref(transform_buffer.1), + ) + }), + size: tg.size, + transform_buffer_offset: tg.transform_buffer_offset, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + }); + crate::ContextBlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + crate::ContextBlasBuildEntry { + blas_id: ::from(e.blas_id), + blas_data: downcast_ref(e.blas_data), + geometries: geometries, + } + }); + + let tlas = tlas.into_iter().map(|e: crate::DynContextTlasBuildEntry| { + crate::ContextTlasBuildEntry { + tlas_id: ::from(e.tlas_id), + tlas_data: downcast_ref(e.tlas_data), + instance_buffer_id: ::from(e.instance_buffer_id), + instance_buffer_data: downcast_ref(e.instance_buffer_data), + instance_count: e.instance_count, + } + }); + + Context::command_encoder_build_acceleration_structures_unsafe_tlas( + self, + &encoder, + encoder_data, + blas, + tlas, + ) + } } pub trait QueueWriteBuffer: Send + Sync { diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index d62fc332be..6d918e6fa4 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -2969,6 +2969,65 @@ impl CommandEncoder { let id = self.id.as_ref().unwrap(); DynContext::command_encoder_pop_debug_group(&*self.context, id, self.data.as_ref()); } + + /// Build bottom and top level acceleration structures + pub unsafe fn build_acceleration_structures_unsafe_tlas<'a>( + &mut self, + blas: impl IntoIterator>, + tlas: impl IntoIterator>, + ) { + let id = self.id.as_ref().unwrap(); + + let mut blas = blas.into_iter().map(|e: &BlasBuildEntry| { + let geometries = match e.geometry { + BlasGeometries::TriangleGeometries(triangle_geometries) => { + let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry| { + DynContextBlasTriangleGeometry { + size: tg.size, + vertex_buffer: (tg.vertex_buffer.id, tg.vertex_buffer.data.as_ref()), + + index_buffer: tg + .index_buffer + .map(|index_buffer| (index_buffer.id, index_buffer.data.as_ref())), + + transform_buffer: tg.transform_buffer.map(|transform_buffer| { + (transform_buffer.id, transform_buffer.data.as_ref()) + }), + + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + } + }); + DynContextBlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + DynContextBlasBuildEntry { + blas_id: e.blas.id, + blas_data: e.blas.data.as_ref(), + geometries: geometries, + } + }); + + let mut tlas = tlas + .into_iter() + .map(|e: &TlasBuildEntry| DynContextTlasBuildEntry { + tlas_id: e.tlas.id, + tlas_data: e.tlas.data.as_ref(), + instance_buffer_id: e.instance_buffer.id, + instance_buffer_data: e.instance_buffer.data.as_ref(), + instance_count: e.instance_count, + }); + + DynContext::command_encoder_build_acceleration_structures_unsafe_tlas( + &*self.context, + id, + self.data.as_ref(), + &mut blas, + &mut tlas, + ); + } } /// [`Features::TIMESTAMP_QUERY`] must be enabled on the device in order to call these functions. @@ -4533,18 +4592,30 @@ pub type CreateTlasDescriptor<'a> = wgt::CreateTlasDescriptor>; static_assertions::assert_impl_all!(CreateTlasDescriptor: Send, Sync); #[derive(Debug)] -pub struct BlasTriangleGeometry { - pub size: BlasTriangleGeometrySizeDescriptor, - pub vertex_buffer: Buffer, +pub struct BlasTriangleGeometry<'a> { + pub size: &'a BlasTriangleGeometrySizeDescriptor, + pub vertex_buffer: &'a Buffer, pub first_vertex: u32, pub vertex_stride: wgt::BufferAddress, - pub index_buffer: Option, + pub index_buffer: Option<&'a Buffer>, pub index_buffer_offset: Option, - pub transform_buffer: Option, + pub transform_buffer: Option<&'a Buffer>, pub transform_buffer_offset: Option, } static_assertions::assert_impl_all!(BlasTriangleGeometry: Send, Sync); +#[derive(Debug)] +pub enum BlasGeometries<'a> { + TriangleGeometries(&'a [BlasTriangleGeometry<'a>]), +} +static_assertions::assert_impl_all!(BlasGeometries: Send, Sync); + +pub struct BlasBuildEntry<'a> { + pub blas: &'a Blas, + pub geometry: &'a BlasGeometries<'a>, +} +static_assertions::assert_impl_all!(BlasBuildEntry: Send, Sync); + #[derive(Debug)] pub struct Blas { context: Arc, @@ -4560,3 +4631,68 @@ pub struct Tlas { data: Box, } static_assertions::assert_impl_all!(Tlas: Send, Sync); + +pub struct TlasBuildEntry<'a> { + pub tlas: &'a Tlas, + pub instance_buffer: &'a Buffer, + pub instance_count: u32, +} +static_assertions::assert_impl_all!(TlasBuildEntry: Send, Sync); + +pub(crate) struct DynContextBlasTriangleGeometry<'a> { + size: &'a BlasTriangleGeometrySizeDescriptor, + vertex_buffer: (ObjectId, &'a Data), + index_buffer: Option<(ObjectId, &'a Data)>, + transform_buffer: Option<(ObjectId, &'a Data)>, + first_vertex: u32, + vertex_stride: wgt::BufferAddress, + index_buffer_offset: Option, + transform_buffer_offset: Option, +} + +pub(crate) enum DynContextBlasGeometries<'a> { + TriangleGeometries(Box> + 'a>), +} + +pub(crate) struct DynContextBlasBuildEntry<'a> { + blas_id: ObjectId, + blas_data: &'a crate::Data, + geometries: DynContextBlasGeometries<'a>, +} + +pub(crate) struct DynContextTlasBuildEntry<'a> { + tlas_id: ObjectId, + tlas_data: &'a crate::Data, + instance_buffer_id: ObjectId, + instance_buffer_data: &'a crate::Data, + instance_count: u32, +} + +pub struct ContextBlasTriangleGeometry<'a, T: Context> { + size: &'a BlasTriangleGeometrySizeDescriptor, + vertex_buffer: (T::BufferId, &'a T::BufferData), + index_buffer: Option<(T::BufferId, &'a T::BufferData)>, + transform_buffer: Option<(T::BufferId, &'a T::BufferData)>, + first_vertex: u32, + vertex_stride: wgt::BufferAddress, + index_buffer_offset: Option, + transform_buffer_offset: Option, +} + +pub enum ContextBlasGeometries<'a, T: Context> { + TriangleGeometries(Box> + 'a>), +} + +pub struct ContextBlasBuildEntry<'a, T: Context> { + blas_id: T::BlasId, + blas_data: &'a T::BlasData, + geometries: ContextBlasGeometries<'a, T>, +} + +pub struct ContextTlasBuildEntry<'a, T: Context> { + tlas_id: T::TlasId, + tlas_data: &'a T::TlasData, + instance_buffer_id: T::BufferId, + instance_buffer_data: &'a T::BufferData, + instance_count: u32, +} From cfc7e3d80900854f9c5d46c84ebafa37da2d701a Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 29 Mar 2023 04:45:35 +0200 Subject: [PATCH 035/146] WIP blas build --- wgpu-core/src/command/compute.rs | 2 + wgpu-core/src/command/ray_tracing.rs | 289 ++++++++++++++++++++++++--- wgpu-core/src/command/render.rs | 2 + wgpu-core/src/device/mod.rs | 2 +- wgpu-core/src/hub.rs | 5 + wgpu-core/src/ray_tracing.rs | 25 +++ wgpu-core/src/resource.rs | 3 + wgpu-core/src/track/mod.rs | 12 ++ wgpu-types/src/lib.rs | 2 + 9 files changed, 308 insertions(+), 34 deletions(-) diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index e369823775..f494d37475 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -385,6 +385,8 @@ impl Global { None, None, Some(&*query_set_guard), + None, + None, ); let hal_desc = hal::ComputePassDescriptor { label: base.label }; diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index eb36ff0cc0..44f26abf6c 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -3,7 +3,7 @@ use crate::device::trace::Command as TraceCommand; use crate::{ command::{clear_texture, CommandBuffer, CommandEncoderError}, conv, - device::{Device, DeviceError, MissingDownlevelFlags}, + device::{queue::TempResource, Device, DeviceError, MissingDownlevelFlags}, error::{ErrorFormatter, PrettyError}, hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Storage, Token}, id::{self, BlasId, BufferId, CommandEncoderId, TlasId}, @@ -11,18 +11,24 @@ use crate::{ has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, TextureInitTrackerAction, }, - ray_tracing::{BlasBuildEntry, BuildAccelerationStructureError, TlasBuildEntry}, + ray_tracing::{ + BlasBuildEntry, BlasBuildEntryStorage, BlasGeometriesStorage, + BuildAccelerationStructureError, TlasBuildEntry, + }, resource::{self, Texture, TextureErrorDimension}, track::TextureSelector, LabelHelpers, LifeGuard, Stored, }; use arrayvec::ArrayVec; -use hal::{AccelerationStructureTriangleIndices, CommandEncoder as _, Device as _}; +use hal::{ + AccelerationStructureTriangleIndices, AccelerationStructureTriangleTransform, + CommandEncoder as _, Device as _, +}; use thiserror::Error; use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages}; -use std::iter; +use std::{borrow::Borrow, iter}; impl Global { pub fn command_encoder_build_acceleration_structures_unsafe_tlas<'a, A: HalApi>( @@ -36,26 +42,31 @@ impl Global { let hub = A::hub(self); let mut token = Token::root(); - let (device_guard, mut token) = hub.devices.read(&mut token); + let (mut device_guard, mut token) = hub.devices.write(&mut token); let (mut cmd_buf_guard, mut token) = hub.command_buffers.write(&mut token); let cmd_buf = CommandBuffer::get_encoder_mut(&mut *cmd_buf_guard, command_encoder_id)?; - let (buffer_guard, _) = hub.buffers.read(&mut token); - - let device = &device_guard[cmd_buf.device_id.value]; + let (buffer_guard, mut token) = hub.buffers.read(&mut token); + let (blas_guard, mut token) = hub.blas_s.read(&mut token); + let (tlas_guard, _) = hub.tlas_s.read(&mut token); - let blas_build_descriptors = Vec::>::new(); + let device = &mut device_guard[cmd_buf.device_id.value]; - let blas_build_entries = Vec::>::new(); - - // for blas in blas_iter.into_iter(){ - // match blas.geometries { - // crate::ray_tracing::BlasGeometries::TriangleGeometries(triangle_geometries) => { - - // }, - // } - // } + let blas_storage: Vec<_> = blas_iter + .into_iter() + .map(|e| { + let geometries = match e.geometries { + crate::ray_tracing::BlasGeometries::TriangleGeometries(triangle_geometries) => { + BlasGeometriesStorage::TriangleGeometries(triangle_geometries.collect()) + } + }; + BlasBuildEntryStorage { + blas_id: e.blas_id, + geometries, + } + }) + .collect(); - todo!() + let tlas_storage: Vec<_> = tlas_iter.collect(); // #[cfg(feature = "trace")] // if let Some(ref mut list) = cmd_buf.commands { @@ -68,19 +79,231 @@ impl Global { // }); // } - // let (src_buffer, src_pending) = cmd_buf - // .trackers - // .buffers - // .set_single(&*buffer_guard, source, hal::BufferUses::COPY_SRC) - // .ok_or(TransferError::InvalidBuffer(source))?; - // let src_raw = src_buffer - // .raw - // .as_ref() - // .ok_or(TransferError::InvalidBuffer(source))?; - // if !src_buffer.usage.contains(BufferUsages::COPY_SRC) { - // return Err(TransferError::MissingCopySrcUsageFlag.into()); - // } - // // expecting only a single barrier - // let src_barrier = src_pending.map(|pending| pending.into_hal(src_buffer)); + let mut barriers = Vec::>::new(); + + let mut triangle_geometry_storage = + Vec::>>::new(); + + for entry in &blas_storage { + match &entry.geometries { + BlasGeometriesStorage::TriangleGeometries(triangle_geometries) => { + triangle_geometry_storage + .push(Vec::>::new()); + + for mesh in triangle_geometries { + let vertex_buffer = { + let (vertex_buffer, vertex_pending) = cmd_buf + .trackers + .buffers + .set_single( + &*buffer_guard, + mesh.vertex_buffer, + hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) + .ok_or(BuildAccelerationStructureError::InvalidBuffer( + mesh.vertex_buffer, + ))?; + let vertex_raw = vertex_buffer.raw.as_ref().ok_or( + BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer), + )?; + if !vertex_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + mesh.vertex_buffer, + ), + ); + } + if let Some(barrier) = + vertex_pending.map(|pending| pending.into_hal(vertex_buffer)) + { + barriers.push(barrier); + } + let vertex_buffer_offset = + mesh.first_vertex as u64 * mesh.vertex_stride; + cmd_buf.buffer_memory_init_actions.extend( + vertex_buffer.initialization_status.create_action( + mesh.vertex_buffer, + vertex_buffer_offset + ..(vertex_buffer_offset + + mesh.size.vertex_count as u64 * mesh.vertex_stride), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + vertex_raw + }; + let index_buffer = if let Some(index_id) = mesh.index_buffer { + let (index_buffer, index_pending) = cmd_buf + .trackers + .buffers + .set_single( + &*buffer_guard, + index_id, + hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) + .ok_or(BuildAccelerationStructureError::InvalidBuffer(index_id))?; + let index_raw = index_buffer + .raw + .as_ref() + .ok_or(BuildAccelerationStructureError::InvalidBuffer(index_id))?; + if !index_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + index_id, + ), + ); + } + if let Some(barrier) = + index_pending.map(|pending| pending.into_hal(index_buffer)) + { + barriers.push(barrier); + } + let index_buffer_size = mesh.size.index_count.unwrap() as u64 + * match mesh.size.index_format.unwrap() { + wgt::IndexFormat::Uint16 => 2, + wgt::IndexFormat::Uint32 => 4, + }; + cmd_buf.buffer_memory_init_actions.extend( + index_buffer.initialization_status.create_action( + index_id, + mesh.index_buffer_offset.unwrap() + ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + Some(index_raw) + } else { + None + }; + let transform_buffer = if let Some(transform_id) = mesh.index_buffer { + let (transform_buffer, transform_pending) = cmd_buf + .trackers + .buffers + .set_single( + &*buffer_guard, + transform_id, + hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) + .ok_or(BuildAccelerationStructureError::InvalidBuffer( + transform_id, + ))?; + let transform_raw = transform_buffer.raw.as_ref().ok_or( + BuildAccelerationStructureError::InvalidBuffer(transform_id), + )?; + if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + transform_id, + ), + ); + } + if let Some(barrier) = + transform_pending.map(|pending| pending.into_hal(transform_buffer)) + { + barriers.push(barrier); + } + cmd_buf.buffer_memory_init_actions.extend( + transform_buffer.initialization_status.create_action( + transform_id, + mesh.transform_buffer_offset.unwrap() + ..(mesh.index_buffer_offset.unwrap() + 48), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + Some(transform_raw) + } else { + None + }; + + let triangles = hal::AccelerationStructureTriangles { + vertex_buffer: Some(vertex_buffer), + vertex_format: mesh.size.vertex_format, + first_vertex: mesh.first_vertex, + vertex_count: mesh.size.vertex_count, + vertex_stride: mesh.vertex_stride, + indices: index_buffer.map(|index_buffer| { + AccelerationStructureTriangleIndices { + format: mesh.size.index_format.unwrap(), + buffer: Some(index_buffer), + offset: mesh.index_buffer_offset.unwrap() as u32, + count: mesh.size.index_count.unwrap(), + } + }), + transform: transform_buffer.map(|transform_buffer| { + AccelerationStructureTriangleTransform { + buffer: transform_buffer, + offset: mesh.transform_buffer_offset.unwrap() as u32, + } + }), + flags: mesh.size.flags, + }; + triangle_geometry_storage + .last_mut() + .unwrap() + .push(triangles); + } + } + }; + } + + let mut ac_entry_storage = Vec::>::new(); + + let mut triangel_geometrie_counter = 0; + for entry in &blas_storage { + match &entry.geometries { + BlasGeometriesStorage::TriangleGeometries(_) => { + ac_entry_storage.push(hal::AccelerationStructureEntries::Triangles( + &triangle_geometry_storage[triangel_geometrie_counter], + )); + triangel_geometrie_counter += 1; + } + } + } + + let scratch_size = 1000000; + + let scratch_buffer = unsafe { + device + .raw + .create_buffer(&hal::BufferDescriptor { + label: Some("(wgpu) scratch buffer"), + size: scratch_size, + usage: hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, + memory_flags: hal::MemoryFlags::empty(), + }) + .unwrap() + }; + + let mut blas_descriptors = + Vec::>::with_capacity(blas_storage.len()); + + for (i, entry) in blas_storage.iter().enumerate() { + let blas = cmd_buf + .trackers + .blas_s + .add_single(&blas_guard, entry.blas_id) + .ok_or(BuildAccelerationStructureError::InvalidBlas(entry.blas_id))?; + + blas_descriptors.push(hal::BuildAccelerationStructureDescriptor { + entries: &ac_entry_storage[i], + mode: hal::AccelerationStructureBuildMode::Build, // TODO + flags: blas.flags, + source_acceleration_structure: None, + destination_acceleration_structure: blas.raw.as_ref().unwrap(), + scratch_buffer: &scratch_buffer, + }) + } + + device + .pending_writes + .temp_resources + .push(TempResource::Buffer(scratch_buffer)); + + let cmd_buf_raw = cmd_buf.encoder.open(); + unsafe { + cmd_buf_raw.transition_buffers(barriers.into_iter()); + } + Ok(()) + + // todo!() } } diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 5de2a48ff6..dc99889c46 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1275,6 +1275,8 @@ impl Global { Some(&*render_pipeline_guard), Some(&*bundle_guard), Some(&*query_set_guard), + None, + None, ); let raw = &mut cmd_buf.encoder.raw; diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 8733553542..ce64521dda 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -337,7 +337,7 @@ pub struct Device { // TODO: move this behind another mutex. This would allow several methods to // switch to borrow Device immutably, such as `write_buffer`, `write_texture`, // and `buffer_unmap`. - pending_writes: queue::PendingWrites, + pub(crate) pending_writes: queue::PendingWrites, #[cfg(feature = "trace")] pub(crate) trace: Option>, } diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 7af6ba45ff..4451357bbc 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -543,8 +543,13 @@ impl Access> for TextureView {} impl Access> for Root {} impl Access> for Device {} +impl Access> for CommandBuffer {} +impl Access> for Buffer {} impl Access> for Root {} impl Access> for Device {} +impl Access> for CommandBuffer {} +impl Access> for Buffer {} +impl Access> for Blas {} #[cfg(debug_assertions)] thread_local! { diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 4a1cb71db0..0930315bc6 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -28,6 +28,14 @@ use std::iter; pub enum BuildAccelerationStructureError { #[error(transparent)] Encoder(#[from] CommandEncoderError), + #[error("Buffer {0:?} is invalid or destroyed")] + InvalidBuffer(BufferId), + #[error("Buffer {0:?} is missing `BLAS_INPUT` usage flag")] + MissingBlasInputUsageFlag(BufferId), + #[error("Blas {0:?} is invalid or destroyed")] + InvalidBlas(BlasId), + #[error("Tlas {0:?} is invalid or destroyed")] + InvalidTlas(TlasId), } impl Device { @@ -96,6 +104,9 @@ impl Device { }, life_guard: LifeGuard::new(blas_desc.label.borrow_or_default()), size_info, + sizes, + flags: blas_desc.flags, + update_mode: blas_desc.update_mode, }) } @@ -181,6 +192,8 @@ impl Global { let id = fid.assign(blas, &mut token); log::info!("Created blas {:?} with {:?}", id, desc); + device.trackers.lock().blas_s.insert_single(id, ref_count); + return (id.0, None); }; @@ -223,6 +236,8 @@ impl Global { let id = fid.assign(tlas, &mut token); log::info!("Created blas {:?} with {:?}", id, desc); + device.trackers.lock().tlas_s.insert_single(id, ref_count); + return (id.0, None); }; @@ -231,6 +246,7 @@ impl Global { } } +#[derive(Debug)] pub struct BlasTriangleGeometry<'a> { pub size: &'a wgt::BlasTriangleGeometrySizeDescriptor, pub vertex_buffer: BufferId, @@ -256,3 +272,12 @@ pub struct TlasBuildEntry { pub instance_buffer_id: BufferId, pub instance_count: u32, } + +pub enum BlasGeometriesStorage<'a> { + TriangleGeometries(Vec>), +} + +pub struct BlasBuildEntryStorage<'a> { + pub blas_id: BlasId, + pub geometries: BlasGeometriesStorage<'a>, +} diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index c4af8296ec..faa00899ef 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -804,6 +804,9 @@ pub struct Blas { pub(crate) device_id: Stored, pub(crate) life_guard: LifeGuard, pub(crate) size_info: hal::AccelerationStructureBuildSizes, + pub(crate) sizes: wgt::BlasGeometrySizeDescriptors, + pub(crate) flags: wgt::AccelerationStructureFlags, + pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, } impl Resource for Blas { diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index b2548f08ae..a91d42a2f9 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -484,6 +484,8 @@ pub(crate) struct Tracker { pub render_pipelines: StatelessTracker, id::RenderPipelineId>, pub bundles: StatelessTracker, id::RenderBundleId>, pub query_sets: StatelessTracker, id::QuerySetId>, + pub blas_s: StatelessTracker, id::BlasId>, + pub tlas_s: StatelessTracker, id::TlasId>, } impl Tracker { @@ -498,6 +500,8 @@ impl Tracker { render_pipelines: StatelessTracker::new(), bundles: StatelessTracker::new(), query_sets: StatelessTracker::new(), + blas_s: StatelessTracker::new(), + tlas_s: StatelessTracker::new(), } } @@ -515,6 +519,8 @@ impl Tracker { render_pipelines: Option<&hub::Storage, id::RenderPipelineId>>, bundles: Option<&hub::Storage, id::RenderBundleId>>, query_sets: Option<&hub::Storage, id::QuerySetId>>, + blas_s: Option<&hub::Storage, id::BlasId>>, + tlas_s: Option<&hub::Storage, id::TlasId>>, ) { if let Some(buffers) = buffers { self.buffers.set_size(buffers.len()); @@ -543,6 +549,12 @@ impl Tracker { if let Some(query_sets) = query_sets { self.query_sets.set_size(query_sets.len()); }; + if let Some(blas_s) = blas_s { + self.blas_s.set_size(blas_s.len()); + }; + if let Some(tlas_s) = tlas_s { + self.tlas_s.set_size(tlas_s.len()); + }; } /// Iterates through all resources in the given bind group and adopts diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index a5b01422d9..fcb394e6e1 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -4233,6 +4233,8 @@ bitflags::bitflags! { const STORAGE = 1 << 7; /// Allow a buffer to be the indirect buffer in an indirect draw call. const INDIRECT = 1 << 8; + /// Allows a buffer to be used as input for a bottom level acceleration structure build + const BLAS_INPUT = 1 << 9; } } From ffe0b411d97316cfaf3ce741f5d82861f02779ee Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 29 Mar 2023 13:40:41 +0200 Subject: [PATCH 036/146] WIP blas build should work --- wgpu-core/src/command/ray_tracing.rs | 155 +++++++++++++++++++---- wgpu-core/src/conv.rs | 8 ++ wgpu-core/src/ray_tracing.rs | 4 + wgpu-core/src/resource.rs | 2 + wgpu-types/src/lib.rs | 2 + wgpu/examples/hello-ray-triangle/main.rs | 31 ++++- 6 files changed, 171 insertions(+), 31 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 44f26abf6c..ed65699ef1 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -15,20 +15,20 @@ use crate::{ BlasBuildEntry, BlasBuildEntryStorage, BlasGeometriesStorage, BuildAccelerationStructureError, TlasBuildEntry, }, - resource::{self, Texture, TextureErrorDimension}, + resource::{self, Blas, Texture, TextureErrorDimension, Tlas}, track::TextureSelector, LabelHelpers, LifeGuard, Stored, }; use arrayvec::ArrayVec; use hal::{ - AccelerationStructureTriangleIndices, AccelerationStructureTriangleTransform, - CommandEncoder as _, Device as _, + AccelerationStructureInstances, AccelerationStructureTriangleIndices, + AccelerationStructureTriangleTransform, CommandEncoder as _, Device as _, }; use thiserror::Error; use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages}; -use std::{borrow::Borrow, iter}; +use std::{borrow::Borrow, cmp::max, iter}; impl Global { pub fn command_encoder_build_acceleration_structures_unsafe_tlas<'a, A: HalApi>( @@ -79,7 +79,7 @@ impl Global { // }); // } - let mut barriers = Vec::>::new(); + let mut input_barriers = Vec::>::new(); let mut triangle_geometry_storage = Vec::>>::new(); @@ -116,7 +116,7 @@ impl Global { if let Some(barrier) = vertex_pending.map(|pending| pending.into_hal(vertex_buffer)) { - barriers.push(barrier); + input_barriers.push(barrier); } let vertex_buffer_offset = mesh.first_vertex as u64 * mesh.vertex_stride; @@ -155,7 +155,7 @@ impl Global { if let Some(barrier) = index_pending.map(|pending| pending.into_hal(index_buffer)) { - barriers.push(barrier); + input_barriers.push(barrier); } let index_buffer_size = mesh.size.index_count.unwrap() as u64 * match mesh.size.index_format.unwrap() { @@ -174,7 +174,7 @@ impl Global { } else { None }; - let transform_buffer = if let Some(transform_id) = mesh.index_buffer { + let transform_buffer = if let Some(transform_id) = mesh.transform_buffer { let (transform_buffer, transform_pending) = cmd_buf .trackers .buffers @@ -199,7 +199,7 @@ impl Global { if let Some(barrier) = transform_pending.map(|pending| pending.into_hal(transform_buffer)) { - barriers.push(barrier); + input_barriers.push(barrier); } cmd_buf.buffer_memory_init_actions.extend( transform_buffer.initialization_status.create_action( @@ -245,46 +245,113 @@ impl Global { }; } - let mut ac_entry_storage = Vec::>::new(); + let mut blas_entry_storage = Vec::>::new(); + + let mut scratch_buffer_blas_size = 0; + let mut scratch_buffer_blas_offsets = Vec::::new(); + + let mut blas_refs = Vec::<&Blas>::new(); let mut triangel_geometrie_counter = 0; for entry in &blas_storage { match &entry.geometries { BlasGeometriesStorage::TriangleGeometries(_) => { - ac_entry_storage.push(hal::AccelerationStructureEntries::Triangles( + blas_entry_storage.push(hal::AccelerationStructureEntries::Triangles( &triangle_geometry_storage[triangel_geometrie_counter], )); triangel_geometrie_counter += 1; } } + + let blas = cmd_buf + .trackers + .blas_s + .add_single(&blas_guard, entry.blas_id) + .ok_or(BuildAccelerationStructureError::InvalidBlas(entry.blas_id))?; + + scratch_buffer_blas_offsets.push(scratch_buffer_blas_size); + scratch_buffer_blas_size += blas.size_info.build_scratch_size; // TODO Alignment + + blas_refs.push(blas); } - let scratch_size = 1000000; + let mut tlas_refs = Vec::<&Tlas>::new(); + let mut scratch_buffer_tlas_size = 0; + let mut scratch_buffer_tlas_offsets = Vec::::new(); + let mut tlas_entry_storage = Vec::>::new(); + for entry in &tlas_storage { + let instance_buffer = { + let (instance_buffer, instance_pending) = cmd_buf + .trackers + .buffers + .set_single( + &*buffer_guard, + entry.instance_buffer_id, + hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) + .ok_or(BuildAccelerationStructureError::InvalidBuffer( + entry.instance_buffer_id, + ))?; + let instance_raw = instance_buffer.raw.as_ref().ok_or( + BuildAccelerationStructureError::InvalidBuffer(entry.instance_buffer_id), + )?; + if !instance_buffer.usage.contains(BufferUsages::TLAS_INPUT) { + return Err(BuildAccelerationStructureError::MissingTlasInputUsageFlag( + entry.instance_buffer_id, + )); + } + if let Some(barrier) = + instance_pending.map(|pending| pending.into_hal(instance_buffer)) + { + input_barriers.push(barrier); + } + instance_raw + }; + + tlas_entry_storage.push(hal::AccelerationStructureEntries::Instances( + AccelerationStructureInstances { + buffer: Some(instance_buffer), + offset: 0, + count: entry.instance_count, + }, + )); + + let tlas = cmd_buf + .trackers + .tlas_s + .add_single(&tlas_guard, entry.tlas_id) + .ok_or(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id))?; + + scratch_buffer_tlas_offsets.push(scratch_buffer_tlas_size); + scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; // TODO Alignment + + tlas_refs.push(tlas); + } let scratch_buffer = unsafe { device .raw .create_buffer(&hal::BufferDescriptor { label: Some("(wgpu) scratch buffer"), - size: scratch_size, + size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), usage: hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, memory_flags: hal::MemoryFlags::empty(), }) .unwrap() }; + let scratch_buffer_barrier = hal::BufferBarrier:: { + buffer: &scratch_buffer, + usage: hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH + ..hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, + }; + let mut blas_descriptors = Vec::>::with_capacity(blas_storage.len()); - - for (i, entry) in blas_storage.iter().enumerate() { - let blas = cmd_buf - .trackers - .blas_s - .add_single(&blas_guard, entry.blas_id) - .ok_or(BuildAccelerationStructureError::InvalidBlas(entry.blas_id))?; - + for (i, _entry) in blas_storage.iter().enumerate() { + let blas = blas_refs[i]; blas_descriptors.push(hal::BuildAccelerationStructureDescriptor { - entries: &ac_entry_storage[i], + entries: &blas_entry_storage[i], mode: hal::AccelerationStructureBuildMode::Build, // TODO flags: blas.flags, source_acceleration_structure: None, @@ -293,17 +360,49 @@ impl Global { }) } + let mut blas_descriptor_references = + Vec::<&hal::BuildAccelerationStructureDescriptor>::with_capacity(blas_storage.len()); + for (i, _entry) in blas_storage.iter().enumerate() { + blas_descriptor_references.push(&blas_descriptors[i]); + } + + let mut tlas_descriptors = + Vec::>::with_capacity(tlas_storage.len()); + for (i, _entry) in tlas_storage.iter().enumerate() { + let tlas = tlas_refs[i]; + tlas_descriptors.push(hal::BuildAccelerationStructureDescriptor { + entries: &tlas_entry_storage[i], + mode: hal::AccelerationStructureBuildMode::Build, // TODO + flags: tlas.flags, + source_acceleration_structure: None, + destination_acceleration_structure: tlas.raw.as_ref().unwrap(), + scratch_buffer: &scratch_buffer, + }) + } + + let mut tlas_descriptor_references = + Vec::<&hal::BuildAccelerationStructureDescriptor>::with_capacity(tlas_storage.len()); + for (i, _entry) in tlas_storage.iter().enumerate() { + tlas_descriptor_references.push(&tlas_descriptors[i]); + } + + let cmd_buf_raw = cmd_buf.encoder.open(); + unsafe { + cmd_buf_raw.transition_buffers(input_barriers.into_iter()); + if !blas_descriptor_references.is_empty() { + cmd_buf_raw.build_acceleration_structures(&blas_descriptor_references); + } + cmd_buf_raw.transition_buffers(iter::once(scratch_buffer_barrier)); + if !tlas_descriptor_references.is_empty() { + cmd_buf_raw.build_acceleration_structures(&tlas_descriptor_references); + } + } + device .pending_writes .temp_resources .push(TempResource::Buffer(scratch_buffer)); - let cmd_buf_raw = cmd_buf.encoder.open(); - unsafe { - cmd_buf_raw.transition_buffers(barriers.into_iter()); - } Ok(()) - - // todo!() } } diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index 43986c946e..31f445335b 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -95,6 +95,14 @@ pub fn map_buffer_usage(usage: wgt::BufferUsages) -> hal::BufferUses { hal::BufferUses::INDIRECT, usage.contains(wgt::BufferUsages::INDIRECT), ); + u.set( + hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + usage.contains(wgt::BufferUsages::BLAS_INPUT), + ); + u.set( + hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + usage.contains(wgt::BufferUsages::TLAS_INPUT), + ); u } diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 0930315bc6..0c57d6d2ff 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -36,6 +36,8 @@ pub enum BuildAccelerationStructureError { InvalidBlas(BlasId), #[error("Tlas {0:?} is invalid or destroyed")] InvalidTlas(TlasId), + #[error("Buffer {0:?} is missing `TLAS_INPUT` usage flag")] + MissingTlasInputUsageFlag(BufferId), } impl Device { @@ -151,6 +153,8 @@ impl Device { }, life_guard: LifeGuard::new(desc.label.borrow_or_default()), size_info, + flags: desc.flags, + update_mode: desc.update_mode, }) } } diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index faa00899ef..79e4a3b8e7 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -822,6 +822,8 @@ pub struct Tlas { pub(crate) device_id: Stored, pub(crate) life_guard: LifeGuard, pub(crate) size_info: hal::AccelerationStructureBuildSizes, + pub(crate) flags: wgt::AccelerationStructureFlags, + pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, } impl Resource for Tlas { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index fcb394e6e1..414348a227 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -4235,6 +4235,8 @@ bitflags::bitflags! { const INDIRECT = 1 << 8; /// Allows a buffer to be used as input for a bottom level acceleration structure build const BLAS_INPUT = 1 << 9; + /// Allows a buffer to be used as input for a top level acceleration structure build + const TLAS_INPUT = 1 << 10; } } diff --git a/wgpu/examples/hello-ray-triangle/main.rs b/wgpu/examples/hello-ray-triangle/main.rs index 0df828253e..12f8c7f2bd 100644 --- a/wgpu/examples/hello-ray-triangle/main.rs +++ b/wgpu/examples/hello-ray-triangle/main.rs @@ -1,5 +1,6 @@ use bytemuck::{Pod, Zeroable}; -use std::{borrow::Cow, mem, num::NonZeroU32}; +use std::{borrow::Cow, iter, mem, num::NonZeroU32}; +use wgc::ray_tracing::BlasBuildEntry; use wgpu::util::DeviceExt; use winit::{ dpi::{LogicalSize, PhysicalPosition}, @@ -163,13 +164,13 @@ async fn run(event_loop: EventLoop<()>, window: Window) { let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("Vertex Buffer"), contents: bytemuck::cast_slice(&vertex_data), - usage: wgpu::BufferUsages::VERTEX, + usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::BLAS_INPUT, }); let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("Index Buffer"), contents: bytemuck::cast_slice(&index_data), - usage: wgpu::BufferUsages::INDEX, + usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::BLAS_INPUT, }); let blas_geo_size_desc = wgpu::BlasTriangleGeometrySizeDescriptor { @@ -265,6 +266,30 @@ async fn run(event_loop: EventLoop<()>, window: Window) { ], }); + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + unsafe { + encoder.build_acceleration_structures_unsafe_tlas( + iter::once(&wgpu::BlasBuildEntry { + blas: &blas, + geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ + wgpu::BlasTriangleGeometry { + size: &blas_geo_size_desc, + vertex_buffer: &vertex_buf, + first_vertex: 0, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&index_buf), + index_buffer_offset: Some(0), + transform_buffer: None, + transform_buffer_offset: None, + }, + ]), + }), + iter::empty(), + ) + } + queue.submit(Some(encoder.finish())); + event_loop.run(move |event, _, control_flow| { // Have the closure take ownership of the resources. // `event_loop.run` never returns, therefore we must do this to ensure From e8daf51d830f6a6872c2c1a6bf2c22de53c853e7 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 29 Mar 2023 14:38:02 +0200 Subject: [PATCH 037/146] blas handle --- wgpu-core/src/command/ray_tracing.rs | 2 +- wgpu-core/src/ray_tracing.rs | 13 +++++++++---- wgpu-core/src/resource.rs | 2 +- wgpu/src/backend/direct.rs | 11 +++-------- wgpu/src/context.rs | 10 +++++----- wgpu/src/lib.rs | 15 +++++++++++---- 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index ed65699ef1..eb72d2f991 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -355,7 +355,7 @@ impl Global { mode: hal::AccelerationStructureBuildMode::Build, // TODO flags: blas.flags, source_acceleration_structure: None, - destination_acceleration_structure: blas.raw.as_ref().unwrap(), + destination_acceleration_structure: &blas.raw, scratch_buffer: &scratch_buffer, }) } diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 0c57d6d2ff..041ca987e6 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -99,7 +99,7 @@ impl Device { .map_err(DeviceError::from)?; Ok(resource::Blas { - raw: Some(raw), + raw: raw, device_id: Stored { value: id::Valid(self_id), ref_count: self.life_guard.add_ref(), @@ -166,7 +166,7 @@ impl Global { desc: &resource::BlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, id_in: Input, - ) -> (BlasId, Option) { + ) -> (BlasId, Option, Option) { profiling::scope!("Device::create_blas"); let hub = A::hub(self); @@ -191,6 +191,11 @@ impl Global { Ok(blas) => blas, Err(e) => break e, }; + + let handle = unsafe{ + device.raw.get_acceleration_structure_device_address(&blas.raw) + }; + let ref_count = blas.life_guard.add_ref(); let id = fid.assign(blas, &mut token); @@ -198,11 +203,11 @@ impl Global { device.trackers.lock().blas_s.insert_single(id, ref_count); - return (id.0, None); + return (id.0, Some(handle), None); }; let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); - (id, Some(error)) + (id, None, Some(error)) } pub fn device_create_tlas( diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 79e4a3b8e7..a86b358e03 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -800,7 +800,7 @@ pub type BlasDescriptor<'a> = wgt::CreateBlasDescriptor>; pub type TlasDescriptor<'a> = wgt::CreateTlasDescriptor>; pub struct Blas { - pub(crate) raw: Option, + pub(crate) raw: A::AccelerationStructure, pub(crate) device_id: Stored, pub(crate) life_guard: LifeGuard, pub(crate) size_info: hal::AccelerationStructureBuildSizes, diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 285fc66d31..024468f64b 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -2958,9 +2958,9 @@ impl crate::Context for Context { device_data: &Self::DeviceData, desc: &crate::CreateBlasDescriptor<'_>, sizes: wgt::BlasGeometrySizeDescriptors, - ) -> (Self::BlasId, Self::BlasData) { + ) -> (Self::BlasId, Option, Self::BlasData) { let global = &self.0; - let (id, error) = wgc::gfx_select!(device => global.device_create_blas( + let (id, handle, error) = wgc::gfx_select!(device => global.device_create_blas( *device, &desc.map_label(|l| l.map(Borrowed)), sizes, @@ -2975,14 +2975,9 @@ impl crate::Context for Context { "Device::create_blas", ); } - let x: Self::BufferData = Buffer { - error_sink: Arc::clone(&device_data.error_sink), - }; - let x: Self::BlasData = Blas { - error_sink: Arc::clone(&device_data.error_sink), - }; ( id, + handle, Blas { error_sink: Arc::clone(&device_data.error_sink), }, diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index b9020cda0a..af5f686b7f 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -1002,7 +1002,7 @@ pub trait Context: Debug + Send + Sized + Sync { device_data: &Self::DeviceData, desc: &CreateBlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, - ) -> (Self::BlasId, Self::BlasData); + ) -> (Self::BlasId, Option, Self::BlasData); fn device_create_tlas( &self, device: &Self::DeviceId, @@ -1937,7 +1937,7 @@ pub(crate) trait DynContext: Debug + Send + Sync { device_data: &crate::Data, desc: &crate::CreateBlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, - ) -> (ObjectId, Box); + ) -> (ObjectId, Option, Box); fn device_create_tlas( &self, device: &ObjectId, @@ -3908,11 +3908,11 @@ where device_data: &crate::Data, desc: &crate::CreateBlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, - ) -> (ObjectId, Box) { + ) -> (ObjectId, Option, Box) { let device = ::from(*device); let device_data = downcast_ref(device_data); - let (blas, data) = Context::device_create_blas(self, &device, device_data, desc, sizes); - (blas.into(), Box::new(data) as _) + let (blas, handle, data) = Context::device_create_blas(self, &device, device_data, desc, sizes); + (blas.into(), handle, Box::new(data) as _) } fn device_create_tlas( diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 6d918e6fa4..67c90fb29f 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -2249,7 +2249,7 @@ impl Device { desc: &CreateBlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, ) -> Blas { - let (id, data) = DynContext::device_create_blas( + let (id, handle, data) = DynContext::device_create_blas( &*self.context, &self.id, self.data.as_ref(), @@ -2261,15 +2261,16 @@ impl Device { context: Arc::clone(&self.context), id, data, + handle } } - /// Creates a [`Blas`]. - pub fn create_tlas(&self, desc: &CreateTlasDescriptor) -> Blas { + /// Creates a [`Tlas`]. + pub fn create_tlas(&self, desc: &CreateTlasDescriptor) -> Tlas { let (id, data) = DynContext::device_create_tlas(&*self.context, &self.id, self.data.as_ref(), desc); - Blas { + Tlas { context: Arc::clone(&self.context), id, data, @@ -4621,8 +4622,14 @@ pub struct Blas { context: Arc, id: ObjectId, data: Box, + handle: Option, } static_assertions::assert_impl_all!(Blas: Send, Sync); +impl Blas { + pub fn handle(&self) -> Option{ + self.handle + } +} #[derive(Debug)] pub struct Tlas { From f06de72249e900dce1b53ea1d7cdb988fb7199f4 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Thu, 30 Mar 2023 00:55:29 +0200 Subject: [PATCH 038/146] WIP tlas build should work --- wgpu-core/src/ray_tracing.rs | 8 +- wgpu/examples/hello-ray-triangle/main.rs | 197 ++++++++++++++++++++++- wgpu/src/context.rs | 3 +- wgpu/src/lib.rs | 4 +- 4 files changed, 203 insertions(+), 9 deletions(-) diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 041ca987e6..1ff4110b8a 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -140,7 +140,7 @@ impl Device { .create_acceleration_structure(&hal::AccelerationStructureDescriptor { label: desc.label.borrow_option(), size: size_info.acceleration_structure_size, - format: hal::AccelerationStructureFormat::BottomLevel, + format: hal::AccelerationStructureFormat::TopLevel, }) } .map_err(DeviceError::from)?; @@ -192,8 +192,10 @@ impl Global { Err(e) => break e, }; - let handle = unsafe{ - device.raw.get_acceleration_structure_device_address(&blas.raw) + let handle = unsafe { + device + .raw + .get_acceleration_structure_device_address(&blas.raw) }; let ref_count = blas.life_guard.add_ref(); diff --git a/wgpu/examples/hello-ray-triangle/main.rs b/wgpu/examples/hello-ray-triangle/main.rs index 12f8c7f2bd..d2923e3518 100644 --- a/wgpu/examples/hello-ray-triangle/main.rs +++ b/wgpu/examples/hello-ray-triangle/main.rs @@ -1,4 +1,5 @@ use bytemuck::{Pod, Zeroable}; +use glam::{Affine3A, Mat4, Vec3}; use std::{borrow::Cow, iter, mem, num::NonZeroU32}; use wgc::ray_tracing::BlasBuildEntry; use wgpu::util::DeviceExt; @@ -70,6 +71,158 @@ fn create_vertices() -> (Vec, Vec) { (vertex_data.to_vec(), index_data.to_vec()) } +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +struct Uniforms { + view_inverse: [[f32; 4]; 4], + proj_inverse: [[f32; 4]; 4], +} + +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +struct AccelerationStructureInstance { + transform: [f32; 12], + custom_index_and_mask: u32, + shader_binding_table_record_offset_and_flags: u32, + acceleration_structure_reference: u64, +} + +impl std::fmt::Debug for AccelerationStructureInstance { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Instance") + .field("transform", &self.transform) + .field("custom_index()", &self.custom_index()) + .field("mask()", &self.mask()) + .field( + "shader_binding_table_record_offset()", + &self.shader_binding_table_record_offset(), + ) + .field("flags()", &self.flags()) + .field( + "acceleration_structure_reference", + &self.acceleration_structure_reference, + ) + .finish() + } +} + +#[allow(dead_code)] +impl AccelerationStructureInstance { + const LOW_24_MASK: u32 = 0x00ff_ffff; + const MAX_U24: u32 = (1u32 << 24u32) - 1u32; + + #[inline] + fn affine_to_rows(mat: &Affine3A) -> [f32; 12] { + let row_0 = mat.matrix3.row(0); + let row_1 = mat.matrix3.row(1); + let row_2 = mat.matrix3.row(2); + let translation = mat.translation; + [ + row_0.x, + row_0.y, + row_0.z, + translation.x, + row_1.x, + row_1.y, + row_1.z, + translation.y, + row_2.x, + row_2.y, + row_2.z, + translation.z, + ] + } + + #[inline] + fn rows_to_affine(rows: &[f32; 12]) -> Affine3A { + Affine3A::from_cols_array(&[ + rows[0], rows[3], rows[6], rows[9], rows[1], rows[4], rows[7], rows[10], rows[2], + rows[5], rows[8], rows[11], + ]) + } + + pub fn transform_as_affine(&self) -> Affine3A { + Self::rows_to_affine(&self.transform) + } + pub fn set_transform(&mut self, transform: &Affine3A) { + self.transform = Self::affine_to_rows(&transform); + } + + pub fn custom_index(&self) -> u32 { + self.custom_index_and_mask & Self::LOW_24_MASK + } + + pub fn mask(&self) -> u8 { + (self.custom_index_and_mask >> 24) as u8 + } + + pub fn shader_binding_table_record_offset(&self) -> u32 { + self.shader_binding_table_record_offset_and_flags & Self::LOW_24_MASK + } + + pub fn flags(&self) -> u8 { + (self.shader_binding_table_record_offset_and_flags >> 24) as u8 + } + + pub fn set_custom_index(&mut self, custom_index: u32) { + debug_assert!( + custom_index <= Self::MAX_U24, + "custom_index uses more than 24 bits! {custom_index} > {}", + Self::MAX_U24 + ); + self.custom_index_and_mask = + (custom_index & Self::LOW_24_MASK) | (self.custom_index_and_mask & !Self::LOW_24_MASK) + } + + pub fn set_mask(&mut self, mask: u8) { + self.custom_index_and_mask = + (self.custom_index_and_mask & Self::LOW_24_MASK) | (u32::from(mask) << 24) + } + + pub fn set_shader_binding_table_record_offset( + &mut self, + shader_binding_table_record_offset: u32, + ) { + debug_assert!(shader_binding_table_record_offset <= Self::MAX_U24, "shader_binding_table_record_offset uses more than 24 bits! {shader_binding_table_record_offset} > {}", Self::MAX_U24); + self.shader_binding_table_record_offset_and_flags = (shader_binding_table_record_offset + & Self::LOW_24_MASK) + | (self.shader_binding_table_record_offset_and_flags & !Self::LOW_24_MASK) + } + + pub fn set_flags(&mut self, flags: u8) { + self.shader_binding_table_record_offset_and_flags = + (self.shader_binding_table_record_offset_and_flags & Self::LOW_24_MASK) + | (u32::from(flags) << 24) + } + + pub fn new( + transform: &Affine3A, + custom_index: u32, + mask: u8, + shader_binding_table_record_offset: u32, + flags: u8, + acceleration_structure_reference: u64, + ) -> Self { + debug_assert!( + custom_index <= Self::MAX_U24, + "custom_index uses more than 24 bits! {custom_index} > {}", + Self::MAX_U24 + ); + debug_assert!( + shader_binding_table_record_offset <= Self::MAX_U24, + "shader_binding_table_record_offset uses more than 24 bits! {shader_binding_table_record_offset} > {}", Self::MAX_U24 + ); + AccelerationStructureInstance { + transform: Self::affine_to_rows(transform), + custom_index_and_mask: (custom_index & Self::MAX_U24) | (u32::from(mask) << 24), + shader_binding_table_record_offset_and_flags: (shader_binding_table_record_offset + & Self::MAX_U24) + | (u32::from(flags) << 24), + acceleration_structure_reference, + } + } +} + async fn run(event_loop: EventLoop<()>, window: Window) { let size = window.inner_size(); @@ -157,7 +310,22 @@ async fn run(event_loop: EventLoop<()>, window: Window) { ..Default::default() }); - // Create the vertex and index buffers + let uniforms = { + let view = Mat4::look_at_rh(Vec3::new(0.0, 0.0, 2.5), Vec3::ZERO, Vec3::Y); + let proj = Mat4::perspective_rh(59.0_f32.to_radians(), 1.0, 0.001, 1000.0); + + Uniforms { + view_inverse: view.inverse().to_cols_array_2d(), + proj_inverse: proj.inverse().to_cols_array_2d(), + } + }; + + let uniform_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Uniform Buffer"), + contents: bytemuck::cast_slice(&[uniforms]), + usage: wgpu::BufferUsages::UNIFORM, + }); + let vertex_size = mem::size_of::(); let (vertex_data, index_data) = create_vertices(); @@ -199,6 +367,25 @@ async fn run(event_loop: EventLoop<()>, window: Window) { max_instances: 1, }); + let instance = AccelerationStructureInstance::new( + &Affine3A::from_translation(Vec3 { + x: 0.0, + y: 0.0, + z: 0.0, + }), + 0, + 0xff, + 0, + 0, + blas.handle().unwrap(), + ); + + let instance_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Instance Buffer"), + contents: bytemuck::cast_slice(&[instance]), + usage: wgpu::BufferUsages::TLAS_INPUT, + }); + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("rt_computer"), source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), @@ -285,8 +472,12 @@ async fn run(event_loop: EventLoop<()>, window: Window) { }, ]), }), - iter::empty(), - ) + iter::once(&wgpu::TlasBuildEntry { + tlas: &tlas, + instance_buffer: &instance_buf, + instance_count: 1, + }), + ); } queue.submit(Some(encoder.finish())); diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index af5f686b7f..05b7b60657 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -3911,7 +3911,8 @@ where ) -> (ObjectId, Option, Box) { let device = ::from(*device); let device_data = downcast_ref(device_data); - let (blas, handle, data) = Context::device_create_blas(self, &device, device_data, desc, sizes); + let (blas, handle, data) = + Context::device_create_blas(self, &device, device_data, desc, sizes); (blas.into(), handle, Box::new(data) as _) } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 67c90fb29f..3cfa51a865 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -2261,7 +2261,7 @@ impl Device { context: Arc::clone(&self.context), id, data, - handle + handle, } } @@ -4626,7 +4626,7 @@ pub struct Blas { } static_assertions::assert_impl_all!(Blas: Send, Sync); impl Blas { - pub fn handle(&self) -> Option{ + pub fn handle(&self) -> Option { self.handle } } From fd77e7d146629dfb326715b2f273f910ff3470ac Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Thu, 30 Mar 2023 08:04:31 +0200 Subject: [PATCH 039/146] "working" example --- Cargo.lock | 2 +- Cargo.toml | 3 +- wgpu-core/Cargo.toml | 3 +- wgpu-core/src/binding_model.rs | 12 ++- wgpu-core/src/command/ray_tracing.rs | 2 +- wgpu-core/src/device/mod.rs | 22 ++++- wgpu-core/src/hub.rs | 1 + wgpu-core/src/ray_tracing.rs | 2 +- wgpu-core/src/resource.rs | 2 +- wgpu-core/src/track/mod.rs | 3 + wgpu-core/src/validation.rs | 4 + wgpu-hal/Cargo.toml | 6 +- wgpu-hal/src/vulkan/adapter.rs | 3 + wgpu/examples/hello-ray-triangle/main.rs | 88 +++++++++++++++++--- wgpu/examples/hello-ray-triangle/shader.wgsl | 86 +++++++++++++++---- wgpu/src/backend/direct.rs | 3 + wgpu/src/lib.rs | 2 + 17 files changed, 200 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a78b7c94a..96b632c485 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1507,7 +1507,7 @@ dependencies = [ [[package]] name = "naga" version = "0.11.0" -source = "git+https://github.com/gfx-rs/naga?rev=9742f1616c3e3dd2cc9a5880616fc886c391bb9f#9742f1616c3e3dd2cc9a5880616fc886c391bb9f" +source = "git+https://github.com/gfx-rs/naga?rev=53d62b9ede64898681c0dbc70d04296caf90ed16#53d62b9ede64898681c0dbc70d04296caf90ed16" dependencies = [ "bit-set", "bitflags", diff --git a/Cargo.toml b/Cargo.toml index c3f96b5961..eaed94375c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,8 +42,7 @@ version = "0.15" [workspace.dependencies.naga] git = "https://github.com/gfx-rs/naga" -rev = "9742f1616c3e3dd2cc9a5880616fc886c391bb9f" -version = "0.11.0" +rev = "53d62b9ede64898681c0dbc70d04296caf90ed16" [workspace.dependencies] arrayvec = "0.7" diff --git a/wgpu-core/Cargo.toml b/wgpu-core/Cargo.toml index 06adf0f9b1..9f5e7d29a3 100644 --- a/wgpu-core/Cargo.toml +++ b/wgpu-core/Cargo.toml @@ -67,8 +67,7 @@ thiserror = "1" [dependencies.naga] git = "https://github.com/gfx-rs/naga" -rev = "9742f1616c3e3dd2cc9a5880616fc886c391bb9f" -version = "0.11.0" +rev = "53d62b9ede64898681c0dbc70d04296caf90ed16" features = ["clone", "span", "validate"] [dependencies.wgt] diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 347fe015ae..e90877e76a 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -2,7 +2,9 @@ use crate::{ device::{DeviceError, MissingDownlevelFlags, MissingFeatures, SHADER_STAGE_COUNT}, error::{ErrorFormatter, PrettyError}, hub::{HalApi, Resource}, - id::{BindGroupLayoutId, BufferId, DeviceId, SamplerId, TextureId, TextureViewId, Valid}, + id::{ + BindGroupLayoutId, BufferId, DeviceId, SamplerId, TextureId, TextureViewId, TlasId, Valid, + }, init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction}, track::{BindGroupStates, UsageConflict}, validation::{MissingBufferUsageError, MissingTextureUsageError}, @@ -169,6 +171,8 @@ pub enum CreateBindGroupError { StorageReadNotSupported(wgt::TextureFormat), #[error(transparent)] ResourceUsageConflict(#[from] UsageConflict), + #[error("Tlas {0:?} is invalid or destroyed")] + InvalidTlas(TlasId), } impl PrettyError for CreateBindGroupError { @@ -295,6 +299,7 @@ pub(crate) struct BindingTypeMaxCountValidator { storage_buffers: PerStageBindingTypeCounter, storage_textures: PerStageBindingTypeCounter, uniform_buffers: PerStageBindingTypeCounter, + acceleration_structures: PerStageBindingTypeCounter, } impl BindingTypeMaxCountValidator { @@ -330,7 +335,9 @@ impl BindingTypeMaxCountValidator { wgt::BindingType::StorageTexture { .. } => { self.storage_textures.add(binding.visibility, count); } - wgt::BindingType::AccelerationStructure => todo!(), + wgt::BindingType::AccelerationStructure => { + self.acceleration_structures.add(binding.visibility, count); + } } } @@ -680,6 +687,7 @@ pub enum BindingResource<'a> { SamplerArray(Cow<'a, [SamplerId]>), TextureView(TextureViewId), TextureViewArray(Cow<'a, [TextureViewId]>), + AccelerationStructure(TlasId), } #[derive(Clone, Debug, Error)] diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index eb72d2f991..7ada51d9e1 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -375,7 +375,7 @@ impl Global { mode: hal::AccelerationStructureBuildMode::Build, // TODO flags: tlas.flags, source_acceleration_structure: None, - destination_acceleration_structure: tlas.raw.as_ref().unwrap(), + destination_acceleration_structure: &tlas.raw, scratch_buffer: &scratch_buffer, }) } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index ce64521dda..7b6c263013 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -1493,6 +1493,10 @@ impl Device { .flags .contains(wgt::DownlevelFlags::MULTISAMPLED_SHADING), ); + caps.set( + Caps::RAY_QUERY, + self.features.contains(wgt::Features::RAY_QUERY), + ); let info = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), caps) .validate(&module) @@ -1744,7 +1748,7 @@ impl Device { }, ) } - Bt::AccelerationStructure => todo!(), + Bt::AccelerationStructure => (None, WritableStorage::No), }; // Validate the count parameter @@ -2036,7 +2040,8 @@ impl Device { let (buffer_guard, mut token) = hub.buffers.read(token); let (texture_guard, mut token) = hub.textures.read(&mut token); //skip token let (texture_view_guard, mut token) = hub.texture_views.read(&mut token); - let (sampler_guard, _) = hub.samplers.read(&mut token); + let (sampler_guard, mut token) = hub.samplers.read(&mut token); + let (tlas_guard, _) = hub.tlas_s.read(&mut token); let mut used_buffer_ranges = Vec::new(); let mut used_texture_ranges = Vec::new(); @@ -2044,6 +2049,7 @@ impl Device { let mut hal_buffers = Vec::new(); let mut hal_samplers = Vec::new(); let mut hal_textures = Vec::new(); + let mut hal_tlas_s = Vec::new(); for entry in desc.entries.iter() { let binding = entry.binding; // Find the corresponding declaration in the layout @@ -2206,6 +2212,16 @@ impl Device { (res_index, num_bindings) } + Br::AccelerationStructure(id) => { + let tlas = used + .acceleration_structures + .add_single(&*&tlas_guard, id) + .ok_or(Error::InvalidTlas(id))?; + + let res_index = hal_tlas_s.len(); + hal_tlas_s.push(&tlas.raw); + (res_index, 1) + } }; hal_entries.push(hal::BindGroupEntry { @@ -2231,7 +2247,7 @@ impl Device { buffers: &hal_buffers, samplers: &hal_samplers, textures: &hal_textures, - acceleration_structures: &[], + acceleration_structures: &hal_tlas_s, }; let raw = unsafe { self.raw diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 4451357bbc..1693bb6590 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -550,6 +550,7 @@ impl Access> for Device {} impl Access> for CommandBuffer {} impl Access> for Buffer {} impl Access> for Blas {} +impl Access> for Sampler {} #[cfg(debug_assertions)] thread_local! { diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 1ff4110b8a..2e02623e8a 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -146,7 +146,7 @@ impl Device { .map_err(DeviceError::from)?; Ok(resource::Tlas { - raw: Some(raw), + raw: raw, device_id: Stored { value: id::Valid(self_id), ref_count: self.life_guard.add_ref(), diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index a86b358e03..78c3d8af44 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -818,7 +818,7 @@ impl Resource for Blas { } pub struct Tlas { - pub(crate) raw: Option, + pub(crate) raw: A::AccelerationStructure, pub(crate) device_id: Stored, pub(crate) life_guard: LifeGuard, pub(crate) size_info: hal::AccelerationStructureBuildSizes, diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index a91d42a2f9..f56094caa0 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -317,6 +317,7 @@ pub(crate) struct BindGroupStates { pub textures: TextureBindGroupState, pub views: StatelessBindGroupSate, id::TextureViewId>, pub samplers: StatelessBindGroupSate, id::SamplerId>, + pub acceleration_structures: StatelessBindGroupSate, id::TlasId>, } impl BindGroupStates { @@ -326,6 +327,7 @@ impl BindGroupStates { textures: TextureBindGroupState::new(), views: StatelessBindGroupSate::new(), samplers: StatelessBindGroupSate::new(), + acceleration_structures: StatelessBindGroupSate::new(), } } @@ -338,6 +340,7 @@ impl BindGroupStates { self.textures.optimize(); self.views.optimize(); self.samplers.optimize(); + self.acceleration_structures.optimize(); } } diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index bc89f41449..54d03ee7b7 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -17,6 +17,7 @@ enum ResourceType { Sampler { comparison: bool, }, + AccelerationStructure, } #[derive(Debug)] @@ -537,6 +538,7 @@ impl Resource { } usage } + ResourceType::AccelerationStructure => GlobalUse::QUERY, }; if allowed_usage.contains(shader_usage) { @@ -627,6 +629,7 @@ impl Resource { }, } } + ResourceType::AccelerationStructure => BindingType::AccelerationStructure, }) } } @@ -910,6 +913,7 @@ impl Interface { naga::TypeInner::Array { stride, .. } => ResourceType::Buffer { size: wgt::BufferSize::new(stride as u64).unwrap(), }, + naga::TypeInner::AccelerationStructure => ResourceType::AccelerationStructure, ref other => ResourceType::Buffer { size: wgt::BufferSize::new(other.size(&module.constants) as u64).unwrap(), }, diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 722fb1196c..c7962bb39c 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -119,15 +119,13 @@ android_system_properties = "0.1.1" [dependencies.naga] git = "https://github.com/gfx-rs/naga" -rev = "9742f1616c3e3dd2cc9a5880616fc886c391bb9f" -version = "0.11.0" +rev = "53d62b9ede64898681c0dbc70d04296caf90ed16" features = ["clone"] # DEV dependencies [dev-dependencies.naga] git = "https://github.com/gfx-rs/naga" -rev = "9742f1616c3e3dd2cc9a5880616fc886c391bb9f" -version = "0.11.0" +rev = "53d62b9ede64898681c0dbc70d04296caf90ed16" features = ["wgsl-in"] [dev-dependencies] diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index d7252760e8..86a373a4d3 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1368,6 +1368,9 @@ impl super::Adapter { // But this requires cloning the `spv::Options` struct, which has heap allocations. true, // could check `super::Workarounds::SEPARATE_ENTRY_POINTS` ); + if features.contains(wgt::Features::RAY_QUERY) { + capabilities.push(spv::Capability::RayQueryKHR); + } spv::Options { lang_version: (1, 0), flags, diff --git a/wgpu/examples/hello-ray-triangle/main.rs b/wgpu/examples/hello-ray-triangle/main.rs index d2923e3518..ce695f4b45 100644 --- a/wgpu/examples/hello-ray-triangle/main.rs +++ b/wgpu/examples/hello-ray-triangle/main.rs @@ -1,6 +1,6 @@ use bytemuck::{Pod, Zeroable}; -use glam::{Affine3A, Mat4, Vec3}; -use std::{borrow::Cow, iter, mem, num::NonZeroU32}; +use glam::{Affine3A, Mat4, Quat, Vec3}; +use std::{borrow::Cow, iter, mem, num::NonZeroU32, time::Instant}; use wgc::ray_tracing::BlasBuildEntry; use wgpu::util::DeviceExt; use winit::{ @@ -261,7 +261,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) { let swapchain_capabilities = surface.get_capabilities(&adapter); let swapchain_format = swapchain_capabilities.formats[0]; - let config = wgpu::SurfaceConfiguration { + let mut config = wgpu::SurfaceConfiguration { usage: wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::RENDER_ATTACHMENT, format: swapchain_format, width: size.width, @@ -367,11 +367,11 @@ async fn run(event_loop: EventLoop<()>, window: Window) { max_instances: 1, }); - let instance = AccelerationStructureInstance::new( + let mut instance = AccelerationStructureInstance::new( &Affine3A::from_translation(Vec3 { x: 0.0, y: 0.0, - z: 0.0, + z: -3.0, }), 0, 0xff, @@ -383,7 +383,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) { let instance_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("Instance Buffer"), contents: bytemuck::cast_slice(&[instance]), - usage: wgpu::BufferUsages::TLAS_INPUT, + usage: wgpu::BufferUsages::TLAS_INPUT | wgpu::BufferUsages::COPY_DST, }); let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { @@ -408,10 +408,20 @@ async fn run(event_loop: EventLoop<()>, window: Window) { let compute_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { label: None, layout: &compute_bind_group_layout, - entries: &[wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::TextureView(&rt_view), - }], + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&rt_view), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: uniform_buf.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: wgpu::BindingResource::AccelerationStructure(&tlas), + }, + ], }); let blit_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { @@ -481,6 +491,8 @@ async fn run(event_loop: EventLoop<()>, window: Window) { } queue.submit(Some(encoder.finish())); + let mut start_inst = Instant::now(); + event_loop.run(move |event, _, control_flow| { // Have the closure take ownership of the resources. // `event_loop.run` never returns, therefore we must do this to ensure @@ -494,12 +506,20 @@ async fn run(event_loop: EventLoop<()>, window: Window) { &blit_pipeline, ); - *control_flow = ControlFlow::Wait; + *control_flow = ControlFlow::Poll; match event { + winit::event::Event::RedrawEventsCleared => { + window.request_redraw(); + } Event::WindowEvent { event: WindowEvent::Resized(size), .. - } => {} + } => { + config.width = size.width; + config.height = size.height; + surface.configure(&device, &config); + window.request_redraw(); + } Event::RedrawRequested(_) => { let frame = surface .get_current_texture() @@ -508,8 +528,50 @@ async fn run(event_loop: EventLoop<()>, window: Window) { .texture .create_view(&wgpu::TextureViewDescriptor::default()); + let anim_time = start_inst.elapsed().as_secs_f64() as f32; + instance.set_transform(&Affine3A::from_rotation_translation( + Quat::from_euler( + glam::EulerRot::XYZ, + anim_time * 0.342, + anim_time * 0.254, + anim_time * 0.832, + ), + Vec3 { + x: 0.0, + y: 0.0, + z: -3.0, + }, + )); + queue.write_buffer(&instance_buf, 0, bytemuck::cast_slice(&[instance])); + let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + unsafe { + encoder.build_acceleration_structures_unsafe_tlas( + iter::once(&wgpu::BlasBuildEntry { + blas: &blas, + geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ + wgpu::BlasTriangleGeometry { + size: &blas_geo_size_desc, + vertex_buffer: &vertex_buf, + first_vertex: 0, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&index_buf), + index_buffer_offset: Some(0), + transform_buffer: None, + transform_buffer_offset: None, + }, + ]), + }), + iter::once(&wgpu::TlasBuildEntry { + tlas: &tlas, + instance_buffer: &instance_buf, + instance_count: 1, + }), + ); + } + { let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None }); @@ -552,7 +614,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) { fn main() { let event_loop = EventLoop::new(); let window = winit::window::Window::new(&event_loop).unwrap(); - window.set_inner_size(LogicalSize::new(600, 400)); + window.set_inner_size(LogicalSize::new(800, 800)); window.set_outer_position(PhysicalPosition::new(-1000, 0)); window.set_resizable(false); diff --git a/wgpu/examples/hello-ray-triangle/shader.wgsl b/wgpu/examples/hello-ray-triangle/shader.wgsl index b3492eb981..d5320976b1 100644 --- a/wgpu/examples/hello-ray-triangle/shader.wgsl +++ b/wgpu/examples/hello-ray-triangle/shader.wgsl @@ -1,23 +1,81 @@ -// const MAX_BOUNCES: i32 = 3; - -// struct Parameters { -// cam_position: vec3, -// depth: f32, -// cam_orientation: vec4, -// fov: vec2, -// torus_radius: f32, -// rotation_angle: f32, -// }; - -// var parameters: Parameters; -// var acc_struct: acceleration_structure; +/* +let RAY_FLAG_NONE = 0x00u; +let RAY_FLAG_OPAQUE = 0x01u; +let RAY_FLAG_NO_OPAQUE = 0x02u; +let RAY_FLAG_TERMINATE_ON_FIRST_HIT = 0x04u; +let RAY_FLAG_SKIP_CLOSEST_HIT_SHADER = 0x08u; +let RAY_FLAG_CULL_BACK_FACING = 0x10u; +let RAY_FLAG_CULL_FRONT_FACING = 0x20u; +let RAY_FLAG_CULL_OPAQUE = 0x40u; +let RAY_FLAG_CULL_NO_OPAQUE = 0x80u; +let RAY_FLAG_SKIP_TRIANGLES = 0x100u; +let RAY_FLAG_SKIP_AABBS = 0x200u; + +let RAY_QUERY_INTERSECTION_NONE = 0u; +let RAY_QUERY_INTERSECTION_TRIANGLE = 1u; +let RAY_QUERY_INTERSECTION_GENERATED = 2u; +let RAY_QUERY_INTERSECTION_AABB = 4u; + +struct RayDesc { + flags: u32, + cull_mask: u32, + t_min: f32, + t_max: f32, + origin: vec3, + dir: vec3, +} + +struct RayIntersection { + kind: u32, + t: f32, + instance_custom_index: u32, + instance_id: u32, + sbt_record_offset: u32, + geometry_index: u32, + primitive_index: u32, + barycentrics: vec2, + front_face: bool, + object_to_world: mat4x3, + world_to_object: mat4x3, +} +*/ + +struct Uniforms { + view_inv: mat4x4, + proj_inv: mat4x4, +}; + @group(0) @binding(0) var output: texture_storage_2d; +@group(0) @binding(1) +var uniforms: Uniforms; + +@group(0) @binding(2) +var acc_struct: acceleration_structure; @compute @workgroup_size(8, 8) fn main(@builtin(global_invocation_id) global_id: vec3) { let target_size = textureDimensions(output); - let color = vec4(vec2(global_id.xy) / vec2(target_size), 0.0, 0.0); + var color = vec4(vec2(global_id.xy) / vec2(target_size), 0.0, 0.0); + + + let pixel_center = vec2(global_id.yx) + vec2(0.5); + let in_uv = pixel_center/vec2(target_size.yx); + let d = in_uv * 2.0 - 1.0; + + let origin = (uniforms.view_inv * vec4(0.0,0.0,0.0,1.0)).xyz; + let temp = uniforms.proj_inv * vec4(d.x, d.y, 1.0, 1.0); + let direction = (uniforms.view_inv * vec4(normalize(temp.xyz), 0.0)).xyz; + + var rq: ray_query; + rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 0.1, 200.0, origin, direction)); + rayQueryProceed(&rq); + + let intersection = rayQueryGetCommittedIntersection(&rq); + if (intersection.kind != RAY_QUERY_INTERSECTION_NONE) { + color = vec4(intersection.barycentrics, 1.0 - intersection.barycentrics.x - intersection.barycentrics.y, 0.0); + } + textureStore(output, global_id.xy, color); } diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 024468f64b..299fb21c0a 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -1059,6 +1059,9 @@ impl crate::Context for Context { &remaining_arrayed_texture_views[array.len()..]; bm::BindingResource::TextureViewArray(Owned(views)) } + BindingResource::AccelerationStructure(acceleration_structure) => { + bm::BindingResource::AccelerationStructure(acceleration_structure.id.into()) + } }, }) .collect::>(); diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 3cfa51a865..f9867b4071 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -760,6 +760,8 @@ pub enum BindingResource<'a> { /// Corresponds to [`wgt::BindingType::Texture`] and [`wgt::BindingType::StorageTexture`] with /// [`BindGroupLayoutEntry::count`] set to Some. TextureViewArray(&'a [&'a TextureView]), + /// Todo + AccelerationStructure(&'a Tlas), } static_assertions::assert_impl_all!(BindingResource: Send, Sync); From fae31f0a757ff7517c5f3837fc22661de5228833 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Thu, 30 Mar 2023 15:25:16 +0200 Subject: [PATCH 040/146] WIP better iterators --- wgpu-core/src/command/ray_tracing.rs | 42 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 7ada51d9e1..6ddf775b5a 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -66,7 +66,7 @@ impl Global { }) .collect(); - let tlas_storage: Vec<_> = tlas_iter.collect(); + // let tlas_storage: Vec<_> = tlas_iter.collect(); // #[cfg(feature = "trace")] // if let Some(ref mut list) = cmd_buf.commands { @@ -275,11 +275,10 @@ impl Global { blas_refs.push(blas); } - let mut tlas_refs = Vec::<&Tlas>::new(); let mut scratch_buffer_tlas_size = 0; - let mut scratch_buffer_tlas_offsets = Vec::::new(); - let mut tlas_entry_storage = Vec::>::new(); - for entry in &tlas_storage { + + let mut tlas_storage = Vec::<(&Tlas, hal::AccelerationStructureEntries, u64)>::new(); + for entry in tlas_iter { let instance_buffer = { let (instance_buffer, instance_pending) = cmd_buf .trackers @@ -308,24 +307,24 @@ impl Global { instance_raw }; - tlas_entry_storage.push(hal::AccelerationStructureEntries::Instances( - AccelerationStructureInstances { - buffer: Some(instance_buffer), - offset: 0, - count: entry.instance_count, - }, - )); - let tlas = cmd_buf .trackers .tlas_s .add_single(&tlas_guard, entry.tlas_id) .ok_or(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id))?; - scratch_buffer_tlas_offsets.push(scratch_buffer_tlas_size); + let scratch_buffer_offset = scratch_buffer_tlas_size; scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; // TODO Alignment - tlas_refs.push(tlas); + tlas_storage.push(( + tlas, + hal::AccelerationStructureEntries::Instances(AccelerationStructureInstances { + buffer: Some(instance_buffer), + offset: 0, + count: entry.instance_count, + }), + scratch_buffer_offset, + )); } let scratch_buffer = unsafe { @@ -368,10 +367,9 @@ impl Global { let mut tlas_descriptors = Vec::>::with_capacity(tlas_storage.len()); - for (i, _entry) in tlas_storage.iter().enumerate() { - let tlas = tlas_refs[i]; + for (tlas, entries, _scratch_buffer_offset) in &tlas_storage { tlas_descriptors.push(hal::BuildAccelerationStructureDescriptor { - entries: &tlas_entry_storage[i], + entries, mode: hal::AccelerationStructureBuildMode::Build, // TODO flags: tlas.flags, source_acceleration_structure: None, @@ -382,8 +380,8 @@ impl Global { let mut tlas_descriptor_references = Vec::<&hal::BuildAccelerationStructureDescriptor>::with_capacity(tlas_storage.len()); - for (i, _entry) in tlas_storage.iter().enumerate() { - tlas_descriptor_references.push(&tlas_descriptors[i]); + for descriptor in &tlas_descriptors { + tlas_descriptor_references.push(descriptor); } let cmd_buf_raw = cmd_buf.encoder.open(); @@ -392,7 +390,9 @@ impl Global { if !blas_descriptor_references.is_empty() { cmd_buf_raw.build_acceleration_structures(&blas_descriptor_references); } - cmd_buf_raw.transition_buffers(iter::once(scratch_buffer_barrier)); + if !blas_descriptor_references.is_empty() && !tlas_descriptor_references.is_empty() { + cmd_buf_raw.transition_buffers(iter::once(scratch_buffer_barrier)); + } if !tlas_descriptor_references.is_empty() { cmd_buf_raw.build_acceleration_structures(&tlas_descriptor_references); } From 07dae896f5e3d4648193611d82ceb668e425c2d7 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Thu, 30 Mar 2023 17:06:30 +0200 Subject: [PATCH 041/146] iterators as inputs --- wgpu-hal/examples/ray-traced-triangle/main.rs | 32 +++++++++++-------- wgpu-hal/src/dx11/command.rs | 10 ++++-- wgpu-hal/src/dx11/device.rs | 4 +-- wgpu-hal/src/dx12/command.rs | 10 ++++-- wgpu-hal/src/dx12/device.rs | 4 +-- wgpu-hal/src/empty.rs | 14 +++++--- wgpu-hal/src/gles/command.rs | 10 ++++-- wgpu-hal/src/gles/device.rs | 4 +-- wgpu-hal/src/lib.rs | 16 ++++++---- wgpu-hal/src/vulkan/command.rs | 30 +++++++++-------- wgpu-hal/src/vulkan/device.rs | 6 ++-- 11 files changed, 85 insertions(+), 55 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 88c66c4bba..b00fc2f6ee 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -460,7 +460,7 @@ impl Example { transform: None, flags: hal::AccelerationStructureGeometryFlags::OPAQUE, }]; - let blas_entries = hal::AccelerationStructureEntries::Triangles(&blas_triangles); + let blas_entries = hal::AccelerationStructureEntries::Triangles(blas_triangles); let mut tlas_entries = hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { @@ -704,16 +704,18 @@ impl Example { unsafe { cmd_encoder.begin_encoding(Some("init")).unwrap() }; unsafe { - cmd_encoder.build_acceleration_structures(&[ - &hal::BuildAccelerationStructureDescriptor { + cmd_encoder.build_acceleration_structures( + 1, + [hal::BuildAccelerationStructureDescriptor { mode: hal::AccelerationStructureBuildMode::Build, flags: hal::AccelerationStructureBuildFlags::PREFER_FAST_TRACE, destination_acceleration_structure: &blas, scratch_buffer: &scratch_buffer, entries: &blas_entries, source_acceleration_structure: None, - }, - ]); + scratch_buffer_offset: 0, + }], + ); let as_barrier = hal::BufferBarrier { buffer: &scratch_buffer, @@ -722,16 +724,18 @@ impl Example { }; cmd_encoder.transition_buffers(iter::once(as_barrier)); - cmd_encoder.build_acceleration_structures(&[ - &hal::BuildAccelerationStructureDescriptor { + cmd_encoder.build_acceleration_structures( + 1, + [hal::BuildAccelerationStructureDescriptor { mode: hal::AccelerationStructureBuildMode::Build, flags: tlas_flags, destination_acceleration_structure: &tlas, scratch_buffer: &scratch_buffer, entries: &tlas_entries, source_acceleration_structure: None, - }, - ]); + scratch_buffer_offset: 0, + }], + ); let texture_barrier = hal::TextureBarrier { texture: &texture, @@ -836,16 +840,18 @@ impl Example { count: self.instances.len() as u32, offset: 0, }; - ctx.encoder.build_acceleration_structures(&[ - &hal::BuildAccelerationStructureDescriptor { + ctx.encoder.build_acceleration_structures( + 1, + [hal::BuildAccelerationStructureDescriptor { mode: hal::AccelerationStructureBuildMode::Update, flags: tlas_flags, destination_acceleration_structure: &self.tlas, scratch_buffer: &self.scratch_buffer, entries: &hal::AccelerationStructureEntries::Instances(instances), source_acceleration_structure: Some(&self.tlas), - }, - ]); + scratch_buffer_offset: 0, + }], + ); let as_barrier = hal::BufferBarrier { buffer: &self.scratch_buffer, diff --git a/wgpu-hal/src/dx11/command.rs b/wgpu-hal/src/dx11/command.rs index 113a14e179..2d04dc518c 100644 --- a/wgpu-hal/src/dx11/command.rs +++ b/wgpu-hal/src/dx11/command.rs @@ -266,10 +266,14 @@ impl crate::CommandEncoder for super::CommandEncoder { todo!() } - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structures<'a, T>( &mut self, - desc: &[&crate::BuildAccelerationStructureDescriptor], - ) { + _descriptor_count: u32, + _descriptors: T, + ) where + super::Api: 'a, + T: IntoIterator>, + { unimplemented!() } } diff --git a/wgpu-hal/src/dx11/device.rs b/wgpu-hal/src/dx11/device.rs index 373ae7d0b0..cdfaba26f4 100644 --- a/wgpu-hal/src/dx11/device.rs +++ b/wgpu-hal/src/dx11/device.rs @@ -207,9 +207,9 @@ impl crate::Device for super::Device { ) -> Result { unimplemented!() } - unsafe fn get_acceleration_structure_build_sizes( + unsafe fn get_acceleration_structure_build_sizes<'a>( &self, - desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor<'a, super::Api>, ) -> crate::AccelerationStructureBuildSizes { unimplemented!() } diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 0b2068323d..6d24e9862e 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1141,10 +1141,14 @@ impl crate::CommandEncoder for super::CommandEncoder { }; } - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structures<'a, T>( &mut self, - _desc: &[&crate::BuildAccelerationStructureDescriptor], - ) { + _descriptor_count: u32, + _descriptors: T, + ) where + super::Api: 'a, + T: IntoIterator>, + { // Implement using `BuildRaytracingAccelerationStructure`: // https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#buildraytracingaccelerationstructure todo!() diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index dd53b80e43..10c9f4b394 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -1590,9 +1590,9 @@ impl crate::Device for super::Device { } } - unsafe fn get_acceleration_structure_build_sizes( + unsafe fn get_acceleration_structure_build_sizes<'a>( &self, - _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor<'a, super::Api>, ) -> crate::AccelerationStructureBuildSizes { // Implement using `GetRaytracingAccelerationStructurePrebuildInfo`: // https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#getraytracingaccelerationstructureprebuildinfo diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index b86d2f90a1..9f84f83a37 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -243,9 +243,9 @@ impl crate::Device for Context { ) -> DeviceResult { Ok(Resource) } - unsafe fn get_acceleration_structure_build_sizes( + unsafe fn get_acceleration_structure_build_sizes<'a>( &self, - _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor<'a, Api>, ) -> crate::AccelerationStructureBuildSizes { Default::default() } @@ -431,9 +431,13 @@ impl crate::CommandEncoder for Encoder { unsafe fn dispatch(&mut self, count: [u32; 3]) {} unsafe fn dispatch_indirect(&mut self, buffer: &Resource, offset: wgt::BufferAddress) {} - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structures<'a, T>( &mut self, - _desc: &[&crate::BuildAccelerationStructureDescriptor], - ) { + _descriptor_count: u32, + descriptors: T, + ) where + Api: 'a, + T: IntoIterator>, + { } } diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index afff9c08b4..ad91ed904b 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -1061,10 +1061,14 @@ impl crate::CommandEncoder for super::CommandEncoder { }); } - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structures<'a, T>( &mut self, - _desc: &[&crate::BuildAccelerationStructureDescriptor], - ) { + _descriptor_count: u32, + _descriptors: T, + ) where + super::Api: 'a, + T: IntoIterator>, + { unimplemented!() } } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 25dcddde41..fa867412ca 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -1327,9 +1327,9 @@ impl crate::Device for super::Device { ) -> Result<(), crate::DeviceError> { unimplemented!() } - unsafe fn get_acceleration_structure_build_sizes( + unsafe fn get_acceleration_structure_build_sizes<'a>( &self, - _desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + _desc: &crate::GetAccelerationStructureBuildSizesDescriptor<'a, super::Api>, ) -> crate::AccelerationStructureBuildSizes { unimplemented!() } diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 7d32ccf09d..3a772d2444 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -575,10 +575,13 @@ pub trait CommandEncoder: Send + Sync + fmt::Debug { /// Consequences of this limitation: /// - scratch buffers need to be unique /// - a tlas can't be build in the same call with a blas it contains - unsafe fn build_acceleration_structures( + unsafe fn build_acceleration_structures<'a, T>( &mut self, - descriptors: &[&BuildAccelerationStructureDescriptor], - ); + descriptor_count: u32, + descriptors: T, + ) where + A: 'a, + T: IntoIterator>; } bitflags!( @@ -1380,6 +1383,7 @@ pub struct BuildAccelerationStructureDescriptor<'a, A: Api> { pub source_acceleration_structure: Option<&'a A::AccelerationStructure>, pub destination_acceleration_structure: &'a A::AccelerationStructure, pub scratch_buffer: &'a A::Buffer, + pub scratch_buffer_offset: wgt::BufferAddress, } /// - All buffers, buffer addresses and offsets will be ignored. @@ -1400,8 +1404,8 @@ pub struct GetAccelerationStructureBuildSizesDescriptor<'a, A: Api> { #[derive(Debug)] pub enum AccelerationStructureEntries<'a, A: Api> { Instances(AccelerationStructureInstances<'a, A>), - Triangles(&'a [AccelerationStructureTriangles<'a, A>]), - AABBs(&'a [AccelerationStructureAABBs<'a, A>]), + Triangles(Vec>), + AABBs(Vec>), } /// * `first_vertex` - offset in the vertex buffer (as number of vertices) @@ -1454,4 +1458,4 @@ pub struct AccelerationStructureTriangleTransform<'a, A: Api> { } pub type AccelerationStructureBuildFlags = wgt::AccelerationStructureFlags; -pub type AccelerationStructureGeometryFlags = wgt::AccelerationStructureGeometryFlags; \ No newline at end of file +pub type AccelerationStructureGeometryFlags = wgt::AccelerationStructureGeometryFlags; diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 0c7833cb5a..07976c266d 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -366,12 +366,14 @@ impl crate::CommandEncoder for super::CommandEncoder { }; } - unsafe fn build_acceleration_structures( - &mut self, - descriptors: &[&crate::BuildAccelerationStructureDescriptor], - ) { + unsafe fn build_acceleration_structures<'a, T>(&mut self, descriptor_count: u32, descriptors: T) + where + super::Api: 'a, + T: IntoIterator>, + { const CAPACITY_OUTER: usize = 8; const CAPACITY_INNER: usize = 1; + let descriptor_count = descriptor_count as usize; let ray_tracing_functions = match self.device.extension_fns.ray_tracing { Some(ref functions) => functions, @@ -393,22 +395,22 @@ impl crate::CommandEncoder for super::CommandEncoder { let mut ranges_storage = smallvec::SmallVec::< [smallvec::SmallVec<[vk::AccelerationStructureBuildRangeInfoKHR; CAPACITY_INNER]>; CAPACITY_OUTER], - >::with_capacity(descriptors.len()); + >::with_capacity(descriptor_count); let mut geometries_storage = smallvec::SmallVec::< [smallvec::SmallVec<[vk::AccelerationStructureGeometryKHR; CAPACITY_INNER]>; CAPACITY_OUTER], - >::with_capacity(descriptors.len()); + >::with_capacity(descriptor_count); // pointers to all the data required for cmd_build_acceleration_structures let mut geometry_infos = smallvec::SmallVec::< [vk::AccelerationStructureBuildGeometryInfoKHR; CAPACITY_OUTER], - >::with_capacity(descriptors.len()); + >::with_capacity(descriptor_count); let mut ranges_ptrs = smallvec::SmallVec::< [&[vk::AccelerationStructureBuildRangeInfoKHR]; CAPACITY_OUTER], - >::with_capacity(descriptors.len()); + >::with_capacity(descriptor_count); for desc in descriptors { - let (geometries, ranges) = match *desc.entries { + let (geometries, ranges) = match desc.entries { crate::AccelerationStructureEntries::Instances(ref instances) => { let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder( ) @@ -529,9 +531,7 @@ impl crate::CommandEncoder for super::CommandEncoder { ranges_storage.push(ranges); geometries_storage.push(geometries); - } - for (i, desc) in descriptors.iter().enumerate() { let scratch_device_address = unsafe { ray_tracing_functions .buffer_device_address @@ -549,10 +549,9 @@ impl crate::CommandEncoder for super::CommandEncoder { .ty(ty) .mode(conv::map_acceleration_structure_build_mode(desc.mode)) .flags(conv::map_acceleration_structure_flags(desc.flags)) - .geometries(&geometries_storage[i]) // pointer must live .dst_acceleration_structure(desc.destination_acceleration_structure.raw) .scratch_data(vk::DeviceOrHostAddressKHR { - device_address: scratch_device_address, + device_address: scratch_device_address + desc.scratch_buffer_offset, }); if desc.mode == crate::AccelerationStructureBuildMode::Update { @@ -563,6 +562,11 @@ impl crate::CommandEncoder for super::CommandEncoder { } geometry_infos.push(*geometry_info); + } + + for (i, geometry_info) in geometry_infos.iter_mut().enumerate() { + geometry_info.geometry_count = geometries_storage[i].len() as u32; + geometry_info.p_geometries = geometries_storage[i].as_ptr(); ranges_ptrs.push(&ranges_storage[i]); } diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index d27142123d..34ddaa0bad 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -2053,9 +2053,9 @@ impl crate::Device for super::Device { } } - unsafe fn get_acceleration_structure_build_sizes( + unsafe fn get_acceleration_structure_build_sizes<'a>( &self, - desc: &crate::GetAccelerationStructureBuildSizesDescriptor, + desc: &crate::GetAccelerationStructureBuildSizesDescriptor<'a, super::Api>, ) -> crate::AccelerationStructureBuildSizes { const CAPACITY: usize = 8; @@ -2064,7 +2064,7 @@ impl crate::Device for super::Device { None => panic!("Feature `RAY_TRACING` not enabled"), }; - let (geometries, primitive_counts) = match *desc.entries { + let (geometries, primitive_counts) = match desc.entries { crate::AccelerationStructureEntries::Instances(ref instances) => { let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::default(); From d5760299655ab62033c299bf68e01eda99776dad Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Thu, 30 Mar 2023 17:33:37 +0200 Subject: [PATCH 042/146] compiles again --- wgpu-core/src/command/ray_tracing.rs | 85 +++++++++++++--------------- wgpu-core/src/ray_tracing.rs | 2 +- 2 files changed, 41 insertions(+), 46 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 6ddf775b5a..00155427e7 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -81,14 +81,17 @@ impl Global { let mut input_barriers = Vec::>::new(); - let mut triangle_geometry_storage = - Vec::>>::new(); + let mut blas_entry_storage = Vec::>::new(); + + let mut scratch_buffer_blas_size = 0; + let mut scratch_buffer_blas_offsets = Vec::::new(); + + let mut blas_refs = Vec::<&Blas>::new(); for entry in &blas_storage { match &entry.geometries { BlasGeometriesStorage::TriangleGeometries(triangle_geometries) => { - triangle_geometry_storage - .push(Vec::>::new()); + let mut triangle_entries = Vec::>::new(); for mesh in triangle_geometries { let vertex_buffer = { @@ -236,48 +239,30 @@ impl Global { }), flags: mesh.size.flags, }; - triangle_geometry_storage - .last_mut() - .unwrap() - .push(triangles); - } - } - }; - } - - let mut blas_entry_storage = Vec::>::new(); - - let mut scratch_buffer_blas_size = 0; - let mut scratch_buffer_blas_offsets = Vec::::new(); - let mut blas_refs = Vec::<&Blas>::new(); - - let mut triangel_geometrie_counter = 0; - for entry in &blas_storage { - match &entry.geometries { - BlasGeometriesStorage::TriangleGeometries(_) => { + triangle_entries.push(triangles); + } blas_entry_storage.push(hal::AccelerationStructureEntries::Triangles( - &triangle_geometry_storage[triangel_geometrie_counter], + triangle_entries, )); - triangel_geometrie_counter += 1; - } - } - let blas = cmd_buf - .trackers - .blas_s - .add_single(&blas_guard, entry.blas_id) - .ok_or(BuildAccelerationStructureError::InvalidBlas(entry.blas_id))?; + let blas = cmd_buf + .trackers + .blas_s + .add_single(&blas_guard, entry.blas_id) + .ok_or(BuildAccelerationStructureError::InvalidBlas(entry.blas_id))?; - scratch_buffer_blas_offsets.push(scratch_buffer_blas_size); - scratch_buffer_blas_size += blas.size_info.build_scratch_size; // TODO Alignment + scratch_buffer_blas_offsets.push(scratch_buffer_blas_size); + scratch_buffer_blas_size += blas.size_info.build_scratch_size; // TODO Alignment - blas_refs.push(blas); + blas_refs.push(blas); + } + } } let mut scratch_buffer_tlas_size = 0; - let mut tlas_storage = Vec::<(&Tlas, hal::AccelerationStructureEntries, u64)>::new(); + for entry in tlas_iter { let instance_buffer = { let (instance_buffer, instance_pending) = cmd_buf @@ -356,18 +341,19 @@ impl Global { source_acceleration_structure: None, destination_acceleration_structure: &blas.raw, scratch_buffer: &scratch_buffer, + scratch_buffer_offset: scratch_buffer_blas_offsets[i], }) } let mut blas_descriptor_references = - Vec::<&hal::BuildAccelerationStructureDescriptor>::with_capacity(blas_storage.len()); - for (i, _entry) in blas_storage.iter().enumerate() { - blas_descriptor_references.push(&blas_descriptors[i]); + Vec::>::with_capacity(blas_storage.len()); + for descriptor in blas_descriptors { + blas_descriptor_references.push(descriptor); } let mut tlas_descriptors = Vec::>::with_capacity(tlas_storage.len()); - for (tlas, entries, _scratch_buffer_offset) in &tlas_storage { + for (tlas, entries, scratch_buffer_offset) in &tlas_storage { tlas_descriptors.push(hal::BuildAccelerationStructureDescriptor { entries, mode: hal::AccelerationStructureBuildMode::Build, // TODO @@ -375,26 +361,35 @@ impl Global { source_acceleration_structure: None, destination_acceleration_structure: &tlas.raw, scratch_buffer: &scratch_buffer, + scratch_buffer_offset: *scratch_buffer_offset, }) } let mut tlas_descriptor_references = - Vec::<&hal::BuildAccelerationStructureDescriptor>::with_capacity(tlas_storage.len()); - for descriptor in &tlas_descriptors { + Vec::>::with_capacity(tlas_storage.len()); + for descriptor in tlas_descriptors { tlas_descriptor_references.push(descriptor); } let cmd_buf_raw = cmd_buf.encoder.open(); + let scratch_buffer_barrier_needed = + !blas_descriptor_references.is_empty() && !tlas_descriptor_references.is_empty(); unsafe { cmd_buf_raw.transition_buffers(input_barriers.into_iter()); if !blas_descriptor_references.is_empty() { - cmd_buf_raw.build_acceleration_structures(&blas_descriptor_references); + cmd_buf_raw.build_acceleration_structures( + blas_descriptor_references.len() as u32, + blas_descriptor_references, + ); } - if !blas_descriptor_references.is_empty() && !tlas_descriptor_references.is_empty() { + if scratch_buffer_barrier_needed { cmd_buf_raw.transition_buffers(iter::once(scratch_buffer_barrier)); } if !tlas_descriptor_references.is_empty() { - cmd_buf_raw.build_acceleration_structures(&tlas_descriptor_references); + cmd_buf_raw.build_acceleration_structures( + tlas_descriptor_references.len() as u32, + tlas_descriptor_references, + ); } } diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 2e02623e8a..d00d5b5575 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -80,7 +80,7 @@ impl Device { unsafe { self.raw.get_acceleration_structure_build_sizes( &hal::GetAccelerationStructureBuildSizesDescriptor { - entries: &hal::AccelerationStructureEntries::Triangles(&entries), + entries: &hal::AccelerationStructureEntries::Triangles(entries), flags: blas_desc.flags, }, ) From b29d21baf8477f8918ad0d4757c4028a1fac4229 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Thu, 30 Mar 2023 18:03:54 +0200 Subject: [PATCH 043/146] improved iterators --- wgpu-core/src/command/ray_tracing.rs | 134 ++++++++++----------------- wgpu-core/src/ray_tracing.rs | 9 -- 2 files changed, 50 insertions(+), 93 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 00155427e7..879aaf9f24 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -12,8 +12,7 @@ use crate::{ TextureInitTrackerAction, }, ray_tracing::{ - BlasBuildEntry, BlasBuildEntryStorage, BlasGeometriesStorage, - BuildAccelerationStructureError, TlasBuildEntry, + BlasBuildEntry, BlasGeometries, BuildAccelerationStructureError, TlasBuildEntry, }, resource::{self, Blas, Texture, TextureErrorDimension, Tlas}, track::TextureSelector, @@ -51,23 +50,6 @@ impl Global { let device = &mut device_guard[cmd_buf.device_id.value]; - let blas_storage: Vec<_> = blas_iter - .into_iter() - .map(|e| { - let geometries = match e.geometries { - crate::ray_tracing::BlasGeometries::TriangleGeometries(triangle_geometries) => { - BlasGeometriesStorage::TriangleGeometries(triangle_geometries.collect()) - } - }; - BlasBuildEntryStorage { - blas_id: e.blas_id, - geometries, - } - }) - .collect(); - - // let tlas_storage: Vec<_> = tlas_iter.collect(); - // #[cfg(feature = "trace")] // if let Some(ref mut list) = cmd_buf.commands { // list.push(TraceCommand::CopyBufferToBuffer { @@ -81,16 +63,12 @@ impl Global { let mut input_barriers = Vec::>::new(); - let mut blas_entry_storage = Vec::>::new(); - let mut scratch_buffer_blas_size = 0; - let mut scratch_buffer_blas_offsets = Vec::::new(); + let mut blas_storage = Vec::<(&Blas, hal::AccelerationStructureEntries, u64)>::new(); - let mut blas_refs = Vec::<&Blas>::new(); - - for entry in &blas_storage { - match &entry.geometries { - BlasGeometriesStorage::TriangleGeometries(triangle_geometries) => { + for entry in blas_iter { + match entry.geometries { + BlasGeometries::TriangleGeometries(triangle_geometries) => { let mut triangle_entries = Vec::>::new(); for mesh in triangle_geometries { @@ -242,9 +220,6 @@ impl Global { triangle_entries.push(triangles); } - blas_entry_storage.push(hal::AccelerationStructureEntries::Triangles( - triangle_entries, - )); let blas = cmd_buf .trackers @@ -252,10 +227,14 @@ impl Global { .add_single(&blas_guard, entry.blas_id) .ok_or(BuildAccelerationStructureError::InvalidBlas(entry.blas_id))?; - scratch_buffer_blas_offsets.push(scratch_buffer_blas_size); + let scratch_buffer_offset = scratch_buffer_blas_size; scratch_buffer_blas_size += blas.size_info.build_scratch_size; // TODO Alignment - blas_refs.push(blas); + blas_storage.push(( + blas, + hal::AccelerationStructureEntries::Triangles(triangle_entries), + scratch_buffer_offset, + )) } } } @@ -330,66 +309,53 @@ impl Global { ..hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, }; - let mut blas_descriptors = - Vec::>::with_capacity(blas_storage.len()); - for (i, _entry) in blas_storage.iter().enumerate() { - let blas = blas_refs[i]; - blas_descriptors.push(hal::BuildAccelerationStructureDescriptor { - entries: &blas_entry_storage[i], - mode: hal::AccelerationStructureBuildMode::Build, // TODO - flags: blas.flags, - source_acceleration_structure: None, - destination_acceleration_structure: &blas.raw, - scratch_buffer: &scratch_buffer, - scratch_buffer_offset: scratch_buffer_blas_offsets[i], - }) - } - - let mut blas_descriptor_references = - Vec::>::with_capacity(blas_storage.len()); - for descriptor in blas_descriptors { - blas_descriptor_references.push(descriptor); - } + let blas_descriptors = blas_storage + .iter() + .map(|(blas, entries, scratch_buffer_offset)| { + hal::BuildAccelerationStructureDescriptor { + entries, + mode: hal::AccelerationStructureBuildMode::Build, // TODO + flags: blas.flags, + source_acceleration_structure: None, + destination_acceleration_structure: &blas.raw, + scratch_buffer: &scratch_buffer, + scratch_buffer_offset: *scratch_buffer_offset, + } + }); + + let tlas_descriptors = tlas_storage + .iter() + .map(|(tlas, entries, scratch_buffer_offset)| { + hal::BuildAccelerationStructureDescriptor { + entries, + mode: hal::AccelerationStructureBuildMode::Build, // TODO + flags: tlas.flags, + source_acceleration_structure: None, + destination_acceleration_structure: &tlas.raw, + scratch_buffer: &scratch_buffer, + scratch_buffer_offset: *scratch_buffer_offset, + } + }); - let mut tlas_descriptors = - Vec::>::with_capacity(tlas_storage.len()); - for (tlas, entries, scratch_buffer_offset) in &tlas_storage { - tlas_descriptors.push(hal::BuildAccelerationStructureDescriptor { - entries, - mode: hal::AccelerationStructureBuildMode::Build, // TODO - flags: tlas.flags, - source_acceleration_structure: None, - destination_acceleration_structure: &tlas.raw, - scratch_buffer: &scratch_buffer, - scratch_buffer_offset: *scratch_buffer_offset, - }) - } - - let mut tlas_descriptor_references = - Vec::>::with_capacity(tlas_storage.len()); - for descriptor in tlas_descriptors { - tlas_descriptor_references.push(descriptor); - } + let blas_present = !blas_storage.is_empty(); + let tlas_present = !tlas_storage.is_empty(); let cmd_buf_raw = cmd_buf.encoder.open(); - let scratch_buffer_barrier_needed = - !blas_descriptor_references.is_empty() && !tlas_descriptor_references.is_empty(); unsafe { cmd_buf_raw.transition_buffers(input_barriers.into_iter()); - if !blas_descriptor_references.is_empty() { - cmd_buf_raw.build_acceleration_structures( - blas_descriptor_references.len() as u32, - blas_descriptor_references, - ); + + if blas_present { + cmd_buf_raw + .build_acceleration_structures(blas_storage.len() as u32, blas_descriptors); } - if scratch_buffer_barrier_needed { + + if blas_present && tlas_present { cmd_buf_raw.transition_buffers(iter::once(scratch_buffer_barrier)); } - if !tlas_descriptor_references.is_empty() { - cmd_buf_raw.build_acceleration_structures( - tlas_descriptor_references.len() as u32, - tlas_descriptor_references, - ); + + if tlas_present { + cmd_buf_raw + .build_acceleration_structures(tlas_storage.len() as u32, tlas_descriptors); } } diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index d00d5b5575..7b4733068d 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -283,12 +283,3 @@ pub struct TlasBuildEntry { pub instance_buffer_id: BufferId, pub instance_count: u32, } - -pub enum BlasGeometriesStorage<'a> { - TriangleGeometries(Vec>), -} - -pub struct BlasBuildEntryStorage<'a> { - pub blas_id: BlasId, - pub geometries: BlasGeometriesStorage<'a>, -} From 0b12bf3b2bb7ecd4b086e8e923d11de56ff672d3 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Thu, 30 Mar 2023 18:05:29 +0200 Subject: [PATCH 044/146] some cleanup --- wgpu/examples/hello-ray-triangle/main.rs | 7 +++---- wgpu/src/backend/direct.rs | 6 +++--- wgpu/src/context.rs | 10 +++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/wgpu/examples/hello-ray-triangle/main.rs b/wgpu/examples/hello-ray-triangle/main.rs index ce695f4b45..01a24158ac 100644 --- a/wgpu/examples/hello-ray-triangle/main.rs +++ b/wgpu/examples/hello-ray-triangle/main.rs @@ -1,7 +1,7 @@ use bytemuck::{Pod, Zeroable}; use glam::{Affine3A, Mat4, Quat, Vec3}; -use std::{borrow::Cow, iter, mem, num::NonZeroU32, time::Instant}; -use wgc::ray_tracing::BlasBuildEntry; +use std::{borrow::Cow, iter, mem, time::Instant}; + use wgpu::util::DeviceExt; use winit::{ dpi::{LogicalSize, PhysicalPosition}, @@ -326,7 +326,6 @@ async fn run(event_loop: EventLoop<()>, window: Window) { usage: wgpu::BufferUsages::UNIFORM, }); - let vertex_size = mem::size_of::(); let (vertex_data, index_data) = create_vertices(); let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { @@ -491,7 +490,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) { } queue.submit(Some(encoder.finish())); - let mut start_inst = Instant::now(); + let start_inst = Instant::now(); event_loop.run(move |event, _, control_flow| { // Have the closure take ownership of the resources. diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 299fb21c0a..667a93b25f 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -2,8 +2,8 @@ use crate::{ context::{ObjectId, Unused}, AdapterInfo, BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BufferBinding, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, - ContextBlasBuildEntry, DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, - Operations, PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, + DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, Operations, + PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, ShaderSource, SurfaceStatus, TextureDescriptor, TextureViewDescriptor, UncapturedErrorHandler, }; @@ -3066,7 +3066,7 @@ impl crate::Context for Context { { blas }, - {tlas} + tlas )) { self.handle_error_nolabel( &encoder_data.error_sink, diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 05b7b60657..b1d5a23ed5 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -8,14 +8,14 @@ use wgt::{ }; use crate::{ - BindGroupDescriptor, BindGroupLayoutDescriptor, Blas, Buffer, BufferAsyncError, - BufferDescriptor, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, - ContextBlasBuildEntry, ContextBlasTriangleGeometry, CreateBlasDescriptor, CreateTlasDescriptor, - DeviceDescriptor, Error, ErrorFilter, ImageCopyBuffer, ImageCopyTexture, Maintain, MapMode, + BindGroupDescriptor, BindGroupLayoutDescriptor, Buffer, BufferAsyncError, BufferDescriptor, + CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, + ContextBlasTriangleGeometry, CreateBlasDescriptor, CreateTlasDescriptor, DeviceDescriptor, + Error, ErrorFilter, ImageCopyBuffer, ImageCopyTexture, Maintain, MapMode, PipelineLayoutDescriptor, QuerySetDescriptor, RenderBundleDescriptor, RenderBundleEncoderDescriptor, RenderPassDescriptor, RenderPipelineDescriptor, RequestAdapterOptions, RequestDeviceError, SamplerDescriptor, ShaderModuleDescriptor, - ShaderModuleDescriptorSpirV, Texture, TextureDescriptor, TextureViewDescriptor, Tlas, + ShaderModuleDescriptorSpirV, Texture, TextureDescriptor, TextureViewDescriptor, UncapturedErrorHandler, }; From e13068dc77b85a2f34bb4c133ded4d8276be4b7b Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Fri, 31 Mar 2023 10:00:03 +0200 Subject: [PATCH 045/146] build validation --- wgpu-core/src/command/ray_tracing.rs | 159 +++++++++++++++++++---- wgpu-core/src/ray_tracing.rs | 39 ++++++ wgpu/examples/hello-ray-triangle/main.rs | 16 +-- 3 files changed, 176 insertions(+), 38 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 879aaf9f24..3f1ee712c3 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -25,10 +25,14 @@ use hal::{ AccelerationStructureTriangleTransform, CommandEncoder as _, Device as _, }; use thiserror::Error; -use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages}; +use wgt::{BufferUsages}; use std::{borrow::Borrow, cmp::max, iter}; +// TODO: +// tracing +// automatic build splitting (if to big for spec or scratch buffer) +// comments/documentation impl Global { pub fn command_encoder_build_acceleration_structures_unsafe_tlas<'a, A: HalApi>( &self, @@ -50,16 +54,13 @@ impl Global { let device = &mut device_guard[cmd_buf.device_id.value]; - // #[cfg(feature = "trace")] - // if let Some(ref mut list) = cmd_buf.commands { - // list.push(TraceCommand::CopyBufferToBuffer { - // src: source, - // src_offset: source_offset, - // dst: destination, - // dst_offset: destination_offset, - // size, - // }); - // } + #[cfg(feature = "trace")] + let blas_iter: Box> = if let Some(ref mut _list) = cmd_buf.commands { + // Create temporary allocation, save trace and recreate iterator (same for tlas) + Box::new(blas_iter.map(|x| x)) + } else { + Box::new(blas_iter) + }; let mut input_barriers = Vec::>::new(); @@ -67,11 +68,54 @@ impl Global { let mut blas_storage = Vec::<(&Blas, hal::AccelerationStructureEntries, u64)>::new(); for entry in blas_iter { + let blas = cmd_buf + .trackers + .blas_s + .add_single(&blas_guard, entry.blas_id) + .ok_or(BuildAccelerationStructureError::InvalidBlas(entry.blas_id))?; + match entry.geometries { BlasGeometries::TriangleGeometries(triangle_geometries) => { let mut triangle_entries = Vec::>::new(); - for mesh in triangle_geometries { + for (i, mesh) in triangle_geometries.enumerate() { + let size_desc = match &blas.sizes { + wgt::BlasGeometrySizeDescriptors::Triangles { desc } => desc, + // _ => { + // return Err( + // BuildAccelerationStructureError::IncompatibleBlasBuildSizes( + // entry.blas_id, + // ), + // ) + // } + }; + if i >= size_desc.len() { + return Err( + BuildAccelerationStructureError::IncompatibleBlasBuildSizes( + entry.blas_id, + ), + ); + } + let size_desc = &size_desc[i]; + + if size_desc.flags != mesh.size.flags + || size_desc.vertex_count < mesh.size.vertex_count + || size_desc.vertex_format != mesh.size.vertex_format + || size_desc.index_count.is_none() != mesh.size.index_count.is_none() + || (size_desc.index_count.is_none() + || size_desc.index_count.unwrap() < mesh.size.index_count.unwrap()) + || size_desc.index_format.is_none() != mesh.size.index_format.is_none() + || (size_desc.index_format.is_none() + || size_desc.index_format.unwrap() + != mesh.size.index_format.unwrap()) + { + return Err( + BuildAccelerationStructureError::IncompatibleBlasBuildSizes( + entry.blas_id, + ), + ); + } + let vertex_buffer = { let (vertex_buffer, vertex_pending) = cmd_buf .trackers @@ -99,6 +143,24 @@ impl Global { { input_barriers.push(barrier); } + if mesh.size.vertex_count - mesh.first_vertex <= 0 { + return Err(BuildAccelerationStructureError::EmptyVertexBuffer( + mesh.vertex_buffer, + )); + } + if vertex_buffer.size + < (mesh.size.vertex_count + mesh.first_vertex) as u64 + * mesh.vertex_stride + { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + mesh.vertex_buffer, + vertex_buffer.size, + (mesh.size.vertex_count + mesh.first_vertex) as u64 + * mesh.vertex_stride, + ), + ); + } let vertex_buffer_offset = mesh.first_vertex as u64 * mesh.vertex_stride; cmd_buf.buffer_memory_init_actions.extend( @@ -113,6 +175,16 @@ impl Global { vertex_raw }; let index_buffer = if let Some(index_id) = mesh.index_buffer { + if mesh.index_buffer_offset.is_none() + || mesh.size.index_count.is_none() + || mesh.size.index_count.is_none() + { + return Err( + BuildAccelerationStructureError::MissingAssociatedData( + index_id, + ), + ); + } let (index_buffer, index_pending) = cmd_buf .trackers .buffers @@ -138,11 +210,41 @@ impl Global { { input_barriers.push(barrier); } - let index_buffer_size = mesh.size.index_count.unwrap() as u64 - * match mesh.size.index_format.unwrap() { - wgt::IndexFormat::Uint16 => 2, - wgt::IndexFormat::Uint32 => 4, - }; + let index_stride = match mesh.size.index_format.unwrap() { + wgt::IndexFormat::Uint16 => 2, + wgt::IndexFormat::Uint32 => 4, + }; + let index_buffer_size = + mesh.size.index_count.unwrap() as u64 * index_stride; + + if mesh.size.index_count.unwrap() as u64 + - mesh.index_buffer_offset.unwrap() / index_stride + < 3 + { + return Err(BuildAccelerationStructureError::EmptyIndexBuffer( + index_id, + )); + } + if mesh.size.index_count.unwrap() % 3 != 0 { + return Err(BuildAccelerationStructureError::InvalidIndexCount( + index_id, + mesh.size.index_count.unwrap(), + )); + } + if index_buffer.size + < mesh.size.index_count.unwrap() as u64 * index_stride + + mesh.index_buffer_offset.unwrap() + { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + index_id, + index_buffer.size, + mesh.size.index_count.unwrap() as u64 * index_stride + + mesh.index_buffer_offset.unwrap(), + ), + ); + } + cmd_buf.buffer_memory_init_actions.extend( index_buffer.initialization_status.create_action( index_id, @@ -156,6 +258,13 @@ impl Global { None }; let transform_buffer = if let Some(transform_id) = mesh.transform_buffer { + if mesh.transform_buffer_offset.is_none() { + return Err( + BuildAccelerationStructureError::MissingAssociatedData( + transform_id, + ), + ); + } let (transform_buffer, transform_pending) = cmd_buf .trackers .buffers @@ -182,6 +291,16 @@ impl Global { { input_barriers.push(barrier); } + + if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + transform_id, + transform_buffer.size, + 48 + mesh.transform_buffer_offset.unwrap(), + ), + ); + } cmd_buf.buffer_memory_init_actions.extend( transform_buffer.initialization_status.create_action( transform_id, @@ -221,12 +340,6 @@ impl Global { triangle_entries.push(triangles); } - let blas = cmd_buf - .trackers - .blas_s - .add_single(&blas_guard, entry.blas_id) - .ok_or(BuildAccelerationStructureError::InvalidBlas(entry.blas_id))?; - let scratch_buffer_offset = scratch_buffer_blas_size; scratch_buffer_blas_size += blas.size_info.build_scratch_size; // TODO Alignment diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 7b4733068d..c73b6c2783 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -28,19 +28,49 @@ use std::iter; pub enum BuildAccelerationStructureError { #[error(transparent)] Encoder(#[from] CommandEncoderError), + #[error("Buffer {0:?} is invalid or destroyed")] InvalidBuffer(BufferId), + #[error("Buffer {0:?} is missing `BLAS_INPUT` usage flag")] MissingBlasInputUsageFlag(BufferId), + + #[error( + "Buffer {0:?} size is insufficient for provided size information (size: {1}, required: {2}" + )] + InsufficientBufferSize(BufferId, u64, u64), + + #[error("Buffer {0:?} associated vertex buffer sizes invalid (no vertices)")] + EmptyVertexBuffer(BufferId), + + #[error("Buffer {0:?} associated index buffer sizes invalid (less then three indices)")] + EmptyIndexBuffer(BufferId), + + #[error("Buffer {0:?} associated index count not divisible by 3 (count: {1}")] + InvalidIndexCount(BufferId, u32), + + #[error("Buffer {0:?} associated data contains None")] + MissingAssociatedData(BufferId), + + #[error( + "Blas {0:?} build sizes to may be greater than the descriptor at build time specified" + )] + IncompatibleBlasBuildSizes(BlasId), + #[error("Blas {0:?} is invalid or destroyed")] InvalidBlas(BlasId), + #[error("Tlas {0:?} is invalid or destroyed")] InvalidTlas(TlasId), + #[error("Buffer {0:?} is missing `TLAS_INPUT` usage flag")] MissingTlasInputUsageFlag(BufferId), } impl Device { + // TODO: + // validation + // comments/documentation fn create_blas( &self, self_id: id::DeviceId, @@ -112,6 +142,9 @@ impl Device { }) } + // TODO: + // validation + // comments/documentation fn create_tlas( &self, self_id: id::DeviceId, @@ -160,6 +193,9 @@ impl Device { } impl Global { + // TODO: + // tracing + // comments/documentation pub fn device_create_blas( &self, device_id: id::DeviceId, @@ -212,6 +248,9 @@ impl Global { (id, None, Some(error)) } + // TODO: + // tracing + // comments/documentation pub fn device_create_tlas( &self, device_id: id::DeviceId, diff --git a/wgpu/examples/hello-ray-triangle/main.rs b/wgpu/examples/hello-ray-triangle/main.rs index 01a24158ac..f6c412d866 100644 --- a/wgpu/examples/hello-ray-triangle/main.rs +++ b/wgpu/examples/hello-ray-triangle/main.rs @@ -548,21 +548,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) { unsafe { encoder.build_acceleration_structures_unsafe_tlas( - iter::once(&wgpu::BlasBuildEntry { - blas: &blas, - geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ - wgpu::BlasTriangleGeometry { - size: &blas_geo_size_desc, - vertex_buffer: &vertex_buf, - first_vertex: 0, - vertex_stride: mem::size_of::() as u64, - index_buffer: Some(&index_buf), - index_buffer_offset: Some(0), - transform_buffer: None, - transform_buffer_offset: None, - }, - ]), - }), + iter::empty(), iter::once(&wgpu::TlasBuildEntry { tlas: &tlas, instance_buffer: &instance_buf, From 1f00adf0b5172e889e0cf31851d357b1cb879e87 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Fri, 31 Mar 2023 20:24:54 +0200 Subject: [PATCH 046/146] drop and destroy --- wgpu-core/src/command/ray_tracing.rs | 16 +- wgpu-core/src/device/life.rs | 16 + wgpu-core/src/device/mod.rs | 6 +- wgpu-core/src/device/queue.rs | 4 + wgpu-core/src/device/ray_tracing.rs | 409 +++++++++++++++++++++++ wgpu-core/src/ray_tracing.rs | 231 +------------ wgpu-core/src/resource.rs | 4 +- wgpu/examples/hello-ray-triangle/main.rs | 2 + wgpu/src/backend/direct.rs | 20 ++ wgpu/src/context.rs | 32 ++ wgpu/src/lib.rs | 26 ++ 11 files changed, 529 insertions(+), 237 deletions(-) create mode 100644 wgpu-core/src/device/ray_tracing.rs diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 3f1ee712c3..b13b5d3471 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -25,12 +25,12 @@ use hal::{ AccelerationStructureTriangleTransform, CommandEncoder as _, Device as _, }; use thiserror::Error; -use wgt::{BufferUsages}; +use wgt::BufferUsages; use std::{borrow::Borrow, cmp::max, iter}; // TODO: -// tracing +// tracing // automatic build splitting (if to big for spec or scratch buffer) // comments/documentation impl Global { @@ -74,6 +74,10 @@ impl Global { .add_single(&blas_guard, entry.blas_id) .ok_or(BuildAccelerationStructureError::InvalidBlas(entry.blas_id))?; + if blas.raw.is_none() { + return Err(BuildAccelerationStructureError::InvalidBlas(entry.blas_id)); + } + match entry.geometries { BlasGeometries::TriangleGeometries(triangle_geometries) => { let mut triangle_entries = Vec::>::new(); @@ -390,6 +394,10 @@ impl Global { .add_single(&tlas_guard, entry.tlas_id) .ok_or(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id))?; + if tlas.raw.is_none() { + return Err(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id)); + } + let scratch_buffer_offset = scratch_buffer_tlas_size; scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; // TODO Alignment @@ -430,7 +438,7 @@ impl Global { mode: hal::AccelerationStructureBuildMode::Build, // TODO flags: blas.flags, source_acceleration_structure: None, - destination_acceleration_structure: &blas.raw, + destination_acceleration_structure: &blas.raw.as_ref().unwrap(), scratch_buffer: &scratch_buffer, scratch_buffer_offset: *scratch_buffer_offset, } @@ -444,7 +452,7 @@ impl Global { mode: hal::AccelerationStructureBuildMode::Build, // TODO flags: tlas.flags, source_acceleration_structure: None, - destination_acceleration_structure: &tlas.raw, + destination_acceleration_structure: tlas.raw.as_ref().unwrap(), scratch_buffer: &scratch_buffer, scratch_buffer_offset: *scratch_buffer_offset, } diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 605aea3dab..b42d188dd3 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -32,6 +32,8 @@ pub(super) struct SuspectedResources { pub(super) pipeline_layouts: Vec>, pub(super) render_bundles: Vec>, pub(super) query_sets: Vec>, + pub(super) blas_s: Vec>, + pub(super) tlas_s: Vec>, } impl SuspectedResources { @@ -97,6 +99,7 @@ struct NonReferencedResources { bind_group_layouts: Vec, pipeline_layouts: Vec, query_sets: Vec, + acceleration_structures: Vec, } impl NonReferencedResources { @@ -112,6 +115,7 @@ impl NonReferencedResources { bind_group_layouts: Vec::new(), pipeline_layouts: Vec::new(), query_sets: Vec::new(), + acceleration_structures: Vec::new(), } } @@ -124,6 +128,8 @@ impl NonReferencedResources { self.compute_pipes.extend(other.compute_pipes); self.render_pipes.extend(other.render_pipes); self.query_sets.extend(other.query_sets); + self.acceleration_structures + .extend(other.acceleration_structures); assert!(other.bind_group_layouts.is_empty()); assert!(other.pipeline_layouts.is_empty()); } @@ -189,6 +195,12 @@ impl NonReferencedResources { unsafe { device.destroy_query_set(raw) }; } } + if !self.acceleration_structures.is_empty() { + profiling::scope!("destroy_acceleration_structures"); + for raw in self.acceleration_structures.drain(..) { + unsafe { device.destroy_acceleration_structure(raw) }; + } + } } } @@ -335,6 +347,9 @@ impl LifetimeTracker { last_resources.textures.push(raw); last_resources.texture_views.extend(views); } + TempResource::AccelerationStructure(raw) => { + last_resources.acceleration_structures.push(raw) + } } } @@ -438,6 +453,7 @@ impl LifetimeTracker { resources.texture_views.extend(views); resources.textures.push(raw); } + TempResource::AccelerationStructure(raw) => resources.acceleration_structures.push(raw), } } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 7b6c263013..53386efaa3 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -31,6 +31,8 @@ pub mod queue; #[cfg(any(feature = "trace", feature = "replay"))] pub mod trace; +pub mod ray_tracing; + pub const SHADER_STAGE_COUNT: usize = 3; // Should be large enough for the largest possible texture row. This // value is enough for a 16k texture with float4 format. @@ -2218,8 +2220,10 @@ impl Device { .add_single(&*&tlas_guard, id) .ok_or(Error::InvalidTlas(id))?; + let raw = tlas.raw.as_ref().ok_or(Error::InvalidTlas(id))?; + let res_index = hal_tlas_s.len(); - hal_tlas_s.push(&tlas.raw); + hal_tlas_s.push(raw); (res_index, 1) } }; diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 468339c938..e3dff31933 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -106,6 +106,7 @@ pub struct WrappedSubmissionIndex { pub enum TempResource { Buffer(A::Buffer), Texture(A::Texture, SmallVec<[A::TextureView; 1]>), + AccelerationStructure(A::AccelerationStructure), } /// A queue execution for a particular command encoder. @@ -180,6 +181,9 @@ impl PendingWrites { } device.destroy_texture(texture); }, + TempResource::AccelerationStructure(acceleration_structure) => unsafe { + device.destroy_acceleration_structure(acceleration_structure); + }, } } } diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs new file mode 100644 index 0000000000..ce22ed31b8 --- /dev/null +++ b/wgpu-core/src/device/ray_tracing.rs @@ -0,0 +1,409 @@ +#[cfg(feature = "trace")] +use crate::device::trace::Command as TraceCommand; +use crate::{ + command::{clear_texture, CommandBuffer, CommandEncoderError}, + conv, + device::{queue::TempResource, Device, DeviceError, MissingDownlevelFlags}, + error::{ErrorFormatter, PrettyError}, + hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Storage, Token}, + id::{self, BlasId, BufferId, CommandEncoderId, TlasId}, + init_tracker::{ + has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, + TextureInitTrackerAction, + }, + resource::{self, Texture, TextureErrorDimension}, + track::TextureSelector, + LabelHelpers, LifeGuard, Stored, +}; + +use arrayvec::ArrayVec; +use hal::{AccelerationStructureTriangleIndices, CommandEncoder as _, Device as _}; +use thiserror::Error; +use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages}; + +use std::iter; + +impl Device { + // TODO: + // validation + // comments/documentation + fn create_blas( + &self, + self_id: id::DeviceId, + blas_desc: &resource::BlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, + ) -> Result, resource::CreateBlasError> { + debug_assert_eq!(self_id.backend(), A::VARIANT); + + let size_info = match &sizes { + wgt::BlasGeometrySizeDescriptors::Triangles { desc } => { + let mut entries = + Vec::>::with_capacity(desc.len()); + for x in desc { + if x.index_count.is_some() != x.index_format.is_some() { + return Err(resource::CreateBlasError::Unimplemented); + } + // TODO more validation + let indices = + x.index_count + .map(|count| AccelerationStructureTriangleIndices:: { + format: x.index_format.unwrap(), + buffer: None, + offset: 0, + count, + }); + entries.push(hal::AccelerationStructureTriangles:: { + vertex_buffer: None, + vertex_format: x.vertex_format, + first_vertex: 0, + vertex_count: x.vertex_count, + vertex_stride: 0, + indices: indices, + transform: None, + flags: x.flags, + }); + } + unsafe { + self.raw.get_acceleration_structure_build_sizes( + &hal::GetAccelerationStructureBuildSizesDescriptor { + entries: &hal::AccelerationStructureEntries::Triangles(entries), + flags: blas_desc.flags, + }, + ) + } + } + }; + + let raw = unsafe { + self.raw + .create_acceleration_structure(&hal::AccelerationStructureDescriptor { + label: blas_desc.label.borrow_option(), + size: size_info.acceleration_structure_size, + format: hal::AccelerationStructureFormat::BottomLevel, + }) + } + .map_err(DeviceError::from)?; + + Ok(resource::Blas { + raw: Some(raw), + device_id: Stored { + value: id::Valid(self_id), + ref_count: self.life_guard.add_ref(), + }, + life_guard: LifeGuard::new(blas_desc.label.borrow_or_default()), + size_info, + sizes, + flags: blas_desc.flags, + update_mode: blas_desc.update_mode, + }) + } + + // TODO: + // validation + // comments/documentation + fn create_tlas( + &self, + self_id: id::DeviceId, + desc: &resource::TlasDescriptor, + ) -> Result, resource::CreateTlasError> { + debug_assert_eq!(self_id.backend(), A::VARIANT); + + // TODO validate max_instances + let size_info = unsafe { + self.raw.get_acceleration_structure_build_sizes( + &hal::GetAccelerationStructureBuildSizesDescriptor { + entries: &hal::AccelerationStructureEntries::Instances( + hal::AccelerationStructureInstances { + buffer: None, + offset: 0, + count: desc.max_instances, + }, + ), + flags: desc.flags, + }, + ) + }; + + let raw = unsafe { + self.raw + .create_acceleration_structure(&hal::AccelerationStructureDescriptor { + label: desc.label.borrow_option(), + size: size_info.acceleration_structure_size, + format: hal::AccelerationStructureFormat::TopLevel, + }) + } + .map_err(DeviceError::from)?; + + Ok(resource::Tlas { + raw: Some(raw), + device_id: Stored { + value: id::Valid(self_id), + ref_count: self.life_guard.add_ref(), + }, + life_guard: LifeGuard::new(desc.label.borrow_or_default()), + size_info, + flags: desc.flags, + update_mode: desc.update_mode, + }) + } +} + +impl Global { + // TODO: + // tracing + // comments/documentation + pub fn device_create_blas( + &self, + device_id: id::DeviceId, + desc: &resource::BlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, + id_in: Input, + ) -> (BlasId, Option, Option) { + profiling::scope!("Device::create_blas"); + + let hub = A::hub(self); + let mut token = Token::root(); + let fid = hub.blas_s.prepare(id_in); + + let (device_guard, mut token) = hub.devices.read(&mut token); + let error = loop { + let device = match device_guard.get(device_id) { + Ok(device) => device, + Err(_) => break DeviceError::Invalid.into(), + }; + // #[cfg(feature = "trace")] + // if let Some(ref trace) = device.trace { + // let mut desc = desc.clone(); + // trace + // .lock() + // .add(trace::Action::CreateBlas(fid.id(), desc)); + // } + + let blas = match device.create_blas(device_id, desc, sizes) { + Ok(blas) => blas, + Err(e) => break e, + }; + + let handle = unsafe { + device + .raw + .get_acceleration_structure_device_address(blas.raw.as_ref().unwrap()) + }; + + let ref_count = blas.life_guard.add_ref(); + + let id = fid.assign(blas, &mut token); + log::info!("Created blas {:?} with {:?}", id, desc); + + device.trackers.lock().blas_s.insert_single(id, ref_count); + + return (id.0, Some(handle), None); + }; + + let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); + (id, None, Some(error)) + } + + // TODO: + // tracing + // comments/documentation + pub fn device_create_tlas( + &self, + device_id: id::DeviceId, + desc: &resource::TlasDescriptor, + id_in: Input, + ) -> (TlasId, Option) { + profiling::scope!("Device::create_tlas"); + + let hub = A::hub(self); + let mut token = Token::root(); + let fid = hub.tlas_s.prepare(id_in); + + let (device_guard, mut token) = hub.devices.read(&mut token); + let error = loop { + let device = match device_guard.get(device_id) { + Ok(device) => device, + Err(_) => break DeviceError::Invalid.into(), + }; + // #[cfg(feature = "trace")] + // if let Some(ref trace) = device.trace { + // let mut desc = desc.clone(); + // trace + // .lock() + // .add(trace::Action::CreateTlas(fid.id(), desc)); + // } + + let tlas = match device.create_tlas(device_id, desc) { + Ok(tlas) => tlas, + Err(e) => break e, + }; + let ref_count = tlas.life_guard.add_ref(); + + let id = fid.assign(tlas, &mut token); + log::info!("Created blas {:?} with {:?}", id, desc); + + device.trackers.lock().tlas_s.insert_single(id, ref_count); + + return (id.0, None); + }; + + let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); + (id, Some(error)) + } + + pub fn blas_destroy(&self, blas_id: BlasId) -> Result<(), resource::DestroyError> { + profiling::scope!("Blas::destroy"); + + let hub = A::hub(self); + let mut token = Token::root(); + + let (mut device_guard, mut token) = hub.devices.write(&mut token); + + log::info!("Blas {:?} is destroyed", blas_id); + let (mut blas_guard, _) = hub.blas_s.write(&mut token); + let blas = blas_guard + .get_mut(blas_id) + .map_err(|_| resource::DestroyError::Invalid)?; + + let device = &mut device_guard[blas.device_id.value]; + + // #[cfg(feature = "trace")] + // if let Some(ref trace) = device.trace { + // trace.lock().add(trace::Action::FreeBlas(blas_id)); + // } + + let raw = blas + .raw + .take() + .ok_or(resource::DestroyError::AlreadyDestroyed)?; + let temp = TempResource::AccelerationStructure(raw); + { + let last_submit_index = blas.life_guard.life_count(); + drop(blas_guard); + device + .lock_life(&mut token) + .schedule_resource_destruction(temp, last_submit_index); + } + + Ok(()) + } + + pub fn blas_drop(&self, blas_id: BlasId, wait: bool) { + profiling::scope!("Blas::drop"); + log::debug!("blas {:?} is dropped", blas_id); + + let hub = A::hub(self); + let mut token = Token::root(); + + let (ref_count, last_submit_index, device_id) = { + let (mut blas_guard, _) = hub.blas_s.write(&mut token); + match blas_guard.get_mut(blas_id) { + Ok(blas) => { + let ref_count = blas.life_guard.ref_count.take().unwrap(); + let last_submit_index = blas.life_guard.life_count(); + (ref_count, last_submit_index, blas.device_id.value) + } + Err(crate::hub::InvalidId) => { + hub.blas_s.unregister_locked(blas_id, &mut *blas_guard); + return; + } + } + }; + + let (device_guard, mut token) = hub.devices.read(&mut token); + let device = &device_guard[device_id]; + { + let mut life_lock = device.lock_life(&mut token); + drop(ref_count); + life_lock + .suspected_resources + .blas_s + .push(id::Valid(blas_id)); + } + + if wait { + match device.wait_for_submit(last_submit_index, &mut token) { + Ok(()) => (), + Err(e) => log::error!("Failed to wait for blas {:?}: {:?}", blas_id, e), + } + } + } + + pub fn tlas_destroy(&self, tlas_id: TlasId) -> Result<(), resource::DestroyError> { + profiling::scope!("Tlas::destroy"); + + let hub = A::hub(self); + let mut token = Token::root(); + + let (mut device_guard, mut token) = hub.devices.write(&mut token); + + log::info!("Tlas {:?} is destroyed", tlas_id); + let (mut tlas_guard, _) = hub.tlas_s.write(&mut token); + let tlas = tlas_guard + .get_mut(tlas_id) + .map_err(|_| resource::DestroyError::Invalid)?; + + let device = &mut device_guard[tlas.device_id.value]; + + // #[cfg(feature = "trace")] + // if let Some(ref trace) = device.trace { + // trace.lock().add(trace::Action::FreeTlas(tlas_id)); + // } + + let raw = tlas + .raw + .take() + .ok_or(resource::DestroyError::AlreadyDestroyed)?; + let temp = TempResource::AccelerationStructure(raw); + { + let last_submit_index = tlas.life_guard.life_count(); + drop(tlas_guard); + device + .lock_life(&mut token) + .schedule_resource_destruction(temp, last_submit_index); + } + + Ok(()) + } + + pub fn tlas_drop(&self, tlas_id: TlasId, wait: bool) { + profiling::scope!("Tlas::drop"); + log::debug!("tlas {:?} is dropped", tlas_id); + + let hub = A::hub(self); + let mut token = Token::root(); + + let (ref_count, last_submit_index, device_id) = { + let (mut tlas_guard, _) = hub.tlas_s.write(&mut token); + match tlas_guard.get_mut(tlas_id) { + Ok(tlas) => { + let ref_count = tlas.life_guard.ref_count.take().unwrap(); + let last_submit_index = tlas.life_guard.life_count(); + (ref_count, last_submit_index, tlas.device_id.value) + } + Err(crate::hub::InvalidId) => { + hub.tlas_s.unregister_locked(tlas_id, &mut *tlas_guard); + return; + } + } + }; + + let (device_guard, mut token) = hub.devices.read(&mut token); + let device = &device_guard[device_id]; + { + let mut life_lock = device.lock_life(&mut token); + drop(ref_count); + life_lock + .suspected_resources + .tlas_s + .push(id::Valid(tlas_id)); + } + + if wait { + match device.wait_for_submit(last_submit_index, &mut token) { + Ok(()) => (), + Err(e) => log::error!("Failed to wait for tlas {:?}: {:?}", tlas_id, e), + } + } + } +} diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index c73b6c2783..fcc66d8e81 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -3,7 +3,7 @@ use crate::device::trace::Command as TraceCommand; use crate::{ command::{clear_texture, CommandBuffer, CommandEncoderError}, conv, - device::{Device, DeviceError, MissingDownlevelFlags}, + device::{queue::TempResource, Device, DeviceError, MissingDownlevelFlags}, error::{ErrorFormatter, PrettyError}, hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Storage, Token}, id::{self, BlasId, BufferId, CommandEncoderId, TlasId}, @@ -67,235 +67,6 @@ pub enum BuildAccelerationStructureError { MissingTlasInputUsageFlag(BufferId), } -impl Device { - // TODO: - // validation - // comments/documentation - fn create_blas( - &self, - self_id: id::DeviceId, - blas_desc: &resource::BlasDescriptor, - sizes: wgt::BlasGeometrySizeDescriptors, - ) -> Result, resource::CreateBlasError> { - debug_assert_eq!(self_id.backend(), A::VARIANT); - - let size_info = match &sizes { - wgt::BlasGeometrySizeDescriptors::Triangles { desc } => { - let mut entries = - Vec::>::with_capacity(desc.len()); - for x in desc { - if x.index_count.is_some() != x.index_format.is_some() { - return Err(resource::CreateBlasError::Unimplemented); - } - // TODO more validation - let indices = - x.index_count - .map(|count| AccelerationStructureTriangleIndices:: { - format: x.index_format.unwrap(), - buffer: None, - offset: 0, - count, - }); - entries.push(hal::AccelerationStructureTriangles:: { - vertex_buffer: None, - vertex_format: x.vertex_format, - first_vertex: 0, - vertex_count: x.vertex_count, - vertex_stride: 0, - indices: indices, - transform: None, - flags: x.flags, - }); - } - unsafe { - self.raw.get_acceleration_structure_build_sizes( - &hal::GetAccelerationStructureBuildSizesDescriptor { - entries: &hal::AccelerationStructureEntries::Triangles(entries), - flags: blas_desc.flags, - }, - ) - } - } - }; - - let raw = unsafe { - self.raw - .create_acceleration_structure(&hal::AccelerationStructureDescriptor { - label: blas_desc.label.borrow_option(), - size: size_info.acceleration_structure_size, - format: hal::AccelerationStructureFormat::BottomLevel, - }) - } - .map_err(DeviceError::from)?; - - Ok(resource::Blas { - raw: raw, - device_id: Stored { - value: id::Valid(self_id), - ref_count: self.life_guard.add_ref(), - }, - life_guard: LifeGuard::new(blas_desc.label.borrow_or_default()), - size_info, - sizes, - flags: blas_desc.flags, - update_mode: blas_desc.update_mode, - }) - } - - // TODO: - // validation - // comments/documentation - fn create_tlas( - &self, - self_id: id::DeviceId, - desc: &resource::TlasDescriptor, - ) -> Result, resource::CreateTlasError> { - debug_assert_eq!(self_id.backend(), A::VARIANT); - - // TODO validate max_instances - let size_info = unsafe { - self.raw.get_acceleration_structure_build_sizes( - &hal::GetAccelerationStructureBuildSizesDescriptor { - entries: &hal::AccelerationStructureEntries::Instances( - hal::AccelerationStructureInstances { - buffer: None, - offset: 0, - count: desc.max_instances, - }, - ), - flags: desc.flags, - }, - ) - }; - - let raw = unsafe { - self.raw - .create_acceleration_structure(&hal::AccelerationStructureDescriptor { - label: desc.label.borrow_option(), - size: size_info.acceleration_structure_size, - format: hal::AccelerationStructureFormat::TopLevel, - }) - } - .map_err(DeviceError::from)?; - - Ok(resource::Tlas { - raw: raw, - device_id: Stored { - value: id::Valid(self_id), - ref_count: self.life_guard.add_ref(), - }, - life_guard: LifeGuard::new(desc.label.borrow_or_default()), - size_info, - flags: desc.flags, - update_mode: desc.update_mode, - }) - } -} - -impl Global { - // TODO: - // tracing - // comments/documentation - pub fn device_create_blas( - &self, - device_id: id::DeviceId, - desc: &resource::BlasDescriptor, - sizes: wgt::BlasGeometrySizeDescriptors, - id_in: Input, - ) -> (BlasId, Option, Option) { - profiling::scope!("Device::create_blas"); - - let hub = A::hub(self); - let mut token = Token::root(); - let fid = hub.blas_s.prepare(id_in); - - let (device_guard, mut token) = hub.devices.read(&mut token); - let error = loop { - let device = match device_guard.get(device_id) { - Ok(device) => device, - Err(_) => break DeviceError::Invalid.into(), - }; - // #[cfg(feature = "trace")] - // if let Some(ref trace) = device.trace { - // let mut desc = desc.clone(); - // trace - // .lock() - // .add(trace::Action::CreateBlas(fid.id(), desc)); - // } - - let blas = match device.create_blas(device_id, desc, sizes) { - Ok(blas) => blas, - Err(e) => break e, - }; - - let handle = unsafe { - device - .raw - .get_acceleration_structure_device_address(&blas.raw) - }; - - let ref_count = blas.life_guard.add_ref(); - - let id = fid.assign(blas, &mut token); - log::info!("Created blas {:?} with {:?}", id, desc); - - device.trackers.lock().blas_s.insert_single(id, ref_count); - - return (id.0, Some(handle), None); - }; - - let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); - (id, None, Some(error)) - } - - // TODO: - // tracing - // comments/documentation - pub fn device_create_tlas( - &self, - device_id: id::DeviceId, - desc: &resource::TlasDescriptor, - id_in: Input, - ) -> (id::TlasId, Option) { - profiling::scope!("Device::create_tlas"); - - let hub = A::hub(self); - let mut token = Token::root(); - let fid = hub.tlas_s.prepare(id_in); - - let (device_guard, mut token) = hub.devices.read(&mut token); - let error = loop { - let device = match device_guard.get(device_id) { - Ok(device) => device, - Err(_) => break DeviceError::Invalid.into(), - }; - // #[cfg(feature = "trace")] - // if let Some(ref trace) = device.trace { - // let mut desc = desc.clone(); - // trace - // .lock() - // .add(trace::Action::CreateTlas(fid.id(), desc)); - // } - - let tlas = match device.create_tlas(device_id, desc) { - Ok(tlas) => tlas, - Err(e) => break e, - }; - let ref_count = tlas.life_guard.add_ref(); - - let id = fid.assign(tlas, &mut token); - log::info!("Created blas {:?} with {:?}", id, desc); - - device.trackers.lock().tlas_s.insert_single(id, ref_count); - - return (id.0, None); - }; - - let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); - (id, Some(error)) - } -} - #[derive(Debug)] pub struct BlasTriangleGeometry<'a> { pub size: &'a wgt::BlasTriangleGeometrySizeDescriptor, diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 78c3d8af44..79e4a3b8e7 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -800,7 +800,7 @@ pub type BlasDescriptor<'a> = wgt::CreateBlasDescriptor>; pub type TlasDescriptor<'a> = wgt::CreateTlasDescriptor>; pub struct Blas { - pub(crate) raw: A::AccelerationStructure, + pub(crate) raw: Option, pub(crate) device_id: Stored, pub(crate) life_guard: LifeGuard, pub(crate) size_info: hal::AccelerationStructureBuildSizes, @@ -818,7 +818,7 @@ impl Resource for Blas { } pub struct Tlas { - pub(crate) raw: A::AccelerationStructure, + pub(crate) raw: Option, pub(crate) device_id: Stored, pub(crate) life_guard: LifeGuard, pub(crate) size_info: hal::AccelerationStructureBuildSizes, diff --git a/wgpu/examples/hello-ray-triangle/main.rs b/wgpu/examples/hello-ray-triangle/main.rs index f6c412d866..f375805933 100644 --- a/wgpu/examples/hello-ray-triangle/main.rs +++ b/wgpu/examples/hello-ray-triangle/main.rs @@ -490,6 +490,8 @@ async fn run(event_loop: EventLoop<()>, window: Window) { } queue.submit(Some(encoder.finish())); + vertex_buf.destroy(); + let start_inst = Instant::now(); event_loop.run(move |event, _, control_flow| { diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 667a93b25f..da4768a3f0 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -3075,6 +3075,26 @@ impl crate::Context for Context { ); } } + + fn blas_destroy(&self, blas: &Self::BlasId, _blas_data: &Self::BlasData) { + let global = &self.0; + let _ = wgc::gfx_select!(blas => global.blas_destroy(*blas)); + } + + fn blas_drop(&self, blas: &Self::BlasId, _blas_data: &Self::BlasData) { + let global = &self.0; + wgc::gfx_select!(blas => global.blas_drop(*blas, false)) + } + + fn tlas_destroy(&self, tlas: &Self::TlasId, _tlas_data: &Self::TlasData) { + let global = &self.0; + let _ = wgc::gfx_select!(tlas => global.tlas_destroy(*tlas)); + } + + fn tlas_drop(&self, tlas: &Self::TlasId, _tlas_data: &Self::TlasData) { + let global = &self.0; + wgc::gfx_select!(tlas => global.tlas_drop(*tlas, false)) + } } impl From for wgc::id::Id { diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index b1d5a23ed5..2bc4f94524 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -1016,6 +1016,10 @@ pub trait Context: Debug + Send + Sized + Sync { blas: impl Iterator>, tlas: impl Iterator>, ); + fn blas_destroy(&self, blas: &Self::BlasId, blas_data: &Self::BlasData); + fn blas_drop(&self, blas: &Self::BlasId, blas_data: &Self::BlasData); + fn tlas_destroy(&self, tlas: &Self::TlasId, tlas_data: &Self::TlasData); + fn tlas_drop(&self, tlas: &Self::TlasId, tlas_data: &Self::TlasData); } /// Object id. @@ -1951,6 +1955,10 @@ pub(crate) trait DynContext: Debug + Send + Sync { blas: &mut dyn Iterator>, tlas: &mut dyn Iterator>, ); + fn blas_destroy(&self, blas: &ObjectId, blas_data: &crate::Data); + fn blas_drop(&self, blas: &ObjectId, blas_data: &crate::Data); + fn tlas_destroy(&self, tlas: &ObjectId, tlas_data: &crate::Data); + fn tlas_drop(&self, tlas: &ObjectId, tlas_data: &crate::Data); } // Blanket impl of DynContext for all types which implement Context. @@ -3995,6 +4003,30 @@ where tlas, ) } + + fn blas_destroy(&self, blas: &ObjectId, blas_data: &crate::Data) { + let blas = ::from(*blas); + let blas_data = downcast_ref(blas_data); + Context::blas_destroy(self, &blas, blas_data) + } + + fn blas_drop(&self, blas: &ObjectId, blas_data: &crate::Data) { + let blas = ::from(*blas); + let blas_data = downcast_ref(blas_data); + Context::blas_drop(self, &blas, blas_data) + } + + fn tlas_destroy(&self, tlas: &ObjectId, tlas_data: &crate::Data) { + let tlas = ::from(*tlas); + let tlas_data = downcast_ref(tlas_data); + Context::tlas_destroy(self, &tlas, tlas_data) + } + + fn tlas_drop(&self, tlas: &ObjectId, tlas_data: &crate::Data) { + let tlas = ::from(*tlas); + let tlas_data = downcast_ref(tlas_data); + Context::tlas_drop(self, &tlas, tlas_data) + } } pub trait QueueWriteBuffer: Send + Sync { diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index f9867b4071..15935e6537 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -4631,6 +4631,18 @@ impl Blas { pub fn handle(&self) -> Option { self.handle } + + pub fn destroy(&self) { + DynContext::blas_destroy(&*self.context, &self.id, self.data.as_ref()); + } +} + +impl Drop for Blas { + fn drop(&mut self) { + if !thread::panicking() { + self.context.blas_drop(&self.id, self.data.as_ref()); + } + } } #[derive(Debug)] @@ -4641,6 +4653,20 @@ pub struct Tlas { } static_assertions::assert_impl_all!(Tlas: Send, Sync); +impl Tlas { + pub fn destroy(&self) { + DynContext::tlas_destroy(&*self.context, &self.id, self.data.as_ref()); + } +} + +impl Drop for Tlas { + fn drop(&mut self) { + if !thread::panicking() { + self.context.tlas_drop(&self.id, self.data.as_ref()); + } + } +} + pub struct TlasBuildEntry<'a> { pub tlas: &'a Tlas, pub instance_buffer: &'a Buffer, From 3114a55f0166193d9c36c7aa3a99d561d89c87df Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Fri, 31 Mar 2023 21:19:48 +0200 Subject: [PATCH 047/146] cleanup --- wgpu-core/src/command/ray_tracing.rs | 54 +++++++++---------- wgpu-core/src/device/mod.rs | 4 +- wgpu-core/src/device/ray_tracing.rs | 32 ++++------- wgpu-core/src/ray_tracing.rs | 23 ++------ wgpu-types/src/lib.rs | 21 ++++++++ wgpu/src/backend/direct.rs | 20 ++++--- wgpu/src/context.rs | 37 +++++-------- wgpu/src/lib.rs | 80 +++++++++++++++++++--------- 8 files changed, 136 insertions(+), 135 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index b13b5d3471..6b1b542b5c 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1,33 +1,21 @@ -#[cfg(feature = "trace")] -use crate::device::trace::Command as TraceCommand; +// #[cfg(feature = "trace")] +// use crate::device::trace::Command as TraceCommand; use crate::{ - command::{clear_texture, CommandBuffer, CommandEncoderError}, - conv, - device::{queue::TempResource, Device, DeviceError, MissingDownlevelFlags}, - error::{ErrorFormatter, PrettyError}, - hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Storage, Token}, - id::{self, BlasId, BufferId, CommandEncoderId, TlasId}, - init_tracker::{ - has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, - TextureInitTrackerAction, - }, + command::CommandBuffer, + device::queue::TempResource, + hub::{Global, GlobalIdentityHandlerFactory, HalApi, Token}, + id::CommandEncoderId, + init_tracker::MemoryInitKind, ray_tracing::{ BlasBuildEntry, BlasGeometries, BuildAccelerationStructureError, TlasBuildEntry, }, - resource::{self, Blas, Texture, TextureErrorDimension, Tlas}, - track::TextureSelector, - LabelHelpers, LifeGuard, Stored, + resource::{Blas, Tlas}, }; -use arrayvec::ArrayVec; -use hal::{ - AccelerationStructureInstances, AccelerationStructureTriangleIndices, - AccelerationStructureTriangleTransform, CommandEncoder as _, Device as _, -}; -use thiserror::Error; +use hal::{Device, CommandEncoder}; use wgt::BufferUsages; -use std::{borrow::Borrow, cmp::max, iter}; +use std::{cmp::max, iter}; // TODO: // tracing @@ -84,7 +72,7 @@ impl Global { for (i, mesh) in triangle_geometries.enumerate() { let size_desc = match &blas.sizes { - wgt::BlasGeometrySizeDescriptors::Triangles { desc } => desc, + &wgt::BlasGeometrySizeDescriptors::Triangles { ref desc } => desc, // _ => { // return Err( // BuildAccelerationStructureError::IncompatibleBlasBuildSizes( @@ -147,7 +135,7 @@ impl Global { { input_barriers.push(barrier); } - if mesh.size.vertex_count - mesh.first_vertex <= 0 { + if mesh.size.vertex_count as i64 - mesh.first_vertex as i64 <= 0 { return Err(BuildAccelerationStructureError::EmptyVertexBuffer( mesh.vertex_buffer, )); @@ -325,7 +313,7 @@ impl Global { vertex_count: mesh.size.vertex_count, vertex_stride: mesh.vertex_stride, indices: index_buffer.map(|index_buffer| { - AccelerationStructureTriangleIndices { + hal::AccelerationStructureTriangleIndices { format: mesh.size.index_format.unwrap(), buffer: Some(index_buffer), offset: mesh.index_buffer_offset.unwrap() as u32, @@ -333,7 +321,7 @@ impl Global { } }), transform: transform_buffer.map(|transform_buffer| { - AccelerationStructureTriangleTransform { + hal::AccelerationStructureTriangleTransform { buffer: transform_buffer, offset: mesh.transform_buffer_offset.unwrap() as u32, } @@ -403,7 +391,7 @@ impl Global { tlas_storage.push(( tlas, - hal::AccelerationStructureEntries::Instances(AccelerationStructureInstances { + hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { buffer: Some(instance_buffer), offset: 0, count: entry.instance_count, @@ -432,13 +420,16 @@ impl Global { let blas_descriptors = blas_storage .iter() - .map(|(blas, entries, scratch_buffer_offset)| { + .map(|&(blas,ref entries,ref scratch_buffer_offset)| { + if blas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { + log::info!("only rebuild implemented") + } hal::BuildAccelerationStructureDescriptor { entries, mode: hal::AccelerationStructureBuildMode::Build, // TODO flags: blas.flags, source_acceleration_structure: None, - destination_acceleration_structure: &blas.raw.as_ref().unwrap(), + destination_acceleration_structure: blas.raw.as_ref().unwrap(), scratch_buffer: &scratch_buffer, scratch_buffer_offset: *scratch_buffer_offset, } @@ -446,7 +437,10 @@ impl Global { let tlas_descriptors = tlas_storage .iter() - .map(|(tlas, entries, scratch_buffer_offset)| { + .map(|&(tlas, ref entries, ref scratch_buffer_offset)| { + if tlas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { + log::info!("only rebuild implemented") + } hal::BuildAccelerationStructureDescriptor { entries, mode: hal::AccelerationStructureBuildMode::Build, // TODO diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 53386efaa3..c1cbbfc177 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -18,7 +18,7 @@ use crate::{ }; use arrayvec::ArrayVec; -use hal::{AccelerationStructureTriangleIndices, CommandEncoder as _, Device as _}; +use hal::{CommandEncoder as _, Device as _}; use parking_lot::{Mutex, MutexGuard}; use smallvec::SmallVec; use thiserror::Error; @@ -2217,7 +2217,7 @@ impl Device { Br::AccelerationStructure(id) => { let tlas = used .acceleration_structures - .add_single(&*&tlas_guard, id) + .add_single(&tlas_guard, id) .ok_or(Error::InvalidTlas(id))?; let raw = tlas.raw.as_ref().ok_or(Error::InvalidTlas(id))?; diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index ce22ed31b8..f97153d279 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -1,27 +1,13 @@ -#[cfg(feature = "trace")] -use crate::device::trace::Command as TraceCommand; +// #[cfg(feature = "trace")] +// use crate::device::trace::Command as TraceCommand; use crate::{ - command::{clear_texture, CommandBuffer, CommandEncoderError}, - conv, - device::{queue::TempResource, Device, DeviceError, MissingDownlevelFlags}, - error::{ErrorFormatter, PrettyError}, - hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Storage, Token}, - id::{self, BlasId, BufferId, CommandEncoderId, TlasId}, - init_tracker::{ - has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, - TextureInitTrackerAction, - }, - resource::{self, Texture, TextureErrorDimension}, - track::TextureSelector, - LabelHelpers, LifeGuard, Stored, + device::{queue::TempResource, Device, DeviceError}, + hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Token}, + id::{self, BlasId, TlasId}, + resource, LabelHelpers, LifeGuard, Stored, }; -use arrayvec::ArrayVec; -use hal::{AccelerationStructureTriangleIndices, CommandEncoder as _, Device as _}; -use thiserror::Error; -use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages}; - -use std::iter; +use hal::{AccelerationStructureTriangleIndices, Device as _}; impl Device { // TODO: @@ -36,7 +22,7 @@ impl Device { debug_assert_eq!(self_id.backend(), A::VARIANT); let size_info = match &sizes { - wgt::BlasGeometrySizeDescriptors::Triangles { desc } => { + &wgt::BlasGeometrySizeDescriptors::Triangles { ref desc } => { let mut entries = Vec::>::with_capacity(desc.len()); for x in desc { @@ -58,7 +44,7 @@ impl Device { first_vertex: 0, vertex_count: x.vertex_count, vertex_stride: 0, - indices: indices, + indices, transform: None, flags: x.flags, }); diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index fcc66d8e81..53de7ba991 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -1,27 +1,10 @@ -#[cfg(feature = "trace")] -use crate::device::trace::Command as TraceCommand; use crate::{ - command::{clear_texture, CommandBuffer, CommandEncoderError}, - conv, - device::{queue::TempResource, Device, DeviceError, MissingDownlevelFlags}, - error::{ErrorFormatter, PrettyError}, - hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Storage, Token}, - id::{self, BlasId, BufferId, CommandEncoderId, TlasId}, - init_tracker::{ - has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, - TextureInitTrackerAction, - }, - resource::{self, Texture, TextureErrorDimension}, - track::TextureSelector, - LabelHelpers, LifeGuard, Stored, + command::CommandEncoderError, + id::{BlasId, BufferId, TlasId}, }; -use arrayvec::ArrayVec; -use hal::{AccelerationStructureTriangleIndices, CommandEncoder as _, Device as _}; use thiserror::Error; -use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages}; - -use std::iter; +use wgt::BufferAddress; /// Error encountered while attempting to do a copy on a command encoder. #[derive(Clone, Debug, Error)] diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 414348a227..1dfd964546 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6170,19 +6170,28 @@ impl Default for InstanceDescriptor { #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "trace", derive(serde::Serialize))] #[cfg_attr(feature = "replay", derive(serde::Deserialize))] +/// TODO Docu pub struct BlasTriangleGeometrySizeDescriptor { + /// TODO Docu pub vertex_format: VertexFormat, + /// TODO Docu pub vertex_count: u32, + /// TODO Docu pub index_format: Option, + /// TODO Docu pub index_count: Option, + /// TODO Docu pub flags: AccelerationStructureGeometryFlags, } #[derive(Clone, Debug)] #[cfg_attr(feature = "trace", derive(serde::Serialize))] #[cfg_attr(feature = "replay", derive(serde::Deserialize))] +/// TODO Docu pub enum BlasGeometrySizeDescriptors { + /// TODO Docu Triangles { + /// TODO Docu desc: Vec, }, } @@ -6191,8 +6200,11 @@ pub enum BlasGeometrySizeDescriptors { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "trace", derive(serde::Serialize))] #[cfg_attr(feature = "replay", derive(serde::Deserialize))] +/// TODO Docu pub enum AccelerationStructureUpdateMode { + /// TODO Docu Build, + /// TODO Docu PreferUpdate, } @@ -6200,9 +6212,13 @@ pub enum AccelerationStructureUpdateMode { #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "trace", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] +/// TODO Docu pub struct CreateBlasDescriptor { + /// TODO Docu pub label: L, + /// TODO Docu pub flags: AccelerationStructureFlags, + /// TODO Docu pub update_mode: AccelerationStructureUpdateMode, } @@ -6221,10 +6237,15 @@ impl CreateBlasDescriptor { #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "trace", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] +/// TODO Docu pub struct CreateTlasDescriptor { + /// TODO Docu pub label: L, + /// TODO Docu pub max_instances: u32, + /// TODO Docu pub flags: AccelerationStructureFlags, + /// TODO Docu pub update_mode: AccelerationStructureUpdateMode, } diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index da4768a3f0..b85dbb662b 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -472,12 +472,12 @@ pub struct CommandEncoder { #[derive(Debug)] pub struct Blas { - error_sink: ErrorSink, + // error_sink: ErrorSink, } #[derive(Debug)] pub struct Tlas { - error_sink: ErrorSink, + // error_sink: ErrorSink, } impl crate::Context for Context { @@ -2982,7 +2982,7 @@ impl crate::Context for Context { id, handle, Blas { - error_sink: Arc::clone(&device_data.error_sink), + // error_sink: Arc::clone(&device_data.error_sink), }, ) } @@ -3011,7 +3011,7 @@ impl crate::Context for Context { ( id, Tlas { - error_sink: Arc::clone(&device_data.error_sink), + // error_sink: Arc::clone(&device_data.error_sink), }, ) } @@ -3021,7 +3021,7 @@ impl crate::Context for Context { encoder: &Self::CommandEncoderId, encoder_data: &Self::CommandEncoderData, blas: impl Iterator>, - tlas: impl Iterator>, + tlas: impl Iterator>, ) { let global = &self.0; @@ -3030,11 +3030,9 @@ impl crate::Context for Context { crate::ContextBlasGeometries::TriangleGeometries(triangle_geometries) => { let iter = triangle_geometries.into_iter().map(|tg| { wgc::ray_tracing::BlasTriangleGeometry { - vertex_buffer: tg.vertex_buffer.0, - index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.0), - transform_buffer: tg - .transform_buffer - .map(|transform_buffer| transform_buffer.0), + vertex_buffer: tg.vertex_buffer, + index_buffer: tg.index_buffer, + transform_buffer: tg.transform_buffer, size: tg.size, transform_buffer_offset: tg.transform_buffer_offset, first_vertex: tg.first_vertex, @@ -3047,7 +3045,7 @@ impl crate::Context for Context { }; wgc::ray_tracing::BlasBuildEntry { blas_id: e.blas_id, - geometries: geometries, + geometries, } }); diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 2bc4f94524..81926008ea 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -1014,7 +1014,7 @@ pub trait Context: Debug + Send + Sized + Sync { encoder: &Self::CommandEncoderId, encoder_data: &Self::CommandEncoderData, blas: impl Iterator>, - tlas: impl Iterator>, + tlas: impl Iterator>, ); fn blas_destroy(&self, blas: &Self::BlasId, blas_data: &Self::BlasData); fn blas_drop(&self, blas: &Self::BlasId, blas_data: &Self::BlasData); @@ -1953,7 +1953,7 @@ pub(crate) trait DynContext: Debug + Send + Sync { encoder: &ObjectId, encoder_data: &crate::Data, blas: &mut dyn Iterator>, - tlas: &mut dyn Iterator>, + tlas: &mut dyn Iterator, ); fn blas_destroy(&self, blas: &ObjectId, blas_data: &crate::Data); fn blas_drop(&self, blas: &ObjectId, blas_data: &crate::Data); @@ -3941,7 +3941,7 @@ where encoder: &ObjectId, encoder_data: &crate::Data, blas: &mut dyn Iterator>, - tlas: &mut dyn Iterator>, + tlas: &mut dyn Iterator, ) { let encoder = ::from(*encoder); let encoder_data = downcast_ref(encoder_data); @@ -3953,22 +3953,13 @@ where triangle_geometries .into_iter() .map(|tg| ContextBlasTriangleGeometry { - vertex_buffer: ( - ::from(tg.vertex_buffer.0), - downcast_ref(tg.vertex_buffer.1), - ), - index_buffer: tg.index_buffer.map(|index_buffer| { - ( - ::from(index_buffer.0), - downcast_ref(index_buffer.1), - ) - }), - transform_buffer: tg.transform_buffer.map(|transform_buffer| { - ( - ::from(transform_buffer.0), - downcast_ref(transform_buffer.1), - ) - }), + vertex_buffer: ::from(tg.vertex_buffer), + index_buffer: tg + .index_buffer + .map(::from), + transform_buffer: tg + .transform_buffer + .map(::from), size: tg.size, transform_buffer_offset: tg.transform_buffer_offset, first_vertex: tg.first_vertex, @@ -3980,17 +3971,17 @@ where }; crate::ContextBlasBuildEntry { blas_id: ::from(e.blas_id), - blas_data: downcast_ref(e.blas_data), - geometries: geometries, + // blas_data: downcast_ref(e.blas_data), + geometries, } }); let tlas = tlas.into_iter().map(|e: crate::DynContextTlasBuildEntry| { crate::ContextTlasBuildEntry { tlas_id: ::from(e.tlas_id), - tlas_data: downcast_ref(e.tlas_data), + // tlas_data: downcast_ref(e.tlas_data), instance_buffer_id: ::from(e.instance_buffer_id), - instance_buffer_data: downcast_ref(e.instance_buffer_data), + // instance_buffer_data: downcast_ref(e.instance_buffer_data), instance_count: e.instance_count, } }); diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 15935e6537..455a4b149e 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -2974,6 +2974,8 @@ impl CommandEncoder { } /// Build bottom and top level acceleration structures + /// # Safety + /// TODO pub unsafe fn build_acceleration_structures_unsafe_tlas<'a>( &mut self, blas: impl IntoIterator>, @@ -2987,15 +2989,13 @@ impl CommandEncoder { let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry| { DynContextBlasTriangleGeometry { size: tg.size, - vertex_buffer: (tg.vertex_buffer.id, tg.vertex_buffer.data.as_ref()), + vertex_buffer: tg.vertex_buffer.id, - index_buffer: tg - .index_buffer - .map(|index_buffer| (index_buffer.id, index_buffer.data.as_ref())), + index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.id), - transform_buffer: tg.transform_buffer.map(|transform_buffer| { - (transform_buffer.id, transform_buffer.data.as_ref()) - }), + transform_buffer: tg + .transform_buffer + .map(|transform_buffer| transform_buffer.id), first_vertex: tg.first_vertex, vertex_stride: tg.vertex_stride, @@ -3008,8 +3008,7 @@ impl CommandEncoder { }; DynContextBlasBuildEntry { blas_id: e.blas.id, - blas_data: e.blas.data.as_ref(), - geometries: geometries, + geometries, } }); @@ -3017,9 +3016,7 @@ impl CommandEncoder { .into_iter() .map(|e: &TlasBuildEntry| DynContextTlasBuildEntry { tlas_id: e.tlas.id, - tlas_data: e.tlas.data.as_ref(), instance_buffer_id: e.instance_buffer.id, - instance_buffer_data: e.instance_buffer.data.as_ref(), instance_count: e.instance_count, }); @@ -4573,53 +4570,75 @@ impl Display for Error { } } +/// TODO Docu pub type BlasTriangleGeometrySizeDescriptor = wgt::BlasTriangleGeometrySizeDescriptor; static_assertions::assert_impl_all!(BlasTriangleGeometrySizeDescriptor: Send, Sync); +/// TODO Docu pub type BlasGeometrySizeDescriptors = wgt::BlasGeometrySizeDescriptors; static_assertions::assert_impl_all!(BlasGeometrySizeDescriptors: Send, Sync); +/// TODO Docu pub type AccelerationStructureFlags = wgt::AccelerationStructureFlags; static_assertions::assert_impl_all!(AccelerationStructureFlags: Send, Sync); +/// TODO Docu pub type AccelerationStructureGeometryFlags = wgt::AccelerationStructureGeometryFlags; static_assertions::assert_impl_all!(AccelerationStructureGeometryFlags: Send, Sync); +/// TODO Docu pub type AccelerationStructureUpdateMode = wgt::AccelerationStructureUpdateMode; static_assertions::assert_impl_all!(AccelerationStructureUpdateMode: Send, Sync); +/// TODO Docu pub type CreateBlasDescriptor<'a> = wgt::CreateBlasDescriptor>; static_assertions::assert_impl_all!(CreateBlasDescriptor: Send, Sync); +/// TODO Docu pub type CreateTlasDescriptor<'a> = wgt::CreateTlasDescriptor>; static_assertions::assert_impl_all!(CreateTlasDescriptor: Send, Sync); #[derive(Debug)] +/// TODO Docu pub struct BlasTriangleGeometry<'a> { + /// TODO Docu pub size: &'a BlasTriangleGeometrySizeDescriptor, + /// TODO Docu pub vertex_buffer: &'a Buffer, + /// TODO Docu pub first_vertex: u32, + /// TODO Docu pub vertex_stride: wgt::BufferAddress, + /// TODO Docu pub index_buffer: Option<&'a Buffer>, + /// TODO Docu pub index_buffer_offset: Option, + /// TODO Docu pub transform_buffer: Option<&'a Buffer>, + /// TODO Docu pub transform_buffer_offset: Option, } static_assertions::assert_impl_all!(BlasTriangleGeometry: Send, Sync); #[derive(Debug)] +/// TODO Docu pub enum BlasGeometries<'a> { + /// TODO Docu TriangleGeometries(&'a [BlasTriangleGeometry<'a>]), } static_assertions::assert_impl_all!(BlasGeometries: Send, Sync); +/// TODO Docu pub struct BlasBuildEntry<'a> { + /// TODO Docu pub blas: &'a Blas, + /// TODO Docu pub geometry: &'a BlasGeometries<'a>, } static_assertions::assert_impl_all!(BlasBuildEntry: Send, Sync); #[derive(Debug)] +/// TODO Docu pub struct Blas { context: Arc, id: ObjectId, @@ -4628,10 +4647,11 @@ pub struct Blas { } static_assertions::assert_impl_all!(Blas: Send, Sync); impl Blas { + /// TODO Docu pub fn handle(&self) -> Option { self.handle } - + /// TODO Docu pub fn destroy(&self) { DynContext::blas_destroy(&*self.context, &self.id, self.data.as_ref()); } @@ -4646,6 +4666,7 @@ impl Drop for Blas { } #[derive(Debug)] +/// TODO Docu pub struct Tlas { context: Arc, id: ObjectId, @@ -4654,6 +4675,7 @@ pub struct Tlas { static_assertions::assert_impl_all!(Tlas: Send, Sync); impl Tlas { + /// TODO Docu pub fn destroy(&self) { DynContext::tlas_destroy(&*self.context, &self.id, self.data.as_ref()); } @@ -4667,18 +4689,22 @@ impl Drop for Tlas { } } +/// TODO Docu pub struct TlasBuildEntry<'a> { + /// TODO Docu pub tlas: &'a Tlas, + /// TODO Docu pub instance_buffer: &'a Buffer, + /// TODO Docu pub instance_count: u32, } static_assertions::assert_impl_all!(TlasBuildEntry: Send, Sync); pub(crate) struct DynContextBlasTriangleGeometry<'a> { size: &'a BlasTriangleGeometrySizeDescriptor, - vertex_buffer: (ObjectId, &'a Data), - index_buffer: Option<(ObjectId, &'a Data)>, - transform_buffer: Option<(ObjectId, &'a Data)>, + vertex_buffer: ObjectId, + index_buffer: Option, + transform_buffer: Option, first_vertex: u32, vertex_stride: wgt::BufferAddress, index_buffer_offset: Option, @@ -4691,43 +4717,45 @@ pub(crate) enum DynContextBlasGeometries<'a> { pub(crate) struct DynContextBlasBuildEntry<'a> { blas_id: ObjectId, - blas_data: &'a crate::Data, geometries: DynContextBlasGeometries<'a>, } -pub(crate) struct DynContextTlasBuildEntry<'a> { +pub(crate) struct DynContextTlasBuildEntry { tlas_id: ObjectId, - tlas_data: &'a crate::Data, instance_buffer_id: ObjectId, - instance_buffer_data: &'a crate::Data, instance_count: u32, } +/// TODO Docu pub struct ContextBlasTriangleGeometry<'a, T: Context> { size: &'a BlasTriangleGeometrySizeDescriptor, - vertex_buffer: (T::BufferId, &'a T::BufferData), - index_buffer: Option<(T::BufferId, &'a T::BufferData)>, - transform_buffer: Option<(T::BufferId, &'a T::BufferData)>, + vertex_buffer: T::BufferId, + index_buffer: Option, + transform_buffer: Option, first_vertex: u32, vertex_stride: wgt::BufferAddress, index_buffer_offset: Option, transform_buffer_offset: Option, } +/// TODO Docu pub enum ContextBlasGeometries<'a, T: Context> { + /// TODO Docu TriangleGeometries(Box> + 'a>), } +/// TODO Docu pub struct ContextBlasBuildEntry<'a, T: Context> { blas_id: T::BlasId, - blas_data: &'a T::BlasData, + // blas_data: &'a T::BlasData, geometries: ContextBlasGeometries<'a, T>, } -pub struct ContextTlasBuildEntry<'a, T: Context> { +/// TODO Docu +pub struct ContextTlasBuildEntry { tlas_id: T::TlasId, - tlas_data: &'a T::TlasData, + // tlas_data: &'a T::TlasData, instance_buffer_id: T::BufferId, - instance_buffer_data: &'a T::BufferData, + // instance_buffer_data: &'a T::BufferData, instance_count: u32, } From 28bf5c586d83ed0be41a1dc3fb866a48d9b5b1fd Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sat, 1 Apr 2023 09:41:09 +0200 Subject: [PATCH 048/146] tracker cleanup --- wgpu-core/src/device/life.rs | 55 +++++++++++++++++++++++++++++++++++ wgpu-core/src/device/mod.rs | 14 ++++++++- wgpu-core/src/device/queue.rs | 14 ++++++++- wgpu-core/src/hub.rs | 3 ++ 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index b42d188dd3..f357d587fe 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -49,6 +49,8 @@ impl SuspectedResources { self.pipeline_layouts.clear(); self.render_bundles.clear(); self.query_sets.clear(); + self.blas_s.clear(); + self.tlas_s.clear(); } pub(super) fn extend(&mut self, other: &Self) { @@ -67,6 +69,8 @@ impl SuspectedResources { .extend_from_slice(&other.pipeline_layouts); self.render_bundles.extend_from_slice(&other.render_bundles); self.query_sets.extend_from_slice(&other.query_sets); + self.blas_s.extend_from_slice(&other.blas_s); + self.tlas_s.extend_from_slice(&other.tlas_s); } pub(super) fn add_render_bundle_scope(&mut self, trackers: &RenderBundleScope) { @@ -83,6 +87,7 @@ impl SuspectedResources { self.textures.extend(trackers.textures.used()); self.texture_views.extend(trackers.views.used()); self.samplers.extend(trackers.samplers.used()); + self.tlas_s.extend(trackers.acceleration_structures.used()); } } @@ -808,6 +813,56 @@ impl LifetimeTracker { } } } + + if !self.suspected_resources.blas_s.is_empty() { + let (mut guard, _) = hub.blas_s.write(token); + let mut trackers = trackers.lock(); + + for id in self.suspected_resources.blas_s.drain(..) { + if trackers.blas_s.remove_abandoned(id) { + log::debug!("Blas {:?} will be destroyed", id); + // #[cfg(feature = "trace")] + // if let Some(t) = trace { + // t.lock().add(trace::Action::DestroyBlas(id.0)); + // } + + if let Some(res) = hub.blas_s.unregister_locked(id.0, &mut *guard) { + let submit_index = res.life_guard.life_count(); + self.active + .iter_mut() + .find(|a| a.index == submit_index) + .map_or(&mut self.free_resources, |a| &mut a.last_resources) + .acceleration_structures + .extend(res.raw); + } + } + } + } + + if !self.suspected_resources.tlas_s.is_empty() { + let (mut guard, _) = hub.tlas_s.write(token); + let mut trackers = trackers.lock(); + + for id in self.suspected_resources.tlas_s.drain(..) { + if trackers.tlas_s.remove_abandoned(id) { + log::debug!("Blas {:?} will be destroyed", id); + // #[cfg(feature = "trace")] + // if let Some(t) = trace { + // t.lock().add(trace::Action::DestroyBlas(id.0)); + // } + + if let Some(res) = hub.tlas_s.unregister_locked(id.0, &mut *guard) { + let submit_index = res.life_guard.life_count(); + self.active + .iter_mut() + .find(|a| a.index == submit_index) + .map_or(&mut self.free_resources, |a| &mut a.last_resources) + .acceleration_structures + .extend(res.raw); + } + } + } + } } /// Determine which buffers are ready to map, and which must wait for the diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index c1cbbfc177..c1ab065711 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -564,7 +564,9 @@ impl Device { let (buffer_guard, mut token) = hub.buffers.read(&mut token); let (texture_guard, mut token) = hub.textures.read(&mut token); let (texture_view_guard, mut token) = hub.texture_views.read(&mut token); - let (sampler_guard, _) = hub.samplers.read(&mut token); + let (sampler_guard, mut token) = hub.samplers.read(&mut token); + let (blas_guard, mut token) = hub.blas_s.read(&mut token); + let (tlas_guard, _) = hub.tlas_s.read(&mut token); for id in trackers.buffers.used() { if buffer_guard[id].life_guard.ref_count.is_none() { @@ -606,6 +608,16 @@ impl Device { self.temp_suspected.query_sets.push(id); } } + for id in trackers.blas_s.used() { + if blas_guard[id].life_guard.ref_count.is_none() { + self.temp_suspected.blas_s.push(id); + } + } + for id in trackers.tlas_s.used() { + if tlas_guard[id].life_guard.ref_count.is_none() { + self.temp_suspected.tlas_s.push(id); + } + } } self.lock_life(token) diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index e3dff31933..785e776a8c 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -1061,7 +1061,9 @@ impl Global { let (mut texture_guard, mut token) = hub.textures.write(&mut token); let (texture_view_guard, mut token) = hub.texture_views.read(&mut token); let (sampler_guard, mut token) = hub.samplers.read(&mut token); - let (query_set_guard, _) = hub.query_sets.read(&mut token); + let (query_set_guard, mut token) = hub.query_sets.read(&mut token); + let (blas_guard, mut token) = hub.blas_s.read(&mut token); + let (tlas_guard, _) = hub.tlas_s.read(&mut token); //Note: locking the trackers has to be done after the storages let mut trackers = device.trackers.lock(); @@ -1205,6 +1207,16 @@ impl Global { query_set_guard[sub_id].life_guard.use_at(submit_index); } } + for id in cmdbuf.trackers.blas_s.used() { + if !blas_guard[id].life_guard.use_at(submit_index) { + device.temp_suspected.blas_s.push(id); + } + } + for id in cmdbuf.trackers.tlas_s.used() { + if !tlas_guard[id].life_guard.use_at(submit_index) { + device.temp_suspected.tlas_s.push(id); + } + } let mut baked = cmdbuf.into_baked(); // execute resource transitions diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 1693bb6590..6fc1cdd09f 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -545,12 +545,15 @@ impl Access> for Root {} impl Access> for Device {} impl Access> for CommandBuffer {} impl Access> for Buffer {} +impl Access> for Sampler {} +impl Access> for QuerySet {} impl Access> for Root {} impl Access> for Device {} impl Access> for CommandBuffer {} impl Access> for Buffer {} impl Access> for Blas {} impl Access> for Sampler {} +impl Access> for QuerySet {} #[cfg(debug_assertions)] thread_local! { From 8d03fcd6158b0c9d83fef6f5661c6f27b404c3e3 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sat, 1 Apr 2023 11:48:50 +0200 Subject: [PATCH 049/146] built when used validation --- wgpu-core/src/command/compute.rs | 16 ++- wgpu-core/src/command/mod.rs | 9 ++ wgpu-core/src/command/ray_tracing.rs | 154 ++++++++++++++++++++------- wgpu-core/src/command/render.rs | 16 ++- wgpu-core/src/device/queue.rs | 8 ++ wgpu-core/src/device/ray_tracing.rs | 3 + wgpu-core/src/hub.rs | 4 + wgpu-core/src/ray_tracing.rs | 36 +++++++ wgpu-core/src/resource.rs | 3 + wgpu/src/context.rs | 8 +- 10 files changed, 212 insertions(+), 45 deletions(-) diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index f494d37475..2d65ae3c11 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -362,7 +362,8 @@ impl Global { let (pipeline_guard, mut token) = hub.compute_pipelines.read(&mut token); let (query_set_guard, mut token) = hub.query_sets.read(&mut token); let (buffer_guard, mut token) = hub.buffers.read(&mut token); - let (texture_guard, _) = hub.textures.read(&mut token); + let (texture_guard, mut token) = hub.textures.read(&mut token); + let (tlas_guard, _) = hub.tlas_s.read(&mut token); let mut state = State { binder: Binder::new(), @@ -450,6 +451,19 @@ impl Global { ); } + cmd_buf.tlas_actions.extend( + bind_group.used.acceleration_structures.used().filter_map(|id| { + let tlas = &tlas_guard[id]; + if *tlas.built.lock() { + None + } + else + { + Some(crate::ray_tracing::TlasAction{ id: id.0, kind: crate::ray_tracing::AccelerationStructureActionKind::Use }) + } + }), + ); + let pipeline_layout_id = state.binder.pipeline_layout_id; let entries = state.binder.assign_group( index as usize, diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index fcb56cc079..12fdbe57b0 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -20,6 +20,7 @@ use self::memory_init::CommandBufferTextureMemoryActions; use crate::error::{ErrorFormatter, PrettyError}; use crate::init_tracker::BufferInitTrackerAction; +use crate::ray_tracing::{BlasAction, TlasAction}; use crate::track::{Tracker, UsageScope}; use crate::{ hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token}, @@ -88,6 +89,8 @@ pub struct BakedCommands { pub(crate) trackers: Tracker, buffer_memory_init_actions: Vec, texture_memory_actions: CommandBufferTextureMemoryActions, + blas_actions: Vec, + tlas_actions: Vec, } pub(crate) struct DestroyedBufferError(pub id::BufferId); @@ -100,6 +103,8 @@ pub struct CommandBuffer { pub(crate) trackers: Tracker, buffer_memory_init_actions: Vec, texture_memory_actions: CommandBufferTextureMemoryActions, + blas_actions: Vec, + tlas_actions: Vec, limits: wgt::Limits, support_clear_texture: bool, #[cfg(feature = "trace")] @@ -128,6 +133,8 @@ impl CommandBuffer { trackers: Tracker::new(), buffer_memory_init_actions: Default::default(), texture_memory_actions: Default::default(), + blas_actions: Default::default(), + tlas_actions: Default::default(), limits, support_clear_texture: features.contains(wgt::Features::CLEAR_TEXTURE), #[cfg(feature = "trace")] @@ -224,6 +231,8 @@ impl CommandBuffer { trackers: self.trackers, buffer_memory_init_actions: self.buffer_memory_init_actions, texture_memory_actions: self.texture_memory_actions, + blas_actions: self.blas_actions, + tlas_actions: self.tlas_actions, } } } diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 6b1b542b5c..b5fe1e53b8 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -3,20 +3,24 @@ use crate::{ command::CommandBuffer, device::queue::TempResource, - hub::{Global, GlobalIdentityHandlerFactory, HalApi, Token}, - id::CommandEncoderId, + hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token}, + id::{BlasId, CommandEncoderId, TlasId}, init_tracker::MemoryInitKind, ray_tracing::{ - BlasBuildEntry, BlasGeometries, BuildAccelerationStructureError, TlasBuildEntry, + BlasAction, BlasBuildEntry, BlasGeometries, BuildAccelerationStructureError, TlasAction, + TlasBuildEntry, ValidateBlasActionsError, ValidateTlasActionsError, }, resource::{Blas, Tlas}, + FastHashSet, }; -use hal::{Device, CommandEncoder}; +use hal::{CommandEncoder, Device}; use wgt::BufferUsages; use std::{cmp::max, iter}; +use super::BakedCommands; + // TODO: // tracing // automatic build splitting (if to big for spec or scratch buffer) @@ -66,6 +70,13 @@ impl Global { return Err(BuildAccelerationStructureError::InvalidBlas(entry.blas_id)); } + if !*blas.built.lock() { + cmd_buf.blas_actions.push(BlasAction { + id: entry.blas_id, + kind: crate::ray_tracing::AccelerationStructureActionKind::Build, + }); + } + match entry.geometries { BlasGeometries::TriangleGeometries(triangle_geometries) => { let mut triangle_entries = Vec::>::new(); @@ -386,6 +397,13 @@ impl Global { return Err(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id)); } + if !*tlas.built.lock() { + cmd_buf.tlas_actions.push(TlasAction { + id: entry.tlas_id, + kind: crate::ray_tracing::AccelerationStructureActionKind::Build, + }); + } + let scratch_buffer_offset = scratch_buffer_tlas_size; scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; // TODO Alignment @@ -400,6 +418,10 @@ impl Global { )); } + if max(scratch_buffer_blas_size, scratch_buffer_tlas_size) == 0 { + return Ok(()); + } + let scratch_buffer = unsafe { device .raw @@ -418,39 +440,43 @@ impl Global { ..hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, }; - let blas_descriptors = blas_storage - .iter() - .map(|&(blas,ref entries,ref scratch_buffer_offset)| { - if blas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { - log::info!("only rebuild implemented") - } - hal::BuildAccelerationStructureDescriptor { - entries, - mode: hal::AccelerationStructureBuildMode::Build, // TODO - flags: blas.flags, - source_acceleration_structure: None, - destination_acceleration_structure: blas.raw.as_ref().unwrap(), - scratch_buffer: &scratch_buffer, - scratch_buffer_offset: *scratch_buffer_offset, - } - }); - - let tlas_descriptors = tlas_storage - .iter() - .map(|&(tlas, ref entries, ref scratch_buffer_offset)| { - if tlas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { - log::info!("only rebuild implemented") - } - hal::BuildAccelerationStructureDescriptor { - entries, - mode: hal::AccelerationStructureBuildMode::Build, // TODO - flags: tlas.flags, - source_acceleration_structure: None, - destination_acceleration_structure: tlas.raw.as_ref().unwrap(), - scratch_buffer: &scratch_buffer, - scratch_buffer_offset: *scratch_buffer_offset, - } - }); + let blas_descriptors = + blas_storage + .iter() + .map(|&(blas, ref entries, ref scratch_buffer_offset)| { + if blas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { + log::info!("only rebuild implemented") + } + *blas.built.lock() = true; + hal::BuildAccelerationStructureDescriptor { + entries, + mode: hal::AccelerationStructureBuildMode::Build, // TODO + flags: blas.flags, + source_acceleration_structure: None, + destination_acceleration_structure: blas.raw.as_ref().unwrap(), + scratch_buffer: &scratch_buffer, + scratch_buffer_offset: *scratch_buffer_offset, + } + }); + + let tlas_descriptors = + tlas_storage + .iter() + .map(|&(tlas, ref entries, ref scratch_buffer_offset)| { + if tlas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { + log::info!("only rebuild implemented") + } + *tlas.built.lock() = true; + hal::BuildAccelerationStructureDescriptor { + entries, + mode: hal::AccelerationStructureBuildMode::Build, // TODO + flags: tlas.flags, + source_acceleration_structure: None, + destination_acceleration_structure: tlas.raw.as_ref().unwrap(), + scratch_buffer: &scratch_buffer, + scratch_buffer_offset: *scratch_buffer_offset, + } + }); let blas_present = !blas_storage.is_empty(); let tlas_present = !tlas_storage.is_empty(); @@ -482,3 +508,57 @@ impl Global { Ok(()) } } + +impl BakedCommands { + // makes sure a blas is build before it is used + pub(crate) fn validate_blas_actions( + &mut self, + blas_guard: &Storage, BlasId>, + ) -> Result<(), ValidateBlasActionsError> { + let mut built = FastHashSet::default(); + for action in self.blas_actions.drain(..) { + match action.kind { + crate::ray_tracing::AccelerationStructureActionKind::Build => { + built.insert(action.id); + } + crate::ray_tracing::AccelerationStructureActionKind::Use => { + if !built.contains(&action.id) { + let blas = blas_guard + .get(action.id) + .map_err(|_| ValidateBlasActionsError::InvalidBlas(action.id))?; + if !*blas.built.lock() { + return Err(ValidateBlasActionsError::UsedUnbuilt(action.id)); + } + } + } + } + } + Ok(()) + } + + // makes sure a tlas is build before it is used + pub(crate) fn validate_tlas_actions( + &mut self, + tlas_guard: &Storage, TlasId>, + ) -> Result<(), ValidateTlasActionsError> { + let mut built = FastHashSet::default(); + for action in self.tlas_actions.drain(..) { + match action.kind { + crate::ray_tracing::AccelerationStructureActionKind::Build => { + built.insert(action.id); + } + crate::ray_tracing::AccelerationStructureActionKind::Use => { + if !built.contains(&action.id) { + let tlas = tlas_guard + .get(action.id) + .map_err(|_| ValidateTlasActionsError::InvalidTlas(action.id))?; + if !*tlas.built.lock() { + return Err(ValidateTlasActionsError::UsedUnbuilt(action.id)); + } + } + } + } + } + Ok(()) + } +} diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index dc99889c46..c5092c48d5 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1246,7 +1246,8 @@ impl Global { let (query_set_guard, mut token) = hub.query_sets.read(&mut token); let (buffer_guard, mut token) = hub.buffers.read(&mut token); let (texture_guard, mut token) = hub.textures.read(&mut token); - let (view_guard, _) = hub.texture_views.read(&mut token); + let (view_guard, mut token) = hub.texture_views.read(&mut token); + let (tlas_guard, _) = hub.tlas_s.read(&mut token); log::trace!( "Encoding render pass begin in command buffer {:?}", @@ -1356,6 +1357,19 @@ impl Global { ); } + cmd_buf.tlas_actions.extend( + bind_group.used.acceleration_structures.used().filter_map(|id| { + let tlas = &tlas_guard[id]; + if *tlas.built.lock() { + None + } + else + { + Some(crate::ray_tracing::TlasAction{ id: id.0, kind: crate::ray_tracing::AccelerationStructureActionKind::Use }) + } + }), + ); + let pipeline_layout_id = state.binder.pipeline_layout_id; let entries = state.binder.assign_group( index as usize, diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 785e776a8c..d11acfe415 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -319,6 +319,10 @@ pub enum QueueSubmitError { SurfaceUnconfigured, #[error("GPU got stuck :(")] StuckGpu, + #[error(transparent)] + ValidateBlasActionsError(#[from] crate::ray_tracing::ValidateBlasActionsError), + #[error(transparent)] + ValidateTlasActionsError(#[from] crate::ray_tracing::ValidateTlasActionsError), } //TODO: move out common parts of write_xxx. @@ -1233,6 +1237,10 @@ impl Global { baked .initialize_texture_memory(&mut *trackers, &mut *texture_guard, device) .map_err(|err| QueueSubmitError::DestroyedTexture(err.0))?; + + baked.validate_blas_actions(&*blas_guard)?; + baked.validate_tlas_actions(&*tlas_guard)?; + //Note: stateless trackers are not merged: // device already knows these resources exist. CommandBuffer::insert_barriers_from_tracker( diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index f97153d279..f819e8ce75 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -8,6 +8,7 @@ use crate::{ }; use hal::{AccelerationStructureTriangleIndices, Device as _}; +use parking_lot::Mutex; impl Device { // TODO: @@ -81,6 +82,7 @@ impl Device { sizes, flags: blas_desc.flags, update_mode: blas_desc.update_mode, + built: Mutex::new(false), }) } @@ -130,6 +132,7 @@ impl Device { size_info, flags: desc.flags, update_mode: desc.update_mode, + built: Mutex::new(false), }) } } diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 6fc1cdd09f..e6feaac9ef 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -547,6 +547,8 @@ impl Access> for CommandBuffer {} impl Access> for Buffer {} impl Access> for Sampler {} impl Access> for QuerySet {} +impl Access> for Texture {} +impl Access> for TextureView {} impl Access> for Root {} impl Access> for Device {} impl Access> for CommandBuffer {} @@ -554,6 +556,8 @@ impl Access> for Buffer {} impl Access> for Blas {} impl Access> for Sampler {} impl Access> for QuerySet {} +impl Access> for Texture {} +impl Access> for TextureView {} #[cfg(debug_assertions)] thread_local! { diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 53de7ba991..f547b53ec8 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -50,6 +50,24 @@ pub enum BuildAccelerationStructureError { MissingTlasInputUsageFlag(BufferId), } +#[derive(Clone, Debug, Error)] +pub enum ValidateBlasActionsError { + #[error("Blas {0:?} is invalid or destroyed")] + InvalidBlas(BlasId), + + #[error("Blas {0:?} is used before it is build")] + UsedUnbuilt(BlasId), +} + +#[derive(Clone, Debug, Error)] +pub enum ValidateTlasActionsError { + #[error("Tlas {0:?} is invalid or destroyed")] + InvalidTlas(TlasId), + + #[error("Tlas {0:?} is used before it is build")] + UsedUnbuilt(TlasId), +} + #[derive(Debug)] pub struct BlasTriangleGeometry<'a> { pub size: &'a wgt::BlasTriangleGeometrySizeDescriptor, @@ -76,3 +94,21 @@ pub struct TlasBuildEntry { pub instance_buffer_id: BufferId, pub instance_count: u32, } + +#[derive(Debug, Copy, Clone)] +pub(crate) enum AccelerationStructureActionKind { + Build, + Use, +} + +#[derive(Debug, Clone)] +pub(crate) struct BlasAction { + pub id: BlasId, + pub kind: AccelerationStructureActionKind, +} + +#[derive(Debug, Clone)] +pub(crate) struct TlasAction { + pub id: TlasId, + pub kind: AccelerationStructureActionKind, +} diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 79e4a3b8e7..3d7301f6dc 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -8,6 +8,7 @@ use crate::{ Label, LifeGuard, RefCount, Stored, }; +use parking_lot::Mutex; use smallvec::SmallVec; use thiserror::Error; @@ -807,6 +808,7 @@ pub struct Blas { pub(crate) sizes: wgt::BlasGeometrySizeDescriptors, pub(crate) flags: wgt::AccelerationStructureFlags, pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, + pub(crate) built: Mutex, } impl Resource for Blas { @@ -824,6 +826,7 @@ pub struct Tlas { pub(crate) size_info: hal::AccelerationStructureBuildSizes, pub(crate) flags: wgt::AccelerationStructureFlags, pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, + pub(crate) built: Mutex, } impl Resource for Tlas { diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 81926008ea..2bf9f94a74 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -3954,12 +3954,8 @@ where .into_iter() .map(|tg| ContextBlasTriangleGeometry { vertex_buffer: ::from(tg.vertex_buffer), - index_buffer: tg - .index_buffer - .map(::from), - transform_buffer: tg - .transform_buffer - .map(::from), + index_buffer: tg.index_buffer.map(::from), + transform_buffer: tg.transform_buffer.map(::from), size: tg.size, transform_buffer_offset: tg.transform_buffer_offset, first_vertex: tg.first_vertex, From 1515badc3efcc9680955746da4caff8dc3895185 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sat, 1 Apr 2023 11:59:53 +0200 Subject: [PATCH 050/146] clippy --- wgpu-hal/src/vulkan/command.rs | 6 +++--- wgpu-hal/src/vulkan/device.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 07976c266d..3c98221fc1 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -410,7 +410,7 @@ impl crate::CommandEncoder for super::CommandEncoder { >::with_capacity(descriptor_count); for desc in descriptors { - let (geometries, ranges) = match desc.entries { + let (geometries, ranges) = match *desc.entries { crate::AccelerationStructureEntries::Instances(ref instances) => { let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder( ) @@ -430,7 +430,7 @@ impl crate::CommandEncoder for super::CommandEncoder { (smallvec::smallvec![*geometry], smallvec::smallvec![*range]) } - crate::AccelerationStructureEntries::Triangles(in_geometries) => { + crate::AccelerationStructureEntries::Triangles(ref in_geometries) => { let mut ranges = smallvec::SmallVec::< [vk::AccelerationStructureBuildRangeInfoKHR; CAPACITY_INNER], >::with_capacity(in_geometries.len()); @@ -497,7 +497,7 @@ impl crate::CommandEncoder for super::CommandEncoder { } (geometries, ranges) } - crate::AccelerationStructureEntries::AABBs(in_geometries) => { + crate::AccelerationStructureEntries::AABBs(ref in_geometries) => { let mut ranges = smallvec::SmallVec::< [vk::AccelerationStructureBuildRangeInfoKHR; CAPACITY_INNER], >::with_capacity(in_geometries.len()); diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 34ddaa0bad..bd1e2784d3 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -2064,7 +2064,7 @@ impl crate::Device for super::Device { None => panic!("Feature `RAY_TRACING` not enabled"), }; - let (geometries, primitive_counts) = match desc.entries { + let (geometries, primitive_counts) = match *desc.entries { crate::AccelerationStructureEntries::Instances(ref instances) => { let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::default(); @@ -2079,7 +2079,7 @@ impl crate::Device for super::Device { smallvec::smallvec![instances.count], ) } - crate::AccelerationStructureEntries::Triangles(in_geometries) => { + crate::AccelerationStructureEntries::Triangles(ref in_geometries) => { let mut primitive_counts = smallvec::SmallVec::<[u32; CAPACITY]>::with_capacity(in_geometries.len()); let mut geometries = smallvec::SmallVec::< @@ -2115,7 +2115,7 @@ impl crate::Device for super::Device { } (geometries, primitive_counts) } - crate::AccelerationStructureEntries::AABBs(in_geometries) => { + crate::AccelerationStructureEntries::AABBs(ref in_geometries) => { let mut primitive_counts = smallvec::SmallVec::<[u32; CAPACITY]>::with_capacity(in_geometries.len()); let mut geometries = smallvec::SmallVec::< From 4bbfd49b7718f64f6f01bf37ef0b68e7de168452 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sat, 1 Apr 2023 13:14:12 +0200 Subject: [PATCH 051/146] better example with test --- wgpu/examples/hello-ray-triangle/README.md | 9 - wgpu/examples/hello-ray-triangle/main.rs | 619 ----------------- wgpu/examples/ray-cube/README.md | 13 + .../blit.wgsl | 0 wgpu/examples/ray-cube/main.rs | 645 ++++++++++++++++++ wgpu/examples/ray-cube/screenshot.png | Bin 0 -> 325681 bytes .../shader.wgsl | 4 +- 7 files changed, 660 insertions(+), 630 deletions(-) delete mode 100644 wgpu/examples/hello-ray-triangle/README.md delete mode 100644 wgpu/examples/hello-ray-triangle/main.rs create mode 100644 wgpu/examples/ray-cube/README.md rename wgpu/examples/{hello-ray-triangle => ray-cube}/blit.wgsl (100%) create mode 100644 wgpu/examples/ray-cube/main.rs create mode 100644 wgpu/examples/ray-cube/screenshot.png rename wgpu/examples/{hello-ray-triangle => ray-cube}/shader.wgsl (96%) diff --git a/wgpu/examples/hello-ray-triangle/README.md b/wgpu/examples/hello-ray-triangle/README.md deleted file mode 100644 index 6efb0ebcec..0000000000 --- a/wgpu/examples/hello-ray-triangle/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# hello-triangle - -This example renders a triangle to a window with a ray query. - -## To Run - -``` -cargo run --example hello-ray-triangle -``` \ No newline at end of file diff --git a/wgpu/examples/hello-ray-triangle/main.rs b/wgpu/examples/hello-ray-triangle/main.rs deleted file mode 100644 index f375805933..0000000000 --- a/wgpu/examples/hello-ray-triangle/main.rs +++ /dev/null @@ -1,619 +0,0 @@ -use bytemuck::{Pod, Zeroable}; -use glam::{Affine3A, Mat4, Quat, Vec3}; -use std::{borrow::Cow, iter, mem, time::Instant}; - -use wgpu::util::DeviceExt; -use winit::{ - dpi::{LogicalSize, PhysicalPosition}, - event::{Event, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, - window::Window, -}; - -// from cube -#[repr(C)] -#[derive(Clone, Copy, Pod, Zeroable)] -struct Vertex { - _pos: [f32; 4], - _tex_coord: [f32; 2], -} - -fn vertex(pos: [i8; 3], tc: [i8; 2]) -> Vertex { - Vertex { - _pos: [pos[0] as f32, pos[1] as f32, pos[2] as f32, 1.0], - _tex_coord: [tc[0] as f32, tc[1] as f32], - } -} - -fn create_vertices() -> (Vec, Vec) { - let vertex_data = [ - // top (0, 0, 1) - vertex([-1, -1, 1], [0, 0]), - vertex([1, -1, 1], [1, 0]), - vertex([1, 1, 1], [1, 1]), - vertex([-1, 1, 1], [0, 1]), - // bottom (0, 0, -1) - vertex([-1, 1, -1], [1, 0]), - vertex([1, 1, -1], [0, 0]), - vertex([1, -1, -1], [0, 1]), - vertex([-1, -1, -1], [1, 1]), - // right (1, 0, 0) - vertex([1, -1, -1], [0, 0]), - vertex([1, 1, -1], [1, 0]), - vertex([1, 1, 1], [1, 1]), - vertex([1, -1, 1], [0, 1]), - // left (-1, 0, 0) - vertex([-1, -1, 1], [1, 0]), - vertex([-1, 1, 1], [0, 0]), - vertex([-1, 1, -1], [0, 1]), - vertex([-1, -1, -1], [1, 1]), - // front (0, 1, 0) - vertex([1, 1, -1], [1, 0]), - vertex([-1, 1, -1], [0, 0]), - vertex([-1, 1, 1], [0, 1]), - vertex([1, 1, 1], [1, 1]), - // back (0, -1, 0) - vertex([1, -1, 1], [0, 0]), - vertex([-1, -1, 1], [1, 0]), - vertex([-1, -1, -1], [1, 1]), - vertex([1, -1, -1], [0, 1]), - ]; - - let index_data: &[u16] = &[ - 0, 1, 2, 2, 3, 0, // top - 4, 5, 6, 6, 7, 4, // bottom - 8, 9, 10, 10, 11, 8, // right - 12, 13, 14, 14, 15, 12, // left - 16, 17, 18, 18, 19, 16, // front - 20, 21, 22, 22, 23, 20, // back - ]; - - (vertex_data.to_vec(), index_data.to_vec()) -} - -#[repr(C)] -#[derive(Clone, Copy, Pod, Zeroable)] -struct Uniforms { - view_inverse: [[f32; 4]; 4], - proj_inverse: [[f32; 4]; 4], -} - -#[repr(C)] -#[derive(Clone, Copy, Pod, Zeroable)] -struct AccelerationStructureInstance { - transform: [f32; 12], - custom_index_and_mask: u32, - shader_binding_table_record_offset_and_flags: u32, - acceleration_structure_reference: u64, -} - -impl std::fmt::Debug for AccelerationStructureInstance { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Instance") - .field("transform", &self.transform) - .field("custom_index()", &self.custom_index()) - .field("mask()", &self.mask()) - .field( - "shader_binding_table_record_offset()", - &self.shader_binding_table_record_offset(), - ) - .field("flags()", &self.flags()) - .field( - "acceleration_structure_reference", - &self.acceleration_structure_reference, - ) - .finish() - } -} - -#[allow(dead_code)] -impl AccelerationStructureInstance { - const LOW_24_MASK: u32 = 0x00ff_ffff; - const MAX_U24: u32 = (1u32 << 24u32) - 1u32; - - #[inline] - fn affine_to_rows(mat: &Affine3A) -> [f32; 12] { - let row_0 = mat.matrix3.row(0); - let row_1 = mat.matrix3.row(1); - let row_2 = mat.matrix3.row(2); - let translation = mat.translation; - [ - row_0.x, - row_0.y, - row_0.z, - translation.x, - row_1.x, - row_1.y, - row_1.z, - translation.y, - row_2.x, - row_2.y, - row_2.z, - translation.z, - ] - } - - #[inline] - fn rows_to_affine(rows: &[f32; 12]) -> Affine3A { - Affine3A::from_cols_array(&[ - rows[0], rows[3], rows[6], rows[9], rows[1], rows[4], rows[7], rows[10], rows[2], - rows[5], rows[8], rows[11], - ]) - } - - pub fn transform_as_affine(&self) -> Affine3A { - Self::rows_to_affine(&self.transform) - } - pub fn set_transform(&mut self, transform: &Affine3A) { - self.transform = Self::affine_to_rows(&transform); - } - - pub fn custom_index(&self) -> u32 { - self.custom_index_and_mask & Self::LOW_24_MASK - } - - pub fn mask(&self) -> u8 { - (self.custom_index_and_mask >> 24) as u8 - } - - pub fn shader_binding_table_record_offset(&self) -> u32 { - self.shader_binding_table_record_offset_and_flags & Self::LOW_24_MASK - } - - pub fn flags(&self) -> u8 { - (self.shader_binding_table_record_offset_and_flags >> 24) as u8 - } - - pub fn set_custom_index(&mut self, custom_index: u32) { - debug_assert!( - custom_index <= Self::MAX_U24, - "custom_index uses more than 24 bits! {custom_index} > {}", - Self::MAX_U24 - ); - self.custom_index_and_mask = - (custom_index & Self::LOW_24_MASK) | (self.custom_index_and_mask & !Self::LOW_24_MASK) - } - - pub fn set_mask(&mut self, mask: u8) { - self.custom_index_and_mask = - (self.custom_index_and_mask & Self::LOW_24_MASK) | (u32::from(mask) << 24) - } - - pub fn set_shader_binding_table_record_offset( - &mut self, - shader_binding_table_record_offset: u32, - ) { - debug_assert!(shader_binding_table_record_offset <= Self::MAX_U24, "shader_binding_table_record_offset uses more than 24 bits! {shader_binding_table_record_offset} > {}", Self::MAX_U24); - self.shader_binding_table_record_offset_and_flags = (shader_binding_table_record_offset - & Self::LOW_24_MASK) - | (self.shader_binding_table_record_offset_and_flags & !Self::LOW_24_MASK) - } - - pub fn set_flags(&mut self, flags: u8) { - self.shader_binding_table_record_offset_and_flags = - (self.shader_binding_table_record_offset_and_flags & Self::LOW_24_MASK) - | (u32::from(flags) << 24) - } - - pub fn new( - transform: &Affine3A, - custom_index: u32, - mask: u8, - shader_binding_table_record_offset: u32, - flags: u8, - acceleration_structure_reference: u64, - ) -> Self { - debug_assert!( - custom_index <= Self::MAX_U24, - "custom_index uses more than 24 bits! {custom_index} > {}", - Self::MAX_U24 - ); - debug_assert!( - shader_binding_table_record_offset <= Self::MAX_U24, - "shader_binding_table_record_offset uses more than 24 bits! {shader_binding_table_record_offset} > {}", Self::MAX_U24 - ); - AccelerationStructureInstance { - transform: Self::affine_to_rows(transform), - custom_index_and_mask: (custom_index & Self::MAX_U24) | (u32::from(mask) << 24), - shader_binding_table_record_offset_and_flags: (shader_binding_table_record_offset - & Self::MAX_U24) - | (u32::from(flags) << 24), - acceleration_structure_reference, - } - } -} - -async fn run(event_loop: EventLoop<()>, window: Window) { - let size = window.inner_size(); - - let instance = wgpu::Instance::default(); - - let surface = unsafe { instance.create_surface(&window) }.unwrap(); - let adapter = instance - .request_adapter(&wgpu::RequestAdapterOptions { - power_preference: wgpu::PowerPreference::default(), - force_fallback_adapter: false, - // Request an adapter which can render to our surface - compatible_surface: Some(&surface), - }) - .await - .expect("Failed to find an appropriate adapter"); - - // Create the logical device and command queue - let (device, queue) = adapter - .request_device( - &wgpu::DeviceDescriptor { - label: None, - features: wgpu::Features::all_webgpu_mask() - | wgpu::Features::TEXTURE_BINDING_ARRAY - | wgpu::Features::STORAGE_RESOURCE_BINDING_ARRAY - | wgpu::Features::VERTEX_WRITABLE_STORAGE - | wgpu::Features::RAY_QUERY - | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE, - // Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain. - limits: wgpu::Limits::default(), - }, - None, - ) - .await - .expect("Failed to create device"); - - let swapchain_capabilities = surface.get_capabilities(&adapter); - let swapchain_format = swapchain_capabilities.formats[0]; - - let mut config = wgpu::SurfaceConfiguration { - usage: wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::RENDER_ATTACHMENT, - format: swapchain_format, - width: size.width, - height: size.height, - present_mode: wgpu::PresentMode::Fifo, - alpha_mode: swapchain_capabilities.alpha_modes[0], - view_formats: vec![], - }; - - surface.configure(&device, &config); - - let rt_target = device.create_texture(&wgpu::TextureDescriptor { - label: Some("rt_target"), - size: wgpu::Extent3d { - width: size.width, - height: size.height, - depth_or_array_layers: 1, - }, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rgba8Unorm, - usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::STORAGE_BINDING, - view_formats: &[wgpu::TextureFormat::Rgba8Unorm], - }); - - let rt_view = rt_target.create_view(&wgpu::TextureViewDescriptor { - label: None, - format: Some(wgpu::TextureFormat::Rgba8Unorm), - dimension: Some(wgpu::TextureViewDimension::D2), - aspect: wgpu::TextureAspect::All, - base_mip_level: 0, - mip_level_count: None, - base_array_layer: 0, - array_layer_count: None, - }); - - let sampler = device.create_sampler(&wgpu::SamplerDescriptor { - label: Some("rt_sampler"), - address_mode_u: wgpu::AddressMode::ClampToEdge, - address_mode_v: wgpu::AddressMode::ClampToEdge, - address_mode_w: wgpu::AddressMode::ClampToEdge, - mag_filter: wgpu::FilterMode::Linear, - min_filter: wgpu::FilterMode::Linear, - mipmap_filter: wgpu::FilterMode::Nearest, - ..Default::default() - }); - - let uniforms = { - let view = Mat4::look_at_rh(Vec3::new(0.0, 0.0, 2.5), Vec3::ZERO, Vec3::Y); - let proj = Mat4::perspective_rh(59.0_f32.to_radians(), 1.0, 0.001, 1000.0); - - Uniforms { - view_inverse: view.inverse().to_cols_array_2d(), - proj_inverse: proj.inverse().to_cols_array_2d(), - } - }; - - let uniform_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Uniform Buffer"), - contents: bytemuck::cast_slice(&[uniforms]), - usage: wgpu::BufferUsages::UNIFORM, - }); - - let (vertex_data, index_data) = create_vertices(); - - let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Vertex Buffer"), - contents: bytemuck::cast_slice(&vertex_data), - usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::BLAS_INPUT, - }); - - let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Index Buffer"), - contents: bytemuck::cast_slice(&index_data), - usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::BLAS_INPUT, - }); - - let blas_geo_size_desc = wgpu::BlasTriangleGeometrySizeDescriptor { - vertex_format: wgpu::VertexFormat::Float32x4, - vertex_count: vertex_data.len() as u32, - index_format: Some(wgpu::IndexFormat::Uint16), - index_count: Some(index_data.len() as u32), - flags: wgpu::AccelerationStructureGeometryFlags::OPAQUE, - }; - - let blas = device.create_blas( - &wgpu::CreateBlasDescriptor { - label: None, - flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, - update_mode: wgpu::AccelerationStructureUpdateMode::Build, - }, - wgpu::BlasGeometrySizeDescriptors::Triangles { - desc: vec![blas_geo_size_desc.clone()], - }, - ); - - let tlas = device.create_tlas(&wgpu::CreateTlasDescriptor { - label: None, - flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, - update_mode: wgpu::AccelerationStructureUpdateMode::Build, - max_instances: 1, - }); - - let mut instance = AccelerationStructureInstance::new( - &Affine3A::from_translation(Vec3 { - x: 0.0, - y: 0.0, - z: -3.0, - }), - 0, - 0xff, - 0, - 0, - blas.handle().unwrap(), - ); - - let instance_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Instance Buffer"), - contents: bytemuck::cast_slice(&[instance]), - usage: wgpu::BufferUsages::TLAS_INPUT | wgpu::BufferUsages::COPY_DST, - }); - - let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { - label: Some("rt_computer"), - source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), - }); - - let blit_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { - label: Some("blit"), - source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("blit.wgsl"))), - }); - - let compute_pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { - label: Some("rt"), - layout: None, - module: &shader, - entry_point: "main", - }); - - let compute_bind_group_layout = compute_pipeline.get_bind_group_layout(0); - - let compute_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - label: None, - layout: &compute_bind_group_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::TextureView(&rt_view), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: uniform_buf.as_entire_binding(), - }, - wgpu::BindGroupEntry { - binding: 2, - resource: wgpu::BindingResource::AccelerationStructure(&tlas), - }, - ], - }); - - let blit_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: Some("blit"), - layout: None, - vertex: wgpu::VertexState { - module: &blit_shader, - entry_point: "vs_main", - buffers: &[], - }, - fragment: Some(wgpu::FragmentState { - module: &blit_shader, - entry_point: "fs_main", - targets: &[Some(swapchain_format.into())], - }), - primitive: wgpu::PrimitiveState { - topology: wgpu::PrimitiveTopology::TriangleList, - ..Default::default() - }, - depth_stencil: None, - multisample: wgpu::MultisampleState::default(), - multiview: None, - }); - - let blit_bind_group_layout = blit_pipeline.get_bind_group_layout(0); - - let blit_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - label: None, - layout: &blit_bind_group_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::TextureView(&rt_view), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::Sampler(&sampler), - }, - ], - }); - - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - unsafe { - encoder.build_acceleration_structures_unsafe_tlas( - iter::once(&wgpu::BlasBuildEntry { - blas: &blas, - geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ - wgpu::BlasTriangleGeometry { - size: &blas_geo_size_desc, - vertex_buffer: &vertex_buf, - first_vertex: 0, - vertex_stride: mem::size_of::() as u64, - index_buffer: Some(&index_buf), - index_buffer_offset: Some(0), - transform_buffer: None, - transform_buffer_offset: None, - }, - ]), - }), - iter::once(&wgpu::TlasBuildEntry { - tlas: &tlas, - instance_buffer: &instance_buf, - instance_count: 1, - }), - ); - } - queue.submit(Some(encoder.finish())); - - vertex_buf.destroy(); - - let start_inst = Instant::now(); - - event_loop.run(move |event, _, control_flow| { - // Have the closure take ownership of the resources. - // `event_loop.run` never returns, therefore we must do this to ensure - // the resources are properly cleaned up. - let _ = ( - &instance, - &adapter, - &shader, - &blit_shader, - &compute_pipeline, - &blit_pipeline, - ); - - *control_flow = ControlFlow::Poll; - match event { - winit::event::Event::RedrawEventsCleared => { - window.request_redraw(); - } - Event::WindowEvent { - event: WindowEvent::Resized(size), - .. - } => { - config.width = size.width; - config.height = size.height; - surface.configure(&device, &config); - window.request_redraw(); - } - Event::RedrawRequested(_) => { - let frame = surface - .get_current_texture() - .expect("Failed to acquire next swap chain texture"); - let view = frame - .texture - .create_view(&wgpu::TextureViewDescriptor::default()); - - let anim_time = start_inst.elapsed().as_secs_f64() as f32; - instance.set_transform(&Affine3A::from_rotation_translation( - Quat::from_euler( - glam::EulerRot::XYZ, - anim_time * 0.342, - anim_time * 0.254, - anim_time * 0.832, - ), - Vec3 { - x: 0.0, - y: 0.0, - z: -3.0, - }, - )); - queue.write_buffer(&instance_buf, 0, bytemuck::cast_slice(&[instance])); - - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - - unsafe { - encoder.build_acceleration_structures_unsafe_tlas( - iter::empty(), - iter::once(&wgpu::TlasBuildEntry { - tlas: &tlas, - instance_buffer: &instance_buf, - instance_count: 1, - }), - ); - } - - { - let mut cpass = - encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None }); - cpass.set_pipeline(&compute_pipeline); - cpass.set_bind_group(0, &compute_bind_group, &[]); - cpass.dispatch_workgroups(rt_target.width() / 8, rt_target.height() / 8, 1); - } - - { - let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view: &view, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), - store: true, - }, - })], - depth_stencil_attachment: None, - }); - - rpass.set_pipeline(&blit_pipeline); - rpass.set_bind_group(0, &blit_bind_group, &[]); - rpass.draw(0..3, 0..1); - } - - queue.submit(Some(encoder.finish())); - frame.present(); - } - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => *control_flow = ControlFlow::Exit, - _ => {} - } - }); -} - -fn main() { - let event_loop = EventLoop::new(); - let window = winit::window::Window::new(&event_loop).unwrap(); - window.set_inner_size(LogicalSize::new(800, 800)); - window.set_outer_position(PhysicalPosition::new(-1000, 0)); - window.set_resizable(false); - - #[cfg(not(target_arch = "wasm32"))] - { - env_logger::init(); - // Temporarily avoid srgb formats for the swapchain on the web - pollster::block_on(run(event_loop, window)); - } - #[cfg(target_arch = "wasm32")] - { - std::panic::set_hook(Box::new(console_error_panic_hook::hook)); - panic!("no wasm ray tracing support") - } -} diff --git a/wgpu/examples/ray-cube/README.md b/wgpu/examples/ray-cube/README.md new file mode 100644 index 0000000000..f9966e6810 --- /dev/null +++ b/wgpu/examples/ray-cube/README.md @@ -0,0 +1,13 @@ +# ray-cube + +This example renders a ray traced cube with hardware acceleration. + +## To Run + +``` +cargo run --example ray-cube +``` + +## Screenshots + +![Cube example](./screenshot.png) diff --git a/wgpu/examples/hello-ray-triangle/blit.wgsl b/wgpu/examples/ray-cube/blit.wgsl similarity index 100% rename from wgpu/examples/hello-ray-triangle/blit.wgsl rename to wgpu/examples/ray-cube/blit.wgsl diff --git a/wgpu/examples/ray-cube/main.rs b/wgpu/examples/ray-cube/main.rs new file mode 100644 index 0000000000..d129484774 --- /dev/null +++ b/wgpu/examples/ray-cube/main.rs @@ -0,0 +1,645 @@ +use std::{borrow::Cow, future::Future, iter, mem, pin::Pin, task, time::Instant}; + +use bytemuck::{Pod, Zeroable}; +use glam::{Affine3A, Mat4, Quat, Vec3}; +use wgpu::util::DeviceExt; + +#[path = "../framework.rs"] +mod framework; + +// from cube +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +struct Vertex { + _pos: [f32; 4], + _tex_coord: [f32; 2], +} + +fn vertex(pos: [i8; 3], tc: [i8; 2]) -> Vertex { + Vertex { + _pos: [pos[0] as f32, pos[1] as f32, pos[2] as f32, 1.0], + _tex_coord: [tc[0] as f32, tc[1] as f32], + } +} + +fn create_vertices() -> (Vec, Vec) { + let vertex_data = [ + // top (0, 0, 1) + vertex([-1, -1, 1], [0, 0]), + vertex([1, -1, 1], [1, 0]), + vertex([1, 1, 1], [1, 1]), + vertex([-1, 1, 1], [0, 1]), + // bottom (0, 0, -1) + vertex([-1, 1, -1], [1, 0]), + vertex([1, 1, -1], [0, 0]), + vertex([1, -1, -1], [0, 1]), + vertex([-1, -1, -1], [1, 1]), + // right (1, 0, 0) + vertex([1, -1, -1], [0, 0]), + vertex([1, 1, -1], [1, 0]), + vertex([1, 1, 1], [1, 1]), + vertex([1, -1, 1], [0, 1]), + // left (-1, 0, 0) + vertex([-1, -1, 1], [1, 0]), + vertex([-1, 1, 1], [0, 0]), + vertex([-1, 1, -1], [0, 1]), + vertex([-1, -1, -1], [1, 1]), + // front (0, 1, 0) + vertex([1, 1, -1], [1, 0]), + vertex([-1, 1, -1], [0, 0]), + vertex([-1, 1, 1], [0, 1]), + vertex([1, 1, 1], [1, 1]), + // back (0, -1, 0) + vertex([1, -1, 1], [0, 0]), + vertex([-1, -1, 1], [1, 0]), + vertex([-1, -1, -1], [1, 1]), + vertex([1, -1, -1], [0, 1]), + ]; + + let index_data: &[u16] = &[ + 0, 1, 2, 2, 3, 0, // top + 4, 5, 6, 6, 7, 4, // bottom + 8, 9, 10, 10, 11, 8, // right + 12, 13, 14, 14, 15, 12, // left + 16, 17, 18, 18, 19, 16, // front + 20, 21, 22, 22, 23, 20, // back + ]; + + (vertex_data.to_vec(), index_data.to_vec()) +} + +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +struct Uniforms { + view_inverse: [[f32; 4]; 4], + proj_inverse: [[f32; 4]; 4], +} + +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +struct AccelerationStructureInstance { + transform: [f32; 12], + custom_index_and_mask: u32, + shader_binding_table_record_offset_and_flags: u32, + acceleration_structure_reference: u64, +} + +impl std::fmt::Debug for AccelerationStructureInstance { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Instance") + .field("transform", &self.transform) + .field("custom_index()", &self.custom_index()) + .field("mask()", &self.mask()) + .field( + "shader_binding_table_record_offset()", + &self.shader_binding_table_record_offset(), + ) + .field("flags()", &self.flags()) + .field( + "acceleration_structure_reference", + &self.acceleration_structure_reference, + ) + .finish() + } +} + +#[allow(dead_code)] +impl AccelerationStructureInstance { + const LOW_24_MASK: u32 = 0x00ff_ffff; + const MAX_U24: u32 = (1u32 << 24u32) - 1u32; + + #[inline] + fn affine_to_rows(mat: &Affine3A) -> [f32; 12] { + let row_0 = mat.matrix3.row(0); + let row_1 = mat.matrix3.row(1); + let row_2 = mat.matrix3.row(2); + let translation = mat.translation; + [ + row_0.x, + row_0.y, + row_0.z, + translation.x, + row_1.x, + row_1.y, + row_1.z, + translation.y, + row_2.x, + row_2.y, + row_2.z, + translation.z, + ] + } + + #[inline] + fn rows_to_affine(rows: &[f32; 12]) -> Affine3A { + Affine3A::from_cols_array(&[ + rows[0], rows[3], rows[6], rows[9], rows[1], rows[4], rows[7], rows[10], rows[2], + rows[5], rows[8], rows[11], + ]) + } + + pub fn transform_as_affine(&self) -> Affine3A { + Self::rows_to_affine(&self.transform) + } + pub fn set_transform(&mut self, transform: &Affine3A) { + self.transform = Self::affine_to_rows(&transform); + } + + pub fn custom_index(&self) -> u32 { + self.custom_index_and_mask & Self::LOW_24_MASK + } + + pub fn mask(&self) -> u8 { + (self.custom_index_and_mask >> 24) as u8 + } + + pub fn shader_binding_table_record_offset(&self) -> u32 { + self.shader_binding_table_record_offset_and_flags & Self::LOW_24_MASK + } + + pub fn flags(&self) -> u8 { + (self.shader_binding_table_record_offset_and_flags >> 24) as u8 + } + + pub fn set_custom_index(&mut self, custom_index: u32) { + debug_assert!( + custom_index <= Self::MAX_U24, + "custom_index uses more than 24 bits! {custom_index} > {}", + Self::MAX_U24 + ); + self.custom_index_and_mask = + (custom_index & Self::LOW_24_MASK) | (self.custom_index_and_mask & !Self::LOW_24_MASK) + } + + pub fn set_mask(&mut self, mask: u8) { + self.custom_index_and_mask = + (self.custom_index_and_mask & Self::LOW_24_MASK) | (u32::from(mask) << 24) + } + + pub fn set_shader_binding_table_record_offset( + &mut self, + shader_binding_table_record_offset: u32, + ) { + debug_assert!(shader_binding_table_record_offset <= Self::MAX_U24, "shader_binding_table_record_offset uses more than 24 bits! {shader_binding_table_record_offset} > {}", Self::MAX_U24); + self.shader_binding_table_record_offset_and_flags = (shader_binding_table_record_offset + & Self::LOW_24_MASK) + | (self.shader_binding_table_record_offset_and_flags & !Self::LOW_24_MASK) + } + + pub fn set_flags(&mut self, flags: u8) { + self.shader_binding_table_record_offset_and_flags = + (self.shader_binding_table_record_offset_and_flags & Self::LOW_24_MASK) + | (u32::from(flags) << 24) + } + + pub fn new( + transform: &Affine3A, + custom_index: u32, + mask: u8, + shader_binding_table_record_offset: u32, + flags: u8, + acceleration_structure_reference: u64, + ) -> Self { + debug_assert!( + custom_index <= Self::MAX_U24, + "custom_index uses more than 24 bits! {custom_index} > {}", + Self::MAX_U24 + ); + debug_assert!( + shader_binding_table_record_offset <= Self::MAX_U24, + "shader_binding_table_record_offset uses more than 24 bits! {shader_binding_table_record_offset} > {}", Self::MAX_U24 + ); + AccelerationStructureInstance { + transform: Self::affine_to_rows(transform), + custom_index_and_mask: (custom_index & Self::MAX_U24) | (u32::from(mask) << 24), + shader_binding_table_record_offset_and_flags: (shader_binding_table_record_offset + & Self::MAX_U24) + | (u32::from(flags) << 24), + acceleration_structure_reference, + } + } +} + +/// A wrapper for `pop_error_scope` futures that panics if an error occurs. +/// +/// Given a future `inner` of an `Option` for some error type `E`, +/// wait for the future to be ready, and panic if its value is `Some`. +/// +/// This can be done simpler with `FutureExt`, but we don't want to add +/// a dependency just for this small case. +struct ErrorFuture { + inner: F, +} +impl>> Future for ErrorFuture { + type Output = (); + fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<()> { + let inner = unsafe { self.map_unchecked_mut(|me| &mut me.inner) }; + inner.poll(cx).map(|error| { + if let Some(e) = error { + panic!("Rendering {e}"); + } + }) + } +} + +#[allow(dead_code)] +struct Example { + rt_target: wgpu::Texture, + rt_view: wgpu::TextureView, + sampler: wgpu::Sampler, + uniform_buf: wgpu::Buffer, + vertex_buf: wgpu::Buffer, + index_buf: wgpu::Buffer, + blas: wgpu::Blas, + tlas: wgpu::Tlas, + instance: AccelerationStructureInstance, + instance_buf: wgpu::Buffer, + compute_pipeline: wgpu::ComputePipeline, + compute_bind_group: wgpu::BindGroup, + blit_pipeline: wgpu::RenderPipeline, + blit_bind_group: wgpu::BindGroup, + start_inst: Instant, +} + +impl framework::Example for Example { + fn required_features() -> wgpu::Features { + wgpu::Features::TEXTURE_BINDING_ARRAY + | wgpu::Features::STORAGE_RESOURCE_BINDING_ARRAY + | wgpu::Features::VERTEX_WRITABLE_STORAGE + | wgpu::Features::RAY_QUERY + | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE + } + + fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities { + wgpu::DownlevelCapabilities::default() + } + fn required_limits() -> wgpu::Limits { + wgpu::Limits::default() + } + + fn init( + config: &wgpu::SurfaceConfiguration, + _adapter: &wgpu::Adapter, + device: &wgpu::Device, + queue: &wgpu::Queue, + ) -> Self { + let rt_target = device.create_texture(&wgpu::TextureDescriptor { + label: Some("rt_target"), + size: wgpu::Extent3d { + width: config.width, + height: config.height, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8Unorm, + usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::STORAGE_BINDING, + view_formats: &[wgpu::TextureFormat::Rgba8Unorm], + }); + + let rt_view = rt_target.create_view(&wgpu::TextureViewDescriptor { + label: None, + format: Some(wgpu::TextureFormat::Rgba8Unorm), + dimension: Some(wgpu::TextureViewDimension::D2), + aspect: wgpu::TextureAspect::All, + base_mip_level: 0, + mip_level_count: None, + base_array_layer: 0, + array_layer_count: None, + }); + + let sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("rt_sampler"), + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::FilterMode::Nearest, + ..Default::default() + }); + + let uniforms = { + let view = Mat4::look_at_rh(Vec3::new(0.0, 0.0, 2.5), Vec3::ZERO, Vec3::Y); + let proj = Mat4::perspective_rh( + 59.0_f32.to_radians(), + config.height as f32 / config.width as f32, + 0.001, + 1000.0, + ); + + Uniforms { + view_inverse: view.inverse().to_cols_array_2d(), + proj_inverse: proj.inverse().to_cols_array_2d(), + } + }; + + let uniform_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Uniform Buffer"), + contents: bytemuck::cast_slice(&[uniforms]), + usage: wgpu::BufferUsages::UNIFORM, + }); + + let (vertex_data, index_data) = create_vertices(); + + let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(&vertex_data), + usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::BLAS_INPUT, + }); + + let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(&index_data), + usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::BLAS_INPUT, + }); + + let blas_geo_size_desc = wgpu::BlasTriangleGeometrySizeDescriptor { + vertex_format: wgpu::VertexFormat::Float32x4, + vertex_count: vertex_data.len() as u32, + index_format: Some(wgpu::IndexFormat::Uint16), + index_count: Some(index_data.len() as u32), + flags: wgpu::AccelerationStructureGeometryFlags::OPAQUE, + }; + + let blas = device.create_blas( + &wgpu::CreateBlasDescriptor { + label: None, + flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: wgpu::AccelerationStructureUpdateMode::Build, + }, + wgpu::BlasGeometrySizeDescriptors::Triangles { + desc: vec![blas_geo_size_desc.clone()], + }, + ); + + let tlas = device.create_tlas(&wgpu::CreateTlasDescriptor { + label: None, + flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: wgpu::AccelerationStructureUpdateMode::Build, + max_instances: 1, + }); + + let instance = AccelerationStructureInstance::new( + &Affine3A::from_rotation_translation( + Quat::from_rotation_x(45.9_f32.to_radians()), + Vec3 { + x: 0.0, + y: 0.0, + z: -3.0, + }, + ), + 0, + 0xff, + 0, + 0, + blas.handle().unwrap(), + ); + + let instance_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Instance Buffer"), + contents: bytemuck::cast_slice(&[instance]), + usage: wgpu::BufferUsages::TLAS_INPUT | wgpu::BufferUsages::COPY_DST, + }); + + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("rt_computer"), + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), + }); + + let blit_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("blit"), + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("blit.wgsl"))), + }); + + let compute_pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: Some("rt"), + layout: None, + module: &shader, + entry_point: "main", + }); + + let compute_bind_group_layout = compute_pipeline.get_bind_group_layout(0); + + let compute_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &compute_bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&rt_view), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: uniform_buf.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: wgpu::BindingResource::AccelerationStructure(&tlas), + }, + ], + }); + + let blit_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("blit"), + layout: None, + vertex: wgpu::VertexState { + module: &blit_shader, + entry_point: "vs_main", + buffers: &[], + }, + fragment: Some(wgpu::FragmentState { + module: &blit_shader, + entry_point: "fs_main", + targets: &[Some(config.format.into())], + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + ..Default::default() + }, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + multiview: None, + }); + + let blit_bind_group_layout = blit_pipeline.get_bind_group_layout(0); + + let blit_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &blit_bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&rt_view), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::Sampler(&sampler), + }, + ], + }); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + unsafe { + encoder.build_acceleration_structures_unsafe_tlas( + iter::once(&wgpu::BlasBuildEntry { + blas: &blas, + geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ + wgpu::BlasTriangleGeometry { + size: &blas_geo_size_desc, + vertex_buffer: &vertex_buf, + first_vertex: 0, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&index_buf), + index_buffer_offset: Some(0), + transform_buffer: None, + transform_buffer_offset: None, + }, + ]), + }), + iter::once(&wgpu::TlasBuildEntry { + tlas: &tlas, + instance_buffer: &instance_buf, + instance_count: 1, + }), + ); + } + queue.submit(Some(encoder.finish())); + + let start_inst = Instant::now(); + + Example { + rt_target, + rt_view, + sampler, + uniform_buf, + vertex_buf, + index_buf, + blas, + tlas, + instance, + instance_buf, + compute_pipeline, + compute_bind_group, + blit_pipeline, + blit_bind_group, + start_inst, + } + } + + fn update(&mut self, _event: winit::event::WindowEvent) { + //empty + } + + fn resize( + &mut self, + _config: &wgpu::SurfaceConfiguration, + _device: &wgpu::Device, + _queue: &wgpu::Queue, + ) { + } + + fn render( + &mut self, + view: &wgpu::TextureView, + device: &wgpu::Device, + queue: &wgpu::Queue, + spawner: &framework::Spawner, + ) { + device.push_error_scope(wgpu::ErrorFilter::Validation); + + let anim_time = self.start_inst.elapsed().as_secs_f64() as f32; + self.instance + .set_transform(&Affine3A::from_rotation_translation( + Quat::from_euler( + glam::EulerRot::XYZ, + anim_time * 0.342, + anim_time * 0.254, + anim_time * 0.832, + ), + Vec3 { + x: 0.0, + y: 0.0, + z: -3.0, + }, + )); + queue.write_buffer( + &self.instance_buf, + 0, + bytemuck::cast_slice(&[self.instance]), + ); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + unsafe { + encoder.build_acceleration_structures_unsafe_tlas( + iter::empty(), + iter::once(&wgpu::TlasBuildEntry { + tlas: &self.tlas, + instance_buffer: &self.instance_buf, + instance_count: 1, + }), + ); + } + + { + let mut cpass = + encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None }); + cpass.set_pipeline(&self.compute_pipeline); + cpass.set_bind_group(0, &self.compute_bind_group, &[]); + cpass.dispatch_workgroups(self.rt_target.width() / 8, self.rt_target.height() / 8, 1); + } + + { + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), + store: true, + }, + })], + depth_stencil_attachment: None, + }); + + rpass.set_pipeline(&self.blit_pipeline); + rpass.set_bind_group(0, &self.blit_bind_group, &[]); + rpass.draw(0..3, 0..1); + } + + queue.submit(Some(encoder.finish())); + + // If an error occurs, report it and panic. + spawner.spawn_local(ErrorFuture { + inner: device.pop_error_scope(), + }); + } +} + +fn main() { + framework::run::("ray-cube"); +} + +#[test] +fn ray_cube() { + framework::test::(framework::FrameworkRefTest { + image_path: "/examples/ray-cube/screenshot.png", + width: 1024, + height: 768, + optional_features: wgpu::Features::default(), + base_test_parameters: framework::test_common::TestParameters { + required_features: ::required_features(), + required_downlevel_properties: + ::required_downlevel_capabilities(), + required_limits: ::required_limits(), + failures: Vec::new(), + }, + tolerance: 1, + max_outliers: 1225, // Bounded by swiftshader + }); +} diff --git a/wgpu/examples/ray-cube/screenshot.png b/wgpu/examples/ray-cube/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..8caa036e47d2f93134249350215b7a066fc89401 GIT binary patch literal 325681 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

y_1*v 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

K-6D;ZqX17~q@GgBXZV1L{ zqzg91@p%QRA&tr2UgC=MuaZUd@cSgbLR^tIBJLZcuw~^p6SK|jm6{79b{hcS)XFb= zSui)FUd*pYOUQp4A=4DnBF zN;|aLW#*Z;Tr!XHwFGj4)-)LL!7~}h8g8rfe-6}HJt0)340CrX{#w*FkNvRo)JYuI z^e&Na{JpODkTEGQr$<@#k*iU+(lrVA%#__=ve8p8wieL)MVg|uH5-VAyN0}njeZjy%J+yF`R5_ z#;aw_^v#rLYJv{R84C{uR)ajn z#`Iz!0LLxe9?$fQ+kiDw^ZuY}@XEIU_9I+STb74!GwGGu72o6H0%rq5uPA2odc`(j7_>x;cZ{oAb? zTnzYi&FYQ*h6#;FMppPkq(~GxM1YaAEJQ9|Xxnw;U|@DLEO*A{WZXd|GVmkwEaXku z+u}&7Ka1Ui9s`hLa_np5>7{B0`+46fT+NB$;Rkj0WgV;#bb9p1_1@CjSEcQviR4Hz zOHR>v!FyD_LfY4iS4xV?EDoI$B0iR`Wbdi>SVR({ox54#!YXgY_r@H~4Dg$jVnl~E zM0%g_G)_vEr>_7`>eJ>(^Bx){TK;iCL|P!%b?H|i7;C(?#fW=fd@9Z%J2Q4!)NP=& z=wn;fYs`rHajTH0Su_sPr9;8Z*geZ(nn)x!LKfP7)68$CQ%BBQq^*P`%7tvHRrZQX z#Y{hX=Slx2snC#?b))x5MUtQqueTGuSxwR1D14`;o&M$ZS7U`3dY811<$leJD_#pN z}{b#RX~dS)uGzXcyQ6%YRk z;Xu!xDwgIKD+0UKJ*3BZcA=~{u^xI3sLCRs6HGcd*=50LUuH^eywcxViN}U$6lmeR zy!5@H!-$$B7T6R;6>b@*Z}crWuNX`{LlqWy3GuDn;Sh%~gUCVTf=axxU-zd!TOC<@ zmAhy9T)uAfoX>TBJMHdNYw$TTjH=nVMR^Lj&UsWW!`|0w3(eUAn|vK9DZRRqWH7A7 zEXynBR0oaqyZGBH$_aYn^HM7WaH|kG4*P-6P0xM)M(|&N36?s?V2x=UV^pC5phUOK z+FO-HnZ2)3vrv3LgSvR@fk zObM~yM^^d7U~?ewEC&G8-gCCXJ6X@a-+?yea}cs|I@Iwx6h4EFA*+E#-z?Qj1Vcfe zO<7bvHZ3&9EzLH+F0-Txfov}E7KJ~naqErZ$m30kjo!VqG~j7_|L?M#<#}Q^0tPT8 z+$18rZMb1~V5#4OaH4H%kuKuzD_MEL2!*K#PS}kXdpY-l1)RK>1Pq)^3xsRQ`qL_X zpB2UZ9V^i8&tCR#x=d+v(%6UwlIxvPqj@gexsIGFUao4#&lj)DoX)ZlKG=oRvVQq& zN{&lSX-%h?-Ql`-p$9bGbM&VRhSMo}Ra&LW&`8-tW$cr|aT6R8=6zt58y9F@e6h!} z6$jmS|KYvwx&gPU5X#G+Y03nGgUF+P)aK9Hsq!B&9wzSQonU0->(*4z;qq426DfeV zA)x}Y2Zy{?KJL1F!AQee*wbC=g~!2_Rm}0<4p+SWatp<5gDJf738{{7#(aN*m;pP zOuXg=Nf*6rPH1X@y7AF`tkJz4<@0Z)R^PU{o-PnVQm%VHt3|r+eXT#!zm(3kB%oyL zp7}1g{X&k-r)Gj1mb*Y$?c*2h$93o`_f)+>yN2Lnp0)~9697QGO;3V}(mk--LmFhn zYnc_^`MJH@$w)8!Du>V+pP_=pO^sT&mDDP(Av8!hLastf5Bo0qIQ7V*(qNkMJifyc{RlU?awg`0B*;C z|LS%mZCWrMbArl-R{=J!EZ9fR$AYr<#lQup%O;l9L>f&^hHRt z+ZYN%ke#kelT(*$Bx|}=maWn_KxI&`m(2nn32QAZ_tmz{jzww&FDH~K2PIN@VOlwH z-!#Y1(>X0211+9Fo`JPevg)PXrbk@zfooEq{^aL#Ca0xwMBd#VC$iG>UT4SZVFSe0 zvU!a887(QKU{$fy0C_V{jK@sb5B^?jSG1}=J5sOkHZ)+MQ-|sBXK|;RKlB(72731D zP*&ERZS@AvV5fv}@HwXdqm5;+l&<(19iMAkTqJFz;q1-adgE9d7;U8=5@1A(s<+DK zDikz#Y+CAg0kP?q;fRrA<|R$gPMW&QzmGk}ED$F%`YKu3ntCD>n|;{7ej>DM6-4Or zx@^0#N)#Dq2E8a$((7|cFwsFVorq;ay({E;G#*{w2|n&Sbh!*Fsj%6EAgzUpmZjU> z|1>SM-uU_*%$wSJWAV>haLxQ!NXm<2Bc^i#5&9GD9=U*5;w~()97epfynbp|dQ-UA zl(Bg(dnkyg_4*0ef2p}@v7kPYax*uzwXo{;^LK-{$Awp)#x)?aeTKIRU2vRma)6&f zCe)?^EP@yQi(?c&P#_Ln_C95(#tMR80M5pzAzbjf2iAF9{%<&muoph9F~#3uUeGxS z#EZ1%-JMXPw&K2l;BV49*UrlceMc@I-Vk$PVL_LfWU(hiqbHBpL^?$OI`QI}irb65 z{?2|iC{uzDqxJz82t)G)J)m&O9ORF`CwVbSn^*lqV3flkd-B!;JWwZmHJH0<*4N|n zi33I(_DC=5SNWH*(hA!-e<$iL9}>-B*Ama@r71bB@`dQZFwlPn7}FqNfYBrEGE6x^ z?JF!{LKccVK+>583_)f5Zv8ST304Hp8m1bWbm$~Ge7Ggj;~YT>8rJswm7bo-aHC_x zsa6bHoD=S3!Q<0~S6u1PmESv^9el|{(qs`Q=e&8>?*W}aPWI6(aA{ZD)pxM8(H@T& z&Tla$(<(`2iIGHw1C_n%cO39FT-+#znRj%}OFFJj(J5oTyzZ7B7`gkyEy)<^cN5o@ z=hhVl8lTUna~=M!+X@ezko+wgy?%pd3h?e{2Y)*|$)3KAo<2K8i;VA*#@5Tw3@;du z5TZ@Dq``J^MfsB@_}8&qBk!Vt4i}*)a|K6s^R-E}Z1b6jF9V`*&=oKv|D>Ij(hopy z4|&ug;|JI*6C^@1jk>u2%Xe8^pW5kuLg z+(Hr!#x6tUsFQ>|7c<%TLehR~JN%S^o;j4m_2I9upu^Pzi`4k7_x-Pfd*xNFN|%)w zN|t_N&S$5Kr@(H_KDs$!%{=-@ck$b*rHL~_;GoWc?~SW&^3Q2Ae=O|;{W*kGs1n65 zO`O=x_tzd3cjh$3YFT?AWb^I4=_fcqDkz$j*?*=bbDJ!9n?I_dz{^yvwr6jVPjhNUIzg8~` zGy9IxR@M+)PWM&3U3Ag9e}ww-)Hh*BKx&KJ!CU#N_7(-tEae=Vz@{~U_R0~Z+UxH1 zpE6QtTLGo+fu-x{1?=;6u&#KjPI}o-3Bg>KxI{ zFe%rY`e1;2+?J{8;tkT$QK#dUjBL>ZAEkG@B$nMr|3h=`~c)A(W)v zX=Jz8CCz2&1pqPGzanEE7=_D!Ryo=(od+Ob;gYZ;u6Q_;Yf?sI*u2~rD?9~z6QZ=>4W!8MHm0nt0_p-S(Z%D@4QSnWfu-fdJ z8PvTHdhq8ZTFaZGIxv-bzwMbGycE8{rfL&c_c2-cfMP$IQXJbOJ0)6<0NzYyEQMj8c$Byth-fRIUG#m3|z;cd#Sf;y2pYBBxdFf=kTpedXi! zAyW7bk zK}}ZW6Q8IZeu?(7nrRXWEOh`sHbO=oTjVsKYcc|KZo&-kH=gfe3I*s4!l3C4M!q}8 zZ{SsyDf1pO9{QHP8<$rW`~fi{;lK*ChaTKXEY+F4naw??K9Hk3(hK(KosU;$!pWZN z*WRB8bR7h5adDDtWhExDbfD#K=le3x54o0`VS$EXS!K^gKj)EtBF+a-J-~;(LX3(6 zleAO~j?)bFV^iU0dliecxV9F{_Go*Ap;V%B z{2Ih_<3%!nswmr?JEFu1!mLvNW)Ce_j2c9-|3TM*OFfN!YD)yh=k8y6H7Sh$uxTk@ z10+S@BHSxTfic&>#{L4jr1$q_!xn)o&ObIbA4{8s2ab-aEI!tmy@uz(kc%$9GAW5+ zNl9U81&;E8%pS~8K~w2hdXoi`QvQIj6TBQ$Qg)iv0Up7S?ALBXxg|!OmU&`fiYbp8 zr-s{W1#eekGAm^K3|j3eZn?kn{0u(=P=UGPwC0c)C_yWy}at% zLII@<)yfdXjjLI^DO#YHV`r%YxXFP!@mY`KYjYvpfhR*>yw?dZ{MFx-n-IQpp3P+@ zSpxg6)oyRg4A*6tkYuc)h>{gV-ll&*kGlp~&}!~PWaISFRSj3^SB(`$rX&C_r9zA% zi<%0HOfbL(IJHyd*O;t#l)3K4*34Bd&|%vaZvov0G*I3NJVR;}DTsfBPAl2pv*8X( z?Y_b^Ej{GHlB?{a3%ZU?5`hJ2+ZVXcj`Z?o@*NP$6x-+03!I8+itCf{T&94l^6nxr zs=eL_FRj4ORce=!KHqJ(o`dZywz!w|R>X|>qROMN?pdpAX~rL(xGk$j^-`Z0S>jK0 zY{Kx9rItHBq|*h5`GKa@mvlMFyegQmZgZVI+I>c!(ok)&tYNjI7IbQctZCI?a6Mpf zqC*ST%Jh}qMRWkBXIuI*ljaJ4dk$WSS4ynAcbPg zS(-U*5Y_!b1dkIzvuvRkl)T%CgG#F6mc(DS?6vDCj2z{#n>AY^@#opwn`A^ zs+q+pAH^?;e%35Lr%g3GBb}5YH{U?pMQtSGy7NNXCuuY2pc_NjFfL=`*+*X`9N46G zvyDGN?4ueI&>=elIp!RAFLHfK1I2wSQL45KxE&DRB8AnMQu$`U9hZjL* z;pp4D_jpFbByq{c(oYWVfHQ=u#QTRYME1`rUmV%g=$Gg=efMV zseCb|rQm>XQ+5Qt#tD|TnH=j!ET=`(YiAq}mHwygOb}EEVOl$Xo)S}OoH1`>o8i}f zS*5Lk@7bIM(7@7a|44cv=_1!&YdQ;9ZG9N8gra@?eQr_e{9>{*zVo)?p(+(ZYRs=9rRkJF8Wg3f~or!4^~VksbCt& z5eHx&q{<&qM2l7S$btfN3(&ayr5wMY^;~Q&2K3M5+{l612hYds99Nn^8QTII7;a#l zz*L&pgr1GDyF(~+c`$P~n!0qE9j&Xw&5wt5Oc z5@Q81#{36+wy)|`1244Ne}18XIa=D;qX=kyyj;nEFivWMBdIW~PXyoL-#HroALr=1 zf9Gh-sy!=c*#58eR~rU;8+*ga094}loOw$70^jnyxOej2tOz(nan|{!B&Xp#1s)ZB zN7(V0qOv17@6|j_QZuaCCuN~6+)^QMyTt?{C^3@=|Fy{tvmIe7B-IG%JiE3&ZSu@1 zNm~$U?_{%6^s){5&SCk?mR(0r#rL;RiqSx-?NUXeSk*XYoBND4%9O|L-1)1+3SvU6Qf{XSB%RZ(`{${Ow9c*yJnF<(Z z-Div+p7c>Ig01Jh>?A0mLKbPbJEdL+lB+AbS6kHGrXEeK8m&iB+=#zqc8(=xy)d}H znP2|Ps)a>n<8d-F;x2n8GUmN;av75G6v)LJ9YiW%n9n=(v}Va-E$k8~zqLXeXx0tq zru_?`k%J-*Z8_{^>G;mW%Fx!z_r@{2Cwa-{@8C*`IZtgOgXZfhcY%Nyp#u@u4%(EU zK+4Sj2s^fk##0{zvSs-?YF#e;z*_lHL(%pHZQ6%i8|==)cD|-)=0VCev0V4#Vd}ED zt8)kgFfrq&m0w?Ffy!>QKoRAsg31*}mre!9W*b&k%~&+-1QTM&t7(ejhgGVY?ouKu_vf zLBeNfrvd*Z2X8!fM}rGi2M!4h#&Z&!K}P$BpB|2GwKWA9~OC-J|#G#Nhousv>& zQ2-E-2nLnFMmldc0M$Wu+*21_Mb4K0G&FTNO79y_g#nKpZ8^|Iee z#?5H{z;y*B69tq2NnugOn#Z0-jYz9mwJJ6L{`Xtg_twWC7_mfHr)B z&$7vcb_DtK)OQZxME~*y7RNgg4X_$#5@`d|z?kl(PT;GLMf|a)Dl^jbGL~d5+ zN}-vYeld@mQDNYm(f#D$K#SV#rw45&^$L!>HB*t>o8b?dOZ7%=qKhf1hu$37858ZL zi>Wkkz55dMt#>9kzV1xPCxC7-{y#F?rVwjDp;Pn1{!TI zb>rq1Yo!$$y2mwxq^m~`Oq9VP&k7I^T{SxS&VWi}3qL z;y-2sTooOFt5QAVK=z2KiD2{|{L9YTDYooKp450wu=xO<_#d`2tL9kXAqUQ6(gx@= zU?e)EK5@QWwrlkO&kSPQ0RnOUm!3PS@;E;X7@tovOuuz!{fbtT^@h;>=yn0tqlDK< zx>k9-4u1v$oUa`lzPx44p(2QO(_@Jj9u^#oo;PZhu~hAYly?4kLDL@XofK=Y^5Nu} z)>#@*Te+Dlg!o}Rq9DC%Y-Y2T;biu1wNGhr0B6{oxhw>8oK<#vIJr6VhNOobttWP8 zOF~-e>w_*>RWgI7GChu4$*!XP-iHJ4_f(knh2qTD>1@I0NIdY9)OqyY!029N2yNi| z+4TSgLEdjtZ+__tqGg*e8?YbBasEyiIHo;vY&k~Qi5(gCjorZ9sMh);t`&x4^W9}8 zjqdBhfl4T&5Ia9mNoxG#XUnhHLf(OF$C~;&E2jiFcD`QUuFNeeS$>pg!1*F6Ed%5P z_JDJ$gltacO#sbgF8)2?wHATV3i@M&_OaqZDX526=VYiK@94X`qqslXsjLx}kEvfd z(#^BJNfx;`XKl=z=QghTnX3ikUrZ%7 z2Vip>C@93pvv*HiC)$GKOuR}H>XZ>5c8DI3hd@MQ=g7>&+pKi_(CQJ|2lM+IXT)R& z0jYMoYil3AH@;yAx+Jv2hSkBv*6*-(1T^c=B9~Y!k-obeLN)xsH4X-7WPpm6QLDXD zB;{eCeW8)%TQSeaF%FNj+!YUJS0PMymU4}30*{&!8T373#Q+>U_t#dkkL?2k)&4q+MeT0|eT=W8GgMM?M*RBNaRk?MSDVoXM{_we z2x6Po?aiFk2|1h+9_+OQNwLGX#$pj^sP~4ZVA_15_y8-uXC{pV<>##>C+nC4rC$Tc z7g~FqmL$$r!EG;Eq!YbGQ|t)9k!U0BeRa+xtZ`wu5nmd@xVZyTE4hMZO1Z0vfN*5` zk;_zHFWm;)^0)(guTc5rv{{R~izQwR__WN#o=S-GJ8pG>;Yr#U^Wqr~lk5bp$^EOu zc3wzEhMZ!=B?ER`6>Y$J|hqHO+9XlnYx%F)`8bsJ~EO+ zjlZ*&5A81|cYUu4zsAe^tT;qW`B|2*S`lTU#k&RBjZ7SKKNpY9P23LzR9^ zU0VKQA!qHiDda`Iw7jhY-Rg^My88ordfr*5&T;NY;&ohZ=iX@mJjoq6HozFfYqm!1a$0r04E z2C1D}5*+4^R_2i+Z3*QO3!i;G(264c9kg}|H>kBEw%iE_x-J>#7g-Fg#R9ABwd$dQ z;FOIAXIj_<3Hf`hXVIEDSl6~;fF$bWHIX#H0^M92il3VwJ}v$Ssw z)ab+OqXgkx)H%EC{Cn$*9k-makbD2ctX8J7(t+d6AEeIPNwIab8{pjtNuIGIst|}~ zRl@b(v}xSXv{cK>XHK&Ty6qjW9G6bqHh<=n;O{QdHAuFz@=;uSAt86bto80}rP_L; z{uHm{PHu?U@@6Ele4*7ro@MvwF^HK1#XeiHh$jRyTV8b4X;YnNWEQNF=HjtxO1$LJ zfh_LiXmEF&{si<)s!{quvv_T%bY(HpwCae}am_MAD!ldHcT~Lhsn+EU zZh_q5$l3>u8$2w7X3;0aLSiI&#?`FQ;=xIIfhE!i5y^YY9nN%5Cb~qKf{3M*60!UG4}0k_4a4fbsBFF?1aO!|BMS{9_Sw3Mo>TBi&wgYkcVV#CyyS_MmF2@Mc)&)X|DZ&3wQah7ef#S zYyhdimo2^$~Z z<0Ijyj9bKS!!k>Ye=1HpymHFqmUX|&?&XAx^+9%V9)p-C_Hp`ACA)sBsp3 z5uKnT$eSNz)m$pdmEI-eblYrQJHSy-T3hIhgsgJuUrP}6BQDf7=>ncrhNVaE))sRp z+>qhCd$ds*1bQO;vzEH^@FX6&9w$Oc+Ip`Ania@Nlk=V{qiCVa&StR1#AvOU+i&Mz zK*C3Wdh#kJ1NN7)zRjzeS18efjQ2gtS1`YmAm&pM9GFENzg9SId7+xH0Gq9C%$5vR z>NI)IxpAi>T+8&4j>d$&899y1V*ipSB3mSqm1NW750+^QCO+B!5T&b5dr@F>GIOtr z*rHA9Qcz!K?QzIo5y%qUH+7MC7KbkQnG2+i ztbEjOciM%N^ z^t#qL>+WsZo%fw zSeM{je9+D=EB1f^#RA4Y(7?J7h-V8Rdm^J}K(^4Hc-4&=jNW}K zQDWo0W>-7u6PVPfXuk6bXdFGr@xBjk_Kqrgc{m=j-s&P*CQC<9=)>CVH4Buox?57_ z64j?*ZWrcg_ptgn(}ZXvOTXwmx&Z#x7_vLeJn%=`(_estRJaPdTa7_uG|4^N4cf9U zr=jgf0uydmuXiTHZ;P*VG~8(FJxowiEiPIJ$dkZZCf^iB3D>qo-DNMO4`^A5t;`$3 z-##vqa$?t?YWC4a6V)OX|3v4%9<_ITJIP<4AKSEX0yv)`m_?Q1?zzu)gTWIX;wEQqYL6!y*SrzN|MB?k2 z&2q{cBcibXTywE5Dn$pGRiH4fIn#?ve=n`L zL+zoIn4wB7QV8sHRemrjRjIqnJeW5$u)%I$jxZ{3KbMqs(B!XA4vuVB`eVOx?$Sw} z9pTB;BXv)b#~S0CK~5;6yY+!0sotc8R9#_~Uwf=V^%oei%Fn1M#_n$z?`1`AX&dIf zThcsr2cn_L%%Kp!zsB9jRBt1fj=zE?urvBML9-6e-oIY;_p5VgJm}wCyEOVghf(bC ze-2|-JAlq1*bmHAyO);&zD|x%KtysaVR92GK~sH72LGz;x1OwAp2p3}Qmx3~K-^~v z>J0@^k&l{4y2vcxXsSi6t`yi*E?xz-vJW_ zA4;h1E`hfkJcG2x7xu=fc4pr{4nZATA7q~iS?L*m;)Pq#t*>2pd%OChwUY5O`g2)n zZ$gEVpTytnuCe|B@~b7x%YFB{=5~oWcL0I@rYei^X;nHJuu5EF+ent25{;&b37#G8 zz3a7$&yM}gjyA z8wIeY2D3;*eS^Gu=H9k(gF*~4xIpW-;xeo)Rtn1<_a_ryRGYhGnDeHY!#cxshMF{M zp3Z&~7aN9LG{ajv5>)}%{Vvq*Uec}-jE=xGRGW@GNv3QfI7az6o zxK$LMv8T2~zkIr`6GfiaO{d?Mlx=DXa{7oGyjE01o9}x25K>0Tl*qH*AfHH7v;5TH z?zbvmTsIo_$W%iUM{W8Gb4a3V`=ax7 z&{9ad(scota*o-`X%+VKcAiVKBLfQq9O|W>_eS;|K!l(pnjy+=!q9rai6P7d^1YB6 zQePkKZ5D_>XcNX#4h{e! zu`U>kZQYjuRcyYQG69FFa)R<*_Wws#|I$9y^c?XMeE?{elH`6)Q@-cSvNkwtE`6|y zWMJOpz0nCZ@UNh3n8fxE8O%kQEwfKu+exhZ6SHaSr_CyuhfHK`jQt=%ObFTfW;N6Y zt=SUTT7RPmMeS8;WQoN*-QJN{7qUn-KIu9#B)yFLXrOY-e6uMay=5m(if>P0=ISD8 z+G{io`z}qXs%dNqd+E3O6l-+?J{87BvkTTLf*h-%xyuNIlqG~$(>s%8UKpItx|vRx zB)?A+GCS#`@-1Z0rNg`&%(T3os6@{j%}$Y%fdtCPE{5Iv^*LX_n`9gF%PQQsn;FFF z?tI9vyeFJ-!wd*AI8aF9|IhCG94qLL<^DBSRB6?C?=J6HTzOpj&i6tKU?P`Z@_bH6 zm#4pnsQ2e@>ZzF=d`tJxpbsg=ciM2v@T5^YGk$>!qw1V6lsFX3ZzX{&q95|?n%+v# zynne7MT~Y%EwKMdHKHYk^44)Y)2_8;$fgCysqOdYtH@A=+H=0&^xES7Dtd09bI+kr zDQb)@U=^{{et+zpBh(VHHLV$M!G24EBl6b=J?s`&y?R~n{NsQ%B0e7UBOt{0M5{VE z^8!P()k;|KP!|>mRld~Tjg17o2YcrP%=9MQLb-YQDKaLKExH!Jbt4!`<|eK|dgIrw z3A5BdTk4*7OO0>+0O)g*JAEOxT%a>{nFa-lsv#TaeBoFncs{)kPIDOqW}nUf&)LVP z0Q)nevUOS za#!>U&Fei2KIQ`Lg^gK^1(L7yY^`fF?e9$V{R(Tjd+8#tXFgF?Uu_J~&9~c|UHXLC zX=d(5>-N0x+?SjS>sCdWIp3KgFUYjH2ueCneA z+>y83u!H%i@LZB>4wqZNY;oBKzM!h%jY97OEthmhfND^BT4{QI4BOdFLh#ma-{8j5 za-FhC(HgQkW8P>zZ0Qek8K5YLoqn_3<{~6$Q5V@1%7w4)Tzur%P}E)zC46$<{L&HC zHb)dLiqAR1BM_LfEPa?&>`8-l{!c%rpiNRhWZmvfoItaj zy#ZGuQp0lw)5O&1Awau)X0IK)6MBQB`Cg15N(xU6;B#e$BE9#OXk+_2I^G^G`w@;Y z-sB1i^poHyCXto0Kq2(VoAJ> zmcjrV^!WdCGUC4*gJAzN2K81Sz#SMj2UjA(fHG5lfZ=QAC|yQ98j6_*;Fbt3(%72Z zn)97U56VuQV8Qg)5;iyV(c3r+!V5Etd+bLTEY546*x=KBE4@yLM4|JGHD%pGj?+ai z*Mizxnc{*v0iBN33{5b4!gabjDS$QL_4Jw9GSWb1`KjEvCHJn3dQgjQUw5BVpNPxC z1`gNi<%!CutC(xe6f`q+9SL5y0xx%My)ah9bQERqPREWTUbj@a+m0VEc=F3-a-eBO zEoivwaACF9_v8e>P$^$(pk0p+Bg-mDax~t2MCxlf@lh{#m#&dvtJ3tEQP#R8QV#!K zy)&RiajT_u##r&B)xAB7$H}zmncFo0XtnBwjQ6-op|(-1ygl;6jSbMmT)y%QEck@g zkdQ-ncgS?UdxLHEYMS*mZ^ypmQrmG6hs-k7>8uboOBLRe`CTaEihI8zDu|JBwN+Kr zbmhRPw$+VVJKCu}g4_9`qs zU_ckH>si{A5HS5V&Oll=Ln4wXS`STYf?u-}K)rM)J~;d^I*xE()qGB$!%#)1=R%fr zMw%{kWcGb>!@43?H7?$IU$tAj%X`E;*JkDd%UE{<<*9qW3uoN}rO|rxT<0~H_V0y3 zfvlm(01tbJ0q9M1c&00Pqoh%W>DO!)8)1Gwo{`MBEaJX{U3T86u-sr%|Icg8e=!$7tnm< zVL?i?#mMKPs~__a6C?n^v9{RElWtz7M{B$!Qx~4QOh`>A4b5S{yl%1ocIFQ}DuW8X zeNFQ)sxoNz(sGB{MAefR2a&@g0l7{hInp-2bjSQ(h-^Emwc#Rq_!j4J-}D^m6}RUq zRl1CLW{8na$?!8HDc?QsU(FbT5!MLE@M~;YVnc#hzK9j@@{MC~}*O0z!;p%c>?4C>6ZfEVOEOj7ST3NQ1{lV$OT!kqPIN zNOjunbix!X%0iWF58gAKqYu6U7Lud{w|+PZymX8uvhJ)SUL=g8*dtxp|3N7k;$P#x zb$G=E=M_Y+EUq$>leJ+PTd&^VZrU1IKT|&O@#i^+;%b&n%ZpT93JXlt1iv4Xeeeo@ zxxq?sn%FI2a6f+Qu<1<4ftKTn&~z>Brsn1xY=f+Dc(rk#cB-S^Mg2>8&z-5X$DDXp zaWuwd{tX~pH97QHYqr%0m+$HrV_rqOk+ZhC>INXY4n~O!fhAQzb4;3p27i+h_x|rm z2{<4cRsA=jk=g%yTV`#DhVGRYwZfU~4L}d>L&F3IcI`k-z&R`pg*5@O2V|mruCen? ztJ2f*HPI;oMbl`oe-L>2jtGk>16OKVd1}m9@*|rDlpd*38h5I!#h(6yox^Wch0Ka3 zqZ9fnqhMZzWmSed58)|v%-}Tj#5dSL3SgbZoMwaVnPI!Vs$?&3I^fvH*F)ifM9Hey z)aRVnhz8q`-CIbTnKN6CBkWd6+9T7r2W)LH*Q79G#cDn*`-5=+`ni2aW?6$_2rtC$ z${a1+h{)8>xdK-a0xNFoV{j8Y??!_XcdkbJl=cB2mFR<_{G8EJLx_nl6_LpX*(T@* zgmcAsvs|kB?e@#05zc?B2+(sZBC>R(kty^aZjsP(89=6szI4 z6sCN4X`=Ie-M9MIc;)4080{s}{dC`+vQvR&VI?YFeG(T1Ia(MY>GIK|Q1NL#k%pbq zQf(XH53rMTEB*-w7?|>~fz(kO3*>dnWz zr?t53sNqSG8lH*=HowFzSC|@iF{P$N@c<0bJ;NePp+dS(SM=!I3;08iqh$Y0i9K2G_zOoD5F_JMP*JbFk= z-Cv`1cUb|}%i)36AukU;9iicO6a3W*4dkJZMmhRY9!n$Iuth<`c6nYoKU^k4%~BA$ zY*`(+eQZzVxvuj|Qre-g!)T*;wV>HM=h9|HS==WvATL$nalw5%ua?Ia!2&c%s<^y8 zx8>UKOufZWZLih4W4NcvMtDgqWHDe)hl!X)BT5`Qu$<(X3wxA~fY+{HQkA!LWjEjm zG7IF{5GOXxlL&>8*{nKP+^vEi-K)R~Y9C!9%*;QJT-}f@>2a)ey5m}5% zCqwxpl}^nuhlZeE?j8q?NdTXjat^UtpqZ(*ZVcr+pC8lO z>hhUvi$BsuWwb9@yDHvWV2NX?hg8UJrNZc$NFkS&NWr)pnZ8aIJF2mGv6grl^U?E; zbgjx%iUGezMzq=hCYW~Ba zU$5Rl9T`&631zZkH!S}ET%2y5sD7~P?7REI_#D4!;>B{R@wNykD%%NwtwDGvHh)$I zG`Bbc!1QVOu8XUv4})B`;_XTKFVy#q0Nel8A;(y&KFIo~-m^LjWJT`yyaMT4Ps(?^ zIWYVd;2H6&l%DXkuG#IaT0dJorKQ1J=B+dyrB&U_KFqRv5s{@V?N9j0d%u4HOf$-9 z6W5Fmd&3Ph$zVGd7vv|#(x*R57rq*cGNao0>8>=`^Zp7x@9~k>XL(w|*-C^wBG#$9@0l?|FNF-mlkj9M3~` z#2!;n&j&kr_uZ3K5F>!K^c81z2CQ>PUy49u-7A(c>PTn0sNBRGI1IXY_UOD6fCAe$ zzr4*kD`FfAuKdE`r+RBcT}`qK51=C=lfL7&*irrp~`$! zRkq@wv5GGVWhgz=%X`kodwNG0Z0TQE5w#o`k7J@;wxFG>rxgR2<~7DL)fv@696}5@ zCowqe&0()c;en;lU34jvU$Z5A)*_8I_DXU*m*)>~3Qu7FvsuLg zRxNoSNkX|mOKH2#Pv)8#gHf@ALTqVr^<3Rs$Ahu4$+uQ7;_~8QLq%hz4g2TK%&yg5#wdYXXn6IyQq&AQA(c;!deQ8OE7k7R<;7Ga|_Xp-DFb*k_`_&ZWZ+_Yj zU~hnNlK?r%3^`zigZ4c@y(6ZRb~O2#Q1baNy#yqhC{S$chp~tI?bAO{Fkhm7}6w1VS>l*4;sxa8T=|o()!>p zXh|S!(ZgfOtx?dd|9D)r;hY9_`7o05pZ8Bie`gEZ#7yj5^CKHlp>BX$G=m1!2Yn!9 zioI0?V*7Ur>0F{JTvi;iQ~LvWaVHibMWD`Cf3sSkDZ7LStsH|!KJjklCZ7P#xM?9B zyfx1Cv1w?ILo-2$ZBjfp6G>REx_n9o2pI;&nPLOqe3#Wl+#VxaG&)kV@7wJE5c#Z(cGgTIz%O)On%6d zUQS-dqj_Z743~6RR)cGifmrD-of&M0|@BAjeF0`CzmzqESP?|}UkZmeHKPO(t9oSgsx>{0#_?;^bceAU?!CTq+?CEE3#<=gv zYS6?bDTXVt8d}uT;a=ykGO46$AtW!z_AoB5!A_#ms8xP7*Xc+G-6#%soE}hNIX5o@ zmgB;_gqk(yvk1yHH~Qz1dN2$tK9fIG4}k&zwGS%aw{;f>T5fJmNG=GVbFm&3H^m{C zja=Kw#i864pU#*5F77{Na7IHyvO{*Vv{pbo@&lHZmefo2LRP1`Wl zt=;SV>04m_zj+IY0E*F#fAkj6@FUP(@_`2Chr=o>07r^5$A=pQP>?ml^xO-Uz|~hx z({d1B+4Y8?7>(LKD;JHWJ&p>~=L4QsmZYM?&m%Sa?3CIf#r#k$4}}aV`TfOGLXuO& zStXoFXdh4lJd>{Du$m|BU7&;}z*~z8oIVnlPy}3$=j@|u*`-!e?0$gRbXQfVnPYSr zx6rG(kjN7bHEm_7Ir+YYvz(n7Ks{7VgGlJ;D%j7)txauQ*4Z@_HKSY1&n1!Wx5h+w zMaR)}HF_d*9y`r+du|_{w$B}C8BqJ-EaiHrJ79^Aq=!i>cxQ~YRH|l8jTURB*9`C9 zVMbd`D}6Ei9cx$zJC8fKS}1McAYV(IQiCS^YQFFNn8YY>l8FMbk23G*5OifPvi$M^ zZ9tZK2IK+$P<1JZZ0wa?0RY(Byc(fv7A!cfWyPO!J`JW*3&x0KT_vtB@H^xiDf~Yy zGqfZED|>L7qc}$-j5?<@NqZGNl{F#8ewED4^w9X1 zkZ_MI_+)N*25ZZgn?D*Y&3SkJLx=K@&C$X7*WksQJzjw@h6D(~y>nmXr1v^9D zEpMtVnZk(+jZ9AaKPDI}myJ3TeOsrXP(-x z@xgTNKRpyI%_8Tv&Vwo_LbclxIyzOl3;9sGb8#`Dn`i2^fokvN9qJm^w0%4RSu@Aw z`M;S(UPl8Qn0Nn(10zs34b40JX)wHkO}X(Qym=f>e@-15m=unk=L|#gjlEkz{>1lc zqEE@MRRUmFy5#zA@61-(_~VRhj=AJ9AEdT)9*J-MI*)g0w~s_>ePTtD`MmfcOoKOm zm*03|o&QdT9C{U9r4YI~g5;2~`V@M2@6pjkCAU3F1}8qm+>&(+)s|nbj#7_dbQ=&rXP(z@QDq>? zp16nYa#c`J^lW!pD}uhKDLb%S`b*!HiEe`YS;Pe*?P)Xr$xpQ3t2E|(why(ny2&=F z5=91mU{;{yv}CFYupxvsr-9q^yF*flF$ONN7RDem{k~vnYk1P3G(ZWVhF`T04O8RT5 z+Eox#lV#FV@N{IzGaEOmz%u>`Tbb&lvr@S~5bw*lYPand?aQR7`L*_fY%mB*E}L8Y z;&h|lw^5I=U*l+Y(x3Y9Mg`&-N|`k(L&wrZjV}QOMB0Qbiu+9g-+`n>>fKzc)jS{i z``Nmna?kC{AfSGF5)K41Ebeq+t7G+QHN62@3HEQYk^wfSyi4Ej2kXxkY$Sj}66lk! z>q+dTVfBv7f8@?q{r5PI_2Sxf7;T~KWCjqJ0TWpzV6qbd-oy~J+;zFjan8)XV0zKR z_u<~M)WgF$0dGZ-+~UB$*u?fi!;d&dehG2+SDd})VScMe{RrtZ%itE@X|YNQdy<{- zHm!^2UjA~Z!^!BtMh;e+(F)R(0ntr-pFO_(HVd&Ym@A58m$8$nnAL}kzBsY!)R7LI zPad0AYc1%D{~{#5mjXc%fu=KBT3ugNT}j=nnSu>Q18FiMI@h)N!6i;liR)ZT z`T?2EG15@>|3-T-hRmr+Y-FKU*8HBlc$_7Hv#{t>@Trs*H?+xnc2Cwmx9&!m5NDh|x} z8`!FFAs>ovG3BLOEd1%9d;1!}Q+#4Nf9xD${rSeLb?=>IRx*;$YPR<*8-|NR)TM7~ zA;%f%y2Zv5SQ5&>k&AwyIoXid^7A*noNEi`L8q@FTVr=^N{>8GLrL?G?V2^D_Oum!6B!@TevyzPeHpYL78EnF2-Ma{cAUQAi2 zU&J=jJ$O%z;B}?c_klgEc&^JasKIT-bHv?UuL%%xb?A558LsDbhwopUdBUP4OLINC zJ`ei*84yGWhjL3>fSYbaMqc*Bd5CXHKlh_f?iEMA3%9}MEbM^e^M~2BLeJfi1T}6g z`NGmEx5ghZ$!_Ld3gM5rP+kR?Lb8;sr<+yi7|MFJVb?P~a;4SYZL0b4$axVUTq^$C zb3cHd8$pn9&@Z~EN9~Q}*0xN#D1-|yQJAFT@1HY(6f$Zfs#&z4xH3#5A26L*3GySV7zq(a04 z+Fyb^J%+5<7zPOSHS^`NMY)UlDASJB^Zq&H<|oT^_2CGv$^!u82Hcsaeh}yX&wh}W z+Fh&?7&O8GlA8ry`3=t74WE5Lq_m%1!Dq3uCnMugy{PFb1H z{~c#ZG{S8C)X@HffS`7-upNJ>MDJ<{8I0QR6dhi*P<_zA0vY>>;tH+y!aA7gss>?3 zMoMl$Wh+t+GP+mk8iLcf?kTmPhSH1A-CP9hJA( z&So24jGyWqG`;--GH>HPr7RNuq#NXhku?*4Z@1 zvBn-mJJZdRB5R{%3~5gucwp!)epwq@SW1Swr>!+DF(sq&YU&jXzw!55FZOd*qxc<5 zcC{s42$5G;Mc_7=Ut?p5=`F0L+x;S#D9I=T^=T&=bLT9KHdhcC_R^ITIPcBP9RsDSu*YU=?X=ca(46uNyB<|(hK2QU++x(Ai&jP38mP0xaq_L-;9>NL+jhRxe7M`U7b3i%|n`GRT#41Etezg_RZBZaYtB6cJ z)>IvO$rf@moBjf1#YK5QCV$-^$jF1>L zq)x>q62wTmwSkfYp8yiu1~woaw1;kpKTExNcyCtk<5qL1xGo(Q2rVQFlT-2;1!ePH zg>^4RISF9g!;WmwsoV{^6!nAaztuY&67Tvr1! zod>ODPm)`J261(G_oLNo(OzVqH;j>CD(HnkD+wEk=WJ3XnOEddp29+w-5q*6gI!y;UP}EqvTsn*uwMq zF|Ea4eu))!q2&w2PRHtH_!>fFNL4{zRq%5cdWyIMnGeE_NhqKD^A+lO?c>X1+t|Z( zFXLDswRWcbz{_o&aYDONcIaDSe{XoL->k!gy`*Azl}_NJxKI~I!9kBF>6Y_?Li?b4 zv~dUCK;?@YAcB8f-`F_sKe;z_lC_(OU)7I50DC50LWRX zKW0Gn+Q&fE#(2wRH|Ug?TLa@mv#`(y$d~1l&XWG{QGyp8JEyWlXLpbhEf@WAKC?HY zC-amDXK%%zu@a(f%ij{jm+Qx0^o23EM^={-&TZ-|;N0xta42hSc`eB0OIK0$#G=27 z2hW@|mxuKQTdR+&frXbv@7pZi8!>UzOT$wFxl6mnQuI1!fTNK!wKQ-?%FMNbJY7iCGzEyrn4F_l!FC;`f# zzw~`8E@-#)FfLGK{x#;yyo}?czvVM3;oPpgY%5W`MP!%-fuNJ*+8Bcyf~&wREx8z^ zY(zZCyORFGd`DzT3+8?`QLhI9bCIZLK{?aTe3tfIk@jQn_||mv-Cr~^5q^%MOJhL! zEZ`Q1cNJCEx$bSSM(u|P-E_~ngFVw-!t=-8XN%Sb_L&BMgy|8-wZXN@SX@VV-3f3C z8i3ks7@f14P??1O@g8uUzUn=IN*owhsQCc%k@&yQN0D%PqnY4I5jB?o1!f&{0;G;+ z6hNQL-BbI(pl&#QYjey4UR{v&_LuIUCQI!4Bwds?JuZ@HfV5TM$-mChY$UvwX>Xfq zx4F=KiwEo4z`-<0*deO;{I35Y$8$`GuV#tcyTUQ9Y!NF~On9a{7!?X#di>t>J{2L| z{D`k$AgavyuruECyq+%GwLgRO-M7v%;S~!@`xmSt<<`FGUXv{^jWM#8`gLAwnQNwh zwbAoMzL0aN&6JAu!8^yTxM@=p;JXO7dA+<HbG(U^6b_FQ(P^3c<{{V^@1f^R33l7%p^HCr=>L=JQ~}E z?MScFYil4HIGcLU6#vG!ZRbS>IJ@y*G}sD%a9-**FtKBHg%CiG(uOwa?ulE?13vl{ zSFKsaK=P*}LXb|f%-61ip%wp<2LRa3NJN^UP|1jrj4PO8i3HnBHLoQkAy^}W>e}=R zBu+@1Eo@*N9o$3NYQ>xC*An=_H7>bsT{MsBuy}t%$0iSlj{ZYM>J*pX#&1au>_CH6 zyG${~O{+hI=`+vLmIBn?=>z>3eE@M%*Cn`9!$6=Q4D5=8M!q&bQ*|CUG8$Y$+iGCWpt9;)&(yWJu zrCDIu>hCIwq4FpR-;ir=b@%<~F@H~XRm!Ff6TConTqO_Fi zdDVaDcaDU5HZ`$(o$h5!1Z8L!y6I%1D!znR9sln$A71?9UU)3k?U1URRh{RP_h+9A-SB({JY?^RQW7Pz4)K&Y@6ff0o zIja_Ll7#m`E^YoQb)ET5z`U((t-CPsM@kKHwuk{(qmU`eKsdplLuK_W~bk30K+-|`&YFYI-a_C(JOy<$V5i64dZOT1T2 zomV!<&GSJoFF`^b4rfj8lk*Jt`1hVSG5D|NsTva`4o0zz&Ux7~gK+Q7Mn#cUwY&4z z;+}P*TXMx*SFiXn&_9doT|nbFII3P=VF-0xE@%WQv8?CS8(-dsO8-UZFl$sL186V% zbjn|G-B)w3bQ&}L4U;UedKUk6R9CY7gQtBvDP7rR=aMmx*kE5?4JBH0b4Wq3aOxX%dqfR5`&>$gSgI zviHzVtBeD%lUvO;v^m@!5md!QFLPzB)ZEYQN@}07s8OYG(Kr2VXXv+i@vG_%xa+8S zez6#Lz`jM`qW^Vq{XDd<0b+CQ86JM_-P*{#xQ?9atjI1QI@1>8b)f%pa`TBlL=k0` zqAL>Y<;Qe?;@FGTO>uLdw%fws|H98(forvt0#LqG{u|0yO`)Al&8ETb>J48rN2e;= z|AK{`Z#fModHMXGgF2*t46>k64Qd<9v09oAH?VRP!tx8ZLD?r2$dRX0+J9@o0S<)G~wq=wgsZ*ttZ)MLMM(&MgZ1c z0PsA}9jO{~4S1Apo>PL!(^QplX#38Q%qG;5kAEj)yP_6U_qnby9otTE&@|KOGTn+N z`#mth1^J@RNvaNMwv1E2m4BrNI9n^+{r2;BmD7SSsYI>J z`mpMyZb01zsWnxiusmb^3iZ6eH`TxIM6TP+vNveIl@+hKfrvMMekC?s)lxpN0JwaQ zck=)nl>D&QDqWUObG7&TGZhocp!-?J=V`Y78+V=h5?O&k|Jyif6W~v zozFL~_$+NRijSJ1hrtLS6xudkuX-zbpG|I=ADCNI-&8$} zHA_{H{Pw`6t!KBR#;KgIOJHd3+FmlPb!?#Nm5LiEs*zrCeq@)OGzZvF3|F_H62sr8 zJ_B@ZH7~OijsCYMx$vIRwMl}-=jzox*z#!!bzRwSJaDdU5`4QP#efU8_Q%l3|Fl1C z0s`~2rZVcpNL~K#HT9Y8Vv_o)o%CXX!Vl<_ZKKOi+lF=ZrW+DtYy}}~eA%X*XgRpa zJDw?h&Irp7Y7hm>nGOFJxl~68eveRhGyp24OmVpJr?Oi`+jj>@y&@x%PC(&xFYw~l z7zdvi0oN85W7u?r{EE;asH0?rujIC?Q@_!9|AQIB`21vbnDz0mC-{2~8?OZBV?`c$ zAegzU3NCp#A)qFqS(j`JcripJ)jlRGof_>5t7{RCtt<8-3Rg+ZB9#S8hhitQ2ixZ4 z9y-tgp4J)J^-GQ-~_0;)XZZYd{X=k}#_8pzG+r?k$Yq^Zqu#6i_%kZ3S4bWaSY#Hc(zz*?D zePoauw5Di_b_G@U(7nzpKxn)A>FPY*VP%mTL7gA2b`cBJt=gWa4^<^zWR6Usy9M>L zDh~Iyas1%ALW&*F)>W#A{XQoEm9-J}oL1M`Su>1dM7EP~;RuE-v)8g)Gtk50fc{hr zd;YaTWuq{?i9>{Xb}9P_shA&tn(%J7lv%L%tbWNJLN~eEDa3u5!eAlU}qnwy~@RslYzpPyaFDR-43Ye&X zNzZ|dceI&W*8mO7SVb{O;Lm+lYbfXLV}c%b3ra|Pa_PzvT94j65N896GHT)qT+dH7 zMGKw0?3WPpagmqYwwwRZy;(!KrR&hlM$dfj(GQH+wM0~X^;6iVEXv~5?MsP&d`c_` zhpd_LTwUs&(+he-!2U6z7AB)yut5~39$!1B#Zqh0bVF}Q5bLlI?j*BHR38(ADCm%7 z=FaHQfbJ@0Zn_B}y)tX9uimmZ%G#m$(Cq`9QZ3 zn*6$fKp)zo?FFA59Kb6Dx|#dMFM9DCekV=(gb`|8TQmd z0r*P`Y}=)aINcwleB9cf+p}rxnD>G3Yn_|9+XK;qu1P4o0^M`ozI1oB)siEy(|wJi zvOJzZ0oV@;H*_#OlJ_buH4cEGrJi*PAIBKzDsFZkh3|Bbd${O-svZQ=LQ#_xb;YGu z6TWW&qz1_VdFZrIzJCGCU|P16tLM_U_|3GFNa-j#5OU%>PLF||kMdykLo?MMUIYOv zKPKoY_Tgn__LA7aDU|!)a5yF^eoXZ|2){f4_29VN^2j5n=IFm9KsR?QPN|CB2LM%3 z*RO+C=s8hM#Otr(gNYUcEpoHXH)I(-fa*88Ho=MTI?sGgf6foXVRjvJf#yFmlH31) z)6O~;H#TDr2X0wjfXxu?1ldOIgm}!xbRxd2mxik-7FyY)BnJi%H@H)^VGbb-)sdw) z`c*fM#9rfeFj?kj>gY8X=Dr7sHieX|h9=1ys+=g!->W?^sp2|`FmV*hYkgsj#r96#rR(0h^n3gS^ZI^5+m#*vlU3IdsH zk7BF~N!LMGSeSim>#wtl^CDEf#|x+BdywMKjmQoKC%@>s7fOXci+Y1N~3 z6#-rP&%Tixp!+8m0g?h z7sSIN*@}Ev+#x0}VB7y-{iiVd?2k=uh6;ZjhY?#A+2bY7z~SC})Hgm6pr_Texy7@I z#G$&Kz;z2y^Sz$crNHuq3e*^NFT9`4`6cJRE%RwvEnU4y7qq2=PXqV2mb5VOjk3Mc z;1X(yrF=o8s%!gJ8G)3%?Ja{?Cmc+;1=I_@Qxp?4M-5VY3cRpe*YO7ihr>ld5Vt*j zVMLK+Jboc-3|LoHDnJ;PX3bljX6N9iyOy4l=OS~9wY|&TptvX`7={SD@248f@y?#N_SV^lDO5 zoRvz-3Kx-B{orUyX*H(W#av@#@SJG^oAg)d*8QCcmrmg`+dGe4vACEnQA(e~`(B*M zJvOGwDt-M5krGK%a-Dmzb*&gC`L-yRW6}*zem1>77ioISJR4yS+u`7wkMNmp@Wo%f z>ew~3RlxHUhx*wN+`nd6!DgjKoUJ>v54sM&dC27Fg^94{1M$?c_cHj~nvz++q1B$P za}76fxG{7!f+TZWfFu(?=Gnvn)BFQ}#IW*cy2)(5KV;-okZPl=$5xo{Hh!;ezXE_A zKK}=>gUK=L+MAk^`DE~31;2YY&fDzu$`3u&dm1zv;N*MHH%ydCo|IrE(p0D6L)fM| zM?mDyEBT*b@;2@O1h38MWc*kYG`uql`urLQH~|7ysSs$xxAA@*1+bhHABk6mLhuj{ z=KB?Im(QCNEJm^_C`%Ownnw|)x&?nF@J@!QrFb86Xo}XliTa>-F8W#?S`61JFkM0Y zIGfeLT#nIDJ=k5P@!P|7Ct?!Q$Zo;L)7H zpdZO11b~;;za4EJx_5coeaBu%j_L)}kjB%CZio#w0zX-Wv%B03m-NtQ*a}xt`6!_A zj}q~jO+Hhuqt**ndR~Foy#l9Nn5V5IE#vQkkkU`h_1ou#K)tG)AfO9d9@IJ_;zzyJ zUD*NDq6pDR+Rm&e#*|+dFDbUsZZeovWWTnC{(DEW0a6xF&&T2_pJvf(*sb{~$@gM- zkHR-qPmitJ5I%UB3@U`%GoZEk9t%bt>grfryfAXBaqWFbWWp3eQQ>^T)`z?)I|gh_ zgSelMserhjGv7HD9GZ|_Stw<##pY2ka${6yE8sqIZ!lizn7Q--9$u0hB(*;-pXPS( z0_?EEDvEjH;M7y1A~`}xPFQgDu(uGj<-5B56HV?Dw~v7=zp8EXecPYAe;zYq4~o-X z)3<~Vq@>eT+j_6JVrIb96d#>>xd%Ou*BDQPfusqVp#g9Ocxn5cQ8ybdIl7E#6%D+$ zPOYk#>NQnpj(U|Qr*;(ce_OZC(A7)- zqMmlbtp1Zu7@gREb;1Y(xyo4q(6EIm`aH=1X!WiDEPY?2!&}KnXKsqa1Q#E*S^dT6 zAL1{TvOWj}2Qxt88M-9c9!5wc?af|7@qj|R*$;J&eD~V`5UP+>MvpRskmoJecaE5m z_dXIXZ45fd6iVOzYMRal@qG1;J|Vc@Q$t+p{)`@}6l$u5=S zaj%!l@~y|Fm1@j4>pyTD*e8GD>)WtMTrgWqQ@*S9DP6^&T{U#x~yPL z_;pY6KFGaQCeCAb(wE)t+3`ylH|5=913haB?BFwGGwz*iW$OEc!{iZlW?@^RhRHUY zjS|6O!z7%%!c~vaDDZnWK^(@#++w~zc-0#e6^>oy0y;`&@6cFCkps}Y=~$Zf35&&` zK4W@2^Y}|ZvicQOlC^y)R`!YUs1EI?+#56K#uT_^MVTGSTNjwkb2JS_Su)9auN2?i zX^3%aU_JVj?j_^w`h@mbzYI?38L!PGZbAgYS!+GJT!mpQdTEhe>e#6C8moa@1A{>c zmcR$y`F(Wft$^FRJ64;BNNiJkIv(aeEF+g6E#YkH6u>KMZc<<$NePLhJqP^J;pv^1 zowl0F0CVZ!Q68#mXvKF8(>}pW-i$u_V`A?bQ}AKetrWR&6}c=I+C~*f`HaP+Sr3** z%iOvQVm-WhAI9jvQgt*Ta-p6lZ+)Pq$Jt zFU;#0KJ$VcO8TO)WG8C;)#xgkqZclHHxW*{=r%ye-dTWa%#@-X(GeGiHlUTX|H7cR zVf|;@sU;lN5Jn&6#Uqgd5csg_p)8p|43D%QUKe~uNOo=Oa){+=B}Z$ss^X?6=fRl@ z@15ZMb(oC58HTfTu9xY`ff&6e%b|m9E7D@K%ZO~TBhtUi8@4$&TmWE24s?_TLUVp3 zyIgK3h1(D0esBAof7st#?@Iil{mZZOyEYUf9eJFv+B~uCAF9h!Xp}Kr&jP6)UVs!{ zeF7;#EL)YyLF7j(^7Svc&8&o$H8O_r#(bXh3{0cDc-hkt+>Q+hKlZ#4yF&FG~RFSV|Sj4{U( zU|j~z=_x*y&)#Tkb;DZHUPz8(G{QGp2aR8d8#)YPPjpC8m~aI zA#?zIm1YTK^mi*VvsGNJ%?j5F2Nj1_d>ruMAcTfwa~k#AXlzNNS8K`j*$z-ua(rH5 zcmivxywS!&AQ!`w@_7T*TJF)=02_HtJkDrSd+nehLYWX*cu#UR^tV(NrnO84oxj9ySqwJz8#FO@e6~XRsKzBN zHazi^%kM=*WKx#dXeQXW`{6Cba-JeF+lEps;C8uJvUP;ex|-^Gd$US2Es04qx~X+H z()SO`3p^FY%lm%p+>nm%v2dhC>*8^PQJi*2%zR#m|FJX*c5qx*2H4FT8$%_|+>G9j zu)VjChS%(J-ITnqa5IQavZQEpNH*n+v)IuBmW`pd^do|(<`3Mi93a#_es>vwUe2GE z!3`cvdUCGEP5@T_{{P$R|F0aWd!BaM?0+7sbf~9e6=r*V1*q@v?*!}s!;$uF+D&&I zSeAfqonRB|UC71IYUPXfgJUIRPny~BZwwCJoFh%1$Ke>PGWwoMx7arZU`PJ)0(dg? zG|NyO=|lgyizH zVMc|$2Tge{N{-j6pj5pfo%ArN$>M!wjpH+Wc6YnIpBU3ZJU@yR&kBtO=#ayqx#2#a zrmNvjWg&fKu1mAeuumqMv%)Y>beJiZx6DfGX^&hn^m_-;12G$ZTA0pb&W)JIJ7;`T z$1`HyOiTlwR2Z}WsUuojK3f2@l}>r8=f2*3G+6hi>lfbwBzqGJ zAC!yNtoyBPzeL`h*~2@l`2kmfKwrxeJo|J}1@tKlo~ECXuAR9b9VlkD_c%ohm(y5T zwl7!p5~C!_*&HGC)mP==%NCMvz3`q)Xy>u-qTKTqGM{8ap1?^3IEZoGbGH0S&r9|( zO;6S0G)KbziW}$xqyaL-)R&FV0J55W!mn!{CgW`ttUc^G@LgXH>u#w9$a;SXxp7N; z(hYMTDEU-Iv6r?&1t-ZjOC~5$%T~17OU8vE9SG8nqts69vWu8p@?Kvsx>SxwuW~1O zRX@6I8FTr$yGub#N9m2w2m1o_KxgsaJx5Ike1-9qDBx>Up*xhrKgwU>I`eEND3LD5~{VeR(b=#$R5J{NV*{oT;Wvg3N8G2TdiL3!azpywK z0qNF0-v!p!DRLF)+{Gf*;Y=4F;pVQ#`)4~E0+bVwk)m;3@C&0C`;SLN1!t>p z3l<`8g?7ymU9qj13mUBpT(uY;C}gUZe2(Mz`<`#Op6aPuc65 zH}ye{-jj%b{oM8XT1tL#)o|yNZG((zg`HEAj!Db+Rq=IRp}Ai=Y?7S6_E3b?Voa$a zca~#Q-Ocn;z`wcOx@#QOq01ciqC#gbZM*^g75iTNt- zBO%bVhht$mmVLJxLa7R)0_m|UGdnJ&*S7_aF?sc>TEt~;!j9qh0^ zrPcp^S6G5dlyIKImvRXB4W}WHq#o45{JZGw5p8^>!k2!L5zk{bWxbl_l5aVDdB-+A zN-IDDaQ1_Un>`0q2RB7-o5TC%yFbMl&FUH(iKgz|1o_439^asHEF7#KX^242UVmAu z_P2k!y8&R{2QyZKZ%;-Ite@H7J%((I;6KPqC%sw{-UDbvs7wCnTo>8}f8FzxGyaJE zAe}L1&_)#>9z^=6M4P##Ama7-e_-8Do+eNJ8LKS4?!ar{1aWoVblh=@CfrJ2 zg`!7zv*Lnz4&jgHZhmqk3htVJc{XP7zK4I^!Dv5c=}qPvNGV4GsQ}-~jPu)mFCw`W zb4>Rc{b1a4tFp2>kd;qId(?FrA)5<65bw0RTTZV*%@0XW1Fm2tdFC}vJ#L24=gvaLm$lwVh4S7xKs$&+YjF?8v}8qkyNl zBE(OQi#=oej6dWZJJ%ZUDSN}uV=za!CwPICkhCWu*DT25&6@vcUVmE z6Sdq`f4G%zl6MB-9y(^xt3`uJ)wyp5;l29UqtuYKf)aw=`M%r;g_i24&t_-XH$r(F zZ!~)iaz9y719RPTXf4RNyBLHvMCN@tXsc+x6=&Y|eM-c++Wan(NVu;xtT^Y!n@3r& zAk>I%@!#F;P`C_pSGd`nu-KT!11a49n`0{O3ZSGG3W=nCqz@GAE^^+0v& zP!ZJ&l6CCt`TNYmK($Swko$zp;+(23UDQB{h~WBCV024*XIF>J@pEy`(<2Q+(_5r& z3XN6E0wKTsNs7rr*Ep@bxQcfiXy07<5AB-YC_mZv(bes+95-$ARinOV*6Y`C&Nq`<&K> z^XnOVgiCdIBb!rcW?y^*{IdK=zpBI57n4~0ZjOTnW_It1*$O%-zIxyn0am_+oKW2! zT^iJ&d%RPOmGFP7+@GVe*iA^Yh*uk431l@?ZFR4kZmbpaV?L&$>X6L2R*88}#VhQi zLZdb2f5wh)C^>JwbZh*wiU#Gom5_btDo|0bQ~IjLs(L^t9UcU1td9b!*4oW3EQ=NL zG1iwDxXvY}30qkm#xH+=AO7h?XXG2HKtV`wPzM2#Qd4!d;s{o$Adi~26)k?(S8(66 z(%7F4@8US05L@!3{a4iN2iXieH66|GX76jsDx>#b4#BCd-;1CECkyXtalG84O$5JM z&VgTE0fZlp%@ePe$)r0!E@TiZT zO=?=lMdF;eA(d64X^X(C61V02tGz(^+@8kJPMkm`@E9qsLSv?E)IfqoOuGOG(^qg z*~Xper3MRtrtv``pa{qI`0z~q`a#bLr#g8J>%NcFC<9O_|Do~WUr*eft{Wn?|9QEk zfCZLYM<=D&+oyOwvJxnBFLKzTFa)T1*ag*h1>quVoTy%_$j1wRT5l3xAKdmon^Nn* zvavc7O7jWZ_fhAaMt<|N3rk{4K#WSF!TF@1s@>(Bj48^;XPr;$`Y z`gZ;j%TJzsX*5}~c)sxPcLe0^c&&F^rp8EBQPEcNW{_0LP)LLk4wlZrb4N;Mwj z`e{~A{?xDaY(+QIG-mZ{bSTt;z!PD{_A-YUt5k8I!?qi4q(EN2Gnjzs!zI59ILi*H z^tO5O$^OslB4{gI!M#;_yTD>AOF0orCsH`~KqsAR;U!epk1(#xhGEjyN2Q)j8oKErWsL1=p{;X%TJ zE|ej55pF$1PIPOx^mYV75v4rjCcKejYnM6Ud7AbS1LNfT5Yf2m>B2S*TF>xNl~G6B zYAqPzwhHTV%N>6CAvjR^j3oQt-yT2pdCY$OF}nae`&AeAn=YTPJM%ogskS-u^xMOy zUmrfBMp5_^zu3L_d`scYB_+6|#hLS$uAh&(?$2;00Lns)d-&uYl_WG%+o!!T=8If6 zJ~=+oml-m3TTh);U!O>a)a(yiMM|B_sH*?YmO&(EzJT(Yt`!H@vJSRW1e?&v-gOzf zm;#H}AJKS$Fb&52{U0$BXCBs3I#l%(ly53P&ywg>KpO{*^B*b}_u1hpB#763-ql2rz+qfvCgj3?RPnZ3!@8xT3{pXy*TQIu`y5Flc4A-cMJL z{B}TV@6O7W+pAY=iO0CCAas=;vQf3QdaYDh^iTlfQY(ndjAm z$(`tm<#z}td9JT{@5a+}%Gf5z*#jSxWPHcNSeKo5o|zdIAG}WreXA_v2D+caMQaD| zyj5l`clM&AvG~3(i_cpSHqHjT6{?ukbG+^Q^jC+{WRF4|w!*874Na^@`nJe1>3Le+ zufP$(4CY4DraxTxa<@SD+xS6T%gy|jDYaGH)<6?6Gz*&pctVYiPrP-Ql5F2?Be9?; zg{Aw>lg|pJvH2#9bPpl=c7%#@`wfcwy^#kAds4D4?pq<-e}06(kCFZG(EznbO|62` z{p8XQJPOVd-WDo4$uGU2oV7Bs7KEPqX(!KAU6s<7j6Z$hCIu21#x-5UR0D^N?z=jx z%uo&Sr@1${;$hkE6nxAeWzg5C*CLs6G^0rOnZ@~6_+>iB)y|Q9SN=UkvQCv9Mwu~0 zdkl7);>STtzFNLb9W$4zt1x%27(1D@>K+h2F3DVeyGKe8(a15<82^q^S64yY*ubPn z4uaWn{n<@(+d=D$~#;&Wv;X94aet+Gjl$3uHm|y4^?$AT4Uh`T7 znkqWWn`yl>&=GHy!Ce?HXhl7d24AgiAF%=}yQ7D>T51hwUk-+rYLL`|1E-M*DOw^H zjn3ViER!$$jCk~05O}U&so>*Y%BA{SfHRl1c@I$Sx!iUyO37YB-rxDH1M|Q^Y-f}~ z^V;Vs+;hXjv6SYIq^6LNJc@Zjh4{6P5o&XWs)c231)f`$db&CFZvF1D*Isp0E0xC4FLY-nxk6}_IyeuK$~+P6i^IH`jbTRlDO+fkX--Ze4wagAr+ z$$P0!%qSVe;cWkB9 zb>tVmm-t=JH|V-*##VaJ%#N@Q%rn#P?^cIu@n+uvERb2q;d|EGv~L-(!Dk~SZ*h0BHZI9| zBPKA#uh>P(dT@j9aVMPsAKts=M_#xoX{s+q1-8mW**H`<@|a2Q~O zS$Q4NX9?2Y7*hX)Yc*(AC0BVudWo0ENVfR!^&bV1-x=$hnVHtul=eem>n_dmD2og$ zanF2aoDbJYZUlP$e93Na)|fD5keRazo`<=>7v{5(JjCl%@;Km zGOZunB45%}8`5=e$)i4d_bu?=rV=Em4jB422GFe4hwn>NDuOJ?J$1^~w)1?;W|7dUQ&U67+G*2x zq(_aW3Wlj(c94p-DUz8e#U?!;8u7I|De=jJU>#0?vir`uIVcp5pze#UsnB{cC+2LR zk#zl4g{>d=^-Vh)eX@t*UE=3 z3_|5lZRshc$}NtTWy<$0@0Kn$*oK?&ntbi*SAEU3F5 z3Ugy=4IKwTKTrvG92l?fC(G}9I8^jc*uR_^{xdK=h__Kk%zes>ZKX@MxLP922^A>9 z83g+^bDelsDADKh6~SqN+vBwp!XMswy!Vd;)>o2)uY}Ivi{$0&L^0L}zxe|aTtCZy8rF^Ye+=u|4lt~f8rxD^ydibJI#@K3S?_&7rA@Zf z_gtFH^O`17{8OO4$GhC1^sG`2B@m zy8L|&MKCR-aZ(|ypm*iGvR2%lsA)d+JVDf_8O|1n5yQ875lYj`xTkP6sTKaC z$?_O%ir>zY`eJF}hy_M?0>46z3Tylb`4!%yUD$CzZJgkvc%kZ;? zANIVOOHT@r7k>7#C8g{9CH$sC>9KY3iSdzuQGG-}Dd?v`|KU8s-i{0L@jYoj}?4d!8kZf%tu{Ya=wpUOT zlj;@${K2NXMyA!xp>A!CQ~m+fZ)oVJ^`R-kYRO0dU{jz@mDk%a6_4n2Gg5=AyX$HsP{n)LB;LUiA{@so0S(** zqOo5q1HQ7aYgo1moG9=W+4UdqJgMA1F3@2G{^As8(jPjPIaKArpJr+@(p^c7k zZbGARy8(X}Jx|_xqWDQq>Lp03{^wc&D4JWXk&uJZ#<^z$VPQv z%e7bG8ODRx;DneG^Y)6wA95Z&3a|i@6o>A%Y?6wW?pEUnFI>5ddEV3mG214GzpRzc zxt8F3y8;jXL5}v)9X!%s>Zet2)^pW+r#k#zTu| zeYU79`iw|Nt|V|Wgl`H^mT$~a%**v)rfPS&#KM=o3%(olDh0fIn&K=_&@`A>U}(*w z3zvOJN+k)4l%`Af!Wb9eT)I*}C(7VR-EvT*gq_ z#w;1ex3>gajRf`dmONAH7smCM25CJ9Z{wgwf%jR+Yf-NUr-73yp7pP%>$kW;fGZTv zTxy90(l%&Iq98Rhf*eni-IRSDFsvE>=djY2K$ehSzyd%{0K#9E`oV(mFd?N&}4~u%St@3f)5w!?rYn2l0P$Msz;RNOZj!ob>WinI^Qn&gyKwt0sok)uI zEau{sTX>6UMU|#*Ih)f(D9Ey8tP>%k7j)$*a;?2f|%N3q+wAb$6&IvPP zU~X5E!#Xz1H1{kid3w&a>6fy#RdW==0-}t9TRwHVa;qGa@o;H~Xk&oidUbXH=^e-9 zTQOZ>oxgk1tWE9VZY;a*12U1P!3KHf;u=efyrP;U#I(70+Xjsq>(<>$E0w%&DnAKa zwn9e#0o{HywGjtfE7fNUa ze3!#R#alA!G8;Ncz2(=D^EcDFd{}ROXUtp#wgN_yhc6v*dSVj@y#V%v2NT2lMEM3b zO~T$|TK7Fx2otRw9hNTRnET~uG$otkz&6auF%E*b8wHGfWeLaZx3z(%c__i_62^nl>NMv5(Q(wdiUhd=oL_Bs?linQk$?$%r(EC%>v42}1XU zo$3#_4@7*$4Vp>g16OeIvs#3clXT?5FG=E4@sO#_P6d8pc-b|V39lCSveQs%;;;0e z+hS8f687^d@&!>BeP)jler)@$E-TLT)hzFHj3eb%Eut|VC6Cj_k1TTX+Y=|bt5@PA zj9_v8^WSRL4^22wZRS05#%kpjoj=4Lc+LcUUxr_EY<=u7*o<`UeWE zKo+m%U=qLq(+r32R@QhR{#}$PYy@|oT|HORQ2E#<{`tZK;d_NeCB{#Ss+6DAK7S_F z*4m~OP&304@&Q+H9di0T1xSJ`X)tePX*{q8b!U(b`cz?iQ{`0xi-C6pv9m9_l!XH< z(euB)(rjey@Y7BFF`*c%u$S@Z=MruAUgcp11cFZDJ6cpZu!5A~pX**7&56j+p_N{Z zwhj6zs4;z?VOi#4O<%6Kc?lQQ6yLTX4_b{Iv?sd2c0c}crTB6QJ<|ogHFDv*;ZMFt zF*Oe6HoT&xIH!a0e)U8Z(>hw-$R2}6tXJoOtkNQ;@`n6Th?I5@(sFm&i?AHM8%RG~ zo(}3;Q_R{5eO=1mw7}*;ab4%QGnuJ^=QS$K+V%T7X8g2)V4(Xw@N9@TCTJ|g3#+TT zaI*;L{i1U0Z~0U78_Y5^w?U2M*fma;Yl|!)bO6T!+y&5#xxG-ST)tRx8ff?*ch__a zAK+By=T#w-Tnm?RZ8xM39+k0ct`B%=m;aRmtRTI0+=0iW#GZNK^`6gvy@rz@UTqh7W%1d z5QlR>sQ2#qlJk5y6Ba((_j}VC;CoaFZq&(QV6)>bWdgo_GfGLo>7$|P_)#_ZvDKCrIE)CW049$m@~u({vQv`%pPmsaA!Jbu?s8; z@z^1}I%I--KELi(-0AhK+~bsU?{PS=2wM?1KCp^ZSe-WO79$X%A_)XyyDVIpD7|~c znj^;`&Tgmdho<l0eeMtu_Q0~P z>ebND4Up2{o1;G(709w44EzfXDh(Se-EibnEj~Hm>>j1nH<(nGltT}`y^aU^uaezk zk22eT_g@vR1gU^FvY&kzxGN2#$z`Z>=$C?;H0<&9%6?46Ql&&j^?GD&gKH4-G$B{z{lOYx!vU z>IO|jtjw+HVIgURz}04)sjs!(S5X8meHb8H*vlheApuslmTeJMlRxYnaSiMKQnNiK zsyBs~7ID^=+2vv%5E&hN)lya=D?oeI(Tt*`XqX(DgL+M=v!Wm|cH%(PiP+N0rAQFY zn&C3)SLIwb!*Q>y{~Bbo%^KO;#&111tn5^CUpFBTCaRqp{T7y>6DIdc$kYM@XQ+dW zW9su&H$e1I2F$>{3q_LvsYUcuzb!>e2QIwj0KKItJwt%emKHZc;Xg6&qabb@&m-!< zaF$Q{_eYwil$xbXpl$Xde;F_5UbE5WB~-OAEC*358-7utSyCE%-MRJcohc%iTh&AB z!6h7rMA-7SAV~>vLSf@B$C0%~)y!t3iHpY)Vuw+`#@V2#WY&c|HIdf zF7hMAUxR%!rg}Mhip&AqqfOj(S#M44_M6X8<6#A|NC8YX&kbwg^^IkI!Fk6M^ejoE z`+Gop06-pa|JLpP-{iq7h1I$)hV6d`f7SR0{yKG}jw*E8w+D@1_|aK)Z~~+g^l~Kd zX@fkwvhY!6nSoo=Z=dE7T-*B`W zMs{a=jJ|D%9~ZAtcgOhUJ?-@hjdA&7!K^3SVrx+V9i&@jX-=ajR?ftH1Pk~SE21-F zwQ}EAaMK$NOI&ef;*J59g->5u>NlJ44H-tb9vK#6L~jO-Hrbk~-j$H9v#5L$&?e>0 zskI)nh7obj7Y;HKKDx9<@GX)eCo;bjtVh$kSU>@DBB0W~;{M#d4{RX33RJq zg>Ym`RWh78_?L&^^g5AS+2#YsHL=01?M3tCOf=N z)5&mup#8bRgcsTT6mNJG6ZY#N*|XMnbC#q#ISlYG@CkMP6wU42=%=-0tdPxc)0EHm5&MQB^Amn{S#PW&CW~KzFXh>)aIg>6p=x znQ|xW0|}{h2Z6y`&1qhob=Q5Diz%w&X0l$X8y+v%Vy^x2!|jrKT<2fD7e8OE05tkF z;sVz#UDH$5BHg&4u5iGG!q>1+o=?7=47erV3H$S~1qS=-+VmlKSck=*D+!}~ovQn6 zr&vyNbAbBH$)y}1js0zIkXR-_d6EA;d^aV`=N%B09A!U#yuU5}vAWJ?xh-m;)ZE1`|WhQyt5x~-QyL6WN zl5(m-9iR3;4RR_dyD8?aAYgifgA1pFo`fbneQy&y>tUw`9t+bwnl47`wfdKQh(z_R z5FcXYt7CmBSu)uTalZUj+mUW<7v$3hX(ML$Ev)fxybPId9&|)WRyfWs^qWz3I%*>o z_CD6)lg!iUL0(41oyKK6n?{Paq@iI?gV`xJK3lttn!S{plrq1=r4O23s__U z*7r*MF6Nr^5{%(OAUVY^g$x>v7+b@07p8YYPH@(O%Ms_sjIILUU zytKE3)mb!)IvWn|KY$IWBwDktxqo%DTm5slIWnl`*}YPM*v&EMR*W~v^g(JAsuhigG!T?0&+RT@8sAkZtp z(&Xi!J?Gg`kui-x_lzXr;C@8)f=hSF2a;N)`HxEaTyAXlkVSQ(<9_M|Fe&&q5+5W_ zf=*p+&=ZGB(G-f8=JgKz{d}u}E?zkP`vjxNc(&-&_X}fdj(E|ysX`A~V1wIQ+^vdbP+a_YN5Kcrj^5WP++KUSEK1TTA8))sw@wYP7a?q7;q3i9Sy_`RrBgV4I?H$#e<&@zc*;s$m zmX9lU(-plZPri$1J%~oBaQZbIE%+6@Fl(_##guqc)&V|>)gsN6QNcI-=hVmW!&jB- zB?g>|Ju@@XyWEP(=vaw1l2JHcN?*amwv>fIH{xDCQRz=o1}9rdKHUs=@>Nx7I8X3AFI^v>JO+T~4TT~6t$;3HG?-}161SiwpC*ML~E@hX8=Z8fbSa;3k zCg7>lk^1#%IJOn-sLHd#eR{6* z*lC)c;9vVHl^Dq2mFYWdyL~;VRmiC|uS~Y6XT)fZq5I9H#LwakRhhIhtRThl2A47D zeMomr1zO1Oihybj^R{;_0T z?7abUkb3yJ_l++%=i)o>i5uT_#Xc>bmynWoKTeE&*xu3H|LsGsHmv+tQd60_O_LOO z&t($5(K0uvxm7;n0PAu{sv z!vsdFp0$LYaPF|QvGCZ}hLgwE6#dQat>({NE_snv>DRer98VL%yFKI@ty1?Heyn3% zN%9}sy(rnP=0##1DXZ{jIE{`kk-K*KQ|s;0%o!yP_tvF-odmWTo@#7u1RP;B^nG|h zCcqtK)@bia%>VJuNMaV+vaa8{;h<6rBx+S8Vn*glA=fCJTsfoH(FhWX5Jccj`Jlrl z@F5lj7$RfkGcq)0;!-%@32=r0v|#VN!_=x`gGElJT-DbnJK{uCe?a@p%C<+cieaXgP+s?qe}K z+Zu1ubXIO(5q@}0(@{EjZTa+R0$vEqakj$o#+P=m|CnJ}5oZRPu!RXwCGKLnQf?_P z?hG$-nc2|$90|9zCY*{stI8`|Pek5vsVuPI3TQK8y!5pAyB@RUnkjNkOze0gfkK=*mq8?%WbKDVq3v6qbif|`5AUxMDM{6QWAsH&; zJ-OrCSF}vyOwR9i+1-vdJ&-JhgX6$q3CZARaL@NC!B$$rQ^;#-)%t9VS+B|o&Ohlu^Vxz|z=YHh(m?Cte%rI*^}kq}>05 z;={Z~Jl>a36B_zwv1MD%Ov`}9eZCwUkL?6pQy#*8nmq-))11P*ld^2H3Ytp@oTU_n zA=Kp8qO2mDLmoyyJ(fY7rt6PQ>!O^7$`d|I```oAz$XXudc*j*l*(;xlgL8ff&%Td z|HKRTqrZ3!f10qS*DTyFd7yRbWJC#+YE&>15$k)<>k<_`o+0BCJw#SPo@sc)TY31c zh$7fyGT8RXoC`<=!4;mH=&DXN4sw-|YCdaXg>@@*K=TJr! zp8QuFri;qqS3$028MgN5p{0QY`b9MuDZjHn29R&4plO?QIB|RG)LJ`;NRQ4d+spCQ z02wcz2MDp+o+)7-5EILn6kSbDTAv6@&vbVG{Qp7`ZXY$^{pN+{ix}Mxc53jGTa5?K zI~EWo?f`<=NJjN)Op1@uH%y6ymCXGEwy8r6Q5dUlK47Haci*!IIrai*0v`HpMA!{1 z?sAs+F1H)S{q9{w3O6R@w3o0eIbMfLs=r(~MQx3%EW%nCK2YXxB_~QJ)?7^TYgmDt z^)^hKH)nswDkmKwr1}TN@PJpVXwC~dCe8oKxMw}+(X38)g$&Vy|1qH7o5g*Rg@A;;tz!c@vI$U-sv7MBwOqNYH3c zOzR82TD@*w*c#v3_(PhsAH`9BHN`B&e|6z#X$z4L($q%o8N z{L6ucm3?`jp*;|Cz`M#<1>U!G?f*3f#Tc3!jY$i+fEn8a!Tkyu$@SyMk~p<)K-1#Z z2+Sy%mcZ^!wPSA0C?NbpwnOJHaTcZeLWa{}w-@t-rgY7VRuQ5rGcDkgtXzw7&N>Zm zLaB~yt=PNr>eOdrvc5SyG=v+B`07R(;WFnIGRbi34e(s>(lywewa+}-jO7@5_*0)C zc^lG3YnvgqYW2=hIQk5E0=80kS|%g?<7QT^#YAqNu@#+v&9SrEonKqmw4}y}L_Ozd zXzyrUmlu;}ShlY7HS@T-36UbJF;WnB--Y{ccQ?cCaYxAcl!->~TU)EKrxEIkR#NYw zVoaar8Jfap_4#P${8p4oMq+EUL(};z3S`(b@;=~NKJY*fjc^tAv6l20V<&p*1^&zm zMxygvE2E_-jeObzmqjD9kd!9`3K#lkl(4R^-$Tv)lUH#3_Z$gS|Huq z?|fJry`TZ0>DuGEXK53vkh4%AjXD}w3)F2MluF?zI$qun<5F0Xswhci-2Fc!%|f2Qz?oEuy8j3M$%>-B@J? zVGhon?j|hnNYtkbSoKM6zU7*H68qDel9XKG2frNFF6I@rcWj`;87GXwmHy~}V}~^1 zQlr-9Mi17X^v>EB$ggcKx!%4|L%zw4izVLhw$Xz-EXGpq*gnTkuddO}_?!o}(Qiym z557r;TGm#1wfL`pIQWdrVV_Iz7TWum1>G8TmsyFctn96xK(f1f3>U^Pb-&nsIwgX^ zt`(T$3XB-HZJdzt_}!ME50P>0j48?cVPq_ z*IQ#65F%BfBIqFtS8toS0=t;Q2bEEJs$Zb@qldfBIX_VT>hG*`!4CF~Y7d|O4L9P1In~hRct&@pIT$GppPPW(z z8_8UI4?vDP<@I7ag%9MM@Pn;92b^L9^7f2YF00rjz5QPr+lXOK`?49!93DrMnS`;g zb&ne2c-8P*>hda0Wp;@(UdMB*=&_mU#cOq(DU@_2Jl^9Q1(Wv-S}{67sx(bYNXHur ztS@dGxRA?#8QO6nvJKj!1D&EiuOQ$0;VX$Y=0@pK$sT@_??|;QThBoru;87_<>M`S zSHA#^)PTYxF;F1qW2oL$?AC@Vi^pluShX5}L;#@;edfC7)Ijw4hNGgG#>0l&ekjYY zW3#{FQnTdj<@6|r4n#~zY`;87=;&TN%7L_FJhtx%DiwBQqA=7hOsDBiQuMMHrhY#3 zpEQYe8oxD(Rh47+Xh5{mvpr?bAJIU8{B_rRcF)v79S@s(BZZe8=!-X=%$NGP!u^|5 zplJyF!u_E*|K=S>Ef_jN$o+>RB<&+m+f<&@EBT_KHCt}8BKh#Er}gx*3_r72hZL3q zzF1Rr-`2`${d+3%v2=CYymL~JBv7p}Bz8!EgF7w5OV{fN>}iW$eaegq-iv795Y{yA zwipflm|CP$g-a3~W3iJF7%+vg^QWpf+3cGk2rnT@=0@V2TRX9)MiYX3J1tpS4K^Po zXelK8E9WHa7cW1wWJ#Vz&M0{kd7_a;bMm+*a4(#NFlFa5+;4teyUWZrxaP8mObjnE zzvs%qGCU5)TOJt>#jmxWoc64(+Pc2dl2hgc*>B2UR|bUu?X4p~;YYUy8$G8BsQkhO z0SLo@U&P!9%9HZZuPu=Bvu-TpdNQr7N{H9qSXv}V_9{4Z@i^PTPxdFe)FwEHlQ&cOzrN?Y*bM=v{dh^DLS^Bp{>=1d1nV(FL3gKh<&|Hr`+c1@ zl%&V5O_4)e7Bft=58oa*u9#}Asj|3qD(dx+WBuOHm3OEmtj|{Fd5(G+XMcM8cGUF< zuzsVa-f@TRjqP5TW?xqTw6-7~$^sz&mdg6Q_3i*$?{oE|Tf_hQDqA=*QY|qvtusJX z=UNyMOvRG_N$|Z7jC4?RK!7@Mnr+q|Ibif&opRv-Jq6fgKd=d-cChm)f~_(n7njuL>&f5nj6){#n2|8l)L) z6V_X`m!ghe4Emndq)HxWL$^&EH`i4(R);U*bSgw2f#*WRPmO# zg^DMDqU^oU6xeiOo`WnvM&8!jM-{Y!>kX}&7Q25?ZB`_PET%g!&B3IG3Jy>dUv!YE z0AM2&KKdvxYd3TEl5%e@1Ient4iD+}nopkRxQyBYUWSYA^Br=GM{>^bdKQ$dqO*q|#}I9coKAe#l=ZKo_v~w3 zgZrVchRb;DW5SM$ti0*3fQUm4D)4R1oRcfc>|3#UeBz2>6x?kW3mZ!BgVc}q4I|^( z>rinQq}lNFLeX(4ufb{UB&Rs}3a`1`G;;j}<~47;m{$w{K)M*^1<58GbN|tEWh2EQ z+w{D`QN<{OJvlJjG~Gw-*dk04zYIM1MQhb0>C+x=g7u#`*Z`t|eMI~@&Ii=P1_IvM z-Ubhng;wk;xh9E(c^)d&!e@<5GVL7;BZ>`jsPEt)P{XDx|{s0RNcV*ll~8P{@%eSS@=?IGE~oHx_W@LlrsB+80X@ z_h&EtppKu_TYvsk5cgRRYWoYqZs+_I?$$3z^5>8czp<06QO!Wxr!5Xv;tXi+hV2pl z1jV1`JLgs_qH7%{eI;alM8}#;l3N2GWcSwi(hp4}i@}wH5hjyQO!;7W4dVi-`KHAI zvI}c`&RaJobL^(fy6lO3a>}3%f}i8!-n$!f=rY%AURpCR+$HvxcNr82zj3%Sx;Fdv zJ;o_h*9|fEv-tY1Mklh&6;OHSTTfMpfX=4*P{pq~tsr@+AWOd`mPXf6HBbi-VWT2m zZDo;vuI8o1U&vmahO{-olV)G5Xc*+LkNxG zwwVl zM};+`?WY8Mie$!8!mh>hq$NYKV+YJes_i!sP~F#o%E3(X>8-lZ-87Kc=^BdBzAn(l zi{N|b+#*>RPIWV();_#dL zmw~hTG?CX$g3^lXF&T>0(-kY$FV(6oC!mAiAd$T&M+y8c!TAHBgO?Df#HBg)Ov$n= zZ3!ZjG;|>iy}ZVr6+hQYpVOT{CYsDxSPn^zh5MW8+Qyzc%8m6&RcR@*HOKh=%qcH$afzNG-fy(1b3|1Au z1idoZ$O0IUd$ESm1TVxWU1M(=f|6bh&yGW3%Qp>n%V zDwE%4^qeCL{%q!Y@i}Y$c*wj3^mw*Bz^BmLl4=`2D|ydqdIZ+>)fmJo8LlpA@qH9d zX?ncgn62)mRQ?!<5$4s;E;4L63#m3wG5B7j9cPjkJ~`-8IpZXt;WU@30B*7Vi+0dy zwe4KyQ`f0e2qzIG4Ub34ZLAJiP}s1o?(=YHkOnnRb#?|0uK%J4UhR=_x$B%<))^Ps znXJ#&-0n|W)~_UQW4-syRH1cUD60AQHbn!36mdkcGP^L*=XjX2)*h%ct+u%Y{KGr}VJshUR|Hnm=@m6qi`h6O|0 zW1J6o)R~#FWB+LvE3@;x52$HMFh>Lb1T8?J|9}=uk23cI0rr6x!VO|1fzp5MbzE`> zVj1@a`YVqVa4wI`T8?*T+gyW4GL~<^=h4r3_*1;=-Z%;m0d$%=f+X@sRbEv~k5rZW zHt*NI=IOCkn?OW0FLP5k(1~;keslkIS}>mvukzYMm=Mn5?{wuHJe(B>OY6xTfI@bm z>vksV+%{Y$f1@qQjEDQy3S-HLU1!_XPL2J!vp=kIEbJ{uaZXL26^%*WlMx0w>HeaJ z?;6CEWXn}`P0MYFspE;*oe^oTn4)2vv-6@){U>~CT|&|qS^BF2m>B5UN^8kMIQCr* zn=HO;uf5M&EU38&m|pjkUG-bBRY&La%k1+`5FPMu+wAp5Z05{xBdYam%nT%=b_i@mb!))9D&PjCn0kDYQIG_QA4h!VmUncM|gcxaSQx_ zmQ&`M1FJ*zTM=9Q%K~+BY}c9ufmhid$w{Y54p~QIx$+Hc#B3e8otpCowltb%oEzC7XTsH?y}b zfnHDAQGaO;X@EI9A&d4hr=41C)qiFF@P;iwK&|MZ$& z#!^!6k+e0QAi(;8HXCrH8^j85ymKcd`_G>};(xn$FnuS4ii>9NZpu039EuhdxJ$QAic5+It7WID^!u*TROKw*jlK!q4o%|P4@Qr;yWy=#Zc4P^x z1OTGGD=(}B;e|tggoty1dQrRmcXme}d4eT8bF1AG#~p0V z=<2uzZk~DD`CJ+;PhZ2F=Y5*;k4CGL90Z2c<6CpNlY_>$wk2X7Y!?^J zK(^w%NcS*??&yk(>@QR5U-H+lbZDj7oSu(-irs}y+KHHR+BnO={W{0@6=zj@4xU;x zV7*2K@%|nom1TWzuAp$0gHJ`Nv|xUUS$B`VR)_kstB20QZfX~MBY68&7VUxB;h?uw zKcjZbdlI%6O#rg8K)$+UBMdgh{{wzaT zHGi&3IcQm2jrwxR56U{-)?^Gm@H9yi^d8*fy9LZ=U2s;PIE%xBp?Q|Z3X0F<#oMOi zt5cTO`Z&jj(uG9YfW9%kx9&4}MfJnValOrdK55^axO|IvWxf7u;@6@@ExE6w1~$4k z5U+KnOkA#iG7K_U2^fb|)W2F!4>1dY7K4Z&%+^Fm) zq_EOK`XPEy92ddUF!p5rR`zKXLb?4g^h$P#CjP(*Qmj|3c#gz7J7J$%8Wt-gx?wX| zRZWveEY2efy>?6~8P)n1j*Z1nl+b#_F|iW&3uG+ah<4;w=TL+*yg!PoswBazYH&f>Zke-iQO>$petwdk2X789+xeOlZLy{UqNPp`tJuVh z<%+{`0h3PRosJUxlbhzxAo!aV7#+Arj8EX>Daqn>-vqET;`W$=M{HDCAA1RY#Z-(Z z$l|Lsm2nCC_7JH7V0O_kW*$=(^oP3Zhz5H|&=eqj_u^sQHAzv2Pc0g)d{LQQRj6q& zM0k(b)pp8Rk8c(fcz`a5#pq7a`a$VcAyk$|SV0Z_gk}PAGZ3U{pB#1|13(Yt6zW&{ zXYa96-MQ$j<~sqfwsbmcJLl!LdtdzS=g!gT>t6Bt0(Y&WtCgJYyC`W6a;9`WuiQU2 zeZ@!wQlYk~Dgr#JqHqpXW+H_0bRySY#wBK_I@eqZ6{d0zMP8=}NkEh>mvRKXOP|{`%UKWq(QjDlcdGn@fQU9T zm)8s>UI29=&SF}nq`pwTt@BUKtDp$Q70959lKNY53VKt-q z^op>O`jJ*1o@W;Dn?$swI#;h^s1#3GWh-kkP}96x%svM(E9V?mAe%vy#_}r6_jJNi zaSjt;Jm#T{dIrY+3cD5|`9=4OP8r6d9y7|L()SJV$4lNpTc1LxZ|~OV@Q{t9^|czQIZs_5M;>&FBsfwCLQQ z&sg7J{rZ&y)TLk%n*rDv7OGp9vkmrKK#+ZbFKXy&@wfvRTDpu_Fg z7ylDiF`dI>&-*Jj^(6$kzchqpJi)lyd#F|xVC$m8U8hVWhwf602#Sd^l5?0NoM7mJGNgf_PW}d%8QDO#Ks0!- z63Dkr}i#JKzAz? zO@TVZH+|rfO=&Hj`T11cbJk5CIi~}}5R^mK?D{^<&1}|Q`q-@U;}-kDIDKZfq96C+ z!RCTo3#~2)D{tF^$clAleImL)AgdG;j%9Uhll80Tsh_MqbnAG9U_-38o!>Dtt4)TT z7x!YzNX@H!pc1A)lCGRHCXgO#h|CTSulf%QRVBYRt&bSHCpVV_MwOrIQHWe2?Bntz^qQt%rq-6r zC%oOW($*#ugYg%NCj`ZN5H}Xb?R+L{_Do}riL1UWnsco>d~sqMU;YaAPEPJ_-F1X- z>nJ82`3iCL!g=^qq#9|ZxFVQr&ACywJ#bi z<}be_RoIDTZcEg_x_da2pm&R+%pFebL#GoF9fK9?PbNN>)VE$(%<7T~b`RQVF~p~% zAEt4tGGBCNhPH%_aIcW8EPN%zTs#uHjW%8zFeG4(p4rZBTjU+|L)n!=wE^=C(#H~S zd2F1J^iFFW-b9+?w7C&_Qn$gZQOm)oS11*?bnrZ+;Xon5b=M^U)vvm5zX~k7E9`{W z29-fzIh>~ZbOCmMWY6E%h26)DU3O&pVquOV-HTo)DFIi*@I9kqO zPpy~ivC)oJB?5>1qYIzUHd@1i{xX1Q@Z;z56K4fV2b=D z;i)R?!bI#~&ipR{qw<6}o;Xaj_|9qN3&WG<5{-qK>xy+^%cm8z)PzuF`X5y+qn2!3 zDOQz(WH<1sFj#f$N=2^=+xqe`X@)#{!p5yHlSiT0@ajh*E{S5Gokvyl-{|qz4#$(b z8d~x-1vxngLO{4Ue+f7NWoR7RB!azxxBH z1p#NF$KPBAZ}0jAZ-r$w-%C-D_u?-zGbWvGdSG#|xp?n3f=>@>qI+2$6kNmy$Dc}E zBX-K`X3V>+{iTX$y`61oht8}2Fm^a8ATN+RC{ghOBC#wR*Q69X$+B}FyG)*AzB`DHpeul39glur#9Sr{<)O6#^@ zc$uS9mV*Gp2AHOUe*_o3)n`&Q*s2TzxRulFh>`5qc<{tcEd`!8-r50ucMu(YToLts zHK8A@0-Nqj0V~8Nsrf;_@9(e_4*@v+rB@ zXs=5_kCn&ML+&brO(y-~Mj72-TDn3g0 zOPRb0UT)Tf+ppxbi8bpAZ|7Cs!-B1I$vD+xh3+5s1v_-a{*F~3IoY=^-CmYw_*rf%F4W z2_!Mr(s()fY%2}TgDgOg@MIR*5xlDr86k2kQ2STx&!r}yPM+y39-a`&{DjVOB` zP~(Xooyp=X9fbH$ycS${;^k@NnN%Lu6TdQVT#hB#>CYBW7!rvh);c0_qsL8Oz>>gf_Irqb`53^jdi)=9}KS*HUM`26k?f9DZ z=-?ZQd!vS1V2kDIWFMA|yG#W}vqg=?!Owm}fZ_e6u?}hs13~r%-CRu&DFM6kwl}`u zhF7JogAsC6%MkA4;$NQi#)IycIl56d3L-h1aGw5Hwy)x#gApKGY!?XPQC_SQ{-xG= zK?51CJW3V@jH;79)~Bw~E(oxR#RSyas4?-=l(iVBz%uC!yhZSd({$rwu5y9&e8B(M zn+85lj4pkXlP+|U12HjuCJ8&k`A|Eq!er2pc;KaT^szld^fN=$GcvCBvJjq;j0%VhA>Osr(H(;<0Th;+um0h(VQ9mw3Yxi7~YM`Z;Hgm8fR zucgMbzS}+p)Ry*t?w0y6aX_~DoueO%YRpp(s@+Jk+X#cKnwZW0n+G?E5$PwU9Z<|= z9i!0>5mgtbztoyiY>CN(joAlT;U&icnHr_;ig5>HvEqCG{!RAb{!IhVsUAHV$$`vE z$6^7_E(o3I9ya3xs>-DS;*ytw(WrhO(B(cmbw9P!%Qti}ty$HqiURLd@NJvT^Cy3X zTOCtN7MT^5K*4i!#C6n!-=0_CaI(hbktEMrl%~nz-80XNtlLGhoiibnlX<`PyZi)6uon6*gurRF%%B+%>UasT}!dd}T*7 zouAFNonk|a?nz0Zf$~C@fcRJ44=^?F8{+6eCX@cth2;{o7a0x(Zw02WD-XW}9^=+< zrnGF$N*C*7_<{YV1@mV=&4=aLwx4stJrMjTgDi$O+I3kh6h>i${SmuOem?5)bpaE< zAl_$pFU0(r;0sqd8{o7a2iPHaAqRku%(J9?;$WYDc8@!x!5D?~VB=)DTlbXmq;$euxzJclM^Fv{%j!)I?=sgjk{qv3>4)H!>#45J61FD+ zXLr4dWo_`>AxkkYBM~rbmtQSg{gb0v>!o9g;v!jrkTpfD0em})gkOzKgdsQL?~c`1 zJ&bcVCjh8c-A843pnqx5DrPy2^yaWpc5icN%yA?LAUdMI%P`YkNo1cGhvZJtBnjJb zx9FEOfg7M-!%ztfobggrH(lQOsG0B!;u#67C)EFw9Py9!M7`NWd1Snd)h~Bw@xPKK z8nyr_%@hDEZ2*}Fr}7kM@Uc*x{x0lCW=@5N`1W{TnhJU0Z3h3bN?f`KgMTh}YRPrQwr%4%xW z?)+b4FQBLY9((s+EIf(Cp;w5(obnAdAB;z~FtG6n38Qh9x2C?;r zMiPsmAz8_&w^t=HquYIk%*Aw7y|zYD5}KajzX$smmbx*-O#j(fAg19xe!JZls_I`@ zzZ5G18CufH=KD0D+O^hx#$YGsl7dW~sX8kMCeBrFCQ+BW-U=>axbb{Fxo#?$BmaxY zqV6}0kj_R&_o}jK28)&MkyTb(Z8rN#&6-OeAO5wk)+AaduB>?9a*}_wpdznnz(RM! zLgw~(@os7V*T%llY<7xy6;MmCN`AckP}tXomTOx8U;sGl(?}`4GSyGV+U8g*dc)%HXRMxB$% z;iw9jhkHA^2gv2+{bfJyEYRdt&Xdz*6Nw+ecOCfE$+6ndkVyMfTD9%4un28|#W9KB zZIX@L%MXGxuM_&BSmxixP_B%uu}k?MO5N`{_kSmK_WpfRhrZx{Qd~aD&C;;sUpI`|2Lgy70anQnMRkkAS)sB*NuegEA#qtv>aia+&Nb!5!X) zOBg(?Tj1OD{(jY1Rn{dB($hBk)kwbPya^awFwQZ=OMq{S=Uqzp;kRQsx)A*=r9P|n z1;7TpoKLp{5}d+*0*4uS{agOBM~$7!GM`5Lht$Y%S|=T`R+5kh)(6eL87Jcq*}x_& zUwfzp%-h;-6|;L!YR0E%ghVMEQ}tEVg>Fc?6y$r9o#Z*wFLADJ-<~2d+VnSng?3kB z%2H9wm=SkKSJihq=~&fc3_O+8Jw{r2&BM4_ zCXwwWrQQxQ0jjfup_xp~L&VE(5y@0du7NM@zy84G} zW?7Cx*Z5u*K5U8bV4q>#|Fm;d_oCtZp&D%3M%6*}jBl7v>7$Gp@qiWguOz-r=*mE& zUFcStuwEBm{aI38X4X-&eZSyd1uVhzAd z?%9$-vzxSbK;(^ZJ9^FsK7tT|C)&~fK~((5S^a|PrB*%3} z%268o(gymaEvuu@ORTv|w-u{tEq=zzzB!P5PKYhttwg6*27fh2A-vYQ#B=XXg^7 zqcLsPZf;Fsx$V-TuV>ouOsBYR{|_^pA&CuGp$x>01VGTNPSw`LrH+Md0Lhunqf zTEkg7FSr^7_wtyyeBxI)uN!ld3biO)H3AMyFovgrFT+^!u$_QQul^-zRHS2@hcSC2 zQvG=U*SD?;sgWjfsDR0L#eKdSq`U)q>b)(MX!*@bGEkR(D`;(p5j6 zQnWm|$ctNdQ*mtnl!crzi}^ao*R?--)Wgo&7f_3PEIEd#{&hh~whr5oE(_o?S1{|( zLVVM*?MxpHQdM|NrHAjbMjhU7MN#QC!M`74-@5`?HAgD}SPw~Uh{7F$+7p4~S0AC4 z$Bsio0l$pue;QE#Kda)u!+Puht6Gi2EV?fzXk58GIQ<`{5I%j`Cv-MYX(fZR1Sj+7 z;x9KpX#pj;0CW<6*Nx#4DzmsdBE{>}ut3rxX)gqw~Ftm!^q)w67o8IW^V` z`bGUhho@PZt9flUlj;=OB?dcln)lwk@)fUqTxbC_VXL?F4 zbqQnK8G%&Ey^%QndC3#w28xZp!hUA*2dXvtixSSiqS;w#>|BF&iYK(O;jQ`8)KvDv z#&-w9EhB_en)lqDZJ)@1PX?DpM!=2VHX{h_An?`{_9BNa67z%AYu|fftt(F}uofh{ z&(oH(JVFMwa%M064bXsqu)kF*;GDTZ$^iikn!AJ_@5|uZ>(_o7yf}Y{@4$L7(URL- ztiI)!OSn%lFW0?jNxXd_wlhFuDTWYzly>#G`tE`buLjd<;1j`MmuLCX@`n$*0z+a& z9nYQ*PB5>2ZK)|2jAfYfZNv?kMZN7JNVy9gk9j=`e6x399ZT_0tpA~6E3lkd^K3d& z0k(w4U3pPE^8w+*6Yk@jK%I>?8LqoJQg>J-bkSFdxhnZ?^A0%s=|;E>YJTy?t7Y>| zft+Y-Yc@U)sQIpU2f4{#(I(kPamvnh+A3ky+Xr%#n7O43v8eTom55MZ4fwOQN|G$6 zBYfEWRfFub9dHk=Pj{m%TBIV8zYfF6_C;fxZM{CM3O2Mvx+9X2Y$Xb$#~sfBD%z#R zvQ5B#WjRXU2fX2lD)hUEf9eg_JI>iwmRTpyYwpr^dgLSgyyW@{ax}&`qYp{G$T9vr zH*dhYC?jA_>_$yf66ycmW<&a+b#Q2ijAR9wy2~&Aj`ff{S|oOwty9CXx*}SJ;GpQO5A( zuaTLb%{&8!uX8eg3B2v2bA7 z>y%H5sx=PZ^YKNWq$i{eS3G<~pkkI9>rRX-Sun}LeJ@>rjq_GjSB%fz;g<`mJNQdv zjXk~O!JYG{nU!p&5WunN9#w(z;<6qp)pjLtyF^zwcI%+ywY$JN`CksrTZ&YgT#l1b z_QEWb6*}Oou`Sz1ZPOCeeYmnWLF2%f@U-KSf7unk5#_5@6Z7ys31MVdC|uEfZOFo{ zEBn*+$GL;;<;!1Y?sxOwfPKg6m6(>#>x#%`f5k_U;SUR$isLIP39daFu)mDL|MW!& zeJwgN)yFsX;rR8?pJFCg=DZQ&NOzqBxa^7102Qo4pBEm zsc{v!KRvcmJ-@m^y&?X0{H*+ZA#VdI``FA;m^pZ7yuc0Je7!6V|%QbR&cYS z%t|Jd;@nVQH;@x>j{2=FNRr32YuGMw&J)nKN5fGPc8$g_2dUmQzTYo z9x=Xhj8t{q0lGXWQros8{aIt1US=pt0q)(*3jv@l*}omt+NN#*D*};|As@>Idg}H8 zD+@5$uK%aWc9AZridnRL-Y%@t3{P(G`j?E*&2NCq22G8pTUL`XpeKMsGLH&$M0{}N zXQ@UqWAmhPUNTi!@+ zI8jo-qPjW*`ugc4@vNEs?A-Yn8GngR(Qi;_o^ar{xl(oJ7o!mZX$8~Kx2pJH%WC1t zd}Yd0B_ljzD8VL!d}?dUnJ=v$r}_6+kUURUb@J)>S}?xVT=use2F zBHjRQ7YAtwaBsIAJ<~X@_SSlsz~1;>J7BZ-aV0j76?e*CK*7ufACLc#`W1H$Ab>Q# z0lQ6d2X$7L50M#Q z?|e}om4myr&nJ{4w&qs%x#$R31rA7=CT}u*3|D5Rl>Fw^kN{+8)px*7{x#Dh%2L!a z-4Xm0{C4TKS@}=lr|@q>%Qxb^n2WFEoGx?JZr(1Uq1dq4=bcRRm)hhX(*W!^D z>4Hb;W^Eh<{neYqMzEA~hvQBB`|fQV)|+js7;wYu$GA;)^P3koSKjh+ULScASQ#Hk z(xU!2M*be2P&*W`L^ zV+@Ob*$sfAz#vQ%sEW(U;Jfc28=DxtTzl0XA)6nQpr=$fca4Qh2=E`{|0KzRGThF! z)!HNsgK74|t4)n_KXxz5=BC&bPs(kUv|q=>S&~f}e57}DO1BP~Jg`B+IUt?C#e+Yc zmZw%eBOk&z&u3=bSAXr~vYa2sPh_RL_dyaM=fSLg*MUp<(=jD2I=oA_*9|84)lHpw z11m}xU*ypfsy=x0vRJ#U=5Co}V7MH~K|o>hakAxH0(7SlqZ99DIN$>BQpd^puUB{b z2urZ4W)5X5=9mJ1aa_+uk+Q*yHTf+Y-W|XEreLp&JbrQ^^ITU7H6(PUO)5Xn(S&_9 z0MI3UgkEc-Nv-jCq8_;g2mAuCY^XcnyT#EH=}E5;gEG%I?hXE^uIu~HwG5cG#{ZTh zKD0?`CxT`znwfv-2P6B!)>r}|it{CIQ%-!Y@Wsm0&&r9zqF~nb2xi&$JlAO*2G7;f zysj(#;ie7PUj({8`^+y{E=795d4sXmjk)3gU2ZZef;Urx?5|9g5V1kb$Gg@pOUCby zu{2iscI&A@&%gz-XD79tsB%Xj76tZxAGdALp3JrJFH#YJJI@&~xHs&_Y8zA!@Zp0k zb6_K0Hnc!`6SAb~2?@dG>E5tdGw0+?lb&a1f zn~>#=2GE-!%~}3I9or1fWtpn$dADojcZ&uhK^-(U&6yKJ67WU?OeHNw8vdl;1usg2 zcS(SAj6A${&g4cU=-8~NpXK00k2OZWj4bMy*`*1;O#MS7GS0NeTIXyj;qyen5JU_5 za3%EMsp%bjEDP8JKNlt1fA7``Ou#%=a@Y)apU&!t{ZrCSJ6_;10IqptHGSy6+HDfc zo6#~}m20Llb2N@DLw1x-RtRrG+|uNgjsj|Bc5>fHs-u-=7YP-GhU){l(=kf*ay4CT z2sIL)Z_vUv#UDMD2%AitbA(1Tbp;6rj+u+=W_@*4j#N$9msVQcr^r6Hj}#cd@7N!x z!M4p5=PR?*{NxjahNT0y*YX3p#8Dv&O{SkK2V=wqG%i0qui1W@@BK!amt z9CVJjmjwtKsC`3pbv!!?EG}KM(&6U}Ae$+wvg+rSWLMHFPqSnhKpfYLE)>8TJNb`55gz_(kyEb)H#UWexR{t`|sc>|vE_<|H&{z=XUobAndX`+*BkrG_8 zfEwSi5P9$IWCu4duEM!t)!x|pxzMo>qP`VpOsG*IJ+Y@Q7VVXOvfGUxk z&Ohdm@GhLmz4)X8~C9 z(_Ni}!(4#Q7|pfliPQB?n{KeqQ=Kdc4$w}SwT`iE;YV=q2#eUu>!BtdcuZ~7mO!T~#X;1U!c8p+7$~iYhjwUV#-JGZ-)IcZ1C4- z9I^+6$9WO++5=e8Y-siUMx?P?#dVlhVr8$-C)f3fd|zH3u*`TwrKX5)cvtpQT-)++ ziCdgSZ>P_}WpnR#ZGlt_#=ZA3-uvKdSCJX^yCoI7>9Sp@svNW)WQmf9dLz9Ej{aq(?P#sIOc{4F3T z6Sgd|Uvw)2<;!g{Tp`H#qaqlzC8rF!!3oL?0uVJjxWkA5kkN~`8)k|}U{hsgrM5YL zymdPx$zyMzwG+2L^Gdj}LixN2p7D(1B0SjBXg8%e4jx!>gpIvbFVnQSPaX-!U2^I7 z+xnFS+m#!))P>rL26ZTfu+`q8l$Yk#o#wKko#QbHn=AhHbW_?u<4--?IsQ~f1Nfcw zdG}GAS+6nrI9P~mlAy8hJ<%#w8(yxidsdt{4)7PZ2JaHRW#*Z~4#ywko*tau5||85 z=+YFSeD;%bFS9o)wF9sGEWYcJ6q;XZJxy7>Ir0KxYi}xpNIU>hqb+cH-;c!R3|ftROTauwx+g z5gfa_fW>U={4W_Tzte(^Ks0Bm%w&hnnzBjVYg|9EKFcyN>Au-pHhA5J)?9jWdr$S3 zj}u{NS0EL~k5 z6JN>>KqLk_-m#Y+HQCe_iUpTk_cKn)47KQ0>}R$A^zdw1&G;oI*Gd#~+|AYU(&3cc zyiK~&2jz!KBXM~Nb^=@t#^xJeV>}M+Bz?gew4#eme zCAplAo(-s?vSL^JBlC?|i}wBZw`b=btutmXnQXF&V0TA_fr1_jf= zFUI4V_HA5`&gmwl>Yw~rOK8NS))+J^qPrK-2K@m3HkX>Nf&%biAIbuOF0wB9C&Sg> z#px_DoDT7JER`m+ZB?D4%TA*mCRUkUp7!-9HFBD=T+J|)?|A-x=egsBb+>I*9mz@# zVpM{^{ruL4@alG+2BL{$tIld)N~ zo#LBe?N}c`8>XnYjCM2(67OY=FD)vZZB~0}VpT#B6;^{Hg2CwK9@D-_&pK`RPS1qW zZ*wsX=s97iE zdS4dmH9hYxP+fhkac5l`N&u;N}Il}i3 zJMQxzWv9_bAV9%{+N43w;I_kbvY(30bw{D&Y{9*S0&|uT=>GTRu7~UK=DtTyq{lh| zO_;jaG*4|PvoE!2(Thvn%?X~zxzYiV(&$H=hD>=XesWx2<7ic-bRDpmuYtH^D^~93 zOu)FBei(3`+M0-YZ+nuzP)hIEb_c0c(a*Qq7NN`L-=pY&g>UZ5vSC+|+AFapwcEWB z=y(-f#Xf@&*{by7wq++JRsCFHTf0Yss%jq>x@?Po44d<6K&0pA1Z*w!8@R!F@TW>m zDfMlvh8k0z-8wNh9R;^rW7^Oam(jtv2ET4mxr37hKcu@OHb`1nIj&#PY+KwwXK$)# z{mv)KX_V6wlAQ2t9f@BF`+k9o4y`Pz^_o%hckcpcG&}oC%i@PFP2xt)o$^MwvC``d zRK7knU+>afK6A;6t~6|3|NU6)rA{Y*vSCd_p-RrK`E_jfgHow#M{qKCz)!MMze8nQ105MDk%g#~)`(EK&`ILH?>X7*p_E7G!A z2S2FZT-7oVbhl;WjnT;zk|FnNbfi&XeDTH5PffB&l!-_^juyDS0wVd&r6hvsO{(4_`4}?uSEjyXwq=1 zby>5TuK@AKIv$^XBDtDW-151!H2dW1?ThGf6?}`33T8Hx@H1jua_#m^q(f7-R>)uh z`TSaE0-Z{^p}7at?I<0=707|0j|0v82#nz_{_8Xte`z0o)H86IiT#X zoHV&tpS2-Zu&QrBo0pgxVkz_LtebbLdfhU2Zx%g+vN=I~$^V($TwLrjxb{Lu5~bK;<#u1p9Xc$q!Dw#l4lNa}be#tJ2z zn!eo7b9I1SuT1%SA#t0BT}Pu!oWPI$9G#4z<`5?@iT!O|IS~6PNWI2myim3d->Fx; zxUPNj)#ydVaaL^O)y4S=ZZ2LmT%>zPhjp3`SN#61)3!lLGTq8ux-IQQpnKguh<103 z&A;&rs0Phr)sx|;^a6@3Gpz>btS^O@9J24ic?aA?1nPXp+N@Ha7hi|CIyKC?$F_g< zl0+s~J}xHaKVEI%GuQ1lCOmFg&2~k*M;HD&(56NI3cBdJ@9l-wrX|pIvNX>8paPYo z>#Cr-@FP`*Ep?F5eg>VgYk2!U%(^!ChGy*XpKg&LOpzMM2%zV`$ODo=zwKWq^ZNiv zQ@HAT+tiroITfAMHOaNxO=;WpLT#B!}Mg+FMZDoKPBis#AKeZKB~;5x!-Mtdaua&eQ0e`vZH1g~>( zEiSE2h>5uz6FX%mKOuWoI9$Yhi z;l#LbPUQjLLv=qZvLh$H-VHIm*QO?$CrX>#)xKR{HMq+Zq+Q}N4*>&r(@3%gfy1+x zA#`tw)?1Aw+3i>Z4&5HYO~A0g(AshcB+%HhQJ1$XeG>M71e*0fOQ0142{iD3l|VyL zCpAhHo0-eKL9L5)nB~_(0D`dPAriV=dFXlmFXEuXjQMrz7q4MctRdznV8TGyFCoUE z5!3KUSln`q1(P*=d*>F!FTka|N+_fGQv<5~8z;(K7qQ2cnU2;jh4}s?jjJcv7!#k& z&GV&h+8a&BD=)n9aGTAjj8;&4Ys9k(6)7S;fK1+Km5eD~rUT9B;{ydY9iW&U%VpQq5QE;1umQ zo)H7Z#CW)-=cLp+uXrfp!1Y7Uu$%ih1>Ox4pilx-MV{{p&Z*gC{1|!+ymt@BQ2hRt zm~ssH^#Oc~I2`}mMH{IDSZayL33WjQHotf+?54+1i1{i!Vh`o9{1QG z&Ry>5!WOt9-c&ohxUy%oCYT(a^;NaWi$#&R*d^}fzE5n=sHoJS>h+yGLaa>a&_;*} z(7$naV_c^Z@Eh3oii#!o$Be?*ujSWzBqQOK{UT7=PQ<4p7pty1HDZORzeqU2eOTIW zepigISp}!IHX@J^DvMlok?`LxX^Xop%z()SstS29VuEh3>JDC!lQV3y8reCKBjyV^ zS-sn1T2}UN0+hCLfUa45s{_@PG{j0vK0QV>g%C=tYzS*d2)nFk%w7?KH8HLFb0HCU z{)>%t19UJA*nBfhg5LhJP4J`!xK=Y-+U>#!2YTs8vm6bVQUm_e222DEaDq^oBmcUq z^hp2^(n! zH^4D?(tFuhzoOkZt6Kz<-63*=CdlrE8*aC(41|fCm zHYejAWBb;i3qb}slk6K5VYa#nv^Nf<8Ws#ZDx>$IyI&;+aCs z*2Ib+#lT+Owg6r771+Y0Xep8Yo~N0ZeEl-vXj!11=oCi1;LqvZu%|389WgS#q+0u` z-J(3|R7}&N>|LzU9{+E-`=ON+H#9q;KU=R(MMug-z(hsoeWQ<%63|uLlm697*J@(^ z{W#ov@>^?;gkRf5%nX*BKwH6mIb7(N!7uMUGu`4&5E>|h1aI|36Lw^iS~?jV2%Q%` z%CS1ebS(~+#FS0@PSmbbKe+{N#adX2j;v;^!kDf!ljJ?{(Y6adS#5{y9^0{Eu6yRw zCXrubw(o;5TX)m*cK}hr*QEftv8BA=IxBO+PB%sZG7X*no8PQV2LieOv|IQ1 z=+_Pu4|6-GPA`X|9d>tU>U3pl32yLS2@sdGeOq&EvvWvq#f~a%+k%4^THJnjKvf_7 z3u=w>E->86(Vt(k4`cZ)GI^M$$JSH+gW$ zNH~j zCZFbyf$!hMZ89p-I53ty8Bo}mQ$v7QFmJIj2G_J;o^_~KS~+Gw__?VwJ+YBa@G-9| zCh}N6KkhLW@DNlgD9z2LOh86E#JjW`(x@ra74zLr?Pl-bit0i$ms#o!qHtY{_lSJqHc+6;uF#A6sxEYZwOP9F} zrh=S$pEE($m$cOQGNmG4cBy1(VPZvtHmW8|WLFGnk9V%TC9HZGKGV}U@}C6VbiH9E zu%M4vyrhB6$3VO-h46+0Yq}yHJMb7IEQ(qvl+IRG`s*_7A5uNY=~kuA(kzh4RVj$v&w({3^LKONeSfw2rVcNxL+eU%bm&fc38Zz~drnf<}{>!*t zYKcwe36bi5f)u0%6E=BuRgNs7WB*Cv?Wdaq266HKVtJc^JQ+ge-4cjR7y=8jsp-lU z0I1t+{&A(F^#R#jfI@>%Un2D_2iiLkt<~z_kp2&^+%iY4gN>!#Ib^5{rZ9n za^jboeq5oATwcerxONPvQRU|4WM0~vWaw%*sJbG&hm2gR#rMs4%Yk3#yy>GT9Jo)Q zM8r)EIFoNO0$11QSpRs)JA>_U*@jx-VdlJ74PuFrCHmBIRO*? z_3owuEj60H97~42NJUVYIy#u}@r~pW@L$XrNGrX(8DM&#E1o>je8z0*#m%$0w=I6b6#B8lfV($%^ohKj^@#6xEu*O4Z zjBnl}XiK+=r0H|(Nj)q3GqmU+!>V+q4d|5pBNiXx=1x_#@-6H;tujAFTDxL4A1(R8 z2(eSl^s-|fKh^ZLmVrDpZ!*HFT@5xbiCKtQmV`t`9ZrdEIM`Zk6#tU5Ed4He)pv*H zMNL@M_zkJ48f-b+|F0o6hxE~b|Eex0VS*%b2)kV*IFj%~n5~?lXP$HYFDGHPAEFiY z%T8eUNl#C4qF9PQN0dH;VY9$XSp@H2g>A(r_`=iKwLfz*D6l9$i}aK+1$1 zUs*eG6|lR_yskgW-SQ02e(~cC^R&KTSqvL9_H%1h?lN?qJeiD?ic}mB+(|5z@-E<( z9$%=Z+*T}}w-Sl!(j6SvRvige%)}q83N6yP=lJ)9Zk;pS|-Yvb0fT^r7nO z>55YCc0(Ijt<`K*yO6LG4rQ@oIlfp6gO% zPv6fAQaz$Mx935)e$E;oRxYDY@;G8M;eP%n3v3fD%fsw=#;m|JD>X%w&Lj5~P7RzP z<%`)S*mH&7M8zNMey-!#z;p; z0%}3T?b=)p9#nWmzVy|@$3HboYx4fg@%S^k)bj7f+*Z9$Rn7iACa6K>ATMiJnd^E5 z2Dw2%ELM)$v{VkxNH}JafuF}Jlki8G3Zxm5AbiS{HAlTzwG)aN>zPu{_FM2tJr;*! zOv2ICABS}_2RC>4cCvlc0zTv}Ds>Y-h1OARe#{eCh?lk8@UbE}Oc-Q6x zrjRc`8(VIaZHT7)7^~AL4BD$*JXndF58A=)@6fV0ars>>3YlEHn?8N?bpl_Y53h(u z{s6~mmX3Y~Fl~4ke6L?Z+;^sqjAIITcBLnrv&j{t2y0||=zb^wvJi7c!NGpcuu}yl z=X6irv8%fFv7WN4X}lh9ZM^u5Q=8SMkfaY=d>7ME#brAuQf{mryl-7s63rBT@80%o#pGdNer$gbs13`ImWe$qb+%NaO{N^1WQM}MgQcanxI z*S^<)a|PStFyynu9<#wpI*vl}ooMJxq+42#T*(e=d)}msrN*LnO=g^W9o@DIO^jNW zyA|xDkuwFu!S{}bH_1Al!{{)w2`UD$)+WXUx)U+jGPfE1i;MA_h6X4Kv8n;4UvS^o zuzUSD=O*~DiZ_l{WoxHdcWBGWaPFZ%Kfu)3X8=_1Cd=xEm?ys|NASp82UYTT=ygTzP9sA3XhWc%7 z_q`cKwuT+l#}`~H^;B2GQubq$&>6$?=8Y4>fpqiwx+_t&FX4}|Y2-j@XEd?T0(&|N z^15j*0^7xx+xZZwcK&kyo&2&37F~~gsnf==EX|q5G*rxFT9O8=j7RN8|YIpye1bne)PXDsRKxPM@M1pUj zXq!Kero@1fS(GAC?na^^5Xcswtuoho+aMZ$#|^9vwc1T)@31g$!CTf zQhy7wDz@X0(UkX1IrtPT%S>da5{ivBTuOggmb%}ke!oSKvn}|Ii5w)<5SbYSRxKBb zf|?)dj(C9AxlLQHpiks3C1GaNb9fc@XWPuTw@Vv=Q<^Y1eBrPd)OrYJ*!mWJyE{r<@@wCvx*3n<4bTL!zGsMAG4 zAi?k!7R??l5S9#`^Eu09eogLy* zTo~(xl1Z1h?4oQZ9cmLl)-4%zF@nzCOIlI+39P&JsR3BebDmM%HVm-{7q!z$Eb*>G zt?>ahFV|ja)RN`UP__!O>>G~Cawp#?@SPy$`UN2-%$AsW#fTbnT0LSQsaFY1tGZ02 zS>5&=ZDEGdvdJxn=3&Dzn^et)%`kIPW!=HQy-ZVYNNm*O`Tf(6=l&85_WtxMDQ0MPkq1Ni!kc-DNv7^* zBqTvwkel^l;Ipu+pr@(en{Rw+j zi57bNRcoTcCy5dD&O2l8bcM<97i!{;xRvwyd_Iq&uBZCIp$m7peD8{UAV+9u4|A{F zHbCawvoy*g6j#hmIlTzWFk1hcl+*EprHb90c7bZEN^`9m0V<>U}Y zKgI}x9`%ZXz$fQzoblu4k({9U>$_o8=bgdvoeRAUpgYY~Bqq@DnO3^WNxV51h+;Gl zN7ub}Kd<$ST@rdw)`gSVh*~8V!EwzE`{^*C<1WeP{fD_|CXLqfoT`CriS4Vr0j46o zgzZ}f8DUWOeaXn>^oH3eyQKP#bB@SAh!@&3`6BP=^nBPVoPb5ka+5nFt-ZD-Bfj6G zUCj2AbPIf^@*xgF~&X$LzIB)l9PNjpGmv6_d&5YCFpz|msNYY5O%}ae2?ax zE4f||o^v^~bt=5S|D--)wvQMvu8aHNJ8X`5ja$^Y9g-Cgl>?)i)gU6svuQR7yM7Ek*LQ9RJVU}lcFEg-d#jf8?J6I z#`2zGWo(@IdkbqzrX@4Xr#-=LaoB%b)bN0E5Aw+$ixJD^#343&5-GBF5(2EJo|f=y z%)hm3Bhhw^!wGhsxmjM50diP@j!GtmJxz72KzyKFJh|L#EDKD`=byde_=d|Z&Png> zWWWtj#-X0I_j@^5#~}5Z?w(^-MgExU08D?e0wwGayt5u`uAPe93;KL^n{!V>`R; z)1oS zI_p&}+Fn2iq;)toszvoAo{jbvO$k5d`7^W>qJT2eO3?yo0(vgPM`sA;oSsM=PdF!= zirw2#4w|el_MC+JI@4|H+hvfV!u^iz3WgRJ1HKZw*l#n95mo7OUSdK^U0*LOu%~kF zJ`;BGdXwe-g~j{zgGya|-M5ho*c)FmuuxYBf3;F9R*$c*Fpq~ZA`UOutFZ_Xz6Gb3^Xt_E3N3tLz0D(2X=1kJBL4NB~ID7AQR zYnPEr;HblxslsHVmd`ZCtK_hWk#b@E;9ywSW`#+SR&E%O7Vg>L>?huFPmj%sAZ zlnzc20~iyQ&qK3NqCJ4;1F(iAvyhfbH7uQ%0KNOJ2!S^6t?e4 z=oAK2PO{WbTp92kjn zXZn;mS3{tl7BUr`SSasNl|#4Y#!ZQ!tKD5%#cht-#7f~)o{L+`qe@XD_#wsRg*=eE zFE?7m|4lyD!PfWA!;$QxrpNi@Ne7LioXvM8HhYduv}T4(U@Wi~?91=ZB+lvWe?Hcr znSg8$|DZ|^nJgV)mCuWWA1yoyob^?ZUZ0@`=p>*vDNUs~n;oPe=zTJFFnRverfAuU z$Uu>9E#Vm~7&CLD8H{q%7~DKOp)CFWF1N2<>gw~-lRu$j2{8hi(DKI9>UKD$5CQ&~ zMq|of8JtSzu0--(UpGtye~1xD3|79;J*A0s+iJTW34T4oLyVF_zGDv#1ZxsSQyTrs zTgMAo?yOZk)%r3U>r+zH%kK=UWeF-wlpUGF@{vpAy1rb3H&=#`V+0?)BVX8hETaHf z(3kOen_8!IJptU=F;VPgm;uLHoh52*B*I>0rwB*2yDMaW_D*8jVBfl=F&9Vhu3t}E z{Mz+epgzkocdR<51nU&+-bOY_{fkT}&;E|TE5>#kB>8geC@6*P-F znGDuLgqt4%m=}>_&=nhHP#Rto#P2mMGE$ImYy_wT-kK)OOtYKO1it(hhC3dQ$et~< zi=YdwTF!@BAv-V*u7=iM94-*dPi(RUeEW)&Fi`sV5u$_TtTN6(&yxA?%*ZQU%;&J! zYQHeSDr@5d$-AL<*2_IgPA6k;B2w{Mke$}Fe2B8&#vlyTr*dKby#u&$;!3}Qoi@=< zpZmy|Tp4HwFB*1vR{AvNo|F5y94Gq2JEQ{|^Rqp(YslN8g^aKJ$rAm6Q7%n4W2z*z z>FQ5xj)rUpqX=ogaSjYWqsDX&rf!olvXvNLfs|s+cuL9ITQnIU)Qs z*Nbfn^q}?xk1!=RcksiXPKt`OO4L9tr4P5ciS}WV+`i72LpwN;@231=fjFj;th$uF zMRNY#DO1-XhaCu;?{PVf=1gvu%eI(%Tp(n$)SyWR2oz$MQX8=|=NkiCth@fdSbGzH zsQ15p{B0d&PuUq!)KMWBgc+r%Q>dI1MFw+9_AS|l8I*l#wKOtHk)vV`g~E(&h8R;3 zl6{ydON_D1j4|_jcRs)0eczw&_k7O%xqpxQFPO*UIj{F~xt`Z`J&_thBjJ9PJt@@IxMRX#!~|p$E|eo?TVw)$m=`_t`F<+y1Ehv$HJDrp&ck*>|Cw9UCDVh%g>7 zkg^OTpZzX$(<=jr2&x%H-udnWt3Cc;1p{eE{0*!k2FB71- zM&Qvhq(p&kG+;YvDC9?B9U(8p#i^WNpm`Wmb~c}I{5^OFbFYcS+7YlL4`$yIkN*( zObedQ^^`WG#hxx%6V|+J*4m-DS`)eVQ~O}_{V67-az}5u-9fv4PvDt`wDg5=)x;2y zdF(Yl#UgSGVBiA z)NHLSZ;P64N-}}avKn94--(fZcH!>O4G6O^*ItE{<(*Yf!|C$Y%++F;W8gYExkHbg zHR6_+8;XWBo!wU-(IJ*j@Q^O&bR)HHkAA@yj2zOFd#u9sart}jO`ZGuH}z-c+W+rl zu7rM;Fk5K#8@9*sxZoYhhkixj`q=a3+^ww)st&%WUrAn^0XfR6cG2tA9NTxUP8G%> zeb^hat45{B55C8Ob7X=KK0zb2XiNAfk{^amk76tEe^iC~^#<_XSt##ge?SdnL2HCA z?x^-Ynrig>g)+h3PAV&-=Bn33m?o`8-+XQtBzm?}z4ZyQT5kFed6dyJ)_%_O)gm5t z&`@t!#MY})ktIXP4SOMp!JUR>xL@@31{x4x(%NO zQs*4;e+-fC#Mu%Je!(`A)RGTrldZp85aXhYpJXQtuN*K5tr=?#;O?M#EbH{-<72y$ zy*ZU;OV2tRr+u8>PoF&qr~8TBwO?H;n5h(IncCV&vm^9m@i2Dv#hvb{Qp+^LYd>0% zB_gJU^=efI&)F*no`YX9mCHXYab4<^2J(t$WimuB{)P&?N>-b@Tv0RF+LjziuzX4S z`4I_iYpi%z=Xo-4$$cQ8iRl<0u6uFcRGI;H9`w8mAHITA#lNKrwz(DRtPk?7bb9e8 za4!Zwy`UG}r?vbYs>1x0m4xv9w;t9AOE@SXT&;3@WNV|~7VH+r;u?y5>$A5T+cP^Z zcf~s5tift|=a8ED63ZmS*wj2`y3TDmUv&x{0z;3L6nm#dpxSZgJ7VbSBiE9N{r2Xc z+y8J%H^Id2PBqKr1h<2Hned#5Q3gheCuJ1jEu5ys)b1#?30qH7ci8n*9vA5cy^m6j zJFOO%QP!ZZF#UV)hlsnmK}r^VSz62?@%Z1j$c1u$HNcQRf-B|lXM~^@K0XPC8sfD- z{*Vj-j5^B`QZR?5(n!VDGmum}bc+bdSLP>h0LXYaCZWKOM0?D15=BVaM1eHvF+sP1 z<-qR0+U|(i8hZ{U>>HD~6=Ipjp|a}oks_qSNhS$S_vYN#j_U#oBArllCbal^NFbXZG@vxJq$%*BP zo%8o`KEu!QQDw4cWrNo= zJ9(^}=a*bM@>~`{kH}$Ict^-xy-+u;V@tJk@qK8i?~aSTVH!30XsiOp*wUKBwV+jV zcf_BAGqc19Ce)YK7RUY%K>U+kY4stj37^Ub5&!4#PDCk_!; zEy($odohN1y=UBEgO8rlMg%ZlDdPV{r)ASl+|Dm9*n~3&`&1gwgob-f<|!kc@!#3n zQ#b6#NLif5s%QLS;V)g)4-pww!hhNRYdY^7%RRe)d4O3ha}D-deG$WrD$zL*J$6Q$ zf%qwH>YJ&Y1wTXz$Zad1xN=K6rgwAu$nzy!5V_@PGp8;w%{0&KeR9!V5Nl3@nn*so zsyY?=U^F=RGt@mhttx0qO&(o>TubWZbKd)l{)}gJBpjwF(BKg-ruFh-y8zGap zOu^A*1+2so_dpqJ?qv_%W2`M6&DYu+KU1u`y6Xdc%|Jg%HSh)Ca92v+t^Op4#MrpC-CR z?{Qc{hy0OZ#O;IbRh8>G5d(0C^{$F#(wx7?aMLO)OItX`igT}OVr*Cddknz=vO{_- z#N!j9=-1p}VjG$7*>n~iA{YkE7}%RE5E)VLOyQ%KMA2;gHDgoIIxWqq^aP#tVa zZNrBXRI;@KHqZH?@N!AGcb$g2rj)8Vmt6&UA8g)m0$5Co?ryVCc-P#Y(ZqdV~ZK(gKxmd~B`Pe60sbx6JrG~7Ci}ep4*il|~`T~9Ly;Ica zpIg2PjpLgub?)TG$269}R!xlq?}I${<%udWJ`ix5xOJ&g_$Yey5?~UB7z4?<+bZx+ z2yi9@P;B_-P|AlN-(0x22#};pT0jNX!eT!G4Ofz6;~ACYGK zaEIGX^RlaB`xQFQnI;m%vJ6%(2Cf{Fa>+$&>N;JL7e8ZSLatE`@G{-+Zc!ya_e8Ro zKm8aoCkdaB4tYZ+iS=3sGtym1Qsj@4W7odiLXywwElqCbTYGVes{LGpD^qpg;N!qk zrMX@5fz6j)XqNAiHEQ?z!g!xz)AfiQ7pYfJ{8L5O+b)Lio*kyUd~O7>_g$hO6>iPV zUpIR&Ks3*TH)TtFkj&X0YlWG6Xl9cW5I4(ycLfm_?>8rkqkSPN${#7s z>)_vS%pWdHjb*KvsE?6bG^X0O;%i}Y;qU|I?b8*4c3Jo= zbZ6H7$m%b8MiMvACEvX`r0J_oIq2P1$#=ma1d?R|&2Htpj#1QqX?y~X3({GpAxl?@j zeYpD4=*My~EK(&g)gP@CM9(#uoKywJx-8qaS~Vdc_rxseA%XjAJQ=T$Y@D^%TcM_k z3KyAzbSU1^qFlcP;2RoY{pg<1KGpX0vuE_ehSHBn(=3*HQ0P4L4o%jU{pn}#NH_ZR zL=yBa%1m3r9$}~zu!alJk=;4JkiWToii?U?B`uqaU!}>bj}mY7Xm!nDm?Xn_lqY$}q{ zFggjBYB6HbStFce2d!a_T{)GLx_9XeIM4xGTTemlF8OGlASaqSP15f?*sZTEsp%y` zvzYG(0sB|J*=TEQ&DE*tqsrC`Br|=fL>m7oW!_hI=()Tyr@#;$o__W>^Y|QJne>YM z##1>X|3hrwg#?G6{y@$8)2Hn)yCc3E@g3tkq3>q5&>wh zwB0af@%-9P@R;pn_a^0#wF-IGL<;7mOGLB+7S<9#ZJgG%wP6KqR52!64pX{Z#@hP~ zbLoVG5-@%QpV&#+KRc)7U0CH$8C`z@R;A|uzABB{?IXNkwVi8FYvQ^8Q+k=}`%#u0 zCjTr;^EL^q_s@f(?{)i7m(CDf7j&@s3|nkZNa&HGcU3a`%-_%0V$Evo!@I4-fhC6e zR-4fEQ<}XM!6nEq6E)u}B&UWZ(^I!k>!t9m-LRg)jUq5@*huDRy@8xD!`Ai)O)Bty ziF=XBTJPb|2MMCuj(Kj!mLJcUdG0Gpp~k3KPVbawkxR#Kpe%jZ@#-Nx@wx%fu&@HV zu^W~}-=42;Hv1$tWacDj{DJ6p|~y^9l#oSp*-bOmTu!G zOM9{?v?o!)S?0P=tRZ|ByJNrdhily-*N=TN(9l>+L!*uD&u;o9Tt*Uh%fV4awr!2(ZRLN$7_GNm4UARqb99$KDqJ&HihrTb8%O#vBTL5XdT;wyFx-; zFiL;K4k{;1aC`;R?KUsi8aRmp@ za0_DEdBda;m6cNcIMK;*J|S}_q=wM4P`IL!9VwDb?2V_Sg0&wQ~BY%BM7gqex|A(Hk!&@5@?at6jY8o+)g z@(h6!;I>I##5fb2uu5}H3(>n(uI__5>vG&ue$#xQ!NTTEfBE_i`go?T*vla2$;|zY zZHP8zwl!DHA$SdIA6q*__+>(kk96^(H^(lr(O?*UrnKvS+QKHqEhtBgXCB3{ZH!+fvZEKjaLXTXN zpS|c~nM;?n~$LldS^AZQ&92c4QD;1OLoMm8eAH1Avl z32EG37-8+zX7i{e++P(i;AYJ$ZNbSbGAdqb z)?_W|p`lqrzchrSNXIco@;l^%wLavk<9O4g6nIkG;hxg?b~n7DJ9=p3t5TfEz%}sz zQ>Wmq{x+pX<09Dj!=CF|od_w8q3{FORYc$8gPTB-^gs+yWvxfr1vLdCQcYbrwE;ra7)cZuAqP)RbDAbwrJG!Y}};Ba@sH`o4-G zBGUR&_F0%y-*LAVN8Y-t?(y+suUjRJGPhS!65Ok$mzBorIB6fp#e+js+k>8>#y5Xt z279a=Kh8L#TKXj0LBeb|YT~R*H0M@W`#D-9cSt&T%@-O9ce*R)J0+>58bGq~PE)KT zoDV3bpjAoM1CI}VM@IvxCR=+N4#4=&;+Fjg+Ed1n`wQDVN0y9M)AjOIwYd>C)4Bpz zUiKcJRVBYqP1O#pv(4s>tLR<|bKQ6{FUsDg5?FxsdPk1yKhQW#Q(PUATyg z@|sdQRiDJM&dd7RIwbwn1gh2J^Ss?vGpGn8>Jz#5PNbXs<$MBkj?ui-5dWb1c5tML z$}UHedr|YMXu>YJ!s@tP`3+fT@qGD)t}2#ZcsjHY;;w2&Q0aeCj5WOe$XDh|m(F=J zHWG^{T{HDR3AV6zFbYeqg4cajqS!kA5!>y&=%OTu2wFsYgFW$9Bri&&WN7&SFg^1Y zG{Rqz!={a^6Az2x3_)6fxVF4#wAvRD(rx+N&S)5kcMfrTkA`MDha=rlv2(wqCd~9B zI6Yg{pcsIQ$Ki(d#2HlPD=+pNh3=s&d`Ej?udEf@IBohj89Ls~{C&nL-%&MMvf@x{ z@9L?dur6t|t?zh$xo4qt{mi{6iCcB;T@IHxT@ZW6BYS$u8q-tVJ?SxYr(n-I%kQ}O zwemwwU;6v56i-o$P5O`Idu44)gedvc7Uo-itD_30Ow+@@e)|R?go0p4dfT@h0_2K{ zxJzlmt#k2pb>zC2Q46eK&}{%MJMyoGofR~#`q;~bjk|9KLjwNm#w#H{mhaxiB@sJJ zB1Y~sQL36hx~~c)5ZM~>+h=5>G~p2QyNxboG~6r?BB4gf`{|iMApdT1;;vlvZ5fc+ zR%fT-=+7$fIn$IgXPk$2lu4eSGgc?MX7#hD0NV~$*{kz5VywK*u~{jm1KT{rr%A|FMB zIQgQ3rq>x_kHB;p?|llBIXvWfTpIv3_;vi(YX^WKaOic5*?t%SuCI;&8Q%cFPX!}} z1$_ciOSJ*blQ^LyaN1f1Tx|uS4^#;PYI0TcVBw`XswpyYFInQDdF_6B_lmgpH?HVe zpt{=Br{9W|7=@B`q>Ew8k632<{+()0&{pP=0XGV|ArS@BcKIJ0}N<|0* zC3xT0ikNKnLo8-zS}-4WoMrA?OiIp_k)s^#^59gk-XW;F6Y{>mR=f1lRiA2V8~1qp zyvz^U*kw$iXYEd*!UG>%5Rs_m4jxY=t1LLi^18qyh) z8sDC1JCWRI+QNXxdu6Bc{OY2lLQ7A%7WEHtYJ!IWmm0kP)9k~?q0DSVT>nUxinhtx zlVV0u#Y7Q`jSr6)h*qQ&_8pSjHi56dJpwiauTkGj>sWf~Yu*E3m6V39P8(k@GZ8As zW#l*bewtrR8vSNk?Hl?u1|T6JKQeqBe+~SLC#?URT?Mj$-}e@-9Po3qG|<8M9iuJU zzH(m-i=VPHSUTgUf$3*j0mEdWYQ4t-QuJVsr$c{+HSnkX@OEGxotA+JYmZw zR786s+dI2lJN?8?_liiOJrNYss;SIu?GxQayHkLLm>Rt5tggDBSb%y%X0~O^73j}x zOj(3d;wv}$40O-2`SzeNp5p$hWmCBX@|7YJ-uB@@Q|}&-FGkOW-AwRup}EyC6HfRG z8Y__K2|s#b^~!OX*Rzh#An*JfC#sc&2N69k9+p!2lEOeuHHzN-u%CIHJ221D)D)FQ zGNuD#F$8a(LzU6)sWMXIqivFnW^Cu z%j1<8LyP!O*WjgDGrJwuc%fK;1u>MF4i<)`5_$~A3UpOFqsd2Ge2Ot z-w8uLh=)g4>m}T>oYoEhLw;yUk7O}pB-~=LR`^Z1^1GTGDgH(;{LfSmbF&C(f~Rz* zZvUhk65mq?Z@&D%$YzEC#zw|F7I#0}{qM~Zv2%jo z4L2`t66bR#?6t(lu;wj^Kw4u(2t0JNyQPp~1rMA&sv*3oGJUk#^tUYQfk}PXLadI? z_m6X^TiuQKB#cpnPq}r z(Sw6j4Z#(2cr!yYZGV{f=eyfF6LFf8<-_RhBGhKK#l*pom>qakpLZR42Y#!OYsjPt ziO?5LWR;DT>jL5mB0~p$RvAeYSSHoH+k?0K)t>FZeWkMCPQwJr)xpc_;0Z5d?$^P` z7UR&7FRo(7=?&L0y@YqKcv@3Pxr9aegr$_^i_07%;9`1NjPS$rwa6EXDz9AsvfMvw z{x9VoOakAaPX)+jVR6XF?RH$0;OvpHp$NTm!3wq+KXTcM83H518A(o`A_^@}U z$Oi~{ZQ9PPJMoRfy zWdKtIkQZHk2w02Twwfz|XY@R^PI8@qeh>lw3X}v1%E7|m^{v$H&srdd9aknUPXR#w z2LBUA*#TY#JuKeo_}XWrhYkRz6i#W5tM;YzW?P$a)Y|x+PeW}g8s6-1pPIO0?YVpr zT+k&BUFIqV=c%5ipxdDKdt*-_2y&g>U{$$pZGQRRrW7$zX`KsTjrI-Z{u#F&`QHnhl(xmJ}fb4 z=VVGL#O%+P^0}~x+H*dVE-J=6*z2LWwdC~N7R+m8 zHI6zoZ(8?Bl=(i~lkwn`=7=7QdEZdReb_=*-rf0X|B2vZVD{SENmKRD#HrK05ySno z&XXdGYKY6A%rQipbyohzd3U=-rf)VrK1>+&wN~jG=dni3~#@H}RY`%$9$R8}cP?#afhY zg!2o4Nd=_#d8WelXWyPlgO5;{DW=zB+bt<#B)sz^N-Pu-;LTo zM=x5Ge~Y;GH%cqEP22zQ<27{Vz2f87DT$&JWnQgv1i#>OS41?~;|ddHdEe976+wR} zSa;k@9o;>9&;h6DFSu=+`)VX6B3E-+wJk6BB?9%-xiUBU$p>XG(Q8pO_H-mxy6#@3W(woGR7pZ zE1gsU#O>C|jkb1Uy`c8+wq7K}i@)WS&i)i2=-C!reDH~U3&v56GnJ-9D{KIz{@T>^ zau9e!IgImJX};>R4ES#^&mQ;3S<6pxBKwdwgTAq+Vrzm zm0ng&ndYgAFiOk#{b^=$unlR5||-HjqJ<-;O8D(Jo)RLQ;+afOQva!_;u;4 zhZ4VJRiQ_vT{qUpoZ0ur;+kjOU*)!JzI(b!YS@a*2brW-{tqT;(=m|ax9i{G`2F+O zx>-6c^K2oj0D^3lvxT z;I(3j`Ja7H4~4zli_{!I=;l5!nf2{Q+sl3nF*zT|(iQ6HfRTmZQXI zR~>&x97=g*p)d9Q&MA#M4ez_(ig}q{%2k@`do**vBzy>WY^c2kGH)t}_E911mUk5^ z%BbwU;kdC4f@CQN#AKZX9A=+Ka#c3neFYO62TGV zOUDT-U32i##c6Mh9grSmm!zd1$T;NL?JZDDl`tFNv=h=@7cSI+0;dRz*ISId@t=;; zGR))x>=+M}t~X>seUXRR*a~e+HC#Y5fI5x#=XJG2g$-vsoReoId1i&tji{@OxA~$U6qSxTkP%_iCH+z~rZq#q7~=|dP`K_IVM!^g^Y}vZJfi z*qLszC;_6D8D}%g5!3nH62(%-LWV2?wViaEho!PdwS-kpj+ktO2Ou8>WU8b8`TF&2$-Y)qye&0MgD zD$7~XTGY14E1K3V&)#qRTK;yEVq76*$O4Kz?lbFn$%NN)d0vg%pQS}0gdDDqlpTIP zdd+Hkv>J=rTRJc!V%xr$Mf4Nw z02G$maHyHZ9UKwheP5+;Xr8HGbcBy}bU#eo=~Lrub84!##d!lO(i#FAkcX9!`gP@2 z2wUH;lwW|rKc?Up_hExQfZ9juIaK(ZiKL$iwpNYekMB@Ttf7KujoCoUwbgq`27xpG0$D2(tD*A`tD8rc~_+gQ?0$pm1%$1;@f?4YwMEctgALrD|pah&>k)P-xPKuBwv$X42?^ zpulXq2W!&)HhQ^c__L|4VnCq09_ZEIoe;I}M>8W-H#QdJ#J|(R0%Q1uo90%k1y}Q%o<4Q_(79Z%M=c~##iGW-mV_p4?maC#*3Fx!yRzV}r8v`64b z0C@KW8F5i2GY9<=#U|t|b#3&zvgGR@PnhI-%-G*U3^-`EJ~|}lIf>saC;n85+&tKq z@EiKx;?26wDzmzmt^s{(ydQWXm^CZ^K5KeD0kdZA|DUWG)jWH`%1Ou_&lwrI(}q-= zkW9rrG`%#w6L@SKoMxc8Rp*{Y2m_p>$=@ZBDP?_T3$BHP`o<ZW!Np6Da63vm7I` z5Kor9074D%t31Md^nKS(;TGJcm`ulSdiOj6IbBrQ1D2-6P1vv|6*T!yCO=x%0Mc4F zYFhP4#1i$k%3e#!c3gr@R7Q-QyeHKUX55d0-!%Cdl)CT@pvU@k z$cUl*up4E_B%>LndsCMllydfrTLs_3oDZLi_3fC9j$c1wxq)7^Fqr#Sy<{qf9)q~M zxin?#A0NZtiar0>Z>;oCW&EW%5bFOoXa9fHwm<(R!2@A3BAL2d30T$=9pN+debXgi z-N=pmiD_FPq9Z+f4cNEm!lo!$m}7FwAK`;W5U;9scSkQ(J#+eOUB8_Z{a9_mO6p3w zNtF+!Z40WXsQ=mOLDa~KDcJ)Y4piGBtR-IKj^Nx+Xp8fK7^L70rfhRRF!Tf4J-)Ff zhXuJxUjZEj4@#{GpZQy?vKy8DwoYA4R5jiw^{@fHQUuOY5e2_}qG)N)_D6RQ*G*p;{y7{$tsb z+Gexno^5#+#*B0IpVuum9}GsP^~AKVUKd;uYb%d#b%NU_ToDYy_(tE(&**^ zywnb(6WM<@9a>RD%D6V7s(w9s?Rymb%Md>{C4PnB@FwDaYX|cKl=&}z%ow|H-4`RL zaZI7%LwA&vPN%F3Td)3XvFO|Wn@UHXcX)qE1R@BVSrz0{-)~oa#dDvFbTtpH*hR3Z z+Ru-V&YI2l=T{XvJoBW#PwiRF9Wu*wcI-U~(&y{HQie`_swQ?k0#LMPt1<`)*xC|n zVRB2Aio;TfNV~J3xHI0m6Fk4Qa&U%>u@tur7T5s07&`$cIgTL!svvpG=D^adbu?=W zvX+%fKG$*M3_3cUWRJgto6kD_gld5t9W+1oHOol7VZwJFunYSvqG|FS{gW>%k$w0* zQ>3MV`fH1YTV~Q>>0Z}GwdCI})n1XExzfRx$6n=P@^K zJe;~*gIpq8jV}p>m^(MBq`&;qznSqtyTgGyfA(@@!hXrPx!651Yu{E!5qfPgixy>_ zsk=YvF2?tcuk-V67H2QUS%)+U8&7A(&e1PfHD7*QLwG$lxD4(}*`h9!o=N_<12z)Q z#{Q)qQJ()V+K9@WTDlD~=Hs-m5b*_eZDgNw>Y9T@!xk!ad)ml8wk@`Ksvl(XIXC#d zh;CDG5DPbidFRh*Buu@)d|5F~HB&7uLukPnlEtrm4B~T47A2Z0a)*Y@wF-?kb~D#R zzKkjx;7$Ak9q4LrL$oA+;GrqxN2gEhB>lm4m~wbdo&%ASeWC^so(6Cg z%5}n`rH>SCZnbS*7K+GhHQz8cDe9DsAuEu~kG(wJ94n7gz5E%i2h-|o(^1iY!|#d( za`iBz2I($~rP@S@@WIY&m10=fFKs3lW_FJG0DgK#6nl+3+)VqiK*NN0o642ug9Vnp zsy-`w-vz~oz7x$d`ME=nF+L6vEb{Zue1R*z?rfN=-(b#r&4Df?w5aijs_eM<^(vd< zrj1K+@Y2<;b+f;Nxf*}S=r8}hjQ;;Zx(uCT4~=tw*IS6DxfZX0v|pvTy}`fNH!yPU zYy8Cfm=y&wTI(6c>uLFKE7U^Fs=r-|9)Zz!Byd%|=sG#7<_o6|7!OmzZ`lTiW6d`1 z4f4~DQ&Kw^SMV`L5o6NEE zMfjbi&lU#r2jw#}8mIT8Rn@G5IGFFmZKuJ6W&19wMTJ|6Hu}!}zRuC0yW)`{jUhpT zCRT8EO>tG?-{{yFO~=9_=Wsay5SDWG=%B8TmwOk^AoM zcNS)imbm4kUtfYiF42XL8v#Bt%l1iBj9habnt4~nON(y%!pLpN%%$2ijL5kVOO#h{ z)cfS~Q2hn|XQ8(#j@GR0J?Rf{n|iP{qi4?AW~hEznhg|wtWOaQA%z3LJlkk9zC20< z`$MN;JUhbIJBbmSSZ_zVgC!$EGFK?6VCN3{nv4UTvIxu$+i?z{EVm^{L)B z&xkA7cx$u_*Jx$u^Nz+0GsH5sj{T+a~_Hlr@tt z5UhoW9GM31-r6`Xgot2iV%S_AurPG~5G$A`EZ-Lc?x5g6^p?}6Or?=&yJdxmEt(0v zsUjKsae)(l>`{?Fy2`UzOnF%IZp`ZjPqk!x%zJbtVsJmb=XfBi;ZdsdK9sM;d59Z1 z)9FC&Y5)12V)KoN)7&HY%2TqBoE2XZd#i@F%9y+4S#CgVKLk3!&%r@f*ejQSqG99`UaNj!ZG_R_4_ zj&HcYwAny2@^#0z;}`}Bd#41Hqz{^_VZ@f&XGvrWzYx)TAPk*lxW+F2myH^@b}C3;%^=yHv+`e`&HZcIs&G*;&ZM1;T^H|IH)?=n3YtI$a(?MrG z+ndw+504Br5S+5nXuIhVwbEVkgj%uWN7<~OdLwm|Ne3mf1lv;aVG|;_JMeiWre&3q z$vd?K(z{;{kc(o}0^As+s>5;%@@wgtwYL^D1PHESQU&W0bRRNo-OxS`WV+Qj?4U&v z!~Kv-m=}V$MT({C=eXuqb%CI0d+H=2^hNvJ8_>_<(|`C`{7GPnA)fOX!~GH!@q@!8 z_)8Ac#(#2{#@-NTf6g5M6aUp__OA}ZtYUD`*B%d>IcX(uAQ;Usvctvq3ZHrT2ZqvC z%#V0zL@hTI2B||tZ*C;%%i`#!Wb`sFxa#X&%7ZME+}Mv~Xyn)O&SDc8s{+^6ZuB1P zi)%%4q70-&n*41r?Lz==9bh}fz~9-3=Aa?K%r#(XP+T4mHQ3-%gvPm?8#{J)s z)%?j{{+pnG7eFO%<6MKkKFj4BiDf08z=s8QmM_bR@V5J8n}+b2MM`UXJr(Za)n7H- zM)Z?Oa0O=3_dSnXR|J(A-*i}G@?g>pL(6y@w1ftK(>%l&XXyVYpoYm_X9l{V_MT~Q$ zK5*c&U4&g#w0}=7V#sNYzZKpq5iW~e;2ivbk7{B)zPZ3LYP9R^s zi)&n)g_~q7l@X6+Z>Hlj_+GKA%srXwcMf0rU?2o=Y2sk1*$=lnUae$OD2>-IiMB9h$Yw7e&~%dg(X_R z>DxHWe6};#W$yCff>r<&W;Gwe&TvUz`?C1pt4MAZ<3N3_5izTUKUEdr{7`P(SO64!l!lxR~?^lkAr-wFA3Ja0R zi4%7#&UBY=NE>T_sT~tsvxgRi+1X15=}`DD`(`Pp%=x@~{R-j!6B6 z`n$zTz3(2+=_Uu+z-*|0*wA0{@^ezX#*AD}jqx-OIelxQRDzVa|7#rke^a<0WmLs^ zm?eb3h$DN#?VOtU?|^OfiXkR}I&+CYwGv{=0xC7FudQlcS(`f(BK00QHK9o$_+~|( z^W8VKI}+^t1xX^N_Sr9BV3h6smpF33{GuLa$ApS-<=Z8I#Bl=6K$ckD+l3xW0Px9k za|f_1Y(Ix0<^?vR8u443Sz%gvZCJ}P=&goAh;Pg)^!oB6uI$rERWrsN*qj(Ww%We0 z;A97=*JHYGdix$Y)MpA=Te+d9@O9pFuJ$ZqYGsk5x`86*6y~?qsz(xiYC%#dJnk13 zdfhO84Ggqz?oWu|W`8iwQzt{RLoPYf?fa*v< zVaS!O1wdI->&_HRFo>;g6J;OU-J>$&TqR&D0HL9GX|BQwR(8m_tn1`k(m3znj}Z}a z$itzhZ^OuMC;qV96WXvBbj2-h?x;U=-=lL|s@Bka#KT1U*(`7E{Fk)zS+f3*HW z6(({do~91=f=vk_O`aiq)8;+++zsh4*lUoqX)Yge7JRIb*?;v|Q#nev5nnzpnG(0R zNK15NPBa~rtR&VdqNSFLi~Mib!Ba1n z)DYIAnXfa4-w4k|!|dm1ewpgjD8ad_FwI47#PH)-G$p_NbLhxs;p;t=IKd)C-ZHqE zYj+3NYpr1W>Pj8efIvs@iG)@GNMIt*)LXJ^-c$h#Vj)IG0rAYBd0Czc z9o9q%mOA7|X4VBC!U$?ibGxnn{jP$1Y64lWUU{V7SCjrk|4BA@y`|Z5to|6YQA{#N zTMci?m%LAJOF_^{Y8#--g!@D_9VCuF~??F{|E&zgK-N?#`%;yT7~E>^n%e_$$p9Q*86^htO-ei}lM-w4#vK z|9Im3cm4`Uz;A2Qo%G{Z49UnZAu0_X<@INAr50xT5WeYV?MUC{Vrjnhg5spw{ zt$Pw>JRk>Da~-nQ>fVEm_<74ET}-=C`%b`z3lR|kdv9Cta?Yb?5P;@&9K_Mg1#A%@ zaZ8l|0^{8qd2T9&2=d`vDS*+d#qPj8Tb$j)da61UPiQ136`F9m9!3fT@L53a`_^*H zVs(v#a8qqXVU-Zx+=G8YWmNiuk&JTzdpFABLipU6(eazF@tWo6+gcuk*y) zt(yD`dV`(ym`L^WSKn>6*Z*tI3SIC&3*tke^X5i%x@4#0Pv-M3Xu05NwlVPAH$6G= z`ofT+6LLY}xg#s3_B9%7N1@B%R~NOt4xsu+-XJKH2@xO&^tEvhCD7!xMbUzrn0k;? zmIU&MiF-hK!K2!2MELu|y`G!QodA7g-Y%&X!7!)PZ$XZ2!G@%{lx#Ufzc(_}2NBMH ziYM1=_ml2e5nDmx2szQW$O6XqaN)HJ@j@|4+^vD%(O z{9&_h_GrlSzQKTr^4XSdja7QndS%4Zrgik^z7EPnLavZRb1kV$V9wV^%iV}ynQe+1 z$)k@}{eM@oU-W`tkd=3kk$=C1xXSd~pP{oUQ`Bk`>N7}c3XV$j4FvM}OM zw(8bUySN)=r&B|ccxg!$YWXi5g_?9S-g;KWtAB(u2Vm8|ga&pX?6pPtt%#2aJAfk~ z0K#k84o>AzIW0hE!)1C1gg7!&Le)~Kx77WWc*c+0vom}C9Jpx8} ziZAlc(#42KbVie-Rq{Oo*SZwfksRpVrO1|p4-w z+l+6T9xO7PcoxfB;eE#!P=~=$&r@UO+njq9?KV&K@6^BF9WzuK4H|yOSX63{CZuNn zlRYE7^iQwbs{dK|v}c5Jf?k_D;diT$Dz*eYAEO#48KZ8~JeaZnq|wk*rBYfHa0Vrf zAc{@6_y;zH0SaJk;^Hv^Xm*G~Ah@Q00GM3~EuWzx$2JN$6wz>cu2|v)UrijJgB5+> zaMJe->=4Fn#*m+8AP_I@Y`^`U;&vk-8OquX&SjATuFx{P+n}wZ$yh6DTnP+VLe+TF zr@0pn?UrqWl+B3iOCx(gO7S7gy~U;w8$6q3S^sxbq$-e#r2jvrBK>p28Wfcz#wV;O@_C9;$C|J3{ zXgBsGC-5*L)o5LhM%A&2n1mq;nEmUntI&ycu}!N|dK_MT$V%qwrOd_AkcH^FUSFGk zt-Zp$YErr-%kq)U*8 zx~4onStC|kPV<|clZLP_5dbZQn^*CCW?OkrTLS*e3b@*uCL`BOZ>Ium@CJB0Ete$E z?Zb%Jk_{9P_Fp)5%qlUR+D2X#STvU;#>LC!_efE*;h2uZ2dz|_$j~-la3ds% zt%WZsdi3Ml(u{)MtD&7m-@^>Z-Ot$Cx##?G0I^=nH%)_jgq4Hod2h~FOO^L%-%H=b%X)U#WD`OSe6Q_&R z4P2^G5n^Q&B?3~wuqCmzty%@9rAlQ>Ehs96XxWr3*A1{PL_iV&NtB2ILUIWqgsk^> zZnW0UC(!z7G5p$p!hgr}zUQ3hJkNR0Z7(pDZrbKAr7x``0#>%HneCl#^^L16qPz<@ zr=O4gtw<;ajNTsl)kb3cSzSAB!#LU79dEay`|wbngXKlhl?F{x_}{8WR;X zIc`6{mYmWksUlHVO=45xwgA`4@;vS>(NJe9f#taOaqKOaS_0-fB4~ero~dJY#!ozZ z&GHIYcjWcNiSu%*_|CU;0EapK?Ev=Nj<C9#)$0Cc@NAYmb1T@s2SL>CX~BOi>Wx z{Ty}(uaTxPwj~>pxyE&0l)>U8(&VIPdWDwpW96S$M2yi1=Xs~&7p6$2VtsRGUwc7n znYXb&RVTdk+l<}X{?=wzn3P^XG3{IX`$1>j?4fk!QH_>DmCeBb;%m{dS0`8g2UQny z`bFlI7mU|#YlOyT_>=U?XXAD>avat-V$aSt?sgsQ>9eMfL9MNEkjekoEw^oPwUY=v%#^MdC!z(qUz zhr&e{WMqe+MQO&|%yEjL*Wftm_vRQYiH_-KE=y!={+5_FmS^!k5$8-9{ELMyD*?iL zW^Ku$j$3gE$>!i z9#Eh!d1-1`&KJhai#D852kRRolVE1YX$(V(eO4IvZ@p$mQaU%LA36iJJ|kH^<6l)0 zd2?*6`8+X_zOy0W)*q&odc7UI-zksj9p)X{;?p(6{8zf>bx)%>>0%PTrR=hq)ZPW+ZbecM{E`&9%cHKr)Es~T~s)X4q=PTfeICQ}gX>X_N zOxcULwX|HHm6LI@)DQIE6&(i#k?|gbnyK@U=l=CcFYNtXKY#F!ImI${4)K*5abuCu zy>LyzV2G@8O|HN&c#AYE#}inokgP_skcM5{DuSFI6BwKn8V`KEHPcK@OjocEg?z8``=e8{HAI`b{P z9XjMq(Hz_Mct`?G6DG0qoT(qL2@z_jQ7!3QfOt^ZDJk^>sZg14o|5X(0tL%w<=pes zpJ%r!xXk%qmEsrS1$7V33$GuRrEKv^9Oi-H+qWKlU}#GWbRz>ARPA-Yugs>%;=-u% zi!LigB8_Qn4kXgd6&s;95{H!qNMVQ*3W}*^Z-pHHS48!$Ro{YfC041d9lh}dec!!| zK6cwZSu>Yt)VmA^W$owTbJTyA!gZK0O})UUAyi>R8Bssv3(l7@gA8%le2Tu4HuPg{ z`MEzNbf|ya#;5=xr+kZ_3QivH4U`|YYW^qgn#XdqxQBIvR5jno zc0)z_6LRWsFUyBDwdni^n(Dymn7NgM3f%E3i?+zxs)&kFdJ9Cd@|MF&ZJTZ%&Xk0v z@Iu5xw;LmXeE4b~PI=shw702>BnEp)YwZ8zfk$scByW65HC%y|%Xqde36QWAzcV5* z@S0c2#~Dcq@3hzVGan4ZIBlqS_U|-K1tezZP%%y9+#* zE2wUkZ??RJotTsxBCP%U%$K(O{*oQ5Z;_+6H)4!r=329}v<{4gIR(6cK`s7+TY>Cn z@MjSR>rKlTbEi}AH>rnLW<#Vc7^RU$B1)`&1=K4Bqb9#i`S0 zfpaM?*J{96P>+v-b3Yi;x%dJN`=MKc6KN&xSx^P2a22FgxdNC9i)bJA39#TCcW5zX z#hu3!Q>3me&00Tq(b1nO^5x=|GB>>adbHj?g3C>-6Q}D;=72Bkr1^R4WJCft7n~-%1FJM*E-o!AHN^r6J!28GCpV55?y3Q z#;+}zW30{QeMDO_#tXb7PEwvg$B5WFE&|p6*il`SagH9Gcw6vKIU|N%*F4KK`B`J9 zmYZn_TaxoB)J719e%pyX+E1p7 zdnO9jFj1g`2J$)O!D0}uzP+5~7&cz^S}9C&H9VZ;a#Fh!u&0;q9iG;6dQ4jHalq}r z!ZJU}fTCO9-V+Bg25fg7TOR)0gk5unU9b=UpPqZ$>fs?cZ23rr+P-$23jhBJFig5g zjRYdAz_fL_0LM6siswL?$Q-3*qNX>yxd+ELicbx`kkUvAks`J{ZamS^_AWj4c-*@<62sx+txe0oyL(2dcS*isr9pUZz-}B{g9n_bqhAYk*m;!J;lLW|@>7BL zdx!`5;Z`!SXtZLSqlwp!;ob$pVf0fBq<@C3sKfIZu1A7%aUBjeLk86hyBX4M{GGnO zH#;^OFUCUdhj@{=K!iT6ambN`_e~*>QX)fquy6z^k&eLg)X$r7$5M6P4kw@LV!LV~^`?lCch<|G0C#!lo#D;^%9%Oh7qc78BFoUxjwcJcGr_SM9?)ue^#tYk*=e-*r zEV=;S-T}1?2K-RB+P{0e6e}_2BB&n5i&CYsB!yYAww{5%*d@Z=yOw0i71Bl4*9+2! zSH9PJl^!s>5iU|Ob7jj5ERNIas^rG6u0GfZ@?n?l2@>T9wwkm%ccVa<$_PKvuEnR8 zP&Z~&`u!Kkr|+#4plY7h0&Dybt-8dGAYZ*PiqGjF{n}@KXLD9+MElHC$NaJfle`l+ zDC5u(y(BiMLEZ^+p^eWBTc2gw4?XxwR^u0jTHsIDS|>k~QSXT1H*VRj9;d#>T7Vmy zv+K-T9Mtk&ZW?5{?9rL!E{nIt;<>FTb|JjcuFhnj-ty7v)~6_M;cmsB{lMF{gB3@? ztv?Rs)|A~$qnhGSc5~Qkpt(JAlqoNrH4(ShFRg41*jwXEr^B7?9%{3Pb;aYb#*QTE z#QS=}d0YU#ytEM}t6?w-wkQ;hR$ISYMMg$)vHeJPd>%+J|`z?avF6KbgTMyPXMKiH`qVxH2SR5E%M!4C|l^` zH<$U+m-PM`jVLy!j!XIF6K4-VkHU5t8$r->d0JTgP17b5U-!K6W{N;W425U93*M$o zNnEp!d=*yWE&T0DJo{1nV>wfM@apx+?g$t&#h(S}(!;-=u*>^*YA&HYxVCUUYvWZz z&YDH^Z)Z_;q`KH+%dnlVMzm?@@82^myQRnXC->X@77J_p$Z7D^>aXi1FpfB-c6GIa zOF2^}^|Q20mJW}InD_#L`%3X!PhQ%d#d~iH{zTBjag6}xpy6o{q~vdhO3C(Z=q~$& zeX|KSmXp@k-vmQ&8|Ert3)bObw_w?=rTg?N^7;zAQ^Ma3!u|fz+ZA<_&!MLeAr#wJ z%luk=+8T^oavNaeTV43O-{Q011j$pJJJooUN#4EQ+-pz?%RYo9z0TU9mh`@FI#|mb zvs-^**eOVt5uAc_4l8iC&X&TP@+%6ibafF2Zo=YGdJ~@FoZDaxvKKs;KvMz2AY_E& zqbDO^(JAtZyEhwLBZ59U^h{`{nbjyS-MA_9=ch?^J*GRyS8~ON+NQqkKKrw=-d7}r zle1ky1;reG{1MjbY?oqvfv%X_l%(Z#|9snRcc!IX>h<3NU5TLWTT74WMN**Dv8JsD zt<^p?uXzsXc2t@^%Uhen4%SwgBF&pg2IqUm%>ERa_N^XuT~%ec*4!pe+RhXws6>^* zGm0WfLhjG*TUl`pnU%tW{-+Y^?mAZp^_!EgdHQBX-k8V^WU|?_lQwLLjMtY41{w}B z+FO-xHqWR^C1a8O{?~&|-|-tFEuH4Dz4R%ogvPDL1Bs69UTU{>Ci=5Xb#4jMI-mCbLwUEjeqG;}LI zBB`^E@=n~#kZ?{6C{8C!I7brixb6N2B5=6<-i}7gRAk`iFaMT1z@_EOVmyVMR_1AV zU+$4Z=&h(pU9kdbHhj#v!VzT*6p%g6Ef2;y&1eUZ?^smWgIa( zEH16C(8Y7UqMkxkEY61jc@Qgv)!$Zj_Jx{5O8tId4bDt5hF&A^rLCW$>$N=H0RqAs zH|xa-!Ze<&j78H%l{zI>%7d$f!E#nOuOS#g;Rf#{Iu&Rwcfrw#Ggt4q@6YA7{CW1T z@h7u(IS;?5Qf?cOxbhAwZ12LKRw7*Jc>-p_y-R z)2&VnO70u*$#k!%vmQTT3FplGh~;T61=>zddBU5)|FgvN~NIx)|gXsJZB1`Wt!Z9 z_XB@Ph(^T#fx~?2?3H_tJoYR?_l=keVw0k;SX*H34E`PsZa~w-aVKm26q58N9gQMy zHiwGOgh+|<5>~P})|v(v1WSk!eHTSOnZY-S@`5f;ap&UW%fid1n9D05Ssp%yCzX~( z5eDScO(8@_fL}v!ZhwfT7%i=mii`?TR=#}?a>96h4sKV-=(39u9*gXSC@6I|Ut9nS z=?uhTV-z2Wrgxng2eoirYFmxmN4YB<&vX@ZcDBwi_J^(6)|7G7RtnBI{}-i<4a*Qb zI!mXIGP~B#LNai>W{fVou=D@4ybJ{*BE+yKlR>rSuhwK{o1r1jc4mcgTJ>u=wRx6* zRXLp?Vqw!EiwOn&&hBQBsoQu$RjIX9X%EX^+I{#~tUAG!B`+iR;xMmypgdBdcz(xE zTNr0sT{MSAvXEk8SOdZG;nLvgqt9uh8n=DLG%$Im1j!<(0(9kJ z%~q@@xhnick$cJ7yo@?5x~4#Aq6v%g#DiQ^(`Xcjc9|Mczhu(2)!}6lmI;Z*^aip6 zZ?iQnmMpLZFdhFAfXUEFOFSH+ndVZh;HDW>WvNQD$q3cGUKwHho;3KcmtFYqH;Ttuaor2vS?F}+-X1a4J~&-QzD?7XyO-1$0YSh zCuF_9MVHr)j2yZoW9UiCiKn&u8=>u-;|Yn7lG5ehO5*0LR`1mADPAQn&>%VL&e>R- zW{cd@qB5HLEeT{_tlyX}37##Q$kw@II1ql<+VmbN963`bAh-LmEw3q5q^LD>y4PVHAh&mT1OFMBh6l zbbE!cx)bzGhI&T7`&FHLm##*!?4~R)A*Qz5$mM8yEG3Ft>=;&@IGC^Swj#Ph_ZSv* z-wJDwuBq?OrpCY7bad9*49nUOzKf#nx4;n6&%dL#SW%Ph+}j0t6udb2bqIkzNM_q^mxW&?R}pr{7SjIwR!6_0IB?M4FMyj@>n zVK=*74^GYEnMSX<7*I_KDXFtg+C*yQEf-6h5SIX_6dm=2x_NfYmYke0M7C8caA)RL zX=qw#TsWajGS=1=+rp)+*ajc@vs;J9>^gk0xqE*-lHR808aQuu99E#+i;6iiiP`1z z*)K0zA!}F6B?`BY;@>bg>r0i85ycZ6Ha1%E#rt_S@I~_92NEONT2C1)Dm-u%zBEOv z{FZhF>T9KXeY$>bl`qb}>1$=%V0`PIi_NfIOnO+Ptv^?30#P!pSks- zghCRnyPf%y`k?bY$9KEA{@Rdm!E{?Bac%TpK)8yP+l_-6`qHLF#*a)rbaNS_i&&hb zmDK@ZVyCt%y0TUK)LEsuh$}3y@LQGPn3w4!an@aBa*9SFuw!Q26)_ zmRI*@0cDc4iV|qpgM84j(UaNF*jP@fZPGA2tDi^by`a~Aw*UDtLB^e?7WWCSZfij$ zN$E(F|E~d`lWohwzaZeTHbv}@tieMDh7u@sT2bvDM*FUAV*+lXG>4uGN>8W3a@p@? zq&PR7O^PI-`lqKH1~=k`1;n0>oH86p zh&QlyHED>gf@z@jEJ<~oz@(g~n2wmQXa8d369DG?6rV;AF5-X^ZmT`W02Gghjhyex z$rsb9_uO_vkF!@i-ZB}o`I}ELn`1rNh5gRR7sB_!GFDU=oNZQb(rR2TiDPp>BO}W` z1*LIszamjhp$^IxwK%0cN$G)^HBW9ok7zIEN2pHE9lrIIpAg zOs^81CSdC>5|+0(MLkIm7L#8z;2ku?MRDN$pG~HEr|MF$+hi128LBfi7nW@7b!29_#`H zThLZ(aYm{rRYJScpfTmm=EWp+Xx~69XgiggX!ERpaPiAm* orJzaVk9|kaG9C! znpC@mgm#A*7ZtlQmLq)4MBV=|JWEHA;c0wCO2mKSSFouK?@hG->3!+q0;U>u{m7U? zmcE32Hdpz&+RFrbaMC_*vozz84sXlIobM8Pls4fAYjDxWVL0`)_Lqu`8@a!U;YJo3 zoBr+rqVe4v`qWrffew1*Ko%{Yi2j^ZCJEN11j*Sd;FfQ{D4l(ufU@C9llhgwLFUcB zg4`?OGo{<0zepBaz8jU-aKi=pM z6lC+jJL;D%#V%b%FYQ2IfUnGH7NJ>Tte96P8C7Dg>UI zmw?02R8ya4ri1vB`Q*fxL!78EIAO|p`5~}OIF|#&$f7}id=dmbBO%lrkVEicHVK ztWQzT{+X8YuccEO7@HS9x!DiqVu~LRVwXXdMg!%A+}Xw0aH&=2s^tiT-HZa`K_xjr zwF5?iCQvHXNkPU#uXhRSSW%SXdwhYzTRFpwSrq)~F$?S;^r#(>_WoN*T95T7lcEIi ztY+h4GsA^r+-6&A9`Pw2ETfZ3hx--;p9$zs?y~G*1xSMxR^f`I%C(c9#?arvVvn%C z{|d?&R3OD+#vbdWOoIuhVCLOryLta^ObJ<7FW0?j5_30*E{ zIhH)ni5F3LLWP6ybNUB2xl(zkKOdY*K#hFCi+Jxf6JO_uKr~LE7JQ&ri zG>pAHV9_+{w2ao)TBDcI;$<@R8>(iacG3}<$B+psAba@LtsZ6^oPo56|AFEM8u#b^e|kc{Mh$td|1J!^X(%tV5OF2mK%9aK1P=OX$t0>QbiN6Z!qi*U0X{2bopOy$obP8I@Z%d@KyE4-2sO#)? z?T~u$rv$=O>7@t5_qc5EhbHmaW@gc?-b{lsulDpVDU6VVL?~2B+j^v_iT9ZFO+`%g zor8NYyut_1zlyY3wm9=oPs+LpW*6vp3o&e1yzu;edTK#^6DE6}*?w^!Zc3RWfO;xg+)$)g*hsNjlDf!iqcqUWx*N^$|doCWsEj7S&t zkQ`^u9`aMrFie^c_r|Fzu`j65gA=6H7Fv0{Cd z`0#-uj>NjsJy)|%MPm{po#8A!SFbnj_8Ky(jb_ZBYi@;+o?<7V$wS!l zfl2sg{+Yd4S6AG^?+KTVqJ1}F()2bTtmSk6tm=SW7e9yM`5mEgqbzr}4wyl-gRZ|` z6;9bhY4d1{u;T*(xT<6D#12pU2%DM7{CMo5Fdr?_F4C>R*`*-+jKVdLNkYK2!Dhy2 zu?UH-jKsVtS_!$Kt(I%7&|^-!Tp5X!4VOqN+MF=W5Iib2?gPe8o>S#vM;ze41s?`| KQ1agT&;K8yd~}-t literal 0 HcmV?d00001 diff --git a/wgpu/examples/hello-ray-triangle/shader.wgsl b/wgpu/examples/ray-cube/shader.wgsl similarity index 96% rename from wgpu/examples/hello-ray-triangle/shader.wgsl rename to wgpu/examples/ray-cube/shader.wgsl index d5320976b1..0afa96a038 100644 --- a/wgpu/examples/hello-ray-triangle/shader.wgsl +++ b/wgpu/examples/ray-cube/shader.wgsl @@ -57,7 +57,7 @@ var acc_struct: acceleration_structure; @compute @workgroup_size(8, 8) fn main(@builtin(global_invocation_id) global_id: vec3) { let target_size = textureDimensions(output); - var color = vec4(vec2(global_id.xy) / vec2(target_size), 0.0, 0.0); + var color = vec4(vec2(global_id.xy) / vec2(target_size), 0.0, 1.0); let pixel_center = vec2(global_id.yx) + vec2(0.5); @@ -74,7 +74,7 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { let intersection = rayQueryGetCommittedIntersection(&rq); if (intersection.kind != RAY_QUERY_INTERSECTION_NONE) { - color = vec4(intersection.barycentrics, 1.0 - intersection.barycentrics.x - intersection.barycentrics.y, 0.0); + color = vec4(intersection.barycentrics, 1.0 - intersection.barycentrics.x - intersection.barycentrics.y, 1.0); } textureStore(output, global_id.xy, color); From 26e5097049bdf47a2c50b84f18556996cdc1c0cc Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sat, 1 Apr 2023 21:47:10 +0200 Subject: [PATCH 052/146] WIP broken tracing --- player/src/lib.rs | 44 +++++++++++++++ wgpu-core/src/command/ray_tracing.rs | 81 ++++++++++++++++++++++++---- wgpu-core/src/device/ray_tracing.rs | 33 ++++++------ wgpu-core/src/device/trace.rs | 13 +++++ wgpu-core/src/ray_tracing.rs | 32 +++++++++++ wgpu/examples/framework.rs | 1 + 6 files changed, 178 insertions(+), 26 deletions(-) diff --git a/player/src/lib.rs b/player/src/lib.rs index 0ef6080b77..dc4ba753ae 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -136,6 +136,41 @@ impl GlobalPlay for wgc::hub::Global { ) .unwrap(); } + trace::Command::BuildAccelerationStructuresUnsafeTlas { blas, tlas } => { + println!("{blas:?}\n\n{tlas:?}\n\n"); + let blas_iter = (&blas).into_iter().map(|x| { + let geometries = match &x.geometries { + wgc::ray_tracing::TraceBlasGeometries::TriangleGeometries( + triangle_geometries, + ) => { + let iter = triangle_geometries.into_iter().map(|tg| { + wgc::ray_tracing::BlasTriangleGeometry { + size: &tg.size, + vertex_buffer: tg.vertex_buffer, + index_buffer: tg.index_buffer, + transform_buffer: tg.transform_buffer, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + } + }); + wgc::ray_tracing::BlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + wgc::ray_tracing::BlasBuildEntry { + blas_id: x.blas_id, + geometries: geometries, + } + }); + + let tlas_iter = tlas.iter().cloned(); + + self.command_encoder_build_acceleration_structures_unsafe_tlas::( + encoder, blas_iter, tlas_iter, + ) + .unwrap(); + } } } let (cmd_buf, error) = self @@ -370,6 +405,7 @@ impl GlobalPlay for wgc::hub::Global { self.queue_submit::(device, &[]).unwrap(); } Action::Submit(_index, commands) => { + println!("Submit"); let (encoder, error) = self.device_create_command_encoder::( device, &wgt::CommandEncoderDescriptor { label: None }, @@ -381,6 +417,14 @@ impl GlobalPlay for wgc::hub::Global { let cmdbuf = self.encode_commands::(encoder, commands); self.queue_submit::(device, &[cmdbuf]).unwrap(); } + Action::CreateBlas { id, desc, sizes } => { + self.device_maintain_ids::(device).unwrap(); + self.device_create_blas::(device, &desc, sizes, id); + } + Action::CreateTlas { id, desc } => { + self.device_maintain_ids::(device).unwrap(); + self.device_create_tlas::(device, &desc, id); + } } } } diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index b5fe1e53b8..8ca4e08fe7 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1,5 +1,3 @@ -// #[cfg(feature = "trace")] -// use crate::device::trace::Command as TraceCommand; use crate::{ command::CommandBuffer, device::queue::TempResource, @@ -7,8 +5,9 @@ use crate::{ id::{BlasId, CommandEncoderId, TlasId}, init_tracker::MemoryInitKind, ray_tracing::{ - BlasAction, BlasBuildEntry, BlasGeometries, BuildAccelerationStructureError, TlasAction, - TlasBuildEntry, ValidateBlasActionsError, ValidateTlasActionsError, + BlasAction, BlasBuildEntry, BlasGeometries, + BuildAccelerationStructureError, TlasAction, TlasBuildEntry, ValidateBlasActionsError, + ValidateTlasActionsError, }, resource::{Blas, Tlas}, FastHashSet, @@ -47,12 +46,74 @@ impl Global { let device = &mut device_guard[cmd_buf.device_id.value]; #[cfg(feature = "trace")] - let blas_iter: Box> = if let Some(ref mut _list) = cmd_buf.commands { - // Create temporary allocation, save trace and recreate iterator (same for tlas) - Box::new(blas_iter.map(|x| x)) - } else { - Box::new(blas_iter) - }; + let trace_blas: Vec = blas_iter + .map(|x| { + let geometries = match x.geometries { + BlasGeometries::TriangleGeometries(triangle_geometries) => { + crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( + triangle_geometries + .map(|tg| crate::ray_tracing::TraceBlasTriangleGeometry { + size: tg.size.clone(), + vertex_buffer: tg.vertex_buffer, + index_buffer: tg.index_buffer, + transform_buffer: tg.transform_buffer, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + }) + .collect(), + ) + } + }; + crate::ray_tracing::TraceBlasBuildEntry { + blas_id: x.blas_id, + geometries, + } + }) + .collect(); + + #[cfg(feature = "trace")] + let mut trace_tlas: Vec = tlas_iter.collect(); + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf.commands { + list.push( + crate::device::trace::Command::BuildAccelerationStructuresUnsafeTlas { + blas: trace_blas.clone(), + tlas: trace_tlas.clone(), + }, + ); + } + + #[cfg(feature = "trace")] + let blas_iter = (&trace_blas).into_iter().map(|x| { + let geometries = match &x.geometries { + crate::ray_tracing::TraceBlasGeometries::TriangleGeometries(triangle_geometries) => { + let iter = triangle_geometries + .into_iter() + .map(|tg| crate::ray_tracing::BlasTriangleGeometry { + size: &tg.size, + vertex_buffer: tg.vertex_buffer, + index_buffer: tg.index_buffer, + transform_buffer: tg.transform_buffer, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + }); + BlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + BlasBuildEntry { + blas_id: x.blas_id, + geometries: geometries, + } + }); + + #[cfg(feature = "trace")] + let tlas_iter = (&mut trace_tlas).iter(); + let mut input_barriers = Vec::>::new(); diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index f819e8ce75..e5353ceb09 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -1,5 +1,5 @@ -// #[cfg(feature = "trace")] -// use crate::device::trace::Command as TraceCommand; +#[cfg(feature = "trace")] +use crate::device::trace; use crate::{ device::{queue::TempResource, Device, DeviceError}, hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Token}, @@ -160,13 +160,14 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; - // #[cfg(feature = "trace")] - // if let Some(ref trace) = device.trace { - // let mut desc = desc.clone(); - // trace - // .lock() - // .add(trace::Action::CreateBlas(fid.id(), desc)); - // } + #[cfg(feature = "trace")] + if let Some(ref trace) = device.trace { + trace.lock().add(trace::Action::CreateBlas { + id: fid.id(), + desc: desc.clone(), + sizes: sizes.clone(), + }); + } let blas = match device.create_blas(device_id, desc, sizes) { Ok(blas) => blas, @@ -214,13 +215,13 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; - // #[cfg(feature = "trace")] - // if let Some(ref trace) = device.trace { - // let mut desc = desc.clone(); - // trace - // .lock() - // .add(trace::Action::CreateTlas(fid.id(), desc)); - // } + #[cfg(feature = "trace")] + if let Some(ref trace) = device.trace { + trace.lock().add(trace::Action::CreateTlas { + id: fid.id(), + desc: desc.clone(), + }); + } let tlas = match device.create_tlas(device_id, desc) { Ok(tlas) => tlas, diff --git a/wgpu-core/src/device/trace.rs b/wgpu-core/src/device/trace.rs index 57f82c181e..8558bb0620 100644 --- a/wgpu-core/src/device/trace.rs +++ b/wgpu-core/src/device/trace.rs @@ -123,6 +123,15 @@ pub enum Action<'a> { size: wgt::Extent3d, }, Submit(crate::SubmissionIndex, Vec), + CreateBlas { + id: id::BlasId, + desc: crate::resource::BlasDescriptor<'a>, + sizes: wgt::BlasGeometrySizeDescriptors, + }, + CreateTlas { + id: id::TlasId, + desc: crate::resource::TlasDescriptor<'a>, + }, } #[derive(Debug)] @@ -182,6 +191,10 @@ pub enum Command { target_colors: Vec>, target_depth_stencil: Option, }, + BuildAccelerationStructuresUnsafeTlas { + blas: Vec, + tlas: Vec, + }, } #[cfg(feature = "trace")] diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index f547b53ec8..183c0a785b 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -89,6 +89,9 @@ pub struct BlasBuildEntry<'a> { pub geometries: BlasGeometries<'a>, } +#[derive(Debug, Clone)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] pub struct TlasBuildEntry { pub tlas_id: TlasId, pub instance_buffer_id: BufferId, @@ -112,3 +115,32 @@ pub(crate) struct TlasAction { pub id: TlasId, pub kind: AccelerationStructureActionKind, } + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +pub struct TraceBlasTriangleGeometry { + pub size: wgt::BlasTriangleGeometrySizeDescriptor, + pub vertex_buffer: BufferId, + pub index_buffer: Option, + pub transform_buffer: Option, + pub first_vertex: u32, + pub vertex_stride: BufferAddress, + pub index_buffer_offset: Option, + pub transform_buffer_offset: Option, +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +pub enum TraceBlasGeometries { + TriangleGeometries(Vec), +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +pub struct TraceBlasBuildEntry { + pub blas_id: BlasId, + pub geometries: TraceBlasGeometries, +} \ No newline at end of file diff --git a/wgpu/examples/framework.rs b/wgpu/examples/framework.rs index 2e5e25283a..3da7502cf1 100644 --- a/wgpu/examples/framework.rs +++ b/wgpu/examples/framework.rs @@ -222,6 +222,7 @@ async fn setup(title: &str) -> Setup { let needed_limits = E::required_limits().using_resolution(adapter.limits()); let trace_dir = std::env::var("WGPU_TRACE"); + dbg!(&trace_dir); let (device, queue) = adapter .request_device( &wgpu::DeviceDescriptor { From 1bad67133c4ffd1a2b4ebd1afa64fdb5b4dbbe6f Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 4 Apr 2023 12:49:23 +0200 Subject: [PATCH 053/146] fixed tracing --- player/src/lib.rs | 10 +++++----- wgpu-core/src/command/ray_tracing.rs | 22 ++++++++++++---------- wgpu/Cargo.toml | 4 ++++ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/player/src/lib.rs b/player/src/lib.rs index dc4ba753ae..50656d6af8 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -137,7 +137,6 @@ impl GlobalPlay for wgc::hub::Global { .unwrap(); } trace::Command::BuildAccelerationStructuresUnsafeTlas { blas, tlas } => { - println!("{blas:?}\n\n{tlas:?}\n\n"); let blas_iter = (&blas).into_iter().map(|x| { let geometries = match &x.geometries { wgc::ray_tracing::TraceBlasGeometries::TriangleGeometries( @@ -163,11 +162,13 @@ impl GlobalPlay for wgc::hub::Global { geometries: geometries, } }); - - let tlas_iter = tlas.iter().cloned(); + + if !tlas.is_empty() { + log::error!("a trace of command_encoder_build_acceleration_structures_unsafe_tlas containing a tlas build is not replayable! skipping tlas build"); + } self.command_encoder_build_acceleration_structures_unsafe_tlas::( - encoder, blas_iter, tlas_iter, + encoder, blas_iter, std::iter::empty(), ) .unwrap(); } @@ -405,7 +406,6 @@ impl GlobalPlay for wgc::hub::Global { self.queue_submit::(device, &[]).unwrap(); } Action::Submit(_index, commands) => { - println!("Submit"); let (encoder, error) = self.device_create_command_encoder::( device, &wgt::CommandEncoderDescriptor { label: None }, diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 8ca4e08fe7..8cf3c98be5 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -5,9 +5,8 @@ use crate::{ id::{BlasId, CommandEncoderId, TlasId}, init_tracker::MemoryInitKind, ray_tracing::{ - BlasAction, BlasBuildEntry, BlasGeometries, - BuildAccelerationStructureError, TlasAction, TlasBuildEntry, ValidateBlasActionsError, - ValidateTlasActionsError, + BlasAction, BlasBuildEntry, BlasGeometries, BuildAccelerationStructureError, TlasAction, + TlasBuildEntry, ValidateBlasActionsError, ValidateTlasActionsError, }, resource::{Blas, Tlas}, FastHashSet, @@ -21,7 +20,6 @@ use std::{cmp::max, iter}; use super::BakedCommands; // TODO: -// tracing // automatic build splitting (if to big for spec or scratch buffer) // comments/documentation impl Global { @@ -84,15 +82,19 @@ impl Global { 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!"); + } } #[cfg(feature = "trace")] let blas_iter = (&trace_blas).into_iter().map(|x| { let geometries = match &x.geometries { - crate::ray_tracing::TraceBlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = triangle_geometries - .into_iter() - .map(|tg| crate::ray_tracing::BlasTriangleGeometry { + crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( + triangle_geometries, + ) => { + let iter = triangle_geometries.into_iter().map(|tg| { + crate::ray_tracing::BlasTriangleGeometry { size: &tg.size, vertex_buffer: tg.vertex_buffer, index_buffer: tg.index_buffer, @@ -101,7 +103,8 @@ impl Global { vertex_stride: tg.vertex_stride, index_buffer_offset: tg.index_buffer_offset, transform_buffer_offset: tg.transform_buffer_offset, - }); + } + }); BlasGeometries::TriangleGeometries(Box::new(iter)) } }; @@ -114,7 +117,6 @@ impl Global { #[cfg(feature = "trace")] let tlas_iter = (&mut trace_tlas).iter(); - let mut input_barriers = Vec::>::new(); let mut scratch_buffer_blas_size = 0; diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 69cdbe5a8d..a20b0d7dd8 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -85,6 +85,10 @@ test = true name = "stencil-triangles" test = true +[[example]] +name = "ray-cube" +test = true + [features] default = ["wgsl"] # Apply run-time checks, even in release builds. These are in addition From abff39fbd08bcaf1ea403b606bc067a4474310f6 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 4 Apr 2023 19:26:22 +0200 Subject: [PATCH 054/146] WIP working safe build (destruction missing) --- player/src/lib.rs | 6 +- wgpu-core/src/command/ray_tracing.rs | 684 ++++++++++++++++++++++++++- wgpu-core/src/device/ray_tracing.rs | 34 +- wgpu-core/src/device/trace.rs | 4 + wgpu-core/src/ray_tracing.rs | 119 ++++- wgpu-core/src/resource.rs | 22 +- wgpu/examples/ray-cube/main.rs | 102 ++-- wgpu/src/backend/direct.rs | 82 +++- wgpu/src/context.rs | 96 +++- wgpu/src/lib.rs | 168 +++++++ 10 files changed, 1213 insertions(+), 104 deletions(-) diff --git a/player/src/lib.rs b/player/src/lib.rs index 50656d6af8..816dc70c31 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -162,13 +162,15 @@ impl GlobalPlay for wgc::hub::Global { geometries: geometries, } }); - + if !tlas.is_empty() { log::error!("a trace of command_encoder_build_acceleration_structures_unsafe_tlas containing a tlas build is not replayable! skipping tlas build"); } self.command_encoder_build_acceleration_structures_unsafe_tlas::( - encoder, blas_iter, std::iter::empty(), + encoder, + blas_iter, + std::iter::empty(), ) .unwrap(); } diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 8cf3c98be5..0b713f0333 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -5,23 +5,22 @@ use crate::{ id::{BlasId, CommandEncoderId, TlasId}, init_tracker::MemoryInitKind, ray_tracing::{ - BlasAction, BlasBuildEntry, BlasGeometries, BuildAccelerationStructureError, TlasAction, - TlasBuildEntry, ValidateBlasActionsError, ValidateTlasActionsError, + tlas_instance_into_bytes, BlasAction, BlasBuildEntry, BlasGeometries, + BuildAccelerationStructureError, TlasAction, TlasBuildEntry, TlasInstance, TlasPackage, + TraceTlasInstance, ValidateBlasActionsError, ValidateTlasActionsError, }, - resource::{Blas, Tlas}, + resource::{Blas, StagingBuffer, Tlas}, FastHashSet, }; use hal::{CommandEncoder, Device}; use wgt::BufferUsages; -use std::{cmp::max, iter}; +use std::{cmp::max, iter, num::NonZeroU64, ops::Range, ptr}; use super::BakedCommands; -// TODO: -// automatic build splitting (if to big for spec or scratch buffer) -// comments/documentation +// TODO: a lot impl Global { pub fn command_encoder_build_acceleration_structures_unsafe_tlas<'a, A: HalApi>( &self, @@ -570,6 +569,677 @@ impl Global { Ok(()) } + + pub fn command_encoder_build_acceleration_structures<'a, A: HalApi>( + &self, + command_encoder_id: CommandEncoderId, + blas_iter: impl Iterator>, + tlas_iter: impl Iterator>, + ) -> Result<(), BuildAccelerationStructureError> { + profiling::scope!("CommandEncoder::build_acceleration_structures"); + + let hub = A::hub(self); + let mut token = Token::root(); + + let (mut device_guard, mut token) = hub.devices.write(&mut token); + let (mut cmd_buf_guard, mut token) = hub.command_buffers.write(&mut token); + let cmd_buf = CommandBuffer::get_encoder_mut(&mut *cmd_buf_guard, command_encoder_id)?; + let (buffer_guard, mut token) = hub.buffers.read(&mut token); + let (blas_guard, mut token) = hub.blas_s.read(&mut token); + let (tlas_guard, _) = hub.tlas_s.read(&mut token); + + let device = &mut device_guard[cmd_buf.device_id.value]; + + #[cfg(feature = "trace")] + let trace_blas: Vec = blas_iter + .map(|x| { + let geometries = match x.geometries { + BlasGeometries::TriangleGeometries(triangle_geometries) => { + crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( + triangle_geometries + .map(|tg| crate::ray_tracing::TraceBlasTriangleGeometry { + size: tg.size.clone(), + vertex_buffer: tg.vertex_buffer, + index_buffer: tg.index_buffer, + transform_buffer: tg.transform_buffer, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + }) + .collect(), + ) + } + }; + crate::ray_tracing::TraceBlasBuildEntry { + blas_id: x.blas_id, + geometries, + } + }) + .collect(); + + #[cfg(feature = "trace")] + let trace_tlas: Vec = tlas_iter + .map(|x: TlasPackage| { + let instances = x + .instances + .map(|instance| { + if let Some(instance) = instance { + Some(TraceTlasInstance { + blas_id: instance.blas_id, + transform: instance.transform.clone(), + custom_index: instance.custom_index, + mask: instance.mask, + }) + } else { + None + } + }) + .collect(); + crate::ray_tracing::TraceTlasPackage { + tlas_id: x.tlas_id, + instances, + lowest_unmodified: x.lowest_unmodified, + } + }) + .collect(); + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf.commands { + list.push(crate::device::trace::Command::BuildAccelerationStructures { + blas: trace_blas.clone(), + tlas: trace_tlas.clone(), + }); + } + + #[cfg(feature = "trace")] + let blas_iter = (&trace_blas).into_iter().map(|x| { + let geometries = match &x.geometries { + crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( + triangle_geometries, + ) => { + let iter = triangle_geometries.into_iter().map(|tg| { + crate::ray_tracing::BlasTriangleGeometry { + size: &tg.size, + vertex_buffer: tg.vertex_buffer, + index_buffer: tg.index_buffer, + transform_buffer: tg.transform_buffer, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + } + }); + BlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + BlasBuildEntry { + blas_id: x.blas_id, + geometries: geometries, + } + }); + + // dbg!(&trace_tlas); + + #[cfg(feature = "trace")] + let tlas_iter = (&trace_tlas).into_iter().map(|x| { + let instances = x.instances.iter().map(|instance| { + if let Some(instance) = instance { + Some(TlasInstance { + blas_id: instance.blas_id, + transform: &instance.transform, + custom_index: instance.custom_index, + mask: instance.mask, + }) + } else { + None + } + }); + TlasPackage { + tlas_id: x.tlas_id, + instances: Box::new(instances), + lowest_unmodified: x.lowest_unmodified, + } + }); + + let mut input_barriers = Vec::>::new(); + + let mut scratch_buffer_blas_size = 0; + let mut blas_storage = Vec::<(&Blas, hal::AccelerationStructureEntries, u64)>::new(); + + for entry in blas_iter { + let blas = cmd_buf + .trackers + .blas_s + .add_single(&blas_guard, entry.blas_id) + .ok_or(BuildAccelerationStructureError::InvalidBlas(entry.blas_id))?; + + if blas.raw.is_none() { + return Err(BuildAccelerationStructureError::InvalidBlas(entry.blas_id)); + } + + if !*blas.built.lock() { + cmd_buf.blas_actions.push(BlasAction { + id: entry.blas_id, + kind: crate::ray_tracing::AccelerationStructureActionKind::Build, + }); + } + + match entry.geometries { + BlasGeometries::TriangleGeometries(triangle_geometries) => { + let mut triangle_entries = Vec::>::new(); + + for (i, mesh) in triangle_geometries.enumerate() { + let size_desc = match &blas.sizes { + &wgt::BlasGeometrySizeDescriptors::Triangles { ref desc } => desc, + // _ => { + // return Err( + // BuildAccelerationStructureError::IncompatibleBlasBuildSizes( + // entry.blas_id, + // ), + // ) + // } + }; + if i >= size_desc.len() { + return Err( + BuildAccelerationStructureError::IncompatibleBlasBuildSizes( + entry.blas_id, + ), + ); + } + let size_desc = &size_desc[i]; + + if size_desc.flags != mesh.size.flags + || size_desc.vertex_count < mesh.size.vertex_count + || size_desc.vertex_format != mesh.size.vertex_format + || size_desc.index_count.is_none() != mesh.size.index_count.is_none() + || (size_desc.index_count.is_none() + || size_desc.index_count.unwrap() < mesh.size.index_count.unwrap()) + || size_desc.index_format.is_none() != mesh.size.index_format.is_none() + || (size_desc.index_format.is_none() + || size_desc.index_format.unwrap() + != mesh.size.index_format.unwrap()) + { + return Err( + BuildAccelerationStructureError::IncompatibleBlasBuildSizes( + entry.blas_id, + ), + ); + } + + let vertex_buffer = { + let (vertex_buffer, vertex_pending) = cmd_buf + .trackers + .buffers + .set_single( + &*buffer_guard, + mesh.vertex_buffer, + hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) + .ok_or(BuildAccelerationStructureError::InvalidBuffer( + mesh.vertex_buffer, + ))?; + let vertex_raw = vertex_buffer.raw.as_ref().ok_or( + BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer), + )?; + if !vertex_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + mesh.vertex_buffer, + ), + ); + } + if let Some(barrier) = + vertex_pending.map(|pending| pending.into_hal(vertex_buffer)) + { + input_barriers.push(barrier); + } + if mesh.size.vertex_count as i64 - mesh.first_vertex as i64 <= 0 { + return Err(BuildAccelerationStructureError::EmptyVertexBuffer( + mesh.vertex_buffer, + )); + } + if vertex_buffer.size + < (mesh.size.vertex_count + mesh.first_vertex) as u64 + * mesh.vertex_stride + { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + mesh.vertex_buffer, + vertex_buffer.size, + (mesh.size.vertex_count + mesh.first_vertex) as u64 + * mesh.vertex_stride, + ), + ); + } + let vertex_buffer_offset = + mesh.first_vertex as u64 * mesh.vertex_stride; + cmd_buf.buffer_memory_init_actions.extend( + vertex_buffer.initialization_status.create_action( + mesh.vertex_buffer, + vertex_buffer_offset + ..(vertex_buffer_offset + + mesh.size.vertex_count as u64 * mesh.vertex_stride), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + vertex_raw + }; + let index_buffer = if let Some(index_id) = mesh.index_buffer { + if mesh.index_buffer_offset.is_none() + || mesh.size.index_count.is_none() + || mesh.size.index_count.is_none() + { + return Err( + BuildAccelerationStructureError::MissingAssociatedData( + index_id, + ), + ); + } + let (index_buffer, index_pending) = cmd_buf + .trackers + .buffers + .set_single( + &*buffer_guard, + index_id, + hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) + .ok_or(BuildAccelerationStructureError::InvalidBuffer(index_id))?; + let index_raw = index_buffer + .raw + .as_ref() + .ok_or(BuildAccelerationStructureError::InvalidBuffer(index_id))?; + if !index_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + index_id, + ), + ); + } + if let Some(barrier) = + index_pending.map(|pending| pending.into_hal(index_buffer)) + { + input_barriers.push(barrier); + } + let index_stride = match mesh.size.index_format.unwrap() { + wgt::IndexFormat::Uint16 => 2, + wgt::IndexFormat::Uint32 => 4, + }; + let index_buffer_size = + mesh.size.index_count.unwrap() as u64 * index_stride; + + if mesh.size.index_count.unwrap() as u64 + - mesh.index_buffer_offset.unwrap() / index_stride + < 3 + { + return Err(BuildAccelerationStructureError::EmptyIndexBuffer( + index_id, + )); + } + if mesh.size.index_count.unwrap() % 3 != 0 { + return Err(BuildAccelerationStructureError::InvalidIndexCount( + index_id, + mesh.size.index_count.unwrap(), + )); + } + if index_buffer.size + < mesh.size.index_count.unwrap() as u64 * index_stride + + mesh.index_buffer_offset.unwrap() + { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + index_id, + index_buffer.size, + mesh.size.index_count.unwrap() as u64 * index_stride + + mesh.index_buffer_offset.unwrap(), + ), + ); + } + + cmd_buf.buffer_memory_init_actions.extend( + index_buffer.initialization_status.create_action( + index_id, + mesh.index_buffer_offset.unwrap() + ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + Some(index_raw) + } else { + None + }; + let transform_buffer = if let Some(transform_id) = mesh.transform_buffer { + if mesh.transform_buffer_offset.is_none() { + return Err( + BuildAccelerationStructureError::MissingAssociatedData( + transform_id, + ), + ); + } + let (transform_buffer, transform_pending) = cmd_buf + .trackers + .buffers + .set_single( + &*buffer_guard, + transform_id, + hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) + .ok_or(BuildAccelerationStructureError::InvalidBuffer( + transform_id, + ))?; + let transform_raw = transform_buffer.raw.as_ref().ok_or( + BuildAccelerationStructureError::InvalidBuffer(transform_id), + )?; + if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + transform_id, + ), + ); + } + if let Some(barrier) = + transform_pending.map(|pending| pending.into_hal(transform_buffer)) + { + input_barriers.push(barrier); + } + + if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + transform_id, + transform_buffer.size, + 48 + mesh.transform_buffer_offset.unwrap(), + ), + ); + } + cmd_buf.buffer_memory_init_actions.extend( + transform_buffer.initialization_status.create_action( + transform_id, + mesh.transform_buffer_offset.unwrap() + ..(mesh.index_buffer_offset.unwrap() + 48), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + Some(transform_raw) + } else { + None + }; + + let triangles = hal::AccelerationStructureTriangles { + vertex_buffer: Some(vertex_buffer), + vertex_format: mesh.size.vertex_format, + first_vertex: mesh.first_vertex, + vertex_count: mesh.size.vertex_count, + vertex_stride: mesh.vertex_stride, + indices: index_buffer.map(|index_buffer| { + hal::AccelerationStructureTriangleIndices { + format: mesh.size.index_format.unwrap(), + buffer: Some(index_buffer), + offset: mesh.index_buffer_offset.unwrap() as u32, + count: mesh.size.index_count.unwrap(), + } + }), + transform: transform_buffer.map(|transform_buffer| { + hal::AccelerationStructureTriangleTransform { + buffer: transform_buffer, + offset: mesh.transform_buffer_offset.unwrap() as u32, + } + }), + flags: mesh.size.flags, + }; + + triangle_entries.push(triangles); + } + + let scratch_buffer_offset = scratch_buffer_blas_size; + scratch_buffer_blas_size += blas.size_info.build_scratch_size; // TODO Alignment + + blas_storage.push(( + blas, + hal::AccelerationStructureEntries::Triangles(triangle_entries), + scratch_buffer_offset, + )) + } + } + } + + let mut scratch_buffer_tlas_size = 0; + let mut tlas_storage = Vec::<( + &Tlas, + hal::AccelerationStructureEntries, + u64, + Range, + )>::new(); + let mut instance_buffer_staging_source = Vec::::new(); + + for entry in tlas_iter { + let tlas = cmd_buf + .trackers + .tlas_s + .add_single(&tlas_guard, entry.tlas_id) + .ok_or(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id))?; + + if tlas.raw.is_none() { + return Err(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id)); + } + + if !*tlas.built.lock() { + cmd_buf.tlas_actions.push(TlasAction { + id: entry.tlas_id, + kind: crate::ray_tracing::AccelerationStructureActionKind::Build, + }); + } + + let scratch_buffer_offset = scratch_buffer_tlas_size; + scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; // TODO Alignment + + let first_byte_index = instance_buffer_staging_source.len(); + + let mut instance_count = 0; + for instance in entry.instances { + if let Some(instance) = instance { + // TODO validation + let blas = cmd_buf + .trackers + .blas_s + .add_single(&blas_guard, instance.blas_id) + .ok_or(BuildAccelerationStructureError::InvalidBlasForInstance( + instance.blas_id, + ))?; + + instance_buffer_staging_source + .extend(tlas_instance_into_bytes::(&instance, blas.handle)); + + instance_count += 1; + } + } + + tlas_storage.push(( + tlas, + hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { + buffer: Some(&tlas.instance_buffer), + offset: 0, + count: instance_count, + }), + scratch_buffer_offset, + first_byte_index..instance_buffer_staging_source.len(), + )); + } + + if max(scratch_buffer_blas_size, scratch_buffer_tlas_size) == 0 { + return Ok(()); + } + + let scratch_buffer = unsafe { + device + .raw + .create_buffer(&hal::BufferDescriptor { + label: Some("(wgpu) scratch buffer"), + size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), + usage: hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, + memory_flags: hal::MemoryFlags::empty(), + }) + .map_err(crate::device::DeviceError::from)? + }; + + let staging_buffer = unsafe { + device + .raw + .create_buffer(&hal::BufferDescriptor { + label: Some("(wgpu) instance staging buffer"), + size: instance_buffer_staging_source.len() as u64, + usage: hal::BufferUses::MAP_WRITE | hal::BufferUses::COPY_SRC, + memory_flags: hal::MemoryFlags::empty(), + }) + .map_err(crate::device::DeviceError::from)? + }; + + unsafe { + let mapping = device + .raw + .map_buffer( + &staging_buffer, + 0..instance_buffer_staging_source.len() as u64, + ) + .map_err(crate::device::DeviceError::from)?; + ptr::copy_nonoverlapping( + instance_buffer_staging_source.as_ptr(), + mapping.ptr.as_ptr(), + instance_buffer_staging_source.len(), + ); + device + .raw + .unmap_buffer(&staging_buffer) + .map_err(crate::device::DeviceError::from)?; + assert!(mapping.is_coherent); + } + + let blas_descriptors = + blas_storage + .iter() + .map(|&(blas, ref entries, ref scratch_buffer_offset)| { + if blas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { + log::info!("only rebuild implemented") + } + *blas.built.lock() = true; + hal::BuildAccelerationStructureDescriptor { + entries, + mode: hal::AccelerationStructureBuildMode::Build, // TODO + flags: blas.flags, + source_acceleration_structure: None, + destination_acceleration_structure: blas.raw.as_ref().unwrap(), + scratch_buffer: &scratch_buffer, + scratch_buffer_offset: *scratch_buffer_offset, + } + }); + + let tlas_descriptors = tlas_storage.iter().map( + |&(tlas, ref entries, ref scratch_buffer_offset, ref _range)| { + if tlas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { + log::info!("only rebuild implemented") + } + *tlas.built.lock() = true; + hal::BuildAccelerationStructureDescriptor { + entries, + mode: hal::AccelerationStructureBuildMode::Build, // TODO + flags: tlas.flags, + source_acceleration_structure: None, + destination_acceleration_structure: tlas.raw.as_ref().unwrap(), + scratch_buffer: &scratch_buffer, + scratch_buffer_offset: *scratch_buffer_offset, + } + }, + ); + + let scratch_buffer_barrier = hal::BufferBarrier:: { + buffer: &scratch_buffer, + usage: hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH + ..hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, + }; + + let staging_buffer_barrier = hal::BufferBarrier:: { + buffer: &scratch_buffer, + usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, + }; + + let instance_buffer_barriers = tlas_storage.iter().filter_map( + |&(tlas, ref _entries, ref _scratch_buffer_offset, ref range)| { + let size = (range.end - range.start) as u64; + if size == 0 { + None + } else { + Some(hal::BufferBarrier:: { + buffer: &tlas.instance_buffer, + usage: hal::BufferUses::COPY_DST + ..hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + }) + } + }, + ); + + let blas_present = !blas_storage.is_empty(); + let tlas_present = !tlas_storage.is_empty(); + + let cmd_buf_raw = cmd_buf.encoder.open(); + + unsafe { + cmd_buf_raw.transition_buffers(input_barriers.into_iter()); + } + + if blas_present { + unsafe { + cmd_buf_raw + .build_acceleration_structures(blas_storage.len() as u32, blas_descriptors); + } + } + + if blas_present && tlas_present { + unsafe { + cmd_buf_raw.transition_buffers(iter::once(scratch_buffer_barrier)); + } + } + + if tlas_present { + unsafe { + cmd_buf_raw.transition_buffers(iter::once(staging_buffer_barrier)); + } + + for (tlas, _entries, _scratch_buffer_offset, range) in &tlas_storage { + let size = (range.end - range.start) as u64; + if size == 0 { + continue; + } + unsafe { + let temp = hal::BufferCopy { + src_offset: range.start as u64, + dst_offset: 0, + size: NonZeroU64::new(size).unwrap(), + }; + cmd_buf_raw.copy_buffer_to_buffer( + &staging_buffer, + &tlas.instance_buffer, + iter::once(temp), + ); + } + } + + unsafe { + cmd_buf_raw.transition_buffers(instance_buffer_barriers); + } + + unsafe { + cmd_buf_raw + .build_acceleration_structures(tlas_storage.len() as u32, tlas_descriptors); + } + } + + device.pending_writes.temp_resources.extend([ + TempResource::Buffer(scratch_buffer), + TempResource::Buffer(staging_buffer), + ]); + + Ok(()) + } } impl BakedCommands { diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index e5353ceb09..69409ac17e 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -4,6 +4,7 @@ use crate::{ device::{queue::TempResource, Device, DeviceError}, hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Token}, id::{self, BlasId, TlasId}, + ray_tracing::{getRawTlasInstanceSize, CreateBlasError, CreateTlasError}, resource, LabelHelpers, LifeGuard, Stored, }; @@ -19,7 +20,7 @@ impl Device { self_id: id::DeviceId, blas_desc: &resource::BlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, - ) -> Result, resource::CreateBlasError> { + ) -> Result, CreateBlasError> { debug_assert_eq!(self_id.backend(), A::VARIANT); let size_info = match &sizes { @@ -28,7 +29,7 @@ impl Device { Vec::>::with_capacity(desc.len()); for x in desc { if x.index_count.is_some() != x.index_format.is_some() { - return Err(resource::CreateBlasError::Unimplemented); + return Err(CreateBlasError::Unimplemented); } // TODO more validation let indices = @@ -71,6 +72,8 @@ impl Device { } .map_err(DeviceError::from)?; + let handle = unsafe { self.raw.get_acceleration_structure_device_address(&raw) }; + Ok(resource::Blas { raw: Some(raw), device_id: Stored { @@ -83,6 +86,7 @@ impl Device { flags: blas_desc.flags, update_mode: blas_desc.update_mode, built: Mutex::new(false), + handle, }) } @@ -93,7 +97,7 @@ impl Device { &self, self_id: id::DeviceId, desc: &resource::TlasDescriptor, - ) -> Result, resource::CreateTlasError> { + ) -> Result, CreateTlasError> { debug_assert_eq!(self_id.backend(), A::VARIANT); // TODO validate max_instances @@ -122,6 +126,18 @@ impl Device { } .map_err(DeviceError::from)?; + let instance_buffer_size = getRawTlasInstanceSize::(); + let instance_buffer = unsafe { + self.raw.create_buffer(&hal::BufferDescriptor { + label: Some("(wgpu-core) instances_buffer"), + size: instance_buffer_size as u64, + usage: hal::BufferUses::COPY_DST + | hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + memory_flags: hal::MemoryFlags::PREFER_COHERENT, + }) + } + .map_err(DeviceError::from)?; + Ok(resource::Tlas { raw: Some(raw), device_id: Stored { @@ -133,6 +149,7 @@ impl Device { flags: desc.flags, update_mode: desc.update_mode, built: Mutex::new(false), + instance_buffer, }) } } @@ -147,7 +164,7 @@ impl Global { desc: &resource::BlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, id_in: Input, - ) -> (BlasId, Option, Option) { + ) -> (BlasId, Option, Option) { profiling::scope!("Device::create_blas"); let hub = A::hub(self); @@ -173,12 +190,7 @@ impl Global { Ok(blas) => blas, Err(e) => break e, }; - - let handle = unsafe { - device - .raw - .get_acceleration_structure_device_address(blas.raw.as_ref().unwrap()) - }; + let handle = blas.handle; let ref_count = blas.life_guard.add_ref(); @@ -202,7 +214,7 @@ impl Global { device_id: id::DeviceId, desc: &resource::TlasDescriptor, id_in: Input, - ) -> (TlasId, Option) { + ) -> (TlasId, Option) { profiling::scope!("Device::create_tlas"); let hub = A::hub(self); diff --git a/wgpu-core/src/device/trace.rs b/wgpu-core/src/device/trace.rs index 8558bb0620..bd7e723f34 100644 --- a/wgpu-core/src/device/trace.rs +++ b/wgpu-core/src/device/trace.rs @@ -195,6 +195,10 @@ pub enum Command { blas: Vec, tlas: Vec, }, + BuildAccelerationStructures { + blas: Vec, + tlas: Vec, + }, } #[cfg(feature = "trace")] diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 183c0a785b..f050228900 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -1,17 +1,53 @@ +/// Ray tracing +/// Major missing optimizations (no api surface changes needed): +/// - use custom tracker to track build state instead of mutex +/// - 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::{ptr, slice}; + use crate::{ command::CommandEncoderError, + device::DeviceError, + hub::HalApi, id::{BlasId, BufferId, TlasId}, + resource::CreateBufferError, }; use thiserror::Error; use wgt::BufferAddress; +#[derive(Clone, Debug, Error)] +pub enum CreateBlasError { + #[error(transparent)] + Device(#[from] DeviceError), + #[error(transparent)] + CreateBufferError(#[from] CreateBufferError), + #[error("Unimplemented Blas error: this error is not yet implemented")] + Unimplemented, +} + +#[derive(Clone, Debug, Error)] +pub enum CreateTlasError { + #[error(transparent)] + Device(#[from] DeviceError), + #[error(transparent)] + CreateBufferError(#[from] CreateBufferError), + #[error("Unimplemented Tlas error: this error is not yet implemented")] + Unimplemented, +} + /// Error encountered while attempting to do a copy on a command encoder. #[derive(Clone, Debug, Error)] pub enum BuildAccelerationStructureError { #[error(transparent)] Encoder(#[from] CommandEncoderError), + #[error(transparent)] + Device(#[from] DeviceError), + #[error("Buffer {0:?} is invalid or destroyed")] InvalidBuffer(BufferId), @@ -43,6 +79,9 @@ pub enum BuildAccelerationStructureError { #[error("Blas {0:?} is invalid or destroyed")] InvalidBlas(BlasId), + #[error("Blas {0:?} is invalid or destroyed (for instance)")] + InvalidBlasForInstance(BlasId), + #[error("Tlas {0:?} is invalid or destroyed")] InvalidTlas(TlasId), @@ -98,6 +137,20 @@ pub struct TlasBuildEntry { pub instance_count: u32, } +#[derive(Debug)] +pub struct TlasInstance<'a> { + pub blas_id: BlasId, + pub transform: &'a [f32; 12], + pub custom_index: u32, + pub mask: u8, +} + +pub struct TlasPackage<'a> { + pub tlas_id: TlasId, + pub instances: Box>> + 'a>, + pub lowest_unmodified: u32, +} + #[derive(Debug, Copy, Clone)] pub(crate) enum AccelerationStructureActionKind { Build, @@ -143,4 +196,68 @@ pub enum TraceBlasGeometries { pub struct TraceBlasBuildEntry { pub blas_id: BlasId, pub geometries: TraceBlasGeometries, -} \ No newline at end of file +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +pub struct TraceTlasInstance { + pub blas_id: BlasId, + pub transform: [f32; 12], + pub custom_index: u32, + pub mask: u8, +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +pub struct TraceTlasPackage { + pub tlas_id: TlasId, + pub instances: Vec>, + pub lowest_unmodified: u32, +} + +pub(crate) fn getRawTlasInstanceSize() -> usize { + match A::VARIANT { + wgt::Backend::Empty => 0, + wgt::Backend::Vulkan => 64, + _ => unimplemented!(), + } +} + +#[derive(Clone)] +#[repr(C)] +struct RawTlasInstance { + transform: [f32; 12], + custom_index_and_mask: u32, + shader_binding_table_record_offset_and_flags: u32, + acceleration_structure_reference: u64, +} + +pub(crate) fn tlas_instance_into_bytes( + instance: &TlasInstance, + blas_address: u64, +) -> Vec { + match A::VARIANT { + wgt::Backend::Empty => vec![], + wgt::Backend::Vulkan => { + const MAX_U24: u32 = (1u32 << 24u32) - 1u32; + let temp = RawTlasInstance { + transform: instance.transform.clone(), + custom_index_and_mask: (instance.custom_index & MAX_U24) + | (u32::from(instance.mask) << 24), + shader_binding_table_record_offset_and_flags: 0, + acceleration_structure_reference: blas_address, + }; + let temp: *const _ = &temp; + unsafe { + slice::from_raw_parts::( + temp as *const u8, + std::mem::size_of::(), + ) + .to_vec() + } + } + _ => unimplemented!(), + } +} diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 3d7301f6dc..5a690d9d2e 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -809,6 +809,7 @@ pub struct Blas { pub(crate) flags: wgt::AccelerationStructureFlags, pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, pub(crate) built: Mutex, + pub(crate) handle: u64, } impl Resource for Blas { @@ -827,6 +828,7 @@ pub struct Tlas { pub(crate) flags: wgt::AccelerationStructureFlags, pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, pub(crate) built: Mutex, + pub(crate) instance_buffer: A::Buffer, } impl Resource for Tlas { @@ -836,23 +838,3 @@ impl Resource for Tlas { &self.life_guard } } - -#[derive(Clone, Debug, Error)] -pub enum CreateBlasError { - #[error(transparent)] - Device(#[from] DeviceError), - #[error(transparent)] - CreateBufferError(#[from] CreateBufferError), - #[error("Unimplemented Blas error: this error is not yet implemented")] - Unimplemented, -} - -#[derive(Clone, Debug, Error)] -pub enum CreateTlasError { - #[error(transparent)] - Device(#[from] DeviceError), - #[error(transparent)] - CreateBufferError(#[from] CreateBufferError), - #[error("Unimplemented Tlas error: this error is not yet implemented")] - Unimplemented, -} diff --git a/wgpu/examples/ray-cube/main.rs b/wgpu/examples/ray-cube/main.rs index d129484774..ecb526c0dd 100644 --- a/wgpu/examples/ray-cube/main.rs +++ b/wgpu/examples/ray-cube/main.rs @@ -251,9 +251,7 @@ struct Example { vertex_buf: wgpu::Buffer, index_buf: wgpu::Buffer, blas: wgpu::Blas, - tlas: wgpu::Tlas, - instance: AccelerationStructureInstance, - instance_buf: wgpu::Buffer, + tlas_package: wgpu::TlasPackage, compute_pipeline: wgpu::ComputePipeline, compute_bind_group: wgpu::BindGroup, blit_pipeline: wgpu::RenderPipeline, @@ -381,28 +379,6 @@ impl framework::Example for Example { max_instances: 1, }); - let instance = AccelerationStructureInstance::new( - &Affine3A::from_rotation_translation( - Quat::from_rotation_x(45.9_f32.to_radians()), - Vec3 { - x: 0.0, - y: 0.0, - z: -3.0, - }, - ), - 0, - 0xff, - 0, - 0, - blas.handle().unwrap(), - ); - - let instance_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Instance Buffer"), - contents: bytemuck::cast_slice(&[instance]), - usage: wgpu::BufferUsages::TLAS_INPUT | wgpu::BufferUsages::COPY_DST, - }); - let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("rt_computer"), source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), @@ -480,10 +456,26 @@ impl framework::Example for Example { ], }); + let mut tlas_package = wgpu::TlasPackage::new(tlas, 1); + + *tlas_package.get_mut_single(0).unwrap() = Some(wgpu::TlasInstance::new( + &blas, + AccelerationStructureInstance::affine_to_rows(&Affine3A::from_rotation_translation( + Quat::from_rotation_x(45.9_f32.to_radians()), + Vec3 { + x: 0.0, + y: 0.0, + z: -3.0, + }, + )), + 0, + 0xff, + )); + let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); unsafe { - encoder.build_acceleration_structures_unsafe_tlas( + encoder.build_acceleration_structures( iter::once(&wgpu::BlasBuildEntry { blas: &blas, geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ @@ -499,12 +491,32 @@ impl framework::Example for Example { }, ]), }), - iter::once(&wgpu::TlasBuildEntry { - tlas: &tlas, - instance_buffer: &instance_buf, - instance_count: 1, - }), + // iter::empty(), + iter::once(&tlas_package), ); + + // encoder.build_acceleration_structures_unsafe_tlas( + // iter::once(&wgpu::BlasBuildEntry { + // blas: &blas, + // geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ + // wgpu::BlasTriangleGeometry { + // size: &blas_geo_size_desc, + // vertex_buffer: &vertex_buf, + // first_vertex: 0, + // vertex_stride: mem::size_of::() as u64, + // index_buffer: Some(&index_buf), + // index_buffer_offset: Some(0), + // transform_buffer: None, + // transform_buffer_offset: None, + // }, + // ]), + // }), + // iter::once(&wgpu::TlasBuildEntry { + // tlas: &tlas, + // instance_buffer: &instance_buf, + // instance_count: 1, + // }), + // ); } queue.submit(Some(encoder.finish())); @@ -518,9 +530,7 @@ impl framework::Example for Example { vertex_buf, index_buf, blas, - tlas, - instance, - instance_buf, + tlas_package, compute_pipeline, compute_bind_group, blit_pipeline, @@ -551,8 +561,14 @@ impl framework::Example for Example { device.push_error_scope(wgpu::ErrorFilter::Validation); let anim_time = self.start_inst.elapsed().as_secs_f64() as f32; - self.instance - .set_transform(&Affine3A::from_rotation_translation( + + self.tlas_package + .get_mut_single(0) + .unwrap() + .as_mut() + .unwrap() + .transform = + AccelerationStructureInstance::affine_to_rows(&Affine3A::from_rotation_translation( Quat::from_euler( glam::EulerRot::XYZ, anim_time * 0.342, @@ -565,24 +581,12 @@ impl framework::Example for Example { z: -3.0, }, )); - queue.write_buffer( - &self.instance_buf, - 0, - bytemuck::cast_slice(&[self.instance]), - ); let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); unsafe { - encoder.build_acceleration_structures_unsafe_tlas( - iter::empty(), - iter::once(&wgpu::TlasBuildEntry { - tlas: &self.tlas, - instance_buffer: &self.instance_buf, - instance_count: 1, - }), - ); + encoder.build_acceleration_structures(iter::empty(), iter::once(&self.tlas_package)); } { diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index b85dbb662b..cd8d9e9443 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -2,10 +2,11 @@ use crate::{ context::{ObjectId, Unused}, AdapterInfo, BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BufferBinding, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, - DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, Operations, - PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, - SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, ShaderSource, - SurfaceStatus, TextureDescriptor, TextureViewDescriptor, UncapturedErrorHandler, + ContextTlasInstance, ContextTlasPackage, DownlevelCapabilities, Features, Label, Limits, + LoadOp, MapMode, Operations, PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, + RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, + ShaderModuleDescriptorSpirV, ShaderSource, SurfaceStatus, TextureDescriptor, + TextureViewDescriptor, UncapturedErrorHandler, }; use arrayvec::ArrayVec; @@ -3061,9 +3062,76 @@ impl crate::Context for Context { if let Err(cause) = wgc::gfx_select!(encoder => global.command_encoder_build_acceleration_structures_unsafe_tlas( *encoder, - { - blas - }, + blas, + tlas + )) { + self.handle_error_nolabel( + &encoder_data.error_sink, + cause, + "CommandEncoder::build_acceleration_structures_unsafe_tlas", + ); + } + } + + fn command_encoder_build_acceleration_structures<'a>( + &'a self, + encoder: &Self::CommandEncoderId, + encoder_data: &Self::CommandEncoderData, + blas: impl Iterator>, + tlas: impl Iterator>, + ) { + let global = &self.0; + + let blas = blas.map(|e: crate::ContextBlasBuildEntry| { + let geometries = match e.geometries { + crate::ContextBlasGeometries::TriangleGeometries(triangle_geometries) => { + let iter = triangle_geometries.into_iter().map(|tg| { + wgc::ray_tracing::BlasTriangleGeometry { + vertex_buffer: tg.vertex_buffer, + index_buffer: tg.index_buffer, + transform_buffer: tg.transform_buffer, + size: tg.size, + transform_buffer_offset: tg.transform_buffer_offset, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + } + }); + wgc::ray_tracing::BlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + wgc::ray_tracing::BlasBuildEntry { + blas_id: e.blas_id, + geometries, + } + }); + + let mut tlas = tlas.into_iter().map(|e| { + let instances = + e.instances + .into_iter() + .map(|instance: Option>| { + if let Some(instance) = instance { + Some(wgc::ray_tracing::TlasInstance { + blas_id: instance.blas_id, + transform: instance.transform, + custom_index: instance.custom_index, + mask: instance.mask, + }) + } else { + None + } + }); + wgc::ray_tracing::TlasPackage { + tlas_id: e.tlas_id, + instances: Box::new(instances), + lowest_unmodified: e.lowest_unmodified, + } + }); + + if let Err(cause) = wgc::gfx_select!(encoder => global.command_encoder_build_acceleration_structures( + *encoder, + blas, tlas )) { self.handle_error_nolabel( diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 0ad993841e..ea8132fc35 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -10,13 +10,13 @@ use wgt::{ use crate::{ BindGroupDescriptor, BindGroupLayoutDescriptor, Buffer, BufferAsyncError, BufferDescriptor, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, - ContextBlasTriangleGeometry, CreateBlasDescriptor, CreateTlasDescriptor, DeviceDescriptor, - Error, ErrorFilter, ImageCopyBuffer, ImageCopyTexture, Maintain, MapMode, - PipelineLayoutDescriptor, QuerySetDescriptor, RenderBundleDescriptor, - RenderBundleEncoderDescriptor, RenderPassDescriptor, RenderPipelineDescriptor, - RequestAdapterOptions, RequestDeviceError, SamplerDescriptor, ShaderModuleDescriptor, - ShaderModuleDescriptorSpirV, Texture, TextureDescriptor, TextureViewDescriptor, - UncapturedErrorHandler, + ContextBlasTriangleGeometry, ContextTlasInstance, ContextTlasPackage, CreateBlasDescriptor, + CreateTlasDescriptor, DeviceDescriptor, DynContextTlasInstance, DynContextTlasPackage, Error, + ErrorFilter, ImageCopyBuffer, ImageCopyTexture, Maintain, MapMode, PipelineLayoutDescriptor, + QuerySetDescriptor, RenderBundleDescriptor, RenderBundleEncoderDescriptor, + RenderPassDescriptor, RenderPipelineDescriptor, RequestAdapterOptions, RequestDeviceError, + SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, Texture, + TextureDescriptor, TextureViewDescriptor, UncapturedErrorHandler, }; /// Meta trait for an id tracked by a context. @@ -1016,6 +1016,13 @@ pub trait Context: Debug + Send + Sized + Sync { blas: impl Iterator>, tlas: impl Iterator>, ); + fn command_encoder_build_acceleration_structures<'a>( + &'a self, + encoder: &Self::CommandEncoderId, + encoder_data: &Self::CommandEncoderData, + blas: impl Iterator>, + tlas: impl Iterator>, + ); fn blas_destroy(&self, blas: &Self::BlasId, blas_data: &Self::BlasData); fn blas_drop(&self, blas: &Self::BlasId, blas_data: &Self::BlasData); fn tlas_destroy(&self, tlas: &Self::TlasId, tlas_data: &Self::TlasData); @@ -1955,6 +1962,13 @@ pub(crate) trait DynContext: Debug + Send + Sync { blas: &mut dyn Iterator>, tlas: &mut dyn Iterator, ); + fn command_encoder_build_acceleration_structures<'a>( + &self, + encoder: &ObjectId, + encoder_data: &crate::Data, + blas: &mut dyn Iterator>, + tlas: &mut dyn Iterator, + ); fn blas_destroy(&self, blas: &ObjectId, blas_data: &crate::Data); fn blas_drop(&self, blas: &ObjectId, blas_data: &crate::Data); fn tlas_destroy(&self, tlas: &ObjectId, tlas_data: &crate::Data); @@ -3991,6 +4005,74 @@ where ) } + fn command_encoder_build_acceleration_structures<'a>( + &self, + encoder: &ObjectId, + encoder_data: &crate::Data, + blas: &mut dyn Iterator>, + tlas: &mut dyn Iterator, + ) { + let encoder = ::from(*encoder); + let encoder_data = downcast_ref(encoder_data); + + let blas = blas.into_iter().map(|e| { + let geometries = match e.geometries { + crate::DynContextBlasGeometries::TriangleGeometries(triangle_geometries) => { + let iter = + triangle_geometries + .into_iter() + .map(|tg| ContextBlasTriangleGeometry { + vertex_buffer: ::from(tg.vertex_buffer), + index_buffer: tg.index_buffer.map(::from), + transform_buffer: tg.transform_buffer.map(::from), + size: tg.size, + transform_buffer_offset: tg.transform_buffer_offset, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + }); + crate::ContextBlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + crate::ContextBlasBuildEntry { + blas_id: ::from(e.blas_id), + // blas_data: downcast_ref(e.blas_data), + geometries, + } + }); + + let mut tlas = tlas.into_iter().map(|e: DynContextTlasPackage| { + let instances = + e.instances + .into_iter() + .map(|instance: Option| { + if let Some(instance) = instance { + Some(ContextTlasInstance { + blas_id: ::from(instance.blas), + transform: instance.transform, + custom_index: instance.custom_index, + mask: instance.mask, + }) + } else { + None + } + }); + ContextTlasPackage { + tlas_id: ::from(e.tlas_id), + instances: Box::new(instances), + lowest_unmodified: e.lowest_unmodified, + } + }); + + Context::command_encoder_build_acceleration_structures( + self, + &encoder, + encoder_data, + blas, + tlas, + ) + } + fn blas_destroy(&self, blas: &ObjectId, blas_data: &crate::Data) { let blas = ::from(*blas); let blas_data = downcast_ref(blas_data); diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index fe3d6a413c..4a04938f0a 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -3028,6 +3028,72 @@ impl CommandEncoder { &mut tlas, ); } + + /// Build bottom and top level acceleration structures + pub unsafe fn build_acceleration_structures<'a>( + &mut self, + blas: impl IntoIterator>, + tlas: impl IntoIterator, + ) { + let id = self.id.as_ref().unwrap(); + + let mut blas = blas.into_iter().map(|e: &BlasBuildEntry| { + let geometries = match e.geometry { + BlasGeometries::TriangleGeometries(triangle_geometries) => { + let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry| { + DynContextBlasTriangleGeometry { + size: tg.size, + vertex_buffer: tg.vertex_buffer.id, + + index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.id), + + transform_buffer: tg + .transform_buffer + .map(|transform_buffer| transform_buffer.id), + + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + } + }); + DynContextBlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + DynContextBlasBuildEntry { + blas_id: e.blas.id, + geometries, + } + }); + + let mut tlas = tlas.into_iter().map(|e: &TlasPackage| { + let instances = e.instances.iter().map(|instance: &Option| { + if let Some(instance) = instance { + Some(DynContextTlasInstance { + blas: instance.blas, + transform: &instance.transform, + custom_index: instance.custom_index, + mask: instance.mask, + }) + } else { + None + } + }); + DynContextTlasPackage { + tlas_id: e.tlas.id, + instances: Box::new(instances), + lowest_unmodified: e.lowest_unmodified, + } + }); + + DynContext::command_encoder_build_acceleration_structures( + &*self.context, + id, + self.data.as_ref(), + &mut blas, + &mut tlas, + ); + } } /// [`Features::TIMESTAMP_QUERY`] must be enabled on the device in order to call these functions. @@ -4716,6 +4782,95 @@ pub struct TlasBuildEntry<'a> { } static_assertions::assert_impl_all!(TlasBuildEntry: Send, Sync); +/// TODO Docu +/// Very unstable +#[derive(Debug, Clone)] +pub struct TlasInstance { + blas: ObjectId, + pub transform: [f32; 12], + pub custom_index: u32, + pub mask: u8, +} + +impl TlasInstance { + pub fn new(blas: &Blas, transform: [f32; 12], custom_index: u32, mask: u8) -> Self { + Self { + blas: blas.id, + transform, + custom_index, + mask, + } + } + + pub fn set_blas(&mut self, blas: &Blas) { + self.blas = blas.id; + } +} + +pub(crate) struct DynContextTlasInstance<'a> { + blas: ObjectId, + transform: &'a [f32; 12], + custom_index: u32, + mask: u8, +} + +pub struct ContextTlasInstance<'a, T: Context> { + blas_id: T::BlasId, + transform: &'a [f32; 12], + custom_index: u32, + mask: u8, +} + +pub struct TlasPackage { + tlas: Tlas, + instances: Vec>, + lowest_unmodified: u32, +} +static_assertions::assert_impl_all!(TlasPackage: Send, Sync); + +impl TlasPackage { + /// TODO Docu + pub fn new(tlas: Tlas, max_instances: u32) -> Self { + Self::new_with_instances(tlas, vec![None; max_instances as usize]) + } + + /// TODO Docu + pub fn new_with_instances(tlas: Tlas, instances: Vec>) -> Self { + Self { + tlas, + lowest_unmodified: instances.len() as u32, + instances, + } + } + + /// TODO Docu + pub fn get(&self) -> &[Option] { + &self.instances + } + + /// TODO Docu + pub fn get_mut_slice(&mut self, range: Range) -> Option<&mut [Option]> { + if range.end > self.instances.len() { + return None; + } + if range.end as u32 > self.lowest_unmodified { + self.lowest_unmodified = range.end as u32; + } + Some(&mut self.instances[range]) + } + + /// TODO Docu + pub fn get_mut_single(&mut self, index: usize) -> Option<&mut Option> { + if index >= self.instances.len() { + return None; + } + if index as u32 + 1 > self.lowest_unmodified { + self.lowest_unmodified = index as u32 + 1; + } + Some(&mut self.instances[index]) + } +} + pub(crate) struct DynContextBlasTriangleGeometry<'a> { size: &'a BlasTriangleGeometrySizeDescriptor, vertex_buffer: ObjectId, @@ -4742,6 +4897,12 @@ pub(crate) struct DynContextTlasBuildEntry { instance_count: u32, } +pub(crate) struct DynContextTlasPackage<'a> { + tlas_id: ObjectId, + instances: Box>> + 'a>, + lowest_unmodified: u32, +} + /// TODO Docu pub struct ContextBlasTriangleGeometry<'a, T: Context> { size: &'a BlasTriangleGeometrySizeDescriptor, @@ -4775,3 +4936,10 @@ pub struct ContextTlasBuildEntry { // instance_buffer_data: &'a T::BufferData, instance_count: u32, } + +/// TODO Docu +pub struct ContextTlasPackage<'a, T: Context> { + tlas_id: T::TlasId, + instances: Box>> + 'a>, + lowest_unmodified: u32, +} From 0f8119543e9fc908e56a124b610d3f965ca67036 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 5 Apr 2023 07:50:08 +0200 Subject: [PATCH 055/146] fixed destructors, destructor tracing and working tracing for safe build --- player/src/lib.rs | 64 ++++++++++++++++++++++++++++ wgpu-core/src/command/ray_tracing.rs | 6 +-- wgpu-core/src/device/life.rs | 25 +++++++---- wgpu-core/src/device/ray_tracing.rs | 31 ++++++++------ wgpu-core/src/device/trace.rs | 4 ++ wgpu-core/src/resource.rs | 2 +- 6 files changed, 107 insertions(+), 25 deletions(-) diff --git a/player/src/lib.rs b/player/src/lib.rs index 816dc70c31..68c01b7a68 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -174,6 +174,58 @@ impl GlobalPlay for wgc::hub::Global { ) .unwrap(); } + trace::Command::BuildAccelerationStructures { blas, tlas } => { + let blas_iter = (&blas).into_iter().map(|x| { + let geometries = match &x.geometries { + wgc::ray_tracing::TraceBlasGeometries::TriangleGeometries( + triangle_geometries, + ) => { + let iter = triangle_geometries.into_iter().map(|tg| { + wgc::ray_tracing::BlasTriangleGeometry { + size: &tg.size, + vertex_buffer: tg.vertex_buffer, + index_buffer: tg.index_buffer, + transform_buffer: tg.transform_buffer, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + } + }); + wgc::ray_tracing::BlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + wgc::ray_tracing::BlasBuildEntry { + blas_id: x.blas_id, + geometries: geometries, + } + }); + + let tlas_iter = (&tlas).into_iter().map(|x| { + let instances = x.instances.iter().map(|instance| { + if let Some(ref instance) = instance { + Some(wgc::ray_tracing::TlasInstance { + blas_id: instance.blas_id, + transform: &instance.transform, + custom_index: instance.custom_index, + mask: instance.mask, + }) + } else { + None + } + }); + wgc::ray_tracing::TlasPackage { + tlas_id: x.tlas_id, + instances: Box::new(instances), + lowest_unmodified: x.lowest_unmodified, + } + }); + + self.command_encoder_build_acceleration_structures::( + encoder, blas_iter, tlas_iter, + ) + .unwrap(); + } } } let (cmd_buf, error) = self @@ -423,10 +475,22 @@ impl GlobalPlay for wgc::hub::Global { self.device_maintain_ids::(device).unwrap(); self.device_create_blas::(device, &desc, sizes, id); } + Action::FreeBlas(id) => { + self.blas_destroy::(id).unwrap(); + } + Action::DestroyBlas(id) => { + self.blas_drop::(id, true); + } Action::CreateTlas { id, desc } => { self.device_maintain_ids::(device).unwrap(); self.device_create_tlas::(device, &desc, id); } + Action::FreeTlas(id) => { + self.tlas_destroy::(id).unwrap(); + } + Action::DestroyTlas(id) => { + self.tlas_drop::(id, true); + } } } } diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 0b713f0333..b89eba5fcd 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1057,7 +1057,7 @@ impl Global { tlas_storage.push(( tlas, hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { - buffer: Some(&tlas.instance_buffer), + buffer: Some(tlas.instance_buffer.as_ref().unwrap()), offset: 0, count: instance_count, }), @@ -1169,7 +1169,7 @@ impl Global { None } else { Some(hal::BufferBarrier:: { - buffer: &tlas.instance_buffer, + buffer: tlas.instance_buffer.as_ref().unwrap(), usage: hal::BufferUses::COPY_DST ..hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, }) @@ -1217,7 +1217,7 @@ impl Global { }; cmd_buf_raw.copy_buffer_to_buffer( &staging_buffer, - &tlas.instance_buffer, + tlas.instance_buffer.as_ref().unwrap(), iter::once(temp), ); } diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index f357d587fe..7698570056 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -821,10 +821,10 @@ impl LifetimeTracker { for id in self.suspected_resources.blas_s.drain(..) { if trackers.blas_s.remove_abandoned(id) { log::debug!("Blas {:?} will be destroyed", id); - // #[cfg(feature = "trace")] - // if let Some(t) = trace { - // t.lock().add(trace::Action::DestroyBlas(id.0)); - // } + #[cfg(feature = "trace")] + if let Some(t) = trace { + t.lock().add(trace::Action::DestroyBlas(id.0)); + } if let Some(res) = hub.blas_s.unregister_locked(id.0, &mut *guard) { let submit_index = res.life_guard.life_count(); @@ -845,11 +845,11 @@ impl LifetimeTracker { for id in self.suspected_resources.tlas_s.drain(..) { if trackers.tlas_s.remove_abandoned(id) { - log::debug!("Blas {:?} will be destroyed", id); - // #[cfg(feature = "trace")] - // if let Some(t) = trace { - // t.lock().add(trace::Action::DestroyBlas(id.0)); - // } + log::debug!("Tlas {:?} will be destroyed", id); + #[cfg(feature = "trace")] + if let Some(t) = trace { + t.lock().add(trace::Action::DestroyTlas(id.0)); + } if let Some(res) = hub.tlas_s.unregister_locked(id.0, &mut *guard) { let submit_index = res.life_guard.life_count(); @@ -859,6 +859,13 @@ impl LifetimeTracker { .map_or(&mut self.free_resources, |a| &mut a.last_resources) .acceleration_structures .extend(res.raw); + + self.active + .iter_mut() + .find(|a| a.index == submit_index) + .map_or(&mut self.free_resources, |a| &mut a.last_resources) + .buffers + .extend(res.instance_buffer); } } } diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 69409ac17e..13167fe3ec 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -149,7 +149,7 @@ impl Device { flags: desc.flags, update_mode: desc.update_mode, built: Mutex::new(false), - instance_buffer, + instance_buffer: Some(instance_buffer), }) } } @@ -269,10 +269,10 @@ impl Global { let device = &mut device_guard[blas.device_id.value]; - // #[cfg(feature = "trace")] - // if let Some(ref trace) = device.trace { - // trace.lock().add(trace::Action::FreeBlas(blas_id)); - // } + #[cfg(feature = "trace")] + if let Some(ref trace) = device.trace { + trace.lock().add(trace::Action::FreeBlas(blas_id)); + } let raw = blas .raw @@ -347,22 +347,29 @@ impl Global { let device = &mut device_guard[tlas.device_id.value]; - // #[cfg(feature = "trace")] - // if let Some(ref trace) = device.trace { - // trace.lock().add(trace::Action::FreeTlas(tlas_id)); - // } + #[cfg(feature = "trace")] + if let Some(ref trace) = device.trace { + trace.lock().add(trace::Action::FreeTlas(tlas_id)); + } let raw = tlas .raw .take() .ok_or(resource::DestroyError::AlreadyDestroyed)?; + let temp = TempResource::AccelerationStructure(raw); + + let raw_instance_buffer = tlas.instance_buffer.take(); + let temp_instance_buffer = raw_instance_buffer.map(|e| TempResource::Buffer(e)); { let last_submit_index = tlas.life_guard.life_count(); drop(tlas_guard); - device - .lock_life(&mut token) - .schedule_resource_destruction(temp, last_submit_index); + let guard = &mut device.lock_life(&mut token); + + guard.schedule_resource_destruction(temp, last_submit_index); + if let Some(temp_instance_buffer) = temp_instance_buffer { + guard.schedule_resource_destruction(temp_instance_buffer, last_submit_index); + } } Ok(()) diff --git a/wgpu-core/src/device/trace.rs b/wgpu-core/src/device/trace.rs index bd7e723f34..9d67c1a44f 100644 --- a/wgpu-core/src/device/trace.rs +++ b/wgpu-core/src/device/trace.rs @@ -128,10 +128,14 @@ pub enum Action<'a> { desc: crate::resource::BlasDescriptor<'a>, sizes: wgt::BlasGeometrySizeDescriptors, }, + FreeBlas(id::BlasId), + DestroyBlas(id::BlasId), CreateTlas { id: id::TlasId, desc: crate::resource::TlasDescriptor<'a>, }, + FreeTlas(id::TlasId), + DestroyTlas(id::TlasId), } #[derive(Debug)] diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 5a690d9d2e..e7d687dab5 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -828,7 +828,7 @@ pub struct Tlas { pub(crate) flags: wgt::AccelerationStructureFlags, pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, pub(crate) built: Mutex, - pub(crate) instance_buffer: A::Buffer, + pub(crate) instance_buffer: Option, } impl Resource for Tlas { From 9a33bf93cd58621610d9540f94cffa14a27cde9e Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 5 Apr 2023 11:05:32 +0200 Subject: [PATCH 056/146] build age validation --- wgpu-core/src/command/compute.rs | 12 +- wgpu-core/src/command/ray_tracing.rs | 225 +++++++++++++++++---------- wgpu-core/src/command/render.rs | 11 +- wgpu-core/src/device/mod.rs | 2 + wgpu-core/src/device/queue.rs | 8 +- wgpu-core/src/device/ray_tracing.rs | 5 +- wgpu-core/src/ray_tracing.rs | 28 +++- wgpu-core/src/resource.rs | 7 +- wgpu/examples/ray-cube/main.rs | 87 +++++------ wgpu/src/lib.rs | 2 +- 10 files changed, 227 insertions(+), 160 deletions(-) diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 2d65ae3c11..8a3014a976 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -452,14 +452,12 @@ impl Global { } cmd_buf.tlas_actions.extend( - bind_group.used.acceleration_structures.used().filter_map(|id| { + bind_group.used.acceleration_structures.used().map(|id| { let tlas = &tlas_guard[id]; - if *tlas.built.lock() { - None - } - else - { - Some(crate::ray_tracing::TlasAction{ id: id.0, kind: crate::ray_tracing::AccelerationStructureActionKind::Use }) + + crate::ray_tracing::TlasAction { + id: id.0, + kind: crate::ray_tracing::TlasActionKind::Use, } }), ); diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index b89eba5fcd..b9083a4d04 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -10,7 +10,7 @@ use crate::{ TraceTlasInstance, ValidateBlasActionsError, ValidateTlasActionsError, }, resource::{Blas, StagingBuffer, Tlas}, - FastHashSet, + FastHashMap, FastHashSet, }; use hal::{CommandEncoder, Device}; @@ -42,6 +42,14 @@ impl Global { let device = &mut device_guard[cmd_buf.device_id.value]; + let build_command_index = NonZeroU64::new( + device + .last_acceleration_structure_build_command_index + .fetch_add(1, std::sync::atomic::Ordering::Relaxed) + + 1, + ) + .unwrap(); + #[cfg(feature = "trace")] let trace_blas: Vec = blas_iter .map(|x| { @@ -132,12 +140,10 @@ impl Global { return Err(BuildAccelerationStructureError::InvalidBlas(entry.blas_id)); } - if !*blas.built.lock() { - cmd_buf.blas_actions.push(BlasAction { - id: entry.blas_id, - kind: crate::ray_tracing::AccelerationStructureActionKind::Build, - }); - } + cmd_buf.blas_actions.push(BlasAction { + id: entry.blas_id, + kind: crate::ray_tracing::BlasActionKind::Build(build_command_index), + }); match entry.geometries { BlasGeometries::TriangleGeometries(triangle_geometries) => { @@ -459,12 +465,13 @@ impl Global { return Err(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id)); } - if !*tlas.built.lock() { - cmd_buf.tlas_actions.push(TlasAction { - id: entry.tlas_id, - kind: crate::ray_tracing::AccelerationStructureActionKind::Build, - }); - } + cmd_buf.tlas_actions.push(TlasAction { + id: entry.tlas_id, + kind: crate::ray_tracing::TlasActionKind::Build { + build_index: build_command_index, + dependencies: Vec::new(), + }, + }); let scratch_buffer_offset = scratch_buffer_tlas_size; scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; // TODO Alignment @@ -509,7 +516,6 @@ impl Global { if blas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { log::info!("only rebuild implemented") } - *blas.built.lock() = true; hal::BuildAccelerationStructureDescriptor { entries, mode: hal::AccelerationStructureBuildMode::Build, // TODO @@ -528,7 +534,6 @@ impl Global { if tlas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { log::info!("only rebuild implemented") } - *tlas.built.lock() = true; hal::BuildAccelerationStructureDescriptor { entries, mode: hal::AccelerationStructureBuildMode::Build, // TODO @@ -590,6 +595,14 @@ impl Global { let device = &mut device_guard[cmd_buf.device_id.value]; + let build_command_index = NonZeroU64::new( + device + .last_acceleration_structure_build_command_index + .fetch_add(1, std::sync::atomic::Ordering::Relaxed) + + 1, + ) + .unwrap(); + #[cfg(feature = "trace")] let trace_blas: Vec = blas_iter .map(|x| { @@ -718,12 +731,10 @@ impl Global { return Err(BuildAccelerationStructureError::InvalidBlas(entry.blas_id)); } - if !*blas.built.lock() { - cmd_buf.blas_actions.push(BlasAction { - id: entry.blas_id, - kind: crate::ray_tracing::AccelerationStructureActionKind::Build, - }); - } + cmd_buf.blas_actions.push(BlasAction { + id: entry.blas_id, + kind: crate::ray_tracing::BlasActionKind::Build(build_command_index), + }); match entry.geometries { BlasGeometries::TriangleGeometries(triangle_geometries) => { @@ -1023,18 +1034,13 @@ impl Global { return Err(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id)); } - if !*tlas.built.lock() { - cmd_buf.tlas_actions.push(TlasAction { - id: entry.tlas_id, - kind: crate::ray_tracing::AccelerationStructureActionKind::Build, - }); - } - let scratch_buffer_offset = scratch_buffer_tlas_size; scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; // TODO Alignment let first_byte_index = instance_buffer_staging_source.len(); + let mut dependencies = Vec::new(); + let mut instance_count = 0; for instance in entry.instances { if let Some(instance) = instance { @@ -1051,9 +1057,24 @@ impl Global { .extend(tlas_instance_into_bytes::(&instance, blas.handle)); instance_count += 1; + + dependencies.push(instance.blas_id); + + cmd_buf.blas_actions.push(BlasAction { + id: instance.blas_id, + kind: crate::ray_tracing::BlasActionKind::Use, + }); } } + cmd_buf.tlas_actions.push(TlasAction { + id: entry.tlas_id, + kind: crate::ray_tracing::TlasActionKind::Build { + build_index: build_command_index, + dependencies, + }, + }); + tlas_storage.push(( tlas, hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { @@ -1082,37 +1103,41 @@ impl Global { .map_err(crate::device::DeviceError::from)? }; - let staging_buffer = unsafe { - device - .raw - .create_buffer(&hal::BufferDescriptor { - label: Some("(wgpu) instance staging buffer"), - size: instance_buffer_staging_source.len() as u64, - usage: hal::BufferUses::MAP_WRITE | hal::BufferUses::COPY_SRC, - memory_flags: hal::MemoryFlags::empty(), - }) - .map_err(crate::device::DeviceError::from)? - }; + let staging_buffer = if instance_buffer_staging_source.len() > 0 { + unsafe { + let staging_buffer = device + .raw + .create_buffer(&hal::BufferDescriptor { + label: Some("(wgpu) instance staging buffer"), + size: instance_buffer_staging_source.len() as u64, + usage: hal::BufferUses::MAP_WRITE | hal::BufferUses::COPY_SRC, + memory_flags: hal::MemoryFlags::empty(), + }) + .map_err(crate::device::DeviceError::from)?; - unsafe { - let mapping = device - .raw - .map_buffer( - &staging_buffer, - 0..instance_buffer_staging_source.len() as u64, - ) - .map_err(crate::device::DeviceError::from)?; - ptr::copy_nonoverlapping( - instance_buffer_staging_source.as_ptr(), - mapping.ptr.as_ptr(), - instance_buffer_staging_source.len(), - ); - device - .raw - .unmap_buffer(&staging_buffer) - .map_err(crate::device::DeviceError::from)?; - assert!(mapping.is_coherent); - } + let mapping = device + .raw + .map_buffer( + &staging_buffer, + 0..instance_buffer_staging_source.len() as u64, + ) + .map_err(crate::device::DeviceError::from)?; + ptr::copy_nonoverlapping( + instance_buffer_staging_source.as_ptr(), + mapping.ptr.as_ptr(), + instance_buffer_staging_source.len(), + ); + device + .raw + .unmap_buffer(&staging_buffer) + .map_err(crate::device::DeviceError::from)?; + assert!(mapping.is_coherent); + + Some(staging_buffer) + } + } else { + None + }; let blas_descriptors = blas_storage @@ -1121,7 +1146,6 @@ impl Global { if blas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { log::info!("only rebuild implemented") } - *blas.built.lock() = true; hal::BuildAccelerationStructureDescriptor { entries, mode: hal::AccelerationStructureBuildMode::Build, // TODO @@ -1138,7 +1162,6 @@ impl Global { if tlas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { log::info!("only rebuild implemented") } - *tlas.built.lock() = true; hal::BuildAccelerationStructureDescriptor { entries, mode: hal::AccelerationStructureBuildMode::Build, // TODO @@ -1157,11 +1180,6 @@ impl Global { ..hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, }; - let staging_buffer_barrier = hal::BufferBarrier:: { - buffer: &scratch_buffer, - usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, - }; - let instance_buffer_barriers = tlas_storage.iter().filter_map( |&(tlas, ref _entries, ref _scratch_buffer_offset, ref range)| { let size = (range.end - range.start) as u64; @@ -1201,7 +1219,10 @@ impl Global { if tlas_present { unsafe { - cmd_buf_raw.transition_buffers(iter::once(staging_buffer_barrier)); + cmd_buf_raw.transition_buffers(iter::once(hal::BufferBarrier:: { + buffer: staging_buffer.as_ref().unwrap(), + usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, + })); } for (tlas, _entries, _scratch_buffer_offset, range) in &tlas_storage { @@ -1216,7 +1237,7 @@ impl Global { size: NonZeroU64::new(size).unwrap(), }; cmd_buf_raw.copy_buffer_to_buffer( - &staging_buffer, + staging_buffer.as_ref().unwrap(), tlas.instance_buffer.as_ref().unwrap(), iter::once(temp), ); @@ -1231,12 +1252,17 @@ impl Global { cmd_buf_raw .build_acceleration_structures(tlas_storage.len() as u32, tlas_descriptors); } + + device + .pending_writes + .temp_resources + .push(TempResource::Buffer(staging_buffer.unwrap())); } - device.pending_writes.temp_resources.extend([ - TempResource::Buffer(scratch_buffer), - TempResource::Buffer(staging_buffer), - ]); + device + .pending_writes + .temp_resources + .push(TempResource::Buffer(scratch_buffer)); Ok(()) } @@ -1246,20 +1272,24 @@ impl BakedCommands { // makes sure a blas is build before it is used pub(crate) fn validate_blas_actions( &mut self, - blas_guard: &Storage, BlasId>, + blas_guard: &mut Storage, BlasId>, ) -> Result<(), ValidateBlasActionsError> { let mut built = FastHashSet::default(); for action in self.blas_actions.drain(..) { match action.kind { - crate::ray_tracing::AccelerationStructureActionKind::Build => { + crate::ray_tracing::BlasActionKind::Build(id) => { built.insert(action.id); + let blas = blas_guard + .get_mut(action.id) + .map_err(|_| ValidateBlasActionsError::InvalidBlas(action.id))?; + blas.built_index = Some(id); } - crate::ray_tracing::AccelerationStructureActionKind::Use => { + crate::ray_tracing::BlasActionKind::Use => { if !built.contains(&action.id) { let blas = blas_guard .get(action.id) .map_err(|_| ValidateBlasActionsError::InvalidBlas(action.id))?; - if !*blas.built.lock() { + if blas.built_index == None { return Err(ValidateBlasActionsError::UsedUnbuilt(action.id)); } } @@ -1272,22 +1302,47 @@ impl BakedCommands { // makes sure a tlas is build before it is used pub(crate) fn validate_tlas_actions( &mut self, - tlas_guard: &Storage, TlasId>, + blas_guard: &Storage, BlasId>, + tlas_guard: &mut Storage, TlasId>, ) -> Result<(), ValidateTlasActionsError> { - let mut built = FastHashSet::default(); for action in self.tlas_actions.drain(..) { match action.kind { - crate::ray_tracing::AccelerationStructureActionKind::Build => { - built.insert(action.id); + crate::ray_tracing::TlasActionKind::Build { + build_index, + dependencies, + } => { + let tlas = tlas_guard + .get_mut(action.id) + .map_err(|_| ValidateTlasActionsError::InvalidTlas(action.id))?; + + tlas.built_index = Some(build_index); + tlas.dependencies = dependencies; } - crate::ray_tracing::AccelerationStructureActionKind::Use => { - if !built.contains(&action.id) { - let tlas = tlas_guard - .get(action.id) - .map_err(|_| ValidateTlasActionsError::InvalidTlas(action.id))?; - if !*tlas.built.lock() { + crate::ray_tracing::TlasActionKind::Use => { + let tlas = tlas_guard + .get(action.id) + .map_err(|_| ValidateTlasActionsError::InvalidTlas(action.id))?; + + let tlas_build_index = tlas.built_index; + let dependencies = &tlas.dependencies; + + if tlas_build_index == None { + return Err(ValidateTlasActionsError::UsedUnbuilt(action.id)); + } + for dependency in dependencies { + let blas = blas_guard.get(*dependency).map_err(|_| { + ValidateTlasActionsError::InvalidBlas(*dependency, action.id) + })?; + let blas_build_index = blas.built_index; + if blas_build_index == None { return Err(ValidateTlasActionsError::UsedUnbuilt(action.id)); } + if blas_build_index.unwrap() > tlas_build_index.unwrap() { + return Err(ValidateTlasActionsError::BlasNewerThenTlas( + *dependency, + action.id, + )); + } } } } diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index c5092c48d5..ba47b4a344 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1358,14 +1358,11 @@ impl Global { } cmd_buf.tlas_actions.extend( - bind_group.used.acceleration_structures.used().filter_map(|id| { + bind_group.used.acceleration_structures.used().map(|id| { let tlas = &tlas_guard[id]; - if *tlas.built.lock() { - None - } - else - { - Some(crate::ray_tracing::TlasAction{ id: id.0, kind: crate::ray_tracing::AccelerationStructureActionKind::Use }) + crate::ray_tracing::TlasAction { + id: id.0, + kind: crate::ray_tracing::TlasActionKind::Use, } }), ); diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index c1ab065711..017822f75a 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -342,6 +342,7 @@ pub struct Device { pub(crate) pending_writes: queue::PendingWrites, #[cfg(feature = "trace")] pub(crate) trace: Option>, + pub(crate) last_acceleration_structure_build_command_index: std::sync::atomic::AtomicU64, } #[derive(Clone, Debug, Error)] @@ -461,6 +462,7 @@ impl Device { features: desc.features, downlevel, pending_writes, + last_acceleration_structure_build_command_index: std::sync::atomic::AtomicU64::new(0), }) } diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index daac9a04b2..4bd3d814b5 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -1065,8 +1065,8 @@ impl Global { let (texture_view_guard, mut token) = hub.texture_views.read(&mut token); let (sampler_guard, mut token) = hub.samplers.read(&mut token); let (query_set_guard, mut token) = hub.query_sets.read(&mut token); - let (blas_guard, mut token) = hub.blas_s.read(&mut token); - let (tlas_guard, _) = hub.tlas_s.read(&mut token); + let (mut blas_guard, mut token) = hub.blas_s.write(&mut token); + let (mut tlas_guard, _) = hub.tlas_s.write(&mut token); //Note: locking the trackers has to be done after the storages let mut trackers = device.trackers.lock(); @@ -1237,8 +1237,8 @@ impl Global { .initialize_texture_memory(&mut *trackers, &mut *texture_guard, device) .map_err(|err| QueueSubmitError::DestroyedTexture(err.0))?; - baked.validate_blas_actions(&*blas_guard)?; - baked.validate_tlas_actions(&*tlas_guard)?; + baked.validate_blas_actions(&mut *blas_guard)?; + baked.validate_tlas_actions(&*blas_guard, &mut *tlas_guard)?; //Note: stateless trackers are not merged: // device already knows these resources exist. diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 13167fe3ec..f02d17d59f 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -85,8 +85,8 @@ impl Device { sizes, flags: blas_desc.flags, update_mode: blas_desc.update_mode, - built: Mutex::new(false), handle, + built_index: None, }) } @@ -148,7 +148,8 @@ impl Device { size_info, flags: desc.flags, update_mode: desc.update_mode, - built: Mutex::new(false), + built_index: None, + dependencies: Vec::new(), instance_buffer: Some(instance_buffer), }) } diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index f050228900..c37644c344 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -6,7 +6,7 @@ /// - 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::{ptr, slice}; +use std::{num::NonZeroU64, ptr, slice}; use crate::{ command::CommandEncoderError, @@ -105,6 +105,15 @@ pub enum ValidateTlasActionsError { #[error("Tlas {0:?} is used before it is build")] UsedUnbuilt(TlasId), + + #[error("Blas {0:?} is used before it is build (in Tlas {1:?})")] + UsedUnbuiltBlas(BlasId, TlasId), + + #[error("Blas {0:?} is invalid or destroyed (in Tlas {1:?})")] + InvalidBlas(BlasId, TlasId), + + #[error("Blas {0:?} is newer than the containing Tlas {1:?}")] + BlasNewerThenTlas(BlasId, TlasId), } #[derive(Debug)] @@ -152,21 +161,30 @@ pub struct TlasPackage<'a> { } #[derive(Debug, Copy, Clone)] -pub(crate) enum AccelerationStructureActionKind { - Build, +pub(crate) enum BlasActionKind { + Build(NonZeroU64), + Use, +} + +#[derive(Debug, Clone)] +pub(crate) enum TlasActionKind { + Build { + build_index: NonZeroU64, + dependencies: Vec, + }, Use, } #[derive(Debug, Clone)] pub(crate) struct BlasAction { pub id: BlasId, - pub kind: AccelerationStructureActionKind, + pub kind: BlasActionKind, } #[derive(Debug, Clone)] pub(crate) struct TlasAction { pub id: TlasId, - pub kind: AccelerationStructureActionKind, + pub kind: TlasActionKind, } #[derive(Debug, Clone)] diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index e7d687dab5..ed9361e664 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -12,7 +12,7 @@ use parking_lot::Mutex; use smallvec::SmallVec; use thiserror::Error; -use std::{borrow::Borrow, ops::Range, ptr::NonNull}; +use std::{borrow::Borrow, num::NonZeroU64, ops::Range, ptr::NonNull}; /// The status code provided to the buffer mapping callback. /// @@ -808,7 +808,7 @@ pub struct Blas { pub(crate) sizes: wgt::BlasGeometrySizeDescriptors, pub(crate) flags: wgt::AccelerationStructureFlags, pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, - pub(crate) built: Mutex, + pub(crate) built_index: Option, pub(crate) handle: u64, } @@ -827,7 +827,8 @@ pub struct Tlas { pub(crate) size_info: hal::AccelerationStructureBuildSizes, pub(crate) flags: wgt::AccelerationStructureFlags, pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, - pub(crate) built: Mutex, + pub(crate) built_index: Option, + pub(crate) dependencies: Vec, pub(crate) instance_buffer: Option, } diff --git a/wgpu/examples/ray-cube/main.rs b/wgpu/examples/ray-cube/main.rs index ecb526c0dd..e1625bb1e9 100644 --- a/wgpu/examples/ray-cube/main.rs +++ b/wgpu/examples/ray-cube/main.rs @@ -474,50 +474,47 @@ impl framework::Example for Example { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - unsafe { - encoder.build_acceleration_structures( - iter::once(&wgpu::BlasBuildEntry { - blas: &blas, - geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ - wgpu::BlasTriangleGeometry { - size: &blas_geo_size_desc, - vertex_buffer: &vertex_buf, - first_vertex: 0, - vertex_stride: mem::size_of::() as u64, - index_buffer: Some(&index_buf), - index_buffer_offset: Some(0), - transform_buffer: None, - transform_buffer_offset: None, - }, - ]), - }), - // iter::empty(), - iter::once(&tlas_package), - ); - // encoder.build_acceleration_structures_unsafe_tlas( - // iter::once(&wgpu::BlasBuildEntry { - // blas: &blas, - // geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ - // wgpu::BlasTriangleGeometry { - // size: &blas_geo_size_desc, - // vertex_buffer: &vertex_buf, - // first_vertex: 0, - // vertex_stride: mem::size_of::() as u64, - // index_buffer: Some(&index_buf), - // index_buffer_offset: Some(0), - // transform_buffer: None, - // transform_buffer_offset: None, - // }, - // ]), - // }), - // iter::once(&wgpu::TlasBuildEntry { - // tlas: &tlas, - // instance_buffer: &instance_buf, - // instance_count: 1, - // }), - // ); - } + encoder.build_acceleration_structures( + iter::once(&wgpu::BlasBuildEntry { + blas: &blas, + geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ + wgpu::BlasTriangleGeometry { + size: &blas_geo_size_desc, + vertex_buffer: &vertex_buf, + first_vertex: 0, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&index_buf), + index_buffer_offset: Some(0), + transform_buffer: None, + transform_buffer_offset: None, + }, + ]), + }), + // iter::empty(), + iter::once(&tlas_package), + ); + + // encoder.build_acceleration_structures( + // iter::once(&wgpu::BlasBuildEntry { + // blas: &blas, + // geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ + // wgpu::BlasTriangleGeometry { + // size: &blas_geo_size_desc, + // vertex_buffer: &vertex_buf, + // first_vertex: 0, + // vertex_stride: mem::size_of::() as u64, + // index_buffer: Some(&index_buf), + // index_buffer_offset: Some(0), + // transform_buffer: None, + // transform_buffer_offset: None, + // }, + // ]), + // }), + // iter::empty(), + // // iter::once(&tlas_package), + // ); + queue.submit(Some(encoder.finish())); let start_inst = Instant::now(); @@ -585,9 +582,7 @@ impl framework::Example for Example { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - unsafe { - encoder.build_acceleration_structures(iter::empty(), iter::once(&self.tlas_package)); - } + encoder.build_acceleration_structures(iter::empty(), iter::once(&self.tlas_package)); { let mut cpass = diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 4a04938f0a..e7a8ba33b4 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -3030,7 +3030,7 @@ impl CommandEncoder { } /// Build bottom and top level acceleration structures - pub unsafe fn build_acceleration_structures<'a>( + pub fn build_acceleration_structures<'a>( &mut self, blas: impl IntoIterator>, tlas: impl IntoIterator, From c08d4548db4ce2cf60d83621096e500cc644fbcb Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 5 Apr 2023 11:35:50 +0200 Subject: [PATCH 057/146] clippy --- player/src/lib.rs | 22 +++--- wgpu-core/src/command/compute.rs | 5 +- wgpu-core/src/command/ray_tracing.rs | 108 ++++++++++++--------------- wgpu-core/src/command/render.rs | 4 +- wgpu-core/src/device/ray_tracing.rs | 5 +- wgpu-core/src/ray_tracing.rs | 6 +- wgpu-core/src/resource.rs | 1 - wgpu/src/backend/direct.rs | 11 ++- wgpu/src/context.rs | 18 ++--- wgpu/src/lib.rs | 23 +++--- 10 files changed, 91 insertions(+), 112 deletions(-) diff --git a/player/src/lib.rs b/player/src/lib.rs index 68c01b7a68..7884887515 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -137,12 +137,12 @@ impl GlobalPlay for wgc::hub::Global { .unwrap(); } trace::Command::BuildAccelerationStructuresUnsafeTlas { blas, tlas } => { - let blas_iter = (&blas).into_iter().map(|x| { + let blas_iter = blas.iter().map(|x| { let geometries = match &x.geometries { wgc::ray_tracing::TraceBlasGeometries::TriangleGeometries( triangle_geometries, ) => { - let iter = triangle_geometries.into_iter().map(|tg| { + let iter = triangle_geometries.iter().map(|tg| { wgc::ray_tracing::BlasTriangleGeometry { size: &tg.size, vertex_buffer: tg.vertex_buffer, @@ -159,7 +159,7 @@ impl GlobalPlay for wgc::hub::Global { }; wgc::ray_tracing::BlasBuildEntry { blas_id: x.blas_id, - geometries: geometries, + geometries, } }); @@ -175,12 +175,12 @@ impl GlobalPlay for wgc::hub::Global { .unwrap(); } trace::Command::BuildAccelerationStructures { blas, tlas } => { - let blas_iter = (&blas).into_iter().map(|x| { + let blas_iter = blas.iter().map(|x| { let geometries = match &x.geometries { wgc::ray_tracing::TraceBlasGeometries::TriangleGeometries( triangle_geometries, ) => { - let iter = triangle_geometries.into_iter().map(|tg| { + let iter = triangle_geometries.iter().map(|tg| { wgc::ray_tracing::BlasTriangleGeometry { size: &tg.size, vertex_buffer: tg.vertex_buffer, @@ -197,22 +197,20 @@ impl GlobalPlay for wgc::hub::Global { }; wgc::ray_tracing::BlasBuildEntry { blas_id: x.blas_id, - geometries: geometries, + geometries, } }); - let tlas_iter = (&tlas).into_iter().map(|x| { + let tlas_iter = tlas.iter().map(|x| { let instances = x.instances.iter().map(|instance| { - if let Some(ref instance) = instance { - Some(wgc::ray_tracing::TlasInstance { + instance + .as_ref() + .map(|instance| wgc::ray_tracing::TlasInstance { blas_id: instance.blas_id, transform: &instance.transform, custom_index: instance.custom_index, mask: instance.mask, }) - } else { - None - } }); wgc::ray_tracing::TlasPackage { tlas_id: x.tlas_id, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 8a3014a976..c67afefc92 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -362,8 +362,7 @@ impl Global { let (pipeline_guard, mut token) = hub.compute_pipelines.read(&mut token); let (query_set_guard, mut token) = hub.query_sets.read(&mut token); let (buffer_guard, mut token) = hub.buffers.read(&mut token); - let (texture_guard, mut token) = hub.textures.read(&mut token); - let (tlas_guard, _) = hub.tlas_s.read(&mut token); + let (texture_guard, _) = hub.textures.read(&mut token); let mut state = State { binder: Binder::new(), @@ -453,8 +452,6 @@ impl Global { cmd_buf.tlas_actions.extend( bind_group.used.acceleration_structures.used().map(|id| { - let tlas = &tlas_guard[id]; - crate::ray_tracing::TlasAction { id: id.0, kind: crate::ray_tracing::TlasActionKind::Use, diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index b9083a4d04..2577a7e4fe 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -6,11 +6,11 @@ use crate::{ init_tracker::MemoryInitKind, ray_tracing::{ tlas_instance_into_bytes, BlasAction, BlasBuildEntry, BlasGeometries, - BuildAccelerationStructureError, TlasAction, TlasBuildEntry, TlasInstance, TlasPackage, - TraceTlasInstance, ValidateBlasActionsError, ValidateTlasActionsError, + BuildAccelerationStructureError, TlasAction, TlasBuildEntry, TlasPackage, + ValidateBlasActionsError, ValidateTlasActionsError, }, - resource::{Blas, StagingBuffer, Tlas}, - FastHashMap, FastHashSet, + resource::{Blas, Tlas}, + FastHashSet, }; use hal::{CommandEncoder, Device}; @@ -79,7 +79,7 @@ impl Global { .collect(); #[cfg(feature = "trace")] - let mut trace_tlas: Vec = tlas_iter.collect(); + let trace_tlas: Vec = tlas_iter.collect(); #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf.commands { @@ -95,12 +95,12 @@ impl Global { } #[cfg(feature = "trace")] - let blas_iter = (&trace_blas).into_iter().map(|x| { + let blas_iter = trace_blas.iter().map(|x| { let geometries = match &x.geometries { - crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( - triangle_geometries, + &crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( + ref triangle_geometries, ) => { - let iter = triangle_geometries.into_iter().map(|tg| { + let iter = triangle_geometries.iter().map(|tg| { crate::ray_tracing::BlasTriangleGeometry { size: &tg.size, vertex_buffer: tg.vertex_buffer, @@ -117,12 +117,12 @@ impl Global { }; BlasBuildEntry { blas_id: x.blas_id, - geometries: geometries, + geometries, } }); #[cfg(feature = "trace")] - let tlas_iter = (&mut trace_tlas).iter(); + let tlas_iter = trace_tlas.iter(); let mut input_barriers = Vec::>::new(); @@ -637,16 +637,12 @@ impl Global { let instances = x .instances .map(|instance| { - if let Some(instance) = instance { - Some(TraceTlasInstance { - blas_id: instance.blas_id, - transform: instance.transform.clone(), - custom_index: instance.custom_index, - mask: instance.mask, - }) - } else { - None - } + instance.map(|instance| crate::ray_tracing::TraceTlasInstance { + blas_id: instance.blas_id, + transform: *instance.transform, + custom_index: instance.custom_index, + mask: instance.mask, + }) }) .collect(); crate::ray_tracing::TraceTlasPackage { @@ -666,12 +662,12 @@ impl Global { } #[cfg(feature = "trace")] - let blas_iter = (&trace_blas).into_iter().map(|x| { + let blas_iter = trace_blas.iter().map(|x| { let geometries = match &x.geometries { - crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( - triangle_geometries, + &crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( + ref triangle_geometries, ) => { - let iter = triangle_geometries.into_iter().map(|tg| { + let iter = triangle_geometries.iter().map(|tg| { crate::ray_tracing::BlasTriangleGeometry { size: &tg.size, vertex_buffer: tg.vertex_buffer, @@ -688,25 +684,21 @@ impl Global { }; BlasBuildEntry { blas_id: x.blas_id, - geometries: geometries, + geometries, } }); - // dbg!(&trace_tlas); - #[cfg(feature = "trace")] - let tlas_iter = (&trace_tlas).into_iter().map(|x| { + let tlas_iter = trace_tlas.iter().map(|x| { let instances = x.instances.iter().map(|instance| { - if let Some(instance) = instance { - Some(TlasInstance { + instance + .as_ref() + .map(|instance| crate::ray_tracing::TlasInstance { blas_id: instance.blas_id, transform: &instance.transform, custom_index: instance.custom_index, mask: instance.mask, }) - } else { - None - } }); TlasPackage { tlas_id: x.tlas_id, @@ -1042,29 +1034,27 @@ impl Global { let mut dependencies = Vec::new(); let mut instance_count = 0; - for instance in entry.instances { - if let Some(instance) = instance { - // TODO validation - let blas = cmd_buf - .trackers - .blas_s - .add_single(&blas_guard, instance.blas_id) - .ok_or(BuildAccelerationStructureError::InvalidBlasForInstance( - instance.blas_id, - ))?; - - instance_buffer_staging_source - .extend(tlas_instance_into_bytes::(&instance, blas.handle)); - - instance_count += 1; - - dependencies.push(instance.blas_id); - - cmd_buf.blas_actions.push(BlasAction { - id: instance.blas_id, - kind: crate::ray_tracing::BlasActionKind::Use, - }); - } + for instance in entry.instances.flatten() { + // TODO validation + let blas = cmd_buf + .trackers + .blas_s + .add_single(&blas_guard, instance.blas_id) + .ok_or(BuildAccelerationStructureError::InvalidBlasForInstance( + instance.blas_id, + ))?; + + instance_buffer_staging_source + .extend(tlas_instance_into_bytes::(&instance, blas.handle)); + + instance_count += 1; + + dependencies.push(instance.blas_id); + + cmd_buf.blas_actions.push(BlasAction { + id: instance.blas_id, + kind: crate::ray_tracing::BlasActionKind::Use, + }); } cmd_buf.tlas_actions.push(TlasAction { @@ -1103,7 +1093,7 @@ impl Global { .map_err(crate::device::DeviceError::from)? }; - let staging_buffer = if instance_buffer_staging_source.len() > 0 { + let staging_buffer = if !instance_buffer_staging_source.is_empty() { unsafe { let staging_buffer = device .raw @@ -1225,7 +1215,7 @@ impl Global { })); } - for (tlas, _entries, _scratch_buffer_offset, range) in &tlas_storage { + for &(tlas, ref _entries, ref _scratch_buffer_offset, ref range) in &tlas_storage { let size = (range.end - range.start) as u64; if size == 0 { continue; diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index ba47b4a344..96eeaf9c55 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1246,8 +1246,7 @@ impl Global { let (query_set_guard, mut token) = hub.query_sets.read(&mut token); let (buffer_guard, mut token) = hub.buffers.read(&mut token); let (texture_guard, mut token) = hub.textures.read(&mut token); - let (view_guard, mut token) = hub.texture_views.read(&mut token); - let (tlas_guard, _) = hub.tlas_s.read(&mut token); + let (view_guard, _) = hub.texture_views.read(&mut token); log::trace!( "Encoding render pass begin in command buffer {:?}", @@ -1359,7 +1358,6 @@ impl Global { cmd_buf.tlas_actions.extend( bind_group.used.acceleration_structures.used().map(|id| { - let tlas = &tlas_guard[id]; crate::ray_tracing::TlasAction { id: id.0, kind: crate::ray_tracing::TlasActionKind::Use, diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index f02d17d59f..d56ee4d93a 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -4,12 +4,11 @@ use crate::{ device::{queue::TempResource, Device, DeviceError}, hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Token}, id::{self, BlasId, TlasId}, - ray_tracing::{getRawTlasInstanceSize, CreateBlasError, CreateTlasError}, + ray_tracing::{get_raw_tlas_instance_size, CreateBlasError, CreateTlasError}, resource, LabelHelpers, LifeGuard, Stored, }; use hal::{AccelerationStructureTriangleIndices, Device as _}; -use parking_lot::Mutex; impl Device { // TODO: @@ -126,7 +125,7 @@ impl Device { } .map_err(DeviceError::from)?; - let instance_buffer_size = getRawTlasInstanceSize::(); + let instance_buffer_size = get_raw_tlas_instance_size::(); let instance_buffer = unsafe { self.raw.create_buffer(&hal::BufferDescriptor { label: Some("(wgpu-core) instances_buffer"), diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index c37644c344..da568b2581 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -6,7 +6,7 @@ /// - 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, ptr, slice}; +use std::{num::NonZeroU64, slice}; use crate::{ command::CommandEncoderError, @@ -235,7 +235,7 @@ pub struct TraceTlasPackage { pub lowest_unmodified: u32, } -pub(crate) fn getRawTlasInstanceSize() -> usize { +pub(crate) fn get_raw_tlas_instance_size() -> usize { match A::VARIANT { wgt::Backend::Empty => 0, wgt::Backend::Vulkan => 64, @@ -261,7 +261,7 @@ pub(crate) fn tlas_instance_into_bytes( wgt::Backend::Vulkan => { const MAX_U24: u32 = (1u32 << 24u32) - 1u32; let temp = RawTlasInstance { - transform: instance.transform.clone(), + transform: *instance.transform, custom_index_and_mask: (instance.custom_index & MAX_U24) | (u32::from(instance.mask) << 24), shader_binding_table_record_offset_and_flags: 0, diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index ed9361e664..5864e387dd 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -8,7 +8,6 @@ use crate::{ Label, LifeGuard, RefCount, Stored, }; -use parking_lot::Mutex; use smallvec::SmallVec; use thiserror::Error; diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index cd8d9e9443..167fb67075 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -2,11 +2,10 @@ use crate::{ context::{ObjectId, Unused}, AdapterInfo, BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BufferBinding, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, - ContextTlasInstance, ContextTlasPackage, DownlevelCapabilities, Features, Label, Limits, - LoadOp, MapMode, Operations, PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, - RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, - ShaderModuleDescriptorSpirV, ShaderSource, SurfaceStatus, TextureDescriptor, - TextureViewDescriptor, UncapturedErrorHandler, + ContextTlasInstance, DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, + Operations, PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, + SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, ShaderSource, + SurfaceStatus, TextureDescriptor, TextureViewDescriptor, UncapturedErrorHandler, }; use arrayvec::ArrayVec; @@ -3106,7 +3105,7 @@ impl crate::Context for Context { } }); - let mut tlas = tlas.into_iter().map(|e| { + let tlas = tlas.into_iter().map(|e| { let instances = e.instances .into_iter() diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index ea8132fc35..41b2160257 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -4041,21 +4041,17 @@ where } }); - let mut tlas = tlas.into_iter().map(|e: DynContextTlasPackage| { + let tlas = tlas.into_iter().map(|e: DynContextTlasPackage| { let instances = e.instances .into_iter() .map(|instance: Option| { - if let Some(instance) = instance { - Some(ContextTlasInstance { - blas_id: ::from(instance.blas), - transform: instance.transform, - custom_index: instance.custom_index, - mask: instance.mask, - }) - } else { - None - } + instance.map(|instance| ContextTlasInstance { + blas_id: ::from(instance.blas), + transform: instance.transform, + custom_index: instance.custom_index, + mask: instance.mask, + }) }); ContextTlasPackage { tlas_id: ::from(e.tlas_id), diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index e7a8ba33b4..47703f6eac 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -3068,16 +3068,12 @@ impl CommandEncoder { let mut tlas = tlas.into_iter().map(|e: &TlasPackage| { let instances = e.instances.iter().map(|instance: &Option| { - if let Some(instance) = instance { - Some(DynContextTlasInstance { - blas: instance.blas, - transform: &instance.transform, - custom_index: instance.custom_index, - mask: instance.mask, - }) - } else { - None - } + instance.as_ref().map(|instance| DynContextTlasInstance { + blas: instance.blas, + transform: &instance.transform, + custom_index: instance.custom_index, + mask: instance.mask, + }) }); DynContextTlasPackage { tlas_id: e.tlas.id, @@ -4787,12 +4783,16 @@ static_assertions::assert_impl_all!(TlasBuildEntry: Send, Sync); #[derive(Debug, Clone)] pub struct TlasInstance { blas: ObjectId, + /// TODO Docu pub transform: [f32; 12], + /// TODO Docu pub custom_index: u32, + /// TODO Docu pub mask: u8, } impl TlasInstance { + /// TODO Docu pub fn new(blas: &Blas, transform: [f32; 12], custom_index: u32, mask: u8) -> Self { Self { blas: blas.id, @@ -4802,6 +4802,7 @@ impl TlasInstance { } } + /// TODO Docu pub fn set_blas(&mut self, blas: &Blas) { self.blas = blas.id; } @@ -4814,6 +4815,7 @@ pub(crate) struct DynContextTlasInstance<'a> { mask: u8, } +/// TODO Docu pub struct ContextTlasInstance<'a, T: Context> { blas_id: T::BlasId, transform: &'a [f32; 12], @@ -4821,6 +4823,7 @@ pub struct ContextTlasInstance<'a, T: Context> { mask: u8, } +/// TODO Docu pub struct TlasPackage { tlas: Tlas, instances: Vec>, From 5a155b43b0be824f270460a708c2c2fba295d12c Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 5 Apr 2023 18:27:05 +0200 Subject: [PATCH 058/146] added acceleration structure barriers --- wgpu-hal/examples/ray-traced-triangle/main.rs | 37 +++++++++++++++++-- wgpu-hal/src/dx11/command.rs | 7 ++++ wgpu-hal/src/dx12/command.rs | 7 ++++ wgpu-hal/src/empty.rs | 6 +++ wgpu-hal/src/gles/command.rs | 7 ++++ wgpu-hal/src/lib.rs | 21 +++++++++++ wgpu-hal/src/metal/command.rs | 7 ++++ wgpu-hal/src/vulkan/command.rs | 24 ++++++++++++ wgpu-hal/src/vulkan/conv.rs | 24 ++++++++++++ 9 files changed, 136 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index b00fc2f6ee..67630a05f4 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -704,6 +704,11 @@ impl Example { unsafe { cmd_encoder.begin_encoding(Some("init")).unwrap() }; unsafe { + cmd_encoder.place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { + usage: hal::AccelerationStructureUses::empty() + ..hal::AccelerationStructureUses::BUILD_OUTPUT, + }); + cmd_encoder.build_acceleration_structures( 1, [hal::BuildAccelerationStructureDescriptor { @@ -717,12 +722,17 @@ impl Example { }], ); - let as_barrier = hal::BufferBarrier { + let scratch_buffer_barrier = hal::BufferBarrier { buffer: &scratch_buffer, usage: hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT ..hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, }; - cmd_encoder.transition_buffers(iter::once(as_barrier)); + cmd_encoder.transition_buffers(iter::once(scratch_buffer_barrier)); + + cmd_encoder.place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { + usage: hal::AccelerationStructureUses::BUILD_OUTPUT + ..hal::AccelerationStructureUses::BUILD_INPUT, + }); cmd_encoder.build_acceleration_structures( 1, @@ -737,6 +747,11 @@ impl Example { }], ); + cmd_encoder.place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { + usage: hal::AccelerationStructureUses::BUILD_OUTPUT + ..hal::AccelerationStructureUses::SHADER_INPUT, + }); + let texture_barrier = hal::TextureBarrier { texture: &texture, range: wgt::ImageSubresourceRange::default(), @@ -840,6 +855,13 @@ impl Example { count: self.instances.len() as u32, offset: 0, }; + + ctx.encoder + .place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { + usage: hal::AccelerationStructureUses::SHADER_INPUT + ..hal::AccelerationStructureUses::BUILD_INPUT, + }); + ctx.encoder.build_acceleration_structures( 1, [hal::BuildAccelerationStructureDescriptor { @@ -853,12 +875,19 @@ impl Example { }], ); - let as_barrier = hal::BufferBarrier { + ctx.encoder + .place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { + usage: hal::AccelerationStructureUses::BUILD_OUTPUT + ..hal::AccelerationStructureUses::SHADER_INPUT, + }); + + let scratch_buffer_barrier = hal::BufferBarrier { buffer: &self.scratch_buffer, usage: hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT ..hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, }; - ctx.encoder.transition_buffers(iter::once(as_barrier)); + ctx.encoder + .transition_buffers(iter::once(scratch_buffer_barrier)); ctx.encoder.transition_textures(iter::once(target_barrier0)); } diff --git a/wgpu-hal/src/dx11/command.rs b/wgpu-hal/src/dx11/command.rs index 2d04dc518c..813bcdc059 100644 --- a/wgpu-hal/src/dx11/command.rs +++ b/wgpu-hal/src/dx11/command.rs @@ -276,4 +276,11 @@ impl crate::CommandEncoder for super::CommandEncoder { { unimplemented!() } + + unsafe fn place_acceleration_structure_barrier( + &mut self, + _barriers: crate::AccelerationStructureBarrier, + ) { + unimplemented!() + } } diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 6d24e9862e..31e409426d 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1153,4 +1153,11 @@ impl crate::CommandEncoder for super::CommandEncoder { // https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#buildraytracingaccelerationstructure todo!() } + + unsafe fn place_acceleration_structure_barrier( + &mut self, + _barriers: crate::AccelerationStructureBarrier, + ) { + todo!() + } } diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 9f84f83a37..f45f79825f 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -440,4 +440,10 @@ impl crate::CommandEncoder for Encoder { T: IntoIterator>, { } + + unsafe fn place_acceleration_structure_barrier( + &mut self, + _barriers: crate::AccelerationStructureBarrier, + ) { + } } diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index ad91ed904b..6ba8acc016 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -1071,4 +1071,11 @@ impl crate::CommandEncoder for super::CommandEncoder { { unimplemented!() } + + unsafe fn place_acceleration_structure_barrier( + &mut self, + _barriers: crate::AccelerationStructureBarrier, + ) { + unimplemented!() + } } diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 3a772d2444..407fa03632 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -582,6 +582,11 @@ pub trait CommandEncoder: Send + Sync + fmt::Debug { ) where A: 'a, T: IntoIterator>; + + unsafe fn place_acceleration_structure_barrier( + &mut self, + barrier: AccelerationStructureBarrier, + ); } bitflags!( @@ -1459,3 +1464,19 @@ pub struct AccelerationStructureTriangleTransform<'a, A: Api> { pub type AccelerationStructureBuildFlags = wgt::AccelerationStructureFlags; pub type AccelerationStructureGeometryFlags = wgt::AccelerationStructureGeometryFlags; + +bitflags::bitflags! { + pub struct AccelerationStructureUses: u8 { + // For blas used as input for tlas + const BUILD_INPUT = 1 << 0; + // Target for acceleration structure build + const BUILD_OUTPUT = 1 << 1; + // Tlas used in a shader + const SHADER_INPUT = 1 << 2; + } +} + +#[derive(Debug, Clone)] +pub struct AccelerationStructureBarrier { + pub usage: Range, +} diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 493e9ecc50..96c6859365 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -978,4 +978,11 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { unimplemented!() } + + unsafe fn place_acceleration_structure_barrier( + &mut self, + _barriers: crate::AccelerationStructureBarrier, + ) { + unimplemented!() + } } diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 3c98221fc1..d782171f02 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -605,6 +605,30 @@ impl crate::CommandEncoder for super::CommandEncoder { // } } + unsafe fn place_acceleration_structure_barrier( + &mut self, + barrier: crate::AccelerationStructureBarrier, + ) { + let (src_stage, src_access) = + conv::map_acceleration_structure_usage_to_barrier(barrier.usage.start); + let (dst_stage, dst_access) = + conv::map_acceleration_structure_usage_to_barrier(barrier.usage.end); + + unsafe { + self.device.raw.cmd_pipeline_barrier( + self.active, + src_stage | vk::PipelineStageFlags::TOP_OF_PIPE, + dst_stage | vk::PipelineStageFlags::BOTTOM_OF_PIPE, + vk::DependencyFlags::empty(), + &[vk::MemoryBarrier::builder() + .src_access_mask(src_access) + .dst_access_mask(dst_access) + .build()], + &[], + &[], + ) + }; + } // render unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor) { diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index 2269eed978..c0738711fc 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -911,3 +911,27 @@ pub fn map_acceleration_structure_geomety_flags( vk_flags } + +pub fn map_acceleration_structure_usage_to_barrier( + usage: crate::AccelerationStructureUses, +) -> (vk::PipelineStageFlags, vk::AccessFlags) { + let mut stages = vk::PipelineStageFlags::empty(); + let mut access = vk::AccessFlags::empty(); + + if usage.contains(crate::AccelerationStructureUses::BUILD_INPUT) { + stages |= vk::PipelineStageFlags::ACCELERATION_STRUCTURE_BUILD_KHR; + access |= vk::AccessFlags::ACCELERATION_STRUCTURE_READ_KHR; + } + if usage.contains(crate::AccelerationStructureUses::BUILD_OUTPUT) { + stages |= vk::PipelineStageFlags::ACCELERATION_STRUCTURE_BUILD_KHR; + access |= vk::AccessFlags::ACCELERATION_STRUCTURE_WRITE_KHR; + } + if usage.contains(crate::AccelerationStructureUses::SHADER_INPUT) { + stages |= vk::PipelineStageFlags::VERTEX_SHADER + | vk::PipelineStageFlags::FRAGMENT_SHADER + | vk::PipelineStageFlags::COMPUTE_SHADER; + access |= vk::AccessFlags::ACCELERATION_STRUCTURE_READ_KHR; + } + + (stages, access) +} From db00f7e4e952fd8f8cfbebb1f3bff4839bc7de0b Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 5 Apr 2023 19:09:56 +0200 Subject: [PATCH 059/146] instances in examples + barrier "fix" --- wgpu-core/src/command/ray_tracing.rs | 62 +++++++++++++++++++++++++- wgpu-core/src/device/ray_tracing.rs | 2 +- wgpu/examples/ray-cube/main.rs | 46 ++++++++++++------- wgpu/examples/ray-cube/screenshot.png | Bin 325681 -> 487485 bytes 4 files changed, 90 insertions(+), 20 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 2577a7e4fe..cdb2245f00 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -553,6 +553,13 @@ impl Global { cmd_buf_raw.transition_buffers(input_barriers.into_iter()); if blas_present { + cmd_buf_raw.place_acceleration_structure_barrier( + hal::AccelerationStructureBarrier { + usage: hal::AccelerationStructureUses::BUILD_INPUT + ..hal::AccelerationStructureUses::BUILD_OUTPUT, + }, + ); + cmd_buf_raw .build_acceleration_structures(blas_storage.len() as u32, blas_descriptors); } @@ -561,9 +568,31 @@ impl Global { cmd_buf_raw.transition_buffers(iter::once(scratch_buffer_barrier)); } + let mut source_usage = hal::AccelerationStructureUses::empty(); + let mut destination_usage = hal::AccelerationStructureUses::empty(); + if blas_present { + source_usage |= hal::AccelerationStructureUses::BUILD_OUTPUT; + destination_usage |= hal::AccelerationStructureUses::BUILD_INPUT + } + if tlas_present { + source_usage |= hal::AccelerationStructureUses::SHADER_INPUT; + destination_usage |= hal::AccelerationStructureUses::BUILD_OUTPUT; + } + + cmd_buf_raw.place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { + usage: source_usage..destination_usage, + }); + if tlas_present { cmd_buf_raw .build_acceleration_structures(tlas_storage.len() as u32, tlas_descriptors); + + cmd_buf_raw.place_acceleration_structure_barrier( + hal::AccelerationStructureBarrier { + usage: hal::AccelerationStructureUses::BUILD_OUTPUT + ..hal::AccelerationStructureUses::SHADER_INPUT, + }, + ); } } @@ -1112,6 +1141,7 @@ impl Global { 0..instance_buffer_staging_source.len() as u64, ) .map_err(crate::device::DeviceError::from)?; + ptr::copy_nonoverlapping( instance_buffer_staging_source.as_ptr(), mapping.ptr.as_ptr(), @@ -1196,6 +1226,13 @@ impl Global { if blas_present { unsafe { + cmd_buf_raw.place_acceleration_structure_barrier( + hal::AccelerationStructureBarrier { + usage: hal::AccelerationStructureUses::BUILD_INPUT + ..hal::AccelerationStructureUses::BUILD_OUTPUT, + }, + ); + cmd_buf_raw .build_acceleration_structures(blas_storage.len() as u32, blas_descriptors); } @@ -1207,6 +1244,22 @@ impl Global { } } + let mut source_usage = hal::AccelerationStructureUses::empty(); + let mut destination_usage = hal::AccelerationStructureUses::empty(); + if blas_present { + source_usage |= hal::AccelerationStructureUses::BUILD_OUTPUT; + destination_usage |= hal::AccelerationStructureUses::BUILD_INPUT + } + if tlas_present { + source_usage |= hal::AccelerationStructureUses::SHADER_INPUT; + destination_usage |= hal::AccelerationStructureUses::BUILD_OUTPUT; + } + unsafe { + cmd_buf_raw.place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { + usage: source_usage..destination_usage, + }); + } + if tlas_present { unsafe { cmd_buf_raw.transition_buffers(iter::once(hal::BufferBarrier:: { @@ -1236,11 +1289,16 @@ impl Global { unsafe { cmd_buf_raw.transition_buffers(instance_buffer_barriers); - } - unsafe { cmd_buf_raw .build_acceleration_structures(tlas_storage.len() as u32, tlas_descriptors); + + cmd_buf_raw.place_acceleration_structure_barrier( + hal::AccelerationStructureBarrier { + usage: hal::AccelerationStructureUses::BUILD_OUTPUT + ..hal::AccelerationStructureUses::SHADER_INPUT, + }, + ); } device diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index d56ee4d93a..d894f4dac5 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -125,7 +125,7 @@ impl Device { } .map_err(DeviceError::from)?; - let instance_buffer_size = get_raw_tlas_instance_size::(); + let instance_buffer_size = get_raw_tlas_instance_size::() * desc.max_instances as usize; let instance_buffer = unsafe { self.raw.create_buffer(&hal::BufferDescriptor { label: Some("(wgpu-core) instances_buffer"), diff --git a/wgpu/examples/ray-cube/main.rs b/wgpu/examples/ray-cube/main.rs index e1625bb1e9..f2ed53299b 100644 --- a/wgpu/examples/ray-cube/main.rs +++ b/wgpu/examples/ray-cube/main.rs @@ -281,6 +281,8 @@ impl framework::Example for Example { device: &wgpu::Device, queue: &wgpu::Queue, ) -> Self { + let side_count = 8; + let rt_target = device.create_texture(&wgpu::TextureDescriptor { label: Some("rt_target"), size: wgpu::Extent3d { @@ -376,7 +378,7 @@ impl framework::Example for Example { label: None, flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, update_mode: wgpu::AccelerationStructureUpdateMode::Build, - max_instances: 1, + max_instances: side_count*side_count, }); let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { @@ -456,21 +458,31 @@ impl framework::Example for Example { ], }); - let mut tlas_package = wgpu::TlasPackage::new(tlas, 1); - - *tlas_package.get_mut_single(0).unwrap() = Some(wgpu::TlasInstance::new( - &blas, - AccelerationStructureInstance::affine_to_rows(&Affine3A::from_rotation_translation( - Quat::from_rotation_x(45.9_f32.to_radians()), - Vec3 { - x: 0.0, - y: 0.0, - z: -3.0, - }, - )), - 0, - 0xff, - )); + let mut tlas_package = wgpu::TlasPackage::new(tlas, side_count * side_count); + + let dist = 3.0; + + for x in 0..side_count { + for y in 0..side_count { + *tlas_package + .get_mut_single((x + y * side_count) as usize) + .unwrap() = Some(wgpu::TlasInstance::new( + &blas, + AccelerationStructureInstance::affine_to_rows( + &Affine3A::from_rotation_translation( + Quat::from_rotation_x(45.9_f32.to_radians()), + Vec3 { + x: x as f32 * dist, + y: y as f32 * dist, + z: -30.0, + }, + ), + ), + 0, + 0xff, + )); + } + } let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); @@ -575,7 +587,7 @@ impl framework::Example for Example { Vec3 { x: 0.0, y: 0.0, - z: -3.0, + z: -6.0, }, )); diff --git a/wgpu/examples/ray-cube/screenshot.png b/wgpu/examples/ray-cube/screenshot.png index 8caa036e47d2f93134249350215b7a066fc89401..3d5142d1fd05673e7c7c8ec6d8d7c7951a19e2d1 100644 GIT binary patch literal 487485 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 *HI9_`*%qh?aQEdslXA(;V)J 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

Nosh^y6mu?#G#qV5gT7JyYk<8r$!VXBTQjVuw- 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%0DZ0^E`1bKHCTN*`K&KXP2USihSz8340 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

5Uv+0`uP_N|qw=sbl!d=p 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

pT)kIRc}tOg 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%0D#hxgBlln{$1h)f_l99KTGq+L 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 z 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 literal 325681 zcmdSCcUY6zx;`94Wh}_3qo`4$<0y`b8Al-~C60}8P_ZFufT*aTl!%CwkOXxU6#>f# zDkXMQ2oWivq@V~<5h5Z9H7`9t2qA>@@_uh%_Bpf9VK{sL&bh?zFWxKsv#zz)b3gZU zKV@CsvE9jZ;+%;v7|e9buN!y4U}K?AW7s$2p+5x$GfZJ)70N9ef7ugi)Wg6$J$hWh zmt}N6kQm#&nq+N$c-^HY?2RTwP!r-*?D!coZe0qUe|X30(3vq;D&NdHf9cYddzVbc z{_@>a@xc1;C!QVqZqv0(V}BouJk@&P_@m6H`Z~oOUx&0(t*h7qs1YaO=5aLTA@cdP>>V8>O0y$!0LT6dKFctX$Af1bUdY6>>)RFM6KZN|$ zc_VR#B}wdFh8<6ec&GL+=XASDYPFTb&)#dOE~V%>8NfxSr2Rql$2el99HR*F(3~I$ zd(y)DJ=iIs@fdHiJuhZ}A_B4Z8)OVQj z`D;kiy>+=A-m>RPKfMpSJ1dE2*@`gbv70Wf@(rl(Q8n_2LVboWmV!$rxVkWfHPbn# zggvVq1BE@8SD`qA>m}JRE3Cs8S6{L@5U1XUSsB>TvN5g2mDuz6cKAPkCdQB%*ak{V zt-#e~j`zV72{M9l){o?S1{3h6&W!#t+?$<$S4bDe&;t+@kg4fbo5Mts7Q;f32e>$2 z;$G?%PDh;lp<`JX;b(p2Ny6k<+pLb<@)Up|qV>Ts57G0z~1kkGzv$37pOd^2|;LxY~5j z8RT+=$cYdyRUgqlY*v3aH}F`wf1(3RQ-^B=f<ml>RBjgTMEEXST;ZPN<4S)Y$M|kH=bt~bBw32+LRWhYy?aaR{DKuJ_#(1f-m?y9~W6Sx} z!qwjpI>F+%4It^S>g@!Z%7-x=K6(sU_sam6bMMZ>@)VSOFFlx4eRVGdk#hyI9@m9) zB+KItl*}gQt**SZD$c#+O_uvzAL!8i{+EZ&VTw_p>Of{fwoKiRijG^>TsiozkgTw!pUK!`*rtJW-JY6tIMKZbFPVw)&=c?T}Sp zb!k|OZ~0K3Wtq~>ttH1$gJM#)SU-s2K6K>n-I|ndTlqZn76Sj{lazn{Jl5(hHV;V) zm4{W|ES-JZTRRDhn_myyZQM@UkSJPM4ELN3cG|`k>cnwQ=Y>W^UQhF@P(^|4r4|PvDr##75Nvquv7Zz5e=lf>~La-W&rZ9t$!wi1vg0d7XFmEUbgh$;-dw&7J7!lq+tk%!I?;|NQB1LzEK(X;-|- zZVtzj&W4q;`efr@>L|4ah&(~{V>z+&W43XoUjgc{fx2%Z6+@f&dDy!-cN8}XPhJtWGmD6kW`(;(*pRXjvi%jpo07PT!iOi{+_9$l z%eB3}tY8u^hsvc@FrQlj!9(5&f#gC~xLV+C^@Zl2f(r#KPPDYtEd0w1_a zmZIgmwmSUtXL%`ykL=wm>5)FSj9K*)M`_OFughgw7kZe%4v21v6rHxT%*HV8Eu4r- zCyp&z);xmSnev7G_g~zOjh)#7GMMj;kvAM$z-X@)nF(L|cl7V#pM znAi(pHtxb8Wt(Qe)tD-6pH;Iy^4~`8-%mrVVm_vJ(UAL@WTp1YP z6)k=7q#vW1!Ha|WO#OL;MS73oBF{@-wB3NrI^Md0)i-$5*25n4xY0Z6R>7eX!%^pn z52@adVA|h~o`0E4jv9whQFL0_LRg%~>JiR*G%w_UJ+cd8I)|!;LWW^u?YP%dy}1p! zwbDYWj;r(FF%JN1HP2Hbc$tI5+dHC#TRYu5AZ0LK)cZvw`wnbcxa9&5TN_H7!aTLQ zU8C1t%pTB)k3>)K)Vhl;|w!i<@S&h-iAVL@FG6G6* zMiHfaE2jI>AF(W8zgvxDNfW=YCH;lDQ*AlV-#Duc(fIVCXna`5If~KvPBf?Bwc(_< zK_{Kfj{Z7rW(nD3oaZM)ME+nXA|D>xM^U)y4kPZ>$zb#Su8a`u?i@YTS&|afZ%!gL z*5UFY-KBmgZ!$dT{L;G1Fr<^K*~dRX2%BKAZR@YpwjWD(G)N6RE|NJH9NN#}2+~Qy zm)_66=vYey_xGv{)-8m{`^R%fMgsDpQKOrio9+Kt0WA|sNxV$am=8siM~0I)Qb$ic zX!S;$-BM^5K}O!hB)2ac0nRsk;W+3o;;Lj7IqJ2O{)V1Q)EMIPdDbKB<|xMJt=BGrr}7!|?|q z3Y4d1=ei--@8PPQP# zi>rz9utrokBqyAjfz8Y9dwEoI|L0b)MuMnkdWLvDcWg)M^!YigW=L?QULL`Vf9WLI zb`VwfmjDP|FE+cfUOyNC9ojMi9(`$XCb!S?p?_b3v&Pj{khHyR+!uh@@BXA`0`7a#*{w2AmwcnFI^(yG5YZf7+?eo%gUB>o6Qsn->>xDisG6s^(-060yF~UVvOSZEtR2{BL$XNL_-C?c_`KjK zCX0|{K}CcW(U(*YQ9Z?sT!WY-O@yN(hS6zH>TK-4Y|+tyQZTdCl$s?rW)oBj_IYI; z!5ykCob<;~soC(THU0}HJQ@S~ATukMav@Mi>7{V&)&kOdaZQiI&6L$F5~SMk4=RS7 z{@)gzMYWAGJ0(l#E_J?CkfNJsQ0t}4AkzB?XSL@X9IzPm0e&2hg6FacMoJfi| z%#hQenAydSu1CRMulTMX9IQ=O=y% z&i^;{X9_O<;3;YeluWGS7Y{M3_+c{(qsXkpb}nu7nXDYZP&j4&ZctPnzSwjW3#TGD zVSE4JwLpjeV)F>7KZ^9PRVq!NJ$TfI;zqEdFCCivmFjy7jGA+l6kW2x)DuQnr1D$|DuYWw0KR`>w=&arhQE-bOVZ@`d4AdX>H(#R6BLp zOBLCKFxFS!THfRt4b%a_hN8%~U#D%SS8RA87_=Nhn0};U_ff>3H_~r+>kka(1|5cS zgFeHSq>W;3@EgH`>^4JuCx+s?gS7|2q4K_ApsI@+$CuAQ?HD%yyLJpsk0#^dV9_%-P)%S& zcz&h7ER{?e6xN&Y)<9(G14=K%Np`h|ZcK`atsUqagQN8GQWQ|3K6fOaIf_LV4Re6~0;+?UqN|W6I}_TQno0eA zXRvESLp#I>alNY)xjaI-Twpp|<(j1Z+wQTNd85`n)}S2!=N8W#DdZT%E$#_UF_YtP>(PvtAsB(P*guQCF!-Ts>^D;`lEtJ`P(8w#cVYr-z!`vR#IX&{124lbHz9 zz6J$nVnGZSZz!?qER+3NGCyoSdDJqXl04HAe6oP6KMQp>W*?kA!UbJ5TG`~#n$l^# z1_LU3$^S=Ie%Qu?QOn9pT{(ozFGqJ9B-B(GI?m>R0Q z1JhdvG~r2#E_neH5|IQ~>SaiSg2*3OwC}%4h{9d0oI5YWpp{-_SzF+j5q)LWyR$1* zhpkGg!#{1T$3X3~L|@(N-PwN3x32c@f#(;yYc_j7;0KEgz3WVPF`h8abLSp{F4j>O0Oh=vv!9RepIzp8~IgQtMN7%p7>!!tE#9mZs zLmm1wBpkVwkFbZMCd%+%#4;)jLR|FM)CKbwsZef!#jh)m{SVi2Qk!)Y;VPnm z>`oGlAf}HNbC?D4Hx0#D`%oiL*wGRK@{|hkp&^K7j$j|71<_F@*nPzYFANYMgbu0r z3K4p#{?p7qF)-;XG?5+Jl0|>szcpXs{kyF!v#Sx>)8uhbA6-+g>_h4waa)?8xjl>W}E8RYc z!(k5D?+A5Nqh`Mwn$g9Tkn};(-TX`Y+wc<7Xr+aJ(0Z>?4Y6p^NFHRgSoH7URue#I zZ;(5PLuEa~iiD$8))UxA7Bvh?t66x{!EOOY88@6s5A(9&{ zoF0Rm`{(jDeT~aAq9%n7YFR;0q=X#%75ZUVXjjpYT)Dz{gyoGEkrB1xS`Br#C+7_U zAn<6|(x*|9Iy4=Uy1)>PF3=b3fp`{k<{;Joo3WH%TCDu9Wx=RKWU-+zZ#I~tgnB_U z53U)ZnALlfS{UH$Dq*?*SD5~OjQV{)BMa&a@FLS5^9q}DcwsmZxeyY#3P+NFzqG(L zaPcQ-whS~Exl=07IwB2u-|bdPvN9C4`i|6eHA?8sJnC*)-Z9&@yXp~3~uv~9@%mz3w zKm8{V<+ng};@=eR2(3yuSPgGts2)n8>4nwOBQpM+3}+qp*!vEsu`q3~5JB%vN;s}|QLF1uBX18X8>{#+qtfSKzhjM6Mtf8Ql z%z{kZd8B*!rA-_fpE)?b5MDx#`p|)&hWKU3dP0})iyc(LhA(5CJvuWyG&T|!?++cC zH*}{z&zlMSIfP*NVQd>lNpITL(tN2l;%ve1hGkN8lc2bIIlLG9_l+}OL5u&Cd}`>$ zp72c>Emy&z0&&N$sX+WMPVYgVE^Bmeo)Bhv;b{u zLZ5u(=lI+I{Vq=fX*xEc+pLj!TqF;s>C?e9ae&BDcb#Ry2UA%rD{AE`t4*&Hpa+_w zJ~{uIq=Euq!|N>vtQN>VnD0{Vf<{PxJTc*!H}l%-1Vco1p?XDgk95U0$%R!vndk}* zwXeVCtufZsS(@Kyt0e+s^c$Ssc09Cc9c*U${ZIe@e-N3{K7bT3nB4DGNLp1((Db<$ zIzYAldRUV=4b5Zfd(CsGYGasA$V9R<1zo>H>L2qpdOk~IQrF)yI{{UkuvE`gHZO60 ztGbPR)b|)FpuJx`Z5JnE!388V%gT%rf6`aSmBlY8Hs^XKTz3mQlK7_9HubXx1brU0mmlbD2;8wQa~i%<|`7C zv#||&KTW~zI#3#&m;^40)X#-xJL|%9O!SY}z?MSpfS?PZJ?{~XMYV0cyb6?-0|lUK z9DJVuj|GEi@>=pCQ)ET)+<{Y!hh5glkRs?ACvyv$BrHi3b>%AP#g3yPx6>=Kg!#v4 zje7WLsLz`0IV6yt8@A8xhks`_JQ&eWl7gR8J5d@M`3yj6WQu4K2V7%3oY*)}_B%nl z#aGvXJwt+htV13rGrSFbaV7K1aV^`YMIB$7O>NS;A5x^mZ|I&w*OL8$TmI; zXrd0N5~ud2H*ZQ>(@B<5`>EkVQ$GePSSGKPoe0fD2YoD){jBRD*4k$U%37z~{;wCI zSzdDXx;Jn7KslHwP($~iE<_~h2H^G&3WdP>hVyJU-L_W?-RB1B%3qDKXYL6i6icqH zSWy>&}$~FW|HIB zZ|e|amxEfYnGsWUN(I1_i$t8|&_BWRIw52_s)w*-@F=)q9mx|A>DR3zrKquEltx8` zT*No0d;5Xcy(A8+vP5Ye@im-)^fPwok|Drvu_eI*Lwjc;SiduX<9tMe%n} zCTVc0Gyeu61Bqawp2zP>6%ktjwJEEW_>g5kxs%!D&{(ppSKj3WE64zpDBTfO1WSdr z7_%Hb2D&!>q|IO!OazAp9>2_?>IbkHOApiJjZq~40+uaceUpcVDWAM!K~Lyaic~+{ zL&H8A8!@PgHt;ej>oI70Jhbt~+`f~#G=8{o131T@EP_~t^VSDf0sfW2RFWQW zJl!LKH6`SrbL?TtkIn??QC}?Bg?;WcSrG-(9b>Yp9ieS{@uon++s2B(w9t$xJj!smBHqBR}Q-?O?Ys24Ilx4Pb&m)2aO|L_ZvS2mEP zIV$~7S{-M15PHjQQe3^#zCylXlc80CUFQbZ?yGwlcC59VoeaH|Sa*T#A7SCGx&OUksNx1unwecVBm8nTwKCi= z2p?Nbo3HRxZ*H<^Wa-;_Q?O#-fPGavc{1^RT|a94!hB}sCG~QW`8$WjtSdKJ&?Osg zLNT56`zPE*pzh9K2TjSp)Imde56VDq-+~F;ZS(*oIndWXzmgY|8PG$j1G7D}t%MRv z;~K~@$)|=;50uTlBBO!*921y-SR(>9fKjrIBjv%qXr5m21bhh7O^P(rnMw8T_Xv$T zH&S=P1!!w?wQDlKsYP7JCMTl~k$p)m64*U*i*qBN zmaAP-L{_KOr9yiZS9Tt{WTAktMu^h{SAm-}A5ZV5D!c4l1mTLJ0pMLKfp@nBqck5w ztKi{3AtfPLq?tuB$N)VpwMEF|-+!<_d?vLu7}Z-Bcc zw1u^?1Bvd9FeGX~Z6b5PwlrZtIFXeKS3Zsn=(J1i!YOBjOg~l_q)rYek@DY(nOzsL zo+KA)UVXnOs~Km8IjuXij)lOLZHR2ALSu(#h#)W6>Y^?uAq(x{oq8cL6|5#}^NH8E z2hvhc}N^^wqmBs8YZO%{8$SMi1n-K-OnfPbi0%uqB*a!BO9OT8H+>Pa&T z>>U<~j&m!Q#r&Srzdr-_{hO@o*phbu^c>}|Z_98h{~eLTTralh8czqt3ZKYT95tS= z);KdPAQubvTc+`a`9IZqNZWPr&e+RY_Oo_0_^VX<-V#xAFF0+TiY69AV2V|anGxbU zPpIfruyo*(dyQU=&7{r(+yP%K!~+mG3b+80ixI3IGb439by5os~>Hqchx)hJN ztspm0SBe*|I_3B;&j(XcbwLnip}=bbtn^vLcC^2L{$&U!R=73nZp`i;&u0=8?Tm|k z84^?NsVqQxVOh_iN%|_H8{gL<6IajJte|+6HC!pQ0@toX=^F#oi69qyCBX#d&}#-8 zK#x&MMR7=|y^~=E``qjDdlZb2fh^pE(x2li5{Y4reWc2jDi_FaIfA$`vJ}IXRuFjV z4QG3;vm`E(s3#7W!2t#}lqN5qh*>>vx|nNWHr65-j0ayBBeger$N7XM+Db2cH{4AR zpa2E@pN}YCt3MbAPvFD~uh}nz-sJNLZ73B4<|3BoeY0>i&O5kvYHkt0b(RgvmXRn@AUQFocmEVd}NYqJMLmsRd9-1sQi6?`ZJ zw%Y>V;E7denF60|S+R@ewGAbU#zEL{uMt~@7uTP<33%bpI;TT7H#eu9G(ZIgkl?g? zvV_Ar5g27bs=8|d({{_*d(B`oe`A%2v*qO)ZaiX~vK37N-C%?Yq-(ln3PGI!qgbId z*wb6h#tZ;&s*58b3>L3th6>E6Ql_u&EW`}rFnC@jh9f4%T$WDIbm*xtiwFkNouFN4 zTmhDXPt7B=)5KGW)P)sE51`xZt>cF?{PdFnbp(!rwc+@=>+*u2hl>mQ@?toxe&{_% zpb|dfHG%_sF2j?vKJK95B4aeX0ZJL8%q>Krtpm5W&R*6DEPLw^lh524dd}e~6uUks zOJTiqC-tGq6}5D}{}%3W$YzJjp*&R!(Hg zI6Cv#pBj}RzAuR=mR3YkoQpRZqw4^x!0|=qB3?H769U$77aUi#UPQVC4fFI1`{pA8 z)~SiqfK~^6vGOdsc$^rV*7WcR(H`a#%_B``bt(%hsx}y@QdWTB+i&+5f}v1pdO-3? z64eT1-o0#v)^oS2kjv2RR5`^q4& zRy*^oC#7n}iAlxCUMYiHcWNOEnxE8K;lURYn{)Nyou_ZI4&G(8IwL?4i(l0kL2EB% zl?5O)qW&n0(}jd89gm`0PlEONvkK#&A*G;Iq=F`ofb}thz#1sV0w?x0vbp4`>H2Yz z7UKuH%Zwx2pRk-$z&TBYXIPbDF~b*;z-r`?P-2v7o>1xk>HynO?obvY6dy;m@WazV zN@O8!lI3CO3@Rc|GLTetfB5{9ijd@P2=4rh22TMZ0i2R7&f(4l)G<)a zcW}WPHzHnZ3OWS%hp`GbrNR{z9szYCO^oLC3~pEpkWaC)Z=Q!Qr4YiwdajU#JnWC>m5^dST!{g>jOGhLE#IW1ewim7_BDP9v132wv+Y_tEpFwcH|-ngxHc|nfy3Q;UtS$evP zbn{6fKUz{q{I!~gFYN(xaCcidx>S=f-5?y4deXsN$-SOhS7>s)&6AX{QcfR5cvSau zgxnqq{{&Yp3i=&UbN!DH*<`9l(vJn|yUhlipXYzF>Uk)W*gH2)o|X zNeIcC?;vf(ctNsNnJg+dzyD8pcjvI;%Bs``0fJO#x0{b0Uds^{) zB6Cxc>Lw&MhTZ~wq^CcxB27cQ^3(R{EPM$CwE}|86eI7023fSZY>ub)hA8T_LHRR# zL9M>@kmu`~Zuw9)`2LOhl+GFW-8TMjc_$$KpF?$!ryb{?KfyhqKvSNmzX(9V15* zT@MI<%{n8QhZ%Tnk(*U)K2)a$aSlxB3kHQ3|i*ZyWGzNFK zvW=J?5ve&POy4q~fpmx(H6|JCy-wA!FQhegv!1;UIE%lTE7W=pOvNx*edy)jv_mre z!(Ix(r`xh82;2s2ENo@O9#g-WWHxTC+!rjX@I`BH*!+CkX=~sNYJc^@IkFE6-6V!{ z$*%Ir;=u8C9h0G=C)P<^i-wSkcy3@*B#q{Pi)}cATV2;L*sVFs^VL8PaJ=3nGa>z& zfZHYi0Hr;VUkW2w5QN5`5f!_Dk%`{e!pmZuAYg^CY4suV-|=3@?p<(R7h^duh&p(-9>q|_R% zOBiq+*a=auhzKptX!#A#4k5Z0hzH6u5>P-W1ms@t2X~?Hv7@dXBqU9VLZA3F_U??`j)w% z*G_)BJw;LHz+waT!DMBK)&qn7R_O}5YI+uJi@5pE{+s#E7zuxd2Ndd~@;&{?E7fY$!FL5$Y+-)ovp z)7%Ls@?_}z??QGXYd<~A;R|DBcu0X+jHEk>o33E zHPBO?^>ttku@1bZV8J?H3gTc9JrBzUAm4LZjbc#rGuCOyqz%Fw0@m2h#K{mW`g?HK z2Ior>c&5r0d;6^qrl8k?6v(>Vm2c~8TGAL0$I@Z>yD9Aqi->wCY6Rp8MR>0LvXfy|M*ykg0320QIwpXJOuhsWk?KM zBY>mCTgao3axVNa+SFs4yV|I>~R=Um#(l^zhj+1c?nAdkGY}fuKxnx0{{;=BK{v1j@=;agF9MVa@Mpw@Puv5ARD>F?p9wBTcdIoSnV-WB z>*90RM4Y7HnI|8Akdd1Gvi%qx3NE$%$%Q_9C7Rs6^i`=Ed82tqI-3@?Ir{>T`9x9p zt}I>wMWa^1iZVQqyBGj>={%iDYoYCeWUIJ&;@k$MqVEal7HQ_tc}DX@L&a!BI-^KE z7DlWiCwD@)=x70Juz+$KGl50hC}c=cF^;6F8$7s>jWK&98qa2Fvy|Ow%G*|h1Ppl2JkOjCJ6}c+0G5V@6ef1E0~r&8RE6FvzwKo zLbEay?(>f%?;g!*3NoKXq5>&FR@NA--dNKPdT4qc*O3{s`SUC6cO<-k=(qFDzN3Z| z>+7e^Z`Fp>@~JcKPVN6a#ahodPxUP$FMy7@R`zJMA(5PeeuN9`6%DxPdMkBl`XZK- zf~qbCA+7so9%@`jn?C2RF!5qxzup=mfuiIv@VB8H+uuBuzG(ys;;aZF9mfP*i${kI zus#9mG+=($u`S|8ol8p6<6}h_RwgT`&T>0jrnl5traJ^QJj)N#kau|$Hk=M2L17{l z!~2mJqxemutcP45@jNs1_zapp_2a^L`F^*3AY3cJci&Tda9tiDnb*T4>A+gN`K)@T z6-Ain%X1)bs=e4g0TE-Z7ySD9X{GYg=9uvdfBS*5QFQRY`6a*AKbZQ)WWLqg4R6Mu z4Jf!g_L~LYZiJ5=huQJd@84A3UN?D;S7gAqeOD^CTN8RIBvFoz07RtcxVh@gOP*zk zSpn7WXIpy$vx3s|xz8Qg4TbWZEmnxsrHIT2-rJW)O`&VzbbD__7x$Ys45aJ}|A=@7 zTt^yx#vJb`vAf@~^_6-$?Dy`D9rxrvMs5jLKs^!f+CFOIV7S|V95r62+EZlo=B)Ic z6KJ(z_i3vbw7SjoY)9f8WDEu=H?a&0@DdgT+$;;dDNS^1@bB{oaq!4U+SfICx2Wc= zaPES4^~;tuY@2zyF{B~^Y4IUvk&V6@T-~JR5P04yy&Al7&qd{C!=x|+Efw5cE=__V z#Ngbn7U%tY0x>5>YOYVjxRd#M7o~v z3qi9(90PtEjyVejcKwI(kaEmJz+1aaj+>speZ zb|xS_&6EMDU>|G!@h5L~`Y5X=SANXj`SR*)v`5$bW8`OQpvfdh5*-86*abAZy==^` z36GEkYl`xo1(=c|ip+tqt#?nIxD0HwJ9YSN^NR(F5QU@)>HFsFGX9cC-rP@p_2X~V zvi$eTy>1qp<-E&kSR&Q}=kk-EbNXW{n8r;`nMNO3#!XC97%3hNH@eYpbnblj;-Vis zzzot3;`zw5&o;0>o{;YZ&g$=3^&Y659zVXWL4dk0KDoBE<6>iY=c8MqB^*poQ`F=q zmumX1&^Y;%Yz50GVIk>++(aiFGhh{UJ-VX zJoOq<4u=!Od_q0rK$b~(K}S_tp5iF3AjrKcssq1-*(sY2^GabHoHg+^n@cl4ile8N zirew&;3uWoJRF>rilcHY^!cj%_Weq=U_DtDv~MZp(_m!AnUqFm-$Ag=l^q@pIiSTtqIi8nJ* zn%rOBnV9dHd@i~s;sYW-sPKE}t@+a%3tb5c#ERI%72_lAlzK}T`T)y{4C^F~`AM2B za52hwwD6A(AW1124_j6%~DqR;tK>18Z-x995Rm7h|2&C6Yi(Ogyu$&Zm9?Zk(RpGoj43n6Q@egnI{RNPfB%!(of z5CdKn%+LAQnMIsJ`S5Cmhj>=r1Q!RQvt5msG_Gi|y$vxMcYJ&n7^Sm*N_ke<v`Vw{mS}q+-#HDfTi?k@m$w{u#4cfQ;jm|`%ga!ylnMLSB6MEDr=T8EwT<~>^W9~ z_Io;mo%StrsdIDZjF8@kfJepkCyle}Kip)o^PA00!Z|4Io8Z~M7bG1+(0!C%S<)pl zetm-3a#~a}_d1FxECf+Y#J9lleZAu&+tA%1QlLxz+;-2SiH&m~!HJUV>-AV8K7kYG z&iwY8@5xOQK_MLGmg?n6n=px7w9iwyRhsczsulW}epZHczY<<5Z9~snGP%RO`E9P# zG4~+c>f2_TqK4=79~>@*m9z-+96fn=V#cL@rghTR#BHML-NkZ(5rZ3>&oNKjND$uy z)N8lT<$wFabSHX%CF4ZB6AZj?3!ZGn_L4Xsxs_r#%Ic*F?vtM}H)pvjGQu%N7f$53w9aaW> z_HDS|G2Mx?rPX75RNGDe&gQqV)0v-+zAk9U->&VLzc>b8eALr_q0O4*8^hUN~HEj*zO!ZSoZ3q47*U= z*oLi}wwxEK@%pJT$gyqi{2h~<57@xkUi?zkH7jh4bLbrW(lXyP|LKxj%b4GrVl%hW zB^Q)^HII}vsuvDF6N7}WHlg>rA30p1^e@G{C`WwoZ%IlM^hDIve%qN>n2B<(xLR3y zb5G6kZ=(dSBs%^}_r1WPk3pqW;b-j8E~?()2On@Q?+w0|%c`dRk{~Bh;uO^>fJn)u z1u?5*_E)8m9N;1C3{~yso@Q(T__&<+xIz(Ze9*eeb8`CUWGS7yy>^Bz~`o< zBU_sTe755#){_tWecxMt_~yqMj8bdFVic`wq5<4zq9%ysH;U1+@;?^k+292mbS7@OxW-Q#~< z5^cPOh|FKwD`RimZu*Etrb#Jawk?Ya!EeVh?4;-&S!9L9E zE@f4fKRRj*+t1QDbtPv$f&@nHlCSQS{f} zm9ET4IuUVN+mRye&FT#ey2)N0;@ltRGL6UrxV;Yx0lUPFq8s8jV(* z-#De^hrIE}B#l?szR7$8v@tzOOSe>XlgRGlcAxIK^kIRW{Wp#B4MgO7V{mTa8Gl(0 zr~k1ID{Kwh&O6;D^@wY1_cz5bAUYsZ+{q)0%Q-eD%)n1Nq(5^-Fmn^D2)NA0})oK4#JF zSoiA6f}+43+P<3Et9TO|<@7R~YRQb!Kg`Om-CM1t&D!=;=7MV>VAmqy_{agTJt$bb z820gm@x3-YEbqJRseEmeOR#YfX-c2P8q&nRdg8z_yhHY-oGS9hpHx2JtrE_B`NpY+&o`HuXxeEPwV71ABRPqse>&hzRGEMK<$ z*|T3wL+V3$JnflR{CCa`^DuD~$H1#|;CoXOuX^Kqt$%X%SI()habF|Ia`~p_n^K9R zNpi+bj-m=HLD%g6k-4-(us04W>HDOo$|QSt!zG^tiNB!Gxz>I%Q+q`<#4WL{ysS(l ztAeMWOPPulN^>0D$`HZ`EDB~{7(*}eIb364D#3rpR0vgQ_Fa#VRA(N*7HOZc#bI_N zKfMJ{MUbG|a8Er^GgY4)_mmx9@3UlDv7Of2rl;tUYcZ~2P8Ff?Si~*rC;EWatZw$g zP~)1(FZ|{NO0YYPBi{<#Q;Su$%eE?J_*Gcm6|OLEdHV-FlM=CZ+o=tUS|+yTZ8~Oe zVxzeO(aW%N)~G3-D^1q8^w-%qb4{P+Uf%8z-0*Pe%*~tz$8nM1-lgB-_AE0w1;D=b zz~{@y7m?y!V3!z)5d(;Ww!1^+Kf-!wQ4cWhCtlZ&PqYgq&1rIw3jw)lc*x!4_w{ST zi`U#d<_Fv7xTDF)u5WdjcT&W3$)i~D)mAAzZ;iM-J%1&Wz1)29lC>&3Y{U&f6z8%2 z;-jm(U&kFk*gb0wQMjPnCgXiHD;AHBP1w8E@mcH!k4qsD6zWBVK`#$RJ<~wmvmej{7gz{gzYQO#`?IO;0G#itL69kaBz5P0th*o$9RohpJa+a zJ5sj<&#yovve?1BN>)E^FJyG9>AUZ4-Ew@2&(CdMjeQU6&FxJ|?Y~X0J{nXxagO&( zW?x#{OedNvcYZqxzzwq0?T9lW*| zn`7ckmX%(ydO0)cbKA4nT3yFt!9FN!mZGAWEe(FSF7xt28|BoOa~-SmX_MQljA+XH zukFBJr~T}3SoeLAVqXnRY3YiBX(vRk*559^6Tl*%ZH!)MkW)Ts5x-jhQWH?~-7Gk) zhOdjqL4Q-CBM>k_)u%N_`S&e1*)Hhw@^tf0EUL@xTf+>HGU^EJKSWsPzJEWr2K$4n zW11%2&gGRi=KeF9f8~sH*$MRCVT}VciC9AF=M=WlLnzVh&vY)y zxM$hFLDYruAfAjB63JcixwL|nzTq;ecWVY6g|5HkpmkQTvQ-72RWo%_#Qjf;8EJmn zwwQAZFg3(BQkv!hkheXqnz5uavjbm%ZHf_Qmkcq{!EjG8e7Hw`I83-F&SPnD*I&Nn zJiyKsKVV<%IF^-n%U6H3@<;(qs&X^zi|4KRi{4oDT$!Y) z%Z=YujEv2pyw~Pp+n?GTotxaNs1EN{giUD+QM@~zWc%CAG~5hSTFk;9`+s1MjXM4| zHjcb6=&d7r)=Yb^194Ybr|9vAy5VD-zVjQ%T-x#UxHj%;47K5~Pn&R28LFnUrVOvl z8HiEGsK%}XV7K$n>2WZ8E3l^PGjstmSc>nGD&S)tRh9n|&UwLOwX-|tK~vnDTwwG= zwB2Njkr}Y1dOIPv zQLrp^jxWo1wb_<8Exv0mQo1qwIVtj5_Vtay zZ=iI%pNgniyH~by+@0dKD`JPhiI*3yZ02R|N6C?@^RrX}_ZKFhLk{>%>OTqS0J`x? zsx^z_ZD)dMylu@;^Rfcn_=#lyHx~NG8f;yJN4Eib_pVAd@0rwH9~F+%4j&;Bg#Qh9 z!Jv0w32WQ_x6#GXVWf1RAzFR1=Y+V=5=ei1xn{L?9@Z~4Y}T6P&a+eVwm7-0kZyjR zqReo9h4xD*5C_b)niHm0dh1Q*=&w8rblnTbUR`)3#phIA!jn1q0`p|5h}*a>cum8$ zH8o4^;%*>qTPhCQ(+-NJ2RdB*rj{!kvt8*GJ@@zD65`fB;h(H7{&^$vF0Ip9{8@5r zL(}+I1D+}zj1`z=G(T29A(F4h51?VZ;LJwbb`Py>4ZVtPV$GHXPUeQuSsm+*fl~;r5wN_}9h2_>~_8-vG&a#xGN=8&rgV3jxtwu!SiYLo!l=aeITHwUCZmN8#v+oN2ailR# zHm_}Sp=P?t4@tHhms=}u6z>y0`56%(__JbH|NMmD23QvA zmXwT-102hCob8;^=*$%xU2D?jJ^*fZF&fxiWG=2IV$3=j%ebxo!!^(Z7WDBH6g{3< zYVD93F3diO8{4)U771id=!=(zp6_uPbM1Y|`b9ktnv9cP*pXo`%1u+@()aDFoP)}C zG+&@kkI9!UU3U9iW7wg#}Se{OD&O(trfD? zr;-mAJ;s@mM&fUL%!IAokv!n-+;MlkvFTXm2NC)({ohhQeS51a{R4o05*;UiDtrIh~~ zdD?+kZAh2jPDg%oLfhiX+w@}OyGg;|MHF=p$rlsral`A)=1Bj=fwvPk7GtG{PH*`5 zw6q`2?0Pk3Lde!Exc8Oh_>T>%{hGeny=LBKuLXXkw~yFGo}<*;A?1x;Zhq6(OxVaT zy^?pXF|VR)=Xqp6og_JV)wVppg%xx!EAQSu*RaFu^!G#Xf(NxohqyIA37!QmQBo52 z|BQM({>5dflg; zpp%q*Z6fV+za?yWv~zIrlOog9#Ls}vrE{L3M|KVc`?dU5%7Pf=xYG}}&x$Gd^b}$H z>M|r>SeDL>cq{eED5Op%`wYZ+>w8y)>=q}v?kye2S+Ofa`e;#Zy~E~&NitK_#;c!O zKEz%1pRy%WLBBwcbzX5?c`7*(Nj%5H zC&?y1H14rKMT7Th`QQCYCoH!607berIe?urRD+>J&po+4){d6sivjndot6brUDjB@ z!F}2@odOH7v^J&qe^4D>z1WrI^Y78HWQ7p4NVcj84o961{5&qN9{H~P@QJ<$9=q05 z#_spL9&s=vsU&L_N^BF*H?A=8TlVemQAvHZHl>h?e2n_?)wj%pm{tC>mj(AvC;xwx zy=PRDYrC}_P+=(oOA$e;fPx6pA#_wkEEEM5kWN4pLhld)ihxLyjs}RLg49qX5PC~O z3sGr-0HG#GhtLVhoAvB>jJ?NxzxAx=`=>FZ)-Q z+Rr*Z|6XgknI25-RKW+BWD)UIM#Vs$CYL?9YkFaER*Y{s>8oog?qsNsKDWhg2j6=| zw4*iFlIt$IGV`+Y-L4lq(_8Ndk_j}edzG*OiTd9_-WFf0mY<_p0BG6)8$cR$EvG+% z^#Kr27rIQjbslOmfs1%Eom1`w$ZpsNGPhnv18FNU=_&mjAkiOmZ0apl+gm)=8`bWj z3=oulPNon_Y!nBIeDOZZbC%9Uy&0nTE%6Y9lMBo*{OXfRz8C1^!AQA@D2dFc{TssA zx?gAAb56prS8cxcJjT{zrMTekFWEV6+ZgrgdXeliV_Wv?uR)!T?ncT5kv1Wu;f*$Q zmg236@hdXcyYIb#967{*9zoX5tn;o78wMj6I_iDkjL$tbi{@Mu%ZA#6G1vXSCN`$h z`@1@iRO9JBzKALPJ=Bty*swWC1550z%TF+Vk(bOUhxIHKAAUFfuzNt#9Sob*Q-#Wt zKu1}ah=pL{o=$jJ_|7^Ww`R@I7+$W|vaP4In(``BzB%fB zpBAQL$1Yw(fR_1u(1Gox*5#0U9*>8uIK>NyYnuWVU8o%cyYO^9s83|PcD$k+7=3j% z2>t}d65P6}teAmKHd)hz1kZ&8>DI)w@DE&3`uGd7^^P~9^AE|9ADceKFhH%@%LR^k ziK;`*`mIzs+XKm?r+;Y|CogUazPX=^Y4JN7teF&>Kg;5hs+}$v5yAS=&x~s4dwBD@ z!WwiII9bi2a9G}TJJMV@+uU!;V#{B=pZ@#Uk|r@cfjB~)1Icl za(stZ!;+uP!mUz&G9nOsR`o1Lkj?1k`6bD^!^lA!9HkEG*?~18inP~}XM~TEf=ozS z@r*zXV1L?!MXG60AEo(npbH1S%gfslm>jthAxLqBS@uzk$E`cyZ8QNLF0 zZ_?j@1pg&|m>aXq48NFKKmvNiR460M_o=vbwjcK8aXz|c*#a^IGJ@YvT^pCfOvha=PaX(Cd(31XBO0SQb*9CK)1L{2bPl8kp$^%Sp3b`O z$A~udq_yXg)HXxuTD-o!fnD#!M1NNB3P6cJ9)Y9Uy(+Jxg*EeKNf)yxWtagv{Ne~w zkLAJ9Ld#XkuUfe|eUQdzbG275ScYBB8C z{a4wv;KwhLI#GVSzrF>U2$@}8+2z9Er#AUk;q;fZS^rr=HsnE?7CS2_ZtiE>ULox-6YxqSZNh6@% zLnYeWRn zp?SFxrJ;5}z`^N`Bk_}h3|(Y%)3>l$o&WFqK=6Ow2NC775fjNjERWy6-?3&;sXo4L z9oX!Be%kJO*6=#3fGrXT6kgM?9Hk%IR^bS<6%|-`@al=%>+sB*M76|T$m*Azw zo&+FbqsuHFp1yB|eOcy{`kY`Ww;XPAs>+6^QGHm*H%G8)>P?MEX?S&4p{7XaCtlUz zbV*Uzf>=}*0g&xH@yPRXX!8SKYs$5QR4&_5z@E>6>aHiCZe#8HB;e11T;oXH)AhT2 z2W*ipg)Q&jZbnB=O&%SHmNW2C$MyEq zW^(T}G?U}Cdq>1Hx;ze1&;*j&VS*oLW*CSR9<;AmlQ)XxPq>fU(Qqx_T~{Ozk8EwU zoH<=;23KG9lcN|l6VfHib3CK`CU!1l9U8VXgRz(=_D=i*UINvivcG9%C1 zh{?i`WMw|X-w|p*AQI%x7yx}RZf)JQRNH9Y(Ly_UTkkyl#uL4~utrmtFs^@E-+KRl ztZ$z-5OlFbG!;1=l)%^B^qbFc2%S$)%#5z`eMExIRexH{{Bl!@0*Om;ws#gd6uVz( zNLeBMd{DJluBJ#HI`!FrE5_u9&D$n2A9mUX$W{!6Tr5sdSmvQvZYLx*`Q^U3frT}q zl^*TiN_^WyDGhY=@;O%WlE*ltjfn&szdyEoqGf7Ep?^@2N0s#Igo^$Y$0dOS-CYT` zh}|-eTSZe;%jr%x%-gcXE}Edy8qH9*7!%i_G{*_}nV4k_mb7#}sAy*S=>8i%fOvN7 zV}c$FpkO}{)4&+lOvzPBWUz>K{{d2g7F6~#uK$kUB7){=wY02^8zhX6*!80g~B)(29>^u)2J1^ zFW-?($nCf_{tD6ZIJd*OL0ZWp2PKU>6Ev0cFo&ZGKUaCrD<3vdiIh2*P(SRxC82oP z)xUy5i?rW8KnI^_qb45FG(j%&x{qoKyKBwsA0`&MfD{+%l!GnyJKW9Vi zyyq~PIplY2#;5XBlHwqbYT7`44el3u3Xd&}1Xn*n+q_aPS;cPY}Y?TEQ|ExTBMmm-`3KBWMmb~dd&31o_z|+ z*N1Yw56=RJ$MsMMx$VdXNTx@gvfscv(;1QTf~inzBxJs`N58q+4 zIP&3iS)}QHR;9=^bJv6&psa1PAtE_HBQD4pihU%tF8g7@P5a8A_6<>Q|TJZy7q=XBDQ!TpiPDpdW7uL z<#1b;=~c(QjE*`3vX*n`(+aUG)-I~UcaTsW5=5x%y;;+>Ok;pn3U!sic`7#ql?iQx ze)TfmS3U@#h+6FNUM@S?06Rj3pZwU{af!$jlA0$070a9e9{t~;sgp-z5t)u;99txF z-#ndho6(9oOaqwLJ)h(~oNKFizne@Co4u&n{3|@g6%92jfA7aDje4uW^Bgi4Q@P4d z{YBIF;$PCS_zh#lSnez3&FgX$w%aQ7q}qsgH;}Vy$b{&o z#qoE0soZuR`MS&H18U4gp1d1iWYj&N$drve8jjxPa-a$f8e}|bakw_!PM8aLPHSsK?yxLOli0 zx1Q3kn%~b}kE|EJ`@MsiL zthR(L>Rc_*J3c&KxWWlAS7RXn9KOv*oN(Z}Goc1}#+{K&OViB}JKrB?GUd_GaRCow zMUNksQyLG(hcJSnTf7AaodIxVLv|;j2Es}dKO@OjoGbNtm3!mtsRLW+X|-7d=9{I{ z8X-N@ElNySla5iJZqt?!!=)@}mn>8K(LQaJsh;m7&DrtTx7I)y=%M}0FC%Us#5Q3;#ZY#q+D1%Q4}s~cc1Y~cL}NAulRHQ z5a{(HRK4o?;EHHyybO}4=YM?brc6K#E_=t;W!jCz&))d_TNs`2^4avtuH6RTALcq1 zy@C*@3XAb`;}seeheAMSp-e~LV;&b4ebllRVyht(`rTn;%!hh#dFF_(SXOsc(bPas zAR;+L8FNn0AX@7@+{K)>KyIg?s%^UDiD5#%ZK8tBQx!$M7}TgCu%M5BIhJkMqGCx! zwX!3MeRa|pdl!wgegQdky;!L!W1;I14xk-BIu*wkvh#J0=q1SrJ=Pj#D0cS+jr)&x zy<2})8V7(P9p^D{$LSNPv8P;)Mg9nC*}>LuMq25v0SV>mBpE**rQZX4qUuFOzfYfm zp*%A1lb~<@X2D{HyII3R)odN8C~DNvzO)!rH6 z?XyPPiFXCPcnUQNa6tZ0H;_@Fe9Zq_dmQgJzH zLe@_X1j&>c;(U2kX4mR&Ux2p`_7Feq&hRxcRwFJV%l-mw{3iYpv|&nKR43Yh1lpJn zF^(8@o3xSW`G)%I+fErTi;W4B&r(negoV=l_zsST+1o`P$DMDCfswt5NB5FFh6ec{ zaT^3q_wbv*+7^PRF!+4SI@(a{H9o``Nwj?$B@*(u5M1jc9A%eJJ^osTa*c~uk_w76r-x;LE*guhlS3AsP$q)@7ukvjD{#GC{r< zE7bT(hLcCHibAL)$D3aD{CHXY($}OU>4hCw*lFrCsI(ZL_v%apSugHFcI=w0Aq2bE z=|k2x6>-xSqL_Oi-_(IHxT6dkxz?0c9bOFMVoCd-9B|<-(-`##?_oh+td_+{@|Dc#Hgo1F@}FETOJrQ* z|JK^b@)4FlV+=SD`*{edZoWT0HVW{bg{S`Rp~#rLFiz5QaG!e?QDDb78QH5;i|h3M zyst+ByrbCy4uTBgfoI1F*^bsp;<(r+0GajYVeKSz2dfvj&`kbg`PQ+ZJ$- zJdhvg=6EpKRgKcoTw{gU_go6W_w2vz&^RS{+NPYK9SC-46#H{DL{MYo0M9lItrV*m zrqV90YNB*7+z_28-E}-jZ|dzn>M;B)(U0(VDy;QZJQ~r?T(-XbUv$&COu?DMdP1Iz z3<@n><)e$ZHy2XS*w)+DG|-VXjmfrfZ%+oBCX#x0Eg4@oL^UVXpr#}{xDL&adZ-wh zq}s4*5>dX*uxF$%=BJUM`*&K>*`~ptzSUY?93#7X**#zG5H?J3VX$2TA2%|tEwc=C zb!l#YBHD7H()eA#MUR}49*^hEbDyRWpyz`&+xlBqfpEUA?+^Ny2-6bw8Ecqe7Mtf1 zXF)mXnpZ{ML-dg?4__!wNF}92#gI1F&r}a~7+HDUBJi7*Rm$z%mW?cy_nEL*5pO=I zZ=y22P~r-?Ak|0mn(<3#ExpI#WSxg1W=`>0Wxaz#Kx_SmeVQIiYef&7_1y0X#KFdjDNDNi3FkLMY^`w^dlO;Z zlr_Nq=t9oDP4F0>Q+aMj6{Rl1?Bn-3bh);uxqD9TK(;_svi5KTDbRf8Yl77j{nB+X zrGJkbALqA`=MA@RFQb?WH zGS9vbc1KI2buxdUa8Cb?!XX3!CGU6QY4^(HKge{LA2JV=9sO@i`;z}M?PC`ivwBag z2&kev9eAf7mh$JCu9R*vnRrj)t=LCTEQ$F6*2yhsDZS>m88iBPIOs`>Br(y4 zm4(y0aE_1lR*LA`Ubje(1S48}KT#$af<@m=0T2#B0G%gtI}6||Sj!oCw!e&GHlKXR z{bA10NlTpQDUynj0w~GCSSL?AScXVU>G16ySR8R^GRz}KI}%I*Hj4J_n_H%=Mn>5# zF#<4FXkck&RXRc0j@11p}r8M+4rmAQ9kPntstQR}Z^*>`ZU+R6NC;{&R7IGct zy1!F@Lq$oPP=<8IYf0$N5m=&m{4z^MOI8Bsit71AKfr8-bV%R}TCyQOafU*Ir-zL@ z*lw2?zdUQ}(I;rt5+5N?q{+S?u^BmqL^E3SZtaTX5yOOWdse#*eIAMbUP4^qTg-TB zf5jrEaOW?Ifc7_c)RTyR-BC?+y-nj{4uAPe+n!y`F?LhYTY&_QlTM!{ly>t2E8|Wq z3XV>C3`IQlNJu&HdC-43wJ~@rIG$UJkSDRTFx0%zIc5Tys1(tH-bDw}Ue&ksu!k5C zi#ee~-)cmtfv>KzYRX;?&zRI+#!G;a)IU8J#2ttQ+JF@7+&)id0+bjpn31S`w;{k=x7+TM-^`vYHd52pAa%UCXrde$PQ+6+FGROa#tUjHq{y-00+P z34b^1#1jh(-|P;&qPV_?dwK3d_>yM6gJ0BHVO8Iy_TFnTw~JU%;||IjPavpFCVwi+ z-~iM%)#1`4BTjjLRbkLu@4Zm~?o&TK*ZpX;=SW}ByX@}0EZ2Lv?zeqftgs+}DL6~% zy*&L?_hcj)!*E;Iz%|Dz@9%3;q*hrUYpR-*`h2m7^C-vrRZEGW4vw?69FM(~lvc+O z3&ttR>oVab`Lo;8u|Y?22k*&Ryi&Ei+wAsWTQVQx&@k}G0v zNq~J7PgAI%QH5GXXuHglwf=8TRy-ZVc>5?RXdgujZg`V2IY-$9l^miW8&?}>$v=-? zH8Fz=0|E(+|GWU|B|orzWA%K?N-y?F0lhZjwpI3i&~+xOkRRr=u=Ip4-OCSJ86tM& zWyrC%uil4O&o`X2_CL9QmGjQl8T%Dv9H>)*uU;B&zxzIR565r9#n>s^ey9<;oaCV- zJ}YuDy7P!p2~)4C``Yt~JywGDr|i?c){2U2optAlw{dZ23=^yI{Au%5Nh~s4 z#8?ui!j5N0Q$jp~I5InA`Roh&gua8iTG?#=lB{c@g>@$rqzOulU+&L@oTxH!-h8@~ z(}UA(-qW#{u}bOoXgKyWY@lMD?4{e`W+$Cv`Eyym$`^4e46GvLo4EeUSXWkm%UfWL zJ`f$ITNW>;4FjyP*xzTk5dqmGB^|Fzg}(&>!3%`!U1bgbj$ZKKsH{NWvZs*B}(H@*G)hFkL^7f1=(WZSdTe#aI@S- z+UIv2KEwBWe|osvfyg!#N2y64$wOg#)GO=d$7^)0z)f{m)LI&#!;ovynu1UyL|M6U zNFrC2?P)0XuTLe^eatW2PF>3iu=DvM=iMO!o8#YDZ3?;LrlyFmR!W-HjFZ?@tb6sL zj_{y;Lu?Ex!pzcxchYqE=i=D(b~13yzktU>g|q|L$*zhU6IUt8LZVD%vz{-abVu3V zZAwfjHkIPf5k~*8vm3?j%v9GI~yf3=~P@g_EF8IO-j_*VpbKKez1)6 ztRg*nn&Tl^Q`b}YwB;Cnng53Y_@u=q!ezQdQs*Qoz%dxHJfQPSnotG%O zLY|!)qigO$2?69Y@*&@dzO@0(NX4*gPrAMAKNBu=jCAUnf0|Y(M3e+`&y@>?L28Rd z8L{!7vl|YZf9~-_Mi{qz31z&?RmIrU(A`#-P#tfz&?(&ObWlLo;&y60RJ3yHGvTjd*oen)o zUV}2|Xun=5jnp*Rwnmcb#!b&=OE75+>*!6J#$ zC5gxTj)5AEI83%1UGFBnOcZe9p%XhB`l{6zAGp)kI#n7#G5Eb9$(zgJrx~NIDU}H? z>k)n0w}#tXV$fT`Z{A>bbXTr z-@w?C%QuxC`4uh*SdMi$){4`s^~^xYjL&g@NEa(RJS!63>+tyt0jE_41jv%o#UsvM z6a=L2t!hQ&Gg#X?kerbNqf#t)Ru%{LtaqyY9MXH{r>TufwD*vq4{o!|)FT(q;?27m zO9_0^`@go}^|H?ZRpp*A9*darPg-klvWjypK_z&#nXl7J0oV9xoo_lQ6`e&xO856_ zeTLMe5b9^yJ-cNxcBBApYVdi7fJgIF>!Yh1xcjhyy_K}9=SPhp%VuESWZ6$6p)>4) z@YhXAyux9-u-r0my(>+)HgD9IYJz}qqom}(ThGmu7<2RsAQJKXkq@A z{t}-&w-D8|baVDELxGV?~7Hfnj5&Wm$~ zed2j*`xNY;CD)v?mnexGhpWOIr$`;dpWZb?C6#)6Afi_BM6rUYI z*Rwvh+)@<^&*s)&sKz|exMo3mRb$*{VXe_Ye70G0Y7NBWH1T~;VGIvR41E{nW83A7 z09mafF$3qeg3YY>n&;TP{z6U!C6#cuXwztspUPjS|0tXeN^^V*oT%-m3%0^b?Q__Paz31;ikBLgo;f+2#^=`+tHAz1u== zvI-ei-HveTxr8Da&_|Wky0;ov>z*OhYAPvvVC6}atcAAE%*Fm@w8?3*!N^tY!^-=< zx&0DcRA0@>8k~A1oKkCi6~?9)QiKi}3fBit`pX>Z*sU89jcRM;FoN_h;Hki=OZ#}X zWk1hlXvJASXMI4}W~y9Zu-b`=EYmM~bk3f}Mf0S-4Z|(1?ZAY8*jG8W{-b?0Le-s) zU>MB5hnc9*WDCa61%INP$fD4%Q=BHMJlGX@a7`{m+=T48`VZ~hMtdI0%{>-YU~~+A z=jI4#BAEJ?C%*B7d&AMjb|PTLBOb4W3&0iDd%t!$v%rjwm%;SksBp4l9$fZuK%fc+ zvkg9b)D<69%+&~=in&k%jii-;#HZxL!E+ANn8g97=MUo51%~$w;BK5a_Tu4Wxtaa| zv;{V|SoSej^YtOABr^6{!;8JZO##=ZSbwWV>g4?4zMIYYIVXsD#iPgCNRK@yeJ(=_ z=VxrAYH56XuZR2+!p*>#e0VpYSGzmpHGaecClU2?9J7#UFdKMsbWOd-tEHhbl4&s7 zS3;tW4>3-BT##BKjAP|A-m`rZ!R#Pf&*V`wW_**Wu3C@V_Q{$kgGd{Sc~7>( zPV*EAK;r^(ccMXDt~Qj_kZTqV+0_~vLZAi;0kUV>{L2hH=xFmMw7n9|{$(kepP0JT zmvr+Qhe?8bO7ZYTjN5*}1ufsQ**XWX`<$ZoaMuWErbQ?IqY(5tE@Q{ARwC zNckZqv1vX({+h8Vm(NEmS;IxSEijEDBh^$HadA-?2JpJDz_}?{2ZQQS zrwLpHuAB-DeK|p9-IUPidClCqsK*heD)ukN=~wY>!Q~*W7oYKu;yD`>(HoLWQE=a~ zWx?#UvlaoqA9ra(F{0LqZSt36mk?_H(#Up{CT3$B+Af!S*map}_O>=sgy@kJl=l{f za(KFUT4Z8;5W{P@j^q?S->?+WpVu-|_dCJ*5Vp$sZmKMZm7<=Tw4L)|qHeC16jAJ; zRkecQyLTn&H*(?1)LB>2s>&dz3M}%iv?mSkUzF4)>`pr)yb39xgwH##k#+U&o* zG7VY=Tf~>VCo>RcN57MQKQ5wg#Rp_8;>%X~))tHOL`z04gA=#$O!L(DKjl8LrTbbf z2D7%!2(6~x{7HN%pD!HrGb3nEx;-({gJ<)WpVveH`kBz$fwf#0rta<=qiW9_7m6y= z?Ova-U#+q4R?N+5=!tbh=ZJK$*h+GtZ%y{gcJ{bM0>1-xLzf-`Qo zX~l|b^=6+JdJZ(+&dLt&zp0E!;FgTH7#efJlIyzK5Re5VET{0DIU%7|*BRVy(Vp=E zUAd6Pc0MeNPj`raW{r$?()vE7y6!fciQTh$Cy%<9+ba@5PE*1P+B>!Jj&JUDAzeHZ zYq&Bb`H~fm-Igarxi|Lkn9v>LNjR3Osg2oRm3M|e-2_cDA&n=|B!JS-fI}?+^eyyL zXFM&AZ)ZQzEo5Eg$l@MV^nHcOA^Yo{M23i_TF>G*u6bpeId^^)0*@vu#Cjg=vb@_l z(1NC7_*j+L(|f}t){xqz}KgrqIYl~vHjzrh_A|F9;xEmvwyg0Z#I}w^Z(JEttZ22Y3b4QktN%sZ}J=!c;$Dn zP$122aD;3xEB6&&L!OLpE}CZ6d&u%R30qWPO?lRWiDj_^x|XYZZagT&po`zYakZRA zgSRb(-i zZN6M0@|!&*5AmvAa={6$%Xn1cADfSeM|2VUF|EV*K&N_Jq00wfv~HD;uL;!^8L3jwwzNg)5b;07I^%olWyIeC_I zM;$HQY^@MH8zA|{hX|2E??OtZxxi7BO3#v#4bRH&OCiq>nRTO{qk;EQfPnV4$p_hb zC)e|4s3cbUuLxtW_kal2DNeOpS!Qt|sP@1}c=%ZW4E{d-hqD$z1%t0N$a?hbkBI5=D!m=Y65VanlacYFp5U*aot6}Fh5O$YM=%lN3&r?z zoKS3oWI+uk>~rM!g{TLhVo1r9cHW9ZzG%rrov+Mg(>>#LIu~HJPs0U+q4P=;Dp}U; z<^zshCra#&GC>u+CHmu{GkQzg(3+**OJz_<&C)($7Ga_~gB4f{ICgQsI${r9b#I&U z@1y4*n6&Rkt-f=wxW!#weY;Ny|7@%7IQEEPJhkFLl5 zns?HBWVuRwHbDcFM^Zy9xzUmVhiyKRCt<%8KCn|Re9@=M&aOo#?a;VVO{99hY0bl~?D{2++xO(M{T{uq3plMl9+!o+ z{(WLJT^%9}1oIag_46WUd^Qn(S}3}KTEB|*;*=_1B`C*91Fr#>+0CWv}}ssyMK4`4@)nAB{LhJ_+_`#uA1e#Mm@COdiwdxu7>cxfFPq(=dx0P}dr{Yh(Mo<0uz^L9zK!{!mzrjHxYp%km9sx;U@aFY{x^JYfO77h)Sd zX$=#)y%VCM{KT1Ru__rEUJoJ5p z&d@Z?$>!?;)x%}hHSl+=Wag^OiJ$U>ijB3(1IJrW98GuQT?~fd|B2@;9lH3TWm^hY zUvL<)Tga%A-D0#42tEy*muQB&ip{(3MB+0=$c?pi-_%nuaNv$oiMiVuvFp7H|OC(|zx1#)5 zXtqXOVg-mMVXgN|Y|F~cQ0JOEQlb@2?xN)UJ1VnbeCL+0RvuBCmx# z?Xxxeqd_pd*L^j$w6L`33Y_)Ima=Yc_GeYoZcGO`OS9PGl_< zi2V`7ZYmdx46yTh4Y&)2O!Xy}&B}(v3LB{%|3kL=tb6H^E_bDLMdvI#$R4b+7oQ-H z`f_H#pJMAh{(kP;Mo+L2JME88qGB^_dAL_+*3{FEph2Rm+E98z(Po*rpket3SdI!E zNkM(*J}U@73!WfjZboxP`f|{FwJ+0TBtsc`JH7PRBAQC}+!~c@`!5H>a5q0UWm`nR zzOfUSnYNDqC)1W~`wyA6B6m7B0T7I5Yu$#^OSTNo8wI2=ZhO*?P6FgNxhw5mSQgPx zHP#B_b1FYm_$^#ijnJWOF3k2{OIe39;;J^8$JR(JdH$G2gSKi|qWSsjk9E5UU1rWp z(JsOB_c(3k`ez#@Urb5OTFvqLn5+6vFqL*2=0kDua$Ix2?kqJDUcDsB3rw)u7$ek9 z4?AwwG5`F3H-2xlU28lo`#x4SfYI(g5nrAY8(_Xcu#rjmOgU$m6;DdR0%;Bn@_u}x zAP1?^q-3Gf+CKd+wZW;ULbvbsgRZWAsl>)w*%oNL5wi2;Mr|m#@I)50;i8Mw`-N*^ z>|KHYCZPHO3O%$3@F$rNUA%yRMlHTWmeZXpWlvJc^l$(H1ZxeJt%HRV*|46Y5vVD% zo9CXbrqb?4?tZ<(ESHI=2khfw4jOLAIo7Z!#83a)f|<_g$PIT^VzNo%JVkJkXFQy)PpX!^PC`PG$}~L^;OAVMw=Dh`)m9WwY5J z2X32AYFe5YS(e~xS?3gvc%R|NXZQ(a+N=zFq*%SIC2F`05dzB4U&iTTGqX_#5?<>e zncr}g2Dc=XB*UN z|Lk=yz#GoUwIi2^Tin9UY~1@`5|tD?8XvM9HY`%`SEJPG|7w(iI@%P4R5Jdd1;x~s zD(`e`DyE-tUqxuGc{g_69Ps9V6<049<^_NVbI8e88N)&QYX+ZO@U@COmc2;ppu|dz zquX+iJs$J6SDl6>oBa1E9j1|ZG}@<;V08OseD=GL;OD3d^3X^WI}AerB#BHvf7SV zTJ>}+KJ*V#>)oBO@y>=(c5|19wKIINKKXgCNas%Pc!S-V4MwbHA9i`biz0ymqc*!} z=1X$+mD#6m(VgVDf}QORoo_s*jK`LSdM2W)o z%wNR)S=)F;Ro^-&O;3GbN=SKay&>U3xOdEVCXSD7*g(M99^Bhvi)7qvgCDP>8|WF( zw;YemBh&6%djQ^${t#fg2%Ub~GC7J|QW`qQYkH5h`0cAtuDUj;csA9s7_31lRYFG9 zeEp4BPEnA6`L=m^%TiH2Q?i?@u)~6(MKhQ7mSs3C+|<-Ap(Q=fE)g}s9R{a2q$)A&kD$;)CT~7k~o*5fUe_+Sd>5HhTgTF7)b= zxZ?vY4oVMec_W6Gj@(9e|CJ)P-ddq=KZ>QsduJ?~uJth6wVcZyMDO^OR0lrK>k%nA zH28jd7|twxnY&s=AOG)!=?>;^syE=^b_`N?-ooB2Z#ELebSR|(@ zp4D}d)t^~_j!4!kPzmdo*>VCj;4aH2MBpyxKjkM@;9kcmo-5AQv~!+$rN|cxvz^;} z5X)_y;SQe5(A#^$O?D|g6I(;M?cZ30as0#c7iw}PqlCi!#1*7&qSJEJcjINr!!w4- zSl6)KtO6`KXeTZXAJ|^s=)KqpoOvd_?;$aai|XQO@pxy{@8X${y<%e>J-e>g`_5yv zcuDfQl8h!!U*HWGa7QnfGm=MslR{#-7;-EUd%tjp1PE0Z;r;qk?~YLvIDXZv0P{i{f62W3;et$&H+n?K>rHsn@^%z_qsLU+w)k~&dWw{D&kOwi zcpY01SmRUL0HNJLIS5h<_o;}kzIqHX4ixrkV7zV}_iF)hgpz3}q$7vapgae^uSqy@yKwe4R#!;d0P$6 zR4)d^6V-h&ufiGy@amWw8^U3ySsAaCo4cbGX*Of4J~Z&tCx_;dT}-fMzwyk2ahg_O z4a+;%U9uW81KdQSw=8|?@H>2m-_c=&XEVo%7S|QWF=nyN-2YQ-)9_EpNaj|DW^3iH zV)5=MrXTTHiXBb2+_jpM2u)#D3CN%_?;ZanN7 zcwYmHic0uz!cTPN&Zl9>o>Q$@m756WoZ&7?EkI9OX(e(+^5dq{px+rd1#`P%2Uhw4 zHu&LL@BPz%%v#%t!CqbP%}w)M8|Tk|q5f7p3J45HIEt-@G%fqUQt~A8+fNq^2X}JXkoQq@5b1R&YaEVG5?-`apLq=OP)jNbI($It~5@TpM zK3QxW;q%_O;F5@V7N0Ly!DN+SxL?6_xo+QkonH1w$FKXm*o=wPW0^8#ZIm~opPSO7 z6>SF{lUg91NY5Z~6R1vkL0h^yYdqnJP21ZLeGnhB;Tk)Ni%`#+Dg z3cR7bdX&kh{<*)0bfu7#A~kQbj=ZaS((06JW;J)cG4H1Cl^MJRuW~#X|9Fq0>+5*R zlQliZRjskwS2qr8@ntHCmt74Xd-TN;LeP4W;L#UO-)qGf*3TILYdwx80LXwUJm_|i zPyptc#s>c$Wxw;$(oNtb=tIyw8>dS^5|Z0Ge#5d-Ri_G+?}vRFqk&AL2_N6kLUgWt z*$W;aX=?}_E9f!g?R}ue)7M=>bd%SHcfdITr^$xW!Ax2rGF_gOcXYCKH~dg^SU(o= zQ(u?3OWSqaak4wgtBHNVELKbTU&U(vc2jcy(CRa&8Zpx1TS7##tRLAse8RiYCqxgd znfr8v7>C55?53XS?(~UTJ}P-%1dzFxIWZo#+VrPNhnQzKMWrfJbPwJlynpA$!?6%08>UTtcg{N5$`_RNXdx184KnZ~7O3?L!&g$B zya=6^p3MgAQmV_h61!y8(J6cDcika#gbekcZ-Z|dH46i~if;n-l=MujQ_`OeiNo}mjo(X<2 z6^)o`h`)^Q;mc8P4KYe2kY`Jr&vJd-X>o7c;ii(Py2wvmjMiO4e=*T z2TpEAaYoWO6$JsziHkIZ|M@$Q6R`2;=HAzRZmGdUz2rB2s6^X9XU{Be;bk3x1nH6Obv>&EG!U zxJ36hF1VtU0(s9gL(B9|du^w@+VWZ5fgX8PL7QSFi}JpnlmjAvHY~!^CWA=2!cXq@ zd8~{5ax$xbrqdDP*l|(unnj!Egs$JApYC2+*d%{3`DO(^aKv+TBdP7NV&|xcQQAtf z$MA)My@|b-ZLtw?`qS{)o8xuUQpd3b_7mKQ?Tb_8>YHLC^?&a1o&FQJHL*%j3MA2X z-s`dm+4&vEGY6@{$Y0IJF2Y&&Qn$iM^w_N*)2NUx*TX!9Zl7IW38{KVVTDO3`~ELN zxj+8LiGSODyA7`=+mEUNJgsmHfFNMa3TI!g$3|!B|7t_{5au{Ga<_Hk7aXC6hDnqy7(LZ~hMT|No0WQB*>uELoFCSrS>oj8dtD zN`>sklI%NSkZjp^vP`m7)*<_zeH}~oWh`Sxw!vU#%y#DW`hKqKoa=ke`+UwnFh9(7 zpU2$qxAkW+I)o0e3EYOalxYaLqVAz>S2lmcM5jN7rsc5k#+}fWLdScSQZKfpM~BJ` zG0d|CGC<6%K18@Ea>cw1S@W2>Ok-QB-LS330`dE`wA)3O&>1LKem)>QrJEKcIREZ>^pMl&ZVULgYNY zKyi^@*p1_!xI0WzqO)CZO?dUI{Rudmf>~@RzqjV@uy@|p50zxK13$y~*j$F&S z2*)R5N8E@2_nZUm1*XCAWzMzkDwz|hb2kl~MK5lmj&MBS%GfH0+8l!6D9-H6Tjo`^ zAk;FNV>0ss>{S-+gs?01)jb73w3-cYULvXh^lXguqzNz*@lQ6lA>NslS~5kND8v3Q zLBPHV^@Q3lyytvOWV~xXPn6WAt@h~yu_K$4_7Wf9o55Ivwo)L*5~cp!=hcLp8HQm zLlRK3_N7Vw(~Cd4Bg7a#xo6~eM&zvwuU;7UPsrd{6;UL8n`+uqR`d|7b>}7Qi0gLA z(iKGD+fcBB zSHf|20`~l`bP@wjX3YzDM+d}Tjxp|@_DZ%4;Y;$dQWSCX-tK1XpW93vbD4h(Wr5R9 zw|OxEcbI@$-LJqO$Zt=D2>J2ffa+PD@I3%zM6RsrNPTvat0^V;3fd zPEfS*F%b3WI>LPk;Iog0lQZ-FO~^kkqLHSTjIHOB!~RslFvCw`0^TSoZ$LFE#eN_DsQ5c!nF%8$JX>>6OyV z{6C!JXvx^g=_B{0KZ)Jo4*3W$vHzm`z3BNrRr^2Jtc8GSTJd+3bso zHnL8&Ou8X1jlWCH3Rg}~7{B}KP>{*?>hj>DXxy8*5|GYBOxjQXSISSjz4{5LD$_MI zi#L~CF}gxPIg__n@TQW}hk*i$gt{Aj9y92XRP?_ea0i7GSVN~{0YZy24aU1f4a~_T zsZBIs6yHb9{3ol?e`#57mHm+v{_irY>EpUdPcGf(E--qtU+Vynftv)p17J)GZZ$e& zW#IUoa*~QM99(wd16X{SgxOTR1~?bOx#L>cov4k*@0Lpa5^P}G4@D52D<+1h?ngNx zos3vO0zs$2Rm$R#ABsXQ8hebSaI&-v*vgKz>2~{Fx&AuyRXt?y^rHQZv6Vb#S5a_! zmu9H#-LJWFmv3`fCqyp!q@U4tZ@1k~M-LmWNw}}3f4=0ic1!2a%ZTds`B$qaqz#u+ zZ$?7e1-jpt;*Glfq+WB{QS{HVw?8MsBnW6s$cyJN5Kt zbdMyeLMqDBKQ&5udbd{(EezTMrCnJ?%-`hz4XlYO!(1m>YVI7vgYR_T`D6sXz#y|z zIP}7r4^`Nu9U>9aTKOJs4L#ENxc>%{^E>@S0Fx+o^|deC^5uBjxUP5 zk_UT-g1~m~sjn3VY9(K4%!HDRYpmU$Ch^f47@m97Ff3((X~;foSgmNFMuKzt2{4kn zaPIdb!!uV@Q0Jg48ELRGReVkON(VbQegKiZ-4ceLWQBx=z)M{$zCo}`xZsW*@8ghb z-A6l$N>$pV45DfcX>|rW-TBo`t z#1}uLsc~%9S=dHTM{;P!={}8ppBXM0`(CfA)W7qXf514P%+5SqyT0)KkPqJWS&znQ z(rKygbV44&(O8)hA7Z$6AZI-%y!gZ0oQ`|h#D|gN9S2RP z#a_AhnSC)}V;FzcUOapTIHdpsl%A?~tZ9u2(T->@I0V+NXjWl~Y;%@1|1o4XAUv>o zV%dQ2RW9X#)rGUe;N~a15ZyF4ykJW;Sddwd-TYNVdRPV-swMOs*An7N|CQ3_{GVej z15eod&e7ANL9{AcG?`^t!IvNtC)Nr=eM7{?<6T?m4Z+~+MT=QCMx|DHt z_eS}4qN9kWA?+eA-2XR$HSX7)eZBX*qx?NK?~kNe>aU{?DhH zjD;@hx@XMr`-kixPbdFX`|QB=@=U={-ZD6=GbuNh`jo7~528*7`ZB`*LVBvk({ZDv_N-(jvpQ4ftqZd8 zN^J!HGhcUB|J>%7loi)pUhrIv;DI0M|6JwUJRXFw@bCDV^Uop3)9*{=6eANAA!i#M zClt4iGCD{3Tpz?Gk=uq?#Vw5PDaH-CUWs1rPsgMinh3eNcgV8zjUV(L%y;`jfA7iu z;vyQXL55^4+mvloVUsbkV1Z4X-3+2YIbYYNKtX}=g14xx0&uR9A!t}Giw+4BC?D2$ zv%sjT07RgWjSPAMYv`ALL~ntp|Npf>V7j*c8+Wm;NtGfH>&Ub;U>5IW*oEAEL&I0y zZLzVY?Re9e_Gz?inG^Z#zq7F?c0US6fHZ3@X55{jUH1|DCnlpFuMRb<%YjF@(si>2 zEt8&hkjM_;_?}Amkzwr6k&a|$%$-7voU{)_bpNOHSU9Nbji|LNJyLjJ&HrR(JwN0v zX+)gNLELh4xMrL9^K2SQw(EtGncp_2@{o$%9l?>#izi4Em-laIp^xlPUmK*O@&?eT zZ6$ZTmA!|BhZTanbMa3gnZ~%;Sck?QnS_L;*KbPM)Y9A2j)%9O>b-Q-%E>8~*)N9i zx6vt#r_?fihXGlpEzrRC_AA`zv1!zUI0wnwqm`ygw(fe}?TS{I_YLbgt3`^Zdc+6f z>*);hw@e+U0VhG>Y8eLd%yGsHU_g@r=#+c5=NDSB$kSxx8fKK$I|S*N>f4!InNgT* z+j4C~Yt`)O!l^cd!~?Isf1L2~%GbjE=$3Z|2|R}4L1a5kb6T2upukx6eGt(Y$dXRN zhrkTo!FjAO+@Neew)Y{(ZXKl6!=pz}jIDPJoh=SvUp$)DaqFwc{%qY8*L||peUjsd zUrq*2VAgr>TGXBLAxYzM&ANQaaG!j%FW55;&zpTVB!~AazoeoM#vOOWb#8&w*7uxY-Wmab0Nym@eGgAU9mm)UAShN z2;w(L1DzPIQx?{zLXTE}wWnwL*n*WMGj|VVaetXMYe-@WihE_PvXLEvGj+YEx_4D) zO_zT3z$Cx!#j#04t^`;Q+qBc8Y5p8t`>X5UgVm^`nV~nK`XzqQkedIjLi;bH>C)4o zC|b{-e|*b?|KJHU4cz!b8>c_PJu*25m)`7APXs9f&|TaZTk#=&x-1YMch0HVBEjld zRqL5w(J1Uhh3bp%^{$*g17eCyN4{{yV5|ZxX{}oAuCFCTa<$Px@VE2) zgW6U81+JFQe~;Vb$@2Dw-?bd?-IY>s^BGlo62)PJfS9GR4q4f?OiN{U(p7_;PXx!C zAgmzX+HcF^wy4+H?Uo)*AGSs&Hj=kCtFLtvWx0JO_C$;nXTnITEyTtJ9*DM^BVSNJkn1OkD)VGh4Lep2vefAMa zSzwUMvcRgrcb^g$fI4NZ$dampH?iWq5&w@m;#LH!H%?d6WbB0&*a)ogt@wyp{c@lS zx_S@e@%JMI3A{}7DUnxTsJmy|JrEYO#$@2msoW%Co_MG;v{Q&|Y2X#kXq;bt^@oo( zj8Fj16j0}3xwZ18&b@0$wq#7eXMe`F+tw%n8dK5+33>cQ@3U5-V}hOhO>Wyf3w-nK zt!Uf&$9rj)uu6*kf&&c{bfm>fgOib+=M4JtAVf$B@zZLKvUimIsI>c#f2CpvT|al% zb~>w;63SOT7(}#P@D#Rrwt3QJ?X5%6L$19@xOPJb9K3gwnIC-R&b|chdhDIDV;k~M zQ3=mj{)wJl%$}T586>8*>3Q|gRm69{G9Fr_x`Q_M(C4g~-sTEgUdT!^^IV^R;b&DB z9;uECAzA+NguaPws6v9LN)ZTV-$Hgy9gJFSN{H75%t@6#3CU*=F2pf%1H)Hb2mZKz z&6rd|LKMHwaSiC-GX%rpOpsphK}SAj+hls}&Ns6iGh0ukN#@t@z(|F~46}$vhn5M- zHwV9>o(<@W?SI4T<^PxPdcUOYnEx1FUsOf})6(eIp1D+qOjHZQ?pn>i_^{TqjYj0* zRl{{H;zi)0@n~{=J?$=viS_@zL2IB|p# z6StppkM?{1ZOHPl;Bcu?8(ZzaaC+HWT>m6+f&9+_J>U&kmQC_8O}Uc%Q0sq^}u9 zk4<#?lI;WNOg+6is6tj9kw>0jq+7Lf&XsErUN66V_`~;zRK!5udih3y@p1jKI7cS) z7zhluH%%w~L}Z2DU^mM3n%nkv>bWFcc<97YXyI6XoM;P|sBbi#HeYueiV93B8d+M5 z;;kD`#64(w1-mJMQU5{sQ9!cE)tJ;?F^@hZ7$kPobe3;Clj`J!w0bIzqfbKWDDfCu z!boHJ>ad$)t7D{l_8-r%80}K%MQTiz)Z+1nXO6PX!B_$sUzf32Jv?NHlP$D|BTxo} z-heDQv%cl@8J{OLMq$5dNWNBjZG7%spzAS#gc7PGw*p`#NmoXg0lgj1={*u=RKF)s z8W=G}$$7tkm1*{Nig~cSTm#nHRK^I_E-}| zmsVEw{!XT!eF^10d}FNsGE_BuYBNCLANYVf_pos^?wRJwu~ZT$%3|Q8f7~`yW}kg} zNINO{WcFU+nA;3@;+S#r>t_iUAc2-OExfHKY<@!)AOD{0Gi;czOP)1hS~*i(b1oHi zoSyg5VCkcX?O-C0@$ymT$J0)q)$V?kd_1)6Zi*s&GkURmM{`KP@a;^(wS#Nkh*973 zn)a2P$bJ3Bh}XmROM9B#{IRC=EwA!|{`PAwj7u!mE5WS2cp^7d+&yUC)Ai!5$)0bm zq>R<+(Wpja_s2Eju|mBCbG=FAs*Pzvr^Q^`$hwht>~Qe+0lRbj-d50|ZI2L!g3+&b zF01C2Uilv5{VEY3IBc1gFdIdiozk=bGe&w((!52{7L(q|`Wd{(hu$l5pyhA}{Lr?Y z($$?m>lZcpD!0PG#)*!TSSO&uFaqXc&AEi6y?Jq)?~}U%aEuMVdF#sOf-KccG-r(c z+DdJ>@!OnhPfhmpwuss4ImcTcuT90*pKDQwHNsW?)>o;In48_M8uEW%Um_mZF=uPE zCZ2)clav81XI?4T*}n{qo|9Ku18Z@B06mDKgoYQ z++EYdBQ#BVRN_1l_tJ*4=jL0^JJweuWWTShv=@bknT+Ds1(qs(4zPvcjhsRO|LhK1(6r4DCjdA; z!JA4y^llaU`@YE~;+ah?n3ibdwN_2KCL-+rK@;&`;M#v|*!mY-%cQN9zoVlO^u`T} zIIsv1ZWkZ$y}>Cy+eib6HJf&DNB{_De0bOmYe&;8_+&9XJ# zcTXtBgjQ~cPj~)yyzC`IjY{SZWiJx$q00$2`1RFgDsQ|IiL>kfcDIg8Pt+Q)BoX8#GdSXtL&`+^!pBYPt#o^g_P8*x4kwK;4)2FYuiWel5)?Y9SdU(eFjEvMP=U$ zXFKaYvKrDZz%It>HHW^7EX)z=He5B=*2#5h^e5jRpnw?r!|7e#bH zVD;|ghZKz5pn`6fr0;FC9d8jvI*S%x@CA3)I}uwPtQ?$xBDZ|6X?&s(7mI{=&KyMt zFSylmoMpyrh{j6mL!mis^a7vL^~YTaNE64b4b6;`%!xNN%azeTnc$#}dwAl9@vmrM zr?3h>?m1Oh*JU9U_YB)JC5KD4mfD1m8nM~7!#qjHjnvqV91N#%yWor$IJ2hRUhtwK zwZh@VIep=PwePBp#1jAnck2&Z5KV_epkDg_6QH4}cd);>aT{1UPcV|s82|a7jB!-U zc&RDOnpi{ zVUA7Y(Vc6{u^ZZMeyTv^JOrx8x|eMF|8 zZsHCs{CP8~(FrWy#Qnbe;x60*U+>lEt|RX|sUnb%x>2K*5L4BPu5|poP~+M1JMjjq z+K=OcemSR@C$a0_=3e4flfIly6B$tYvLRBCu;&BMHBwj}^%^w4pk?ZFP{mW7Uin8@ zg4mYHjh1xP7OGUTw1%*kvfc^47t3bmW`2gNvCb5J2UZ@_;J}~WId-MTR=_R# zhex#IPU^DVg(a_tpr_07Tu#)eMmyK9++XMpVD)37BU2laVF@!@P@)K+WB^pI`>{Mx z6w?uHNK~ zRh4UbkmYuTwWMNZnQ+6Nz6PATw`s0QGhKaZfkn>g>)zo^(%$5Fax%r=lJNp@asXY_;z3 zR7MyN*v=evDlPgb@K$C7@vA6S%N7K%sJoRa03WS8mdLumEAYwPf;=k9n=biz=Sct= z{qXKYGz1#$+BPqidjRbI>IgR3YtwyUyv2OooZn@h4A;e)PFGskwfEhwD940;So{Tnk^NuWk7( ziolsRXS$9v@wyu9)IOG}f5_d8D1kr+*B3fK#UGR3Mh+q7A2_VJ`$v@-H~n&?wHpcT5qplEdg#AAsfsBSpJ);DU`;+V9BG<{R?n1=^yi*9m2PSogrIbv=H7z|7t*hP|iZB}2Ib{)$)+s;gN#f~>p^skQW!X~SlqGp72bQI5o zrmrUsa!e0F(hN{Hj|BBa9j?`UbSUYOEkFK6uzB(0%i`9s%e`jTNY;BBc_r za8I0lhON~-RB?fiX;Kd)d+@k2OPAqmRbZ}t1r~}%OwvVFZZp1R5^D2nMB*L19PjYM ziWqrcF2R+ohlivuFZ_CB9iUkAk1+qshk_kTvRinHWs~njdje*@@ERAaXOrNWbANF< zMA^C|0h4b$N4Vzi{+_GHlG7^&-bqa3&3v^jzIIBm{_Ca7v;CLOUg@)sR(k4OcJ(F? z>HdoFB4(-1Q;_6{gYg92je~4$bZAgJ>vgtLx8400gU#mdb}Mw>u`!1v`L|4Xy(D)= zAL}fDG5jGNLi4AQ=ig%J^`1h;@_XIK^>VsRkS_~}Z#^6qh^nU`SG}IedUrTOJWfuL zYoA%2A@4{4=t8(C04?;rIHNo~YZ^~hcQecIo~6r$@fi*OTcIg(&CJ5HZVJrs9XAqq z99lbo*8P{}_)oc8f^>|n6(c@LFDOS%!vMl3rv*Mh^9?3|X(_dK0}4>oZW1@KRB^f* z-pKjcMURJRFIvw%mu$N>7a+hsEq?2h%@y032WJlKB!e7P;(Po>3WbFts+^Slt?}Q= zW|JR|wzCQOK(;sM(<5J4Rv|^L+YNg$m#dbNero@mC+3Sqy-g^{jhYr=qde;tkNs^R zh@6M!rsYhr4urwWJHvygrRPi`$?lR)w+dtnm6%g~Uiou=`m`AE4sOW33fsKgvLSBD zzex~-oYZ=)UG8I%L`r*mwI!Otj5JlbYv-9Wspat2?V${x$xl{KC1_93NCZAh!OuYh z_A55(*=M0qTRYZfoZMR{cqW{M&RbKv(-uqzI*adC;SVw<|(Qx*Ng9}*<30A+FNC?#5v)Kd(^J<=4ZV_+N%p! zU$>_EkhE8BIg4T{q7Bh8B@L;+eSgedu5BhwtnQtDy0F{3Yu@hB-1EBem9I)qF!reb zX4oJdKDN&)<`GvwFc{nssf@Ym3;hKu3X|#9D3FMlXePIjG~ zpBdrQguv0!B8q3}g(V9fUzoo{xu{5ulN*E2{hM64%^YMwJ)!PQ?hylG>HPA=;a8B$ zZngF82#J-r`MR~_m>j*Jo;UfvHza)NVz*XzoqLlMQqUL{2?(PX5Cr8_?~p(+K?@+J zBVqx!C2yvxy~h;Hb-JSHZ|k#}H9}pfPrxzq?Kcm(XbOGe*h7 zS?MhQvEkN+-^osQ8?zz@F?oO4@I=MBj4%0}gP)BnY+ERifK|^4Z02k_{f(_54bVQ) z)AfLE8ly0ArW6LGA2u+w`Ik_MIcEQ-efM7$W0-aRA2C|B;(sb)|3{35q>Ir&7S%iS zk@N=q_kAaym5jwTWz($1CjRk&o%lyY;s1Ba`4~ z&Fz!V$LdbsaxEK%;Hk}Zne&7vhuQaK#1e{4I(6f_@5_75NIU46te=;A5;eci%a@q^ zFh_LL>TIoX{zEa{znQGPoT9Ny@vK+bmGA1{Mn36ZO;ehLI6+c)Vt8Z~AHIw;Bo!OK zqHhjLmGu(TH{MpHHa6bo{yUnMyWt$LUNaOuCNbu`*N*|qEa`GtOikrdpL5m^$l#j& zAOE*|y(P^Z8A&c-94u)M84r~dpq39<;XN2}+Si8G zBK5``ou+leMcmC&rzHj&Bn&o_ZL{@Qy`&ngHl@d7T4m8aFRgaQC_8}>#zeg!5jq0F z2he})H(;l}p;T$vbR#C>IQWTZ6KHkFW&ts+3?{zXkV70sa5R;txPQ?#Ug|HnQ&e(U z{0@oVDSGpkqRmiqUqwxQ4!tah&sCz{ShqS?3;vqyuTZ0O*Qv8^hnI!6WfT`0rS;r> zsmxdRF6P4V>5p2=vF?I6({T6jPS=+kpM~m6hPxDcF5AyE5f(gu*BReoub(YgncXA# zf7GPWW=KTaHXxnkMGPV4;-z?{y3h2pmJ_fRp?ArRuY#EQocD1YP4US`D z6CsaO77DLQnV0pgZtLdFa=MV#4%?m;&S*R@kOXC=xlw~0hZWg@G74Kz>wXWFlNnEL z-D@INEaF(3y5=`5hYv;rb7BH0nnZ0RwwAxh!&n0cx2Q{uSZm^hcuYpJCrN zP`inCZc-a$%j}+n2;0`H*>u`nc-(-dhz9M4ZiIMr^%Y4uxM?~%b*55+RbvnD4^|Ec z{la?W3OEiWJ(x*%i|Who>iVOhGLqvg>U#C=(xFTlEq*-f=m(Gctd~#kwa&kd7aR9| zr)tc!ggO~xG6$@SonptL6`hDIN0w!|*sBxp7}N{Uf!5_>_SZT(N_oS_rK<0)YQ}aa z6**ew9IqwI#JTxMO0GH#<`&fz)wuq`{Q<#?OZ(*DgTW1dcm^TW)g)%e$<|FR!KKt^ z(@Fjyq2srw4E`qODFmZ<*T=&d0{RC-ZWsQzY9RbBWGYO;?6!^vYq)`dx|@lVk`l1q z7=i5CC-!0ooDr&ka4ffT<`J;ugMl6D^Ae8QZhckf+O&-8033|FN1f8xiTBT9cUj7s zp9nwy}L~>pu(q%10AJexPIocJ*r&rCW?fn37VDiuWs1oK3FI z>KpavwfxF%=c%5N@s*efPyyGbSnXP=4h6@+7rGN0++V0D|B0!R(aHg>7D#~(>;pM9 zI@AxMIC04}--TS;CLF8gLG!a^%Ob3<`j2xq93cb0OxBFn&}BKAS)qi~4s1Y!lH*IM}AbyExaY@IJ>%byqQ=Z(-ck{p$N_TH&6P21%WJ^S?-CX4G_Ad zr4HKo9a~KsBlr;)Cup+-ydzeDngb<~=Q{!y$fjE|3m6*FnNmOjg!ecBuoY%oACMG- zs-L%H*gbiPjGw+27>r;F!nT3w8PB9pvrM79hIH_$bgn(5Rnp01HtNZz^COMKDwj0Q zer89H(w|x!rxpH=vDG~M$T!G(w2yA`(5UkuwmC1}3odeyCIa9!E!@wvwt*rU-d7;j zKo`pt8T6~vL>}*R&H6i!ak>t1pfEdlle4ff(xj9H{_zd+gxYwt5IBy&rEK4~nxSK#b)l)+{pr3c|Je#_v2Hb0F( z)*vVUBN>V``>9$%_S?yeeCyP9lUk3e&>C#rO*5X|mHh375B=rU%Gd!@->8Mysjg_G z0c5%+*`8ZQsBh3BIHp7!<``#Ura&|=6hlO-Sac_51jy>TNg@|ndaet;BmJ1?aeY?T zz#Orl!+P^<>WBhnTY9`v|ri5 z+73P!1DkbJeBUGM_w()3Umibc+qd{anYNK^n6}e;!xsWolh~@2pE}^|Y?UaoNASOF znHO~T*^}mXVtaP?%@yS zFc?AVCK^8$_!r~{xNM69i83uIRK+0up9G=Gq@zG)mkwIMPoGxCB?fhxk-FD@KrNOV z8i3|tG>sJ^i~M<8&_ye9D53jq7q%LeQT(}lo@=a$^Om&VZS&uMfQ8MzKTp7T16*PVzzB$+Z7^o6$`@Sj8kH?+f>K;IZ27CdoidH zcfQO{g$_tM?9D)m?kAOTC_^w>?4p9>DRSoRQr_Cl7hzmNkMeXSg{cDj7OklBu$p4& zNGWl|6|8Hu3@>er8@yVy4bT38ft&2VOJa7v>l@p0mNM90$uf9~V>{mcZS-xc;PV8a zNcBdDBFnRYnYBINF&4Ip>PQV|L0`Mhnu9c%vn^c2U9Rh;`QsuFOg2=g7kQ;_{bur| zzn_FlKp@i+9s|q#d<{F4p%KFNlNo zUls9~@DP86+A`dAb3R~GvqN$X+i$>!q*gzJ`}mX<98Mo?CQKQ)9%%~-9_b65cgT6^ zGonw4BdE5gkC#91?NZe=erN}d18pmpJy|7;D|sltM@6Z=s^F-`rgz{6npbuG>YcKC zx}h29(rCo}1?cP6m5^kaC5I|UVWD&rLDXR4P{)U@2ISsA!~q_w36JgyW1 zJlFzNi1y$^ZdniwfuZ;!el6mn8vd_KhpV$~m9p9MBKo?an@(Rh#qAqJE653YVcpMvr@i?dEO(P(;;{a&;&~IJ9z^bGiFoxIv zpzV7AOU{f0vy<;>3X1Uv=#ipeCfWIgi{S{Qg?O)RAPITGPQWYJ?G}6WjyU7Azq(>m(kJ;L_VZ;jyi>6O zep{XFkCN)(XX9qQb_Afe3TKbV30juxwh_=t4l%kTDiAZRAqK9fHx#!~j{~W$A3bmU z<-b;!CgnYQ+V{Q@lk^W5F|i8M7i)CXRg^8bT)xFGX$ajI|N1%LLM_BzrLW^>YMpxv zoa`1kAL9SJyNtz@7n=Ha!5>tO?fMjYUsh~{dE!y1KR@GAF*zjvcyOVJ?t@OrF!vu2_;d<7_N_8&@AVGh8C*zr7JnIH>x(W z!B~Q35ltGu@m)N=n+yOILG3~|Bl&9lpN5>x4W+Gkj7!7L&`LK)51(=y9W=N1E-dw32@hd#EkIQi*J|$yetD&1 z3EpI-bm^0BEW&@tMAtn5h>C0ZOuWKXBlw^Bn{ciQ-wh=_^*y+!(icohX2KYKH&H_x4tHIPgASgqH8l&;Sl<)$N zJUZ5FZfzZ-kVep()!n2$U`c+w<$KPbmUqyU0?3$lG&3+YG+dN0`JKn~* zbI?3-exer~JbARxvSNCMN02U(I|MmA}7YK@l zeJi;KZU?^Q2QHQ?yVo@Rqllp4BuFQjXOEUyIkwS3LPsXuMoslB>1*J*G)H+f(JRMt zU1~ZKkq~Hs%9WzLbgBs7;SW+d*fp3w9-BX22jp*W99yms#oYVt-uvL-^7+~UwG&G00MzKW1nn;HZoG)bOkZBX zrW(h;b_2ggozt@N@=G&moUMDd?UbC6_&EHT&<(v#dl}_tIWKX=einTyqFXHDZwxmm zL3J{sw@C5(Ci~D~h9G>H5EGW6t;l5xRLe2x$J6h{4~!fxaySt~d8Sga&(q{2sx5@H z!piFuKl{3Lk2aeMbzfGzej!Z~4A~HOdTzC0bc{>Cr9C&;ETLiBGQd4+6mZMTr#F*! z*-iadk(BD}q#)@}SVG|JXNJwBauCjJE^T9F_ohtrwzab+NyI#x7TMSb$Lv|&5PYue z<#^OVfL~kva<==-i8Auz+0WG@VqR;v9wEm%a__scYUog^4I{8#j@_vhT}|dgoRh|T z(=7YKm`ZLL_C`u=YnkS@N#5~SC?1)`ehDnGgFYv5&dF2 z4S>;s6dTKSB#k%d2_^B&B8~YujE{hK<5}MP&8PMDD=0a_8qfrm1HGr&ovW4AyU2 zzHtbcs@M~B&-;=*1$!kJ(-@?@+53b9dgm=%R5zGzwLfdKwXC}$Hl7|VB(<-2{fC+# z^%AG$XKgPqu{t!I|L(2+^l;_m+&q)D>`D^L-CgwS)NgE;2b(Ju{<0}wiQO_!bKa8! z{kn8(HvgJTivvTgRXysFnxBKO&lX~PrnX{j>5y&zP8cThI{gGkxe|&57dJo->5S+I zy)b`i5q87JOS9dk&wf2_D=b&oe$~&#CME43{zBaUIazZBXe$TE?c|y)FoSRj?1Xu< zAz9`&MHS$IPa|PD@2bqfgit2N#9P{<(h^aMnw~idzIJ_`#*{y8W#g1?A^z4%6y<9d z*ua`QN@HKR&94K~x{42zi=iX|Q;Oiz>e5ri_J%rX7>dZ;@OX9i#pFg%*W(b3v%uN2 z`;y3CMF<>kkxAC}bs1QVCS|tHy2|W06-4whcW|Gz@e9uinwiBEDQrLgD734iJqxo0^dCX2z?Bmjjf=Sbdi;^bFOChXTKhoFN?J5An(ZP zyKmK5($fu;wphi(WG{7ma8TJrpTl)*4%P|*bvaWE>MgZHE3l}517HcN5E#E} zrr27%UO*zlD4j?(=!p>|P`A&O%>q!FgUlFq^IF0A@A2wwG?5YQ78byb18C6*2ib<> zXLM#*Q@I+PWZ0Pe6?Xle&^gt} z%z*@}AT|!7F#dTsYM}hAs2nZ2UGo}b6TSY%XM|`h;$A6^ z=7Q0;-i%45eP-e7zF4PV*B7Nb*E_}yJDNX8g5!*(qE%Jdx0dH{0(Zai@t&wBHg4HM zQ%?(AJa%Ly1-%vCYPy~7=J=|k>(}=Y1__M>Ny)E*j6T&jj8xT^0b!Up&54>p|ATyH zHp~L#Bp;p&`ol%#IvzV5vm3ku1}cJ(+lN;NuBATNaETvlzz$6lLs04c^?SjXE|Z$;7m#VNEFIF@eY< zr&a9VS_DFkJT-(Zpp6Ak5zrNG5+A@t!qEW=piPK^y9sas7&;5QVm*-carkja z5I;axdI;n5S3IW3sw>zz?F)TZ`eim^l-Z`Nw{COv5rNT$Jq)hoyK~4=)8`gx^Epu1 z>sZETd?<&i^^z9EaV*;=pkU=0V9Db6rUl)bYZ?vjOQ@~M|FEX!)jyq-#E}slj_^u4 zuCn_1J+E|k1o}-isWtQY*F2@X@hm-Eq3|Zi&&?k>D;;@W4sZcN(5#}5TnEQO{d451 z;5JVMV!Ay-=+JJ!!MW$`KF>`yhbWk}qi><^xDE(b+&z|~syw?+eissULcuT7X(NyA z0=HmXy45iYHzm}0k9e~O(P~|*e(ES>HS?0&OTN(1&=3}2`Nhl%!(}y~ z&IQ;_%76i1!IC14TMR)D16xT5%a@Zo4C;axqM(ICg+kWb#^kaE%LJ*dD2*03rHZYy z;^Emg<;Q=`h-1r}K%461z3x&bpgy!U{G(a)=#>wE@ZsXF40(?7CEnS<|7pkBn2_cn zT=bLab+;(zdi#R}v&OQ&lPIID-=e6{ap!xIiqKnOwRu@y^bcnv%a+l{&yq>>2oU;*;9-87O z8>iOUmq#)KNaY2O>m~oqT+v zZ3z%AGx<9=<*y3#CWTLRaCXG(=k2uqb(+GJZkN!$$6<>T)=Az z(Fbt(veuH`{0&OVU$m#!-Qo9}i)qz+*ttbVvKr-xSRYPnAT}SEH6UpA>_Cl>Zi~78 z4jo*RZz0%N2D@65?<5Z9)5n zarCD;OqQeS#^akT{$JT=BP%~ad)MP`KlY$1VDqwr76j4tj>XvIY(7Qn`~`(WH7XmQ zT+`gJGOT+Z<+d1c{_3)}GQ|yA*i`G?or7w}v028t&gjmoZpSIq`tPDsG??flq}a@@ zBCjZ>x|5%w##Osh?1l!P&iFomx2}h64CgvWKe4GU(A!f89JFOo7icQY+*Z!dtBF=9YGJzLD%|RB%s`>$7#rE#GnBuW7(D5xLEI zP5b*6NQ^atKpPH0Yq=%A!|`|OV_mgU$&<4O`sY_0{DX`nbp;Vh4a4gzDD#`#-kx;< zAp5x$7cpt&tq{u>v^HncdV5Dv@w2yek7n?y%>2Yo-oS3jxvQ-;GAn|P-I#Sngcma> zC^14Alcz%Rsd1xJJK8PwKUobs>0UV?p7Td+(wB_`H-Ev#EipZ?wq*k#3pV?P?f;(f zMu~Q=evOb8%xofEvkXnjiYdV&1U(>(dl zH1n|oEhwPP63GNaeE>6rT=Fc!c_k=)wb8JL!RhzUFpUyXwf z37u%#l{Wirc;8nMZ*>30;$J@cxuYstC%T~8AknlmibgxmbV+c0R+9};-Dg=zE?{-t z4^MIwjv5C=KNRvS0V#T~y#mVxehZxS;w77tOjO)(*EqvL7f=j+<2}DqA-pIs%D$Ib z0G`Y26U`mI)~onDY$A1@=d|+v!wDJ9!R3xcf0kH>-f-F*X{bDcSFS?FL=ZjJ^s+aX z7C(_Y%Uf$aCL={mh!fwIBK?+D8w^%>l42#E5{SA5U|nD z1T!{pTwnWD9?P9Ly`1f+s-YS^4y!LhejP7@HGE`zWGpBDm|gv%`00qU_XZKi2^R5>t{lcWZY zH;vnW_z&eV^-K*xuZ?v4qec$jq5ZEwg*xny6JyK&%LvcG2u-aF=Iwj)3~eb-4g(no zR~p~5o?`{Tr$>fBjYrtgD~d$wD6z6Hx+Eg0ci%G?k^`qJ*M?(tA%pL`0eh3P_2H zQWWWgYC`W-N+2PG5;~!TnnH4>&%3W{?{nV$JnuSR=jZ#n=lK7}Z;ZQMkWbcLTK7*j z-+}n2?&Hn0w+0f)0^i;V2BkT*d&MWakCz@dXT`!ApDAM`aP)?xgRkq4!3zs~5+k&n z?71Q%qx;p25;Yb!@>4s0FErYYJ0!l$fd(95snut4^mlDB)~k}&cJmBgsm|w_@_P

y_1*v zxCtKGE8M@>2WmGr_5&1!@*O1g#L}IIw`Tc(ds)nIeLdJ{nJjjcS4twu!7RW>tt>7P z5q~?&B^2FZ$vvnn%4QDYp=TyAmm8K2brfxm0V}6!UAcVFLoO}5He5FyLdD`(;2uka zFt6Ospk-K;ta3EU!@7+g|6|dLV%fYzqcRqU{(t{pu` zyS7RL_uUoNm6CF6Io16Rqr)vZPL!xVt5H#!AZ0TreN#>2j&?WXDFhT+Ma|22 zo;On>fOP<{YEQ?u_@&yFQ`QBm|HF3pU;Bzu#d;ZUTypwBMcVJJ1s(ry#<(P={`Lr8 zh$Dih7By!cxwm;UwWg#emenpy=B)+Cy3ed`H2z4f3%Lu0KKMr1UwoDC+tSMFo*?1n z62uNz3QCy*y^kC1c6N|b%pSKAhIZXevnarO+GET9OMCe1o9R#9^g{>Nki%nDNf&;Xto;` z3krQ=u<$)iqn-M9GBcyWPOzecE0@iAmvCI$SGW{bvDz#Au*-;*I(&>U+&?N&;uO>5 zYyIxF;*(1*m4D&2ZdtY#muWlPOdEK=Vb@S*qT2aQTw<@T-$B_&QD_Gazc#&vZoC21 zf_t~J*x;K0;L~qSK;t*pd2{*3pz!$q-o4RU|$8&dezBz+w^8oi%OL@h4JV zZc`t$8nrMh0eSvP#;v#LBiZi~5}jKts$grRc)e&;aC?jD_UDJye^K5a_YGIy`oh?> zENqMO^J3A@4Efzka~?ytz%Fq+?>_5p^n(mESH|sFLfVG4)YlWFX4IaK*fqZ z3&@)f8G^QTLwFdlaZ+2ZNKFeowP>Dw0swj{o9hKSb1q~5*_ms_tct3nuB&^2dkOzc z>jNx`u`h1;$1=x;L0$RA`s^_JIj~CcmY^)Y3ICld%Dun%d)5p5ceCD!fO#$M3aW$B z*31(E0~gU?VI&2(CAYkLAcQMe3#qj6YUnZdMpzf`R%yeTt@y^tp`ij^b{$#)fjf)& z(~CHXIrN&{Cxr94QKjUoGe_VBmvKjF?UV1wX}O5Pz3=opW-K&%o5NM7i3u(>Q945^ z=T(xdj5=#)XT0C|%2_H*d^cny297+ye=FFr4dXu*NI*4U8dYq_+K?BvPE)rH7F=V` zggtY#fk^n-!8YS{khm`@v?Ih%5;9N0=lXVzlcl%=`HG$*v53y6r_|=- ze0U2bzROeZz4s{ou1~Bw)shr`_U1R41|fAis55NWA?2gbY+4NdpJn;ioWk6cV>F1Sg<&jRD^Jhe$n&ENqI zZ@vbs-WhMt?*;DJZLTgf!M2^Ek7gH1!GlF zdDL^K2*CS1l#T2~pZ58zE}`wcH4=Ei!PhtexbtwLqn^~!pqUfQkH<2#*6dvVUK3g) zY-IF77pS7@7iVj=W{&s2H^9+b^>-5VFj(r{>@pXHhN+=!;c%scqqK;s%ez6P7p9eF z>ucl0J#!)=f(}1>-)RPW3?v9`Gr{fK5UU+$}0V$&mkEQr*IXX+_?Y5V7gH>6Y@>SDz)-r+(WmM z<*Ol!_uk7v|2Dg0@nWyC*F_UHq?IouD1*Jm9s=EFa8#IZJyGfS>%c>+(_@)o<_m)YV-JZ@s}80tJqM%+L+)HQfNj$%v}r(N9VS5g$P4 zt9GW`eV=wq5MLO{2y#HpTtgVp`qb-rKK~&^VA^XXNevh_dpQ5owiiw)*|{#^vH6tZ z_rN4gO<*`Y{=1kytDV@rwm_6Q*LC&02BlOU78F*Ib0Xo3+OyPRM$0iZ4JR?A^Qx^< zhYf9eSg9=Zq1guqG*NhKSg|5lB=At=d#H!xPQvaG-lH4?SDR{?E-$4utBESznR3YV z@v6j1JzoxJ(TVoiJ?q7=F?T*R_4hB|L*YMnFAk~Z6gOSlsnfW^A81!9tJ9C`nr(~{ zC55CKw?hiz5xWPpk0|XP0E+S`eS9I9mNhm46E>^aAJC(?AnN%&O08dy>#s7F_*?xp z{x|hIoIZe?L;tqvaQ}l%2Y~`Xbv)p)-846sTj)XX4)cas`u*l3<`))EYAAUa^g$Z@H>M?d} zC_l>cUE)(uB0F_JVcB5+7SGo>mmBe-qD8o(xb?fnG^}jQp7gr~qx%EyQCtEOZ)S5s zSNbxvvYcxs6onf%?6>2vcVU&?xNK~sI;*GH>^7-FtLdd4jq0kTplEqHdFq(&)*!CM zP+d(-)C#YbSZ8>UH^2dpqBgB{VoUFu?a_*Q9dPeBxEH>1N40hFewN?9E6kw^0RV9r z0^E396MPMNBmb{fdFI1F0XUBs+kKx~O24J$LyW}{L0_`R$n5wqTzH@OP-fRWK)MjJ z=o#7?qpn)iF3KWyL|O^}k_r)gntM*hjT!^DBrgv4aOM%zORW7N#uttpw<2s#9{jYu zr*d&|-1_#@@&H7RK}65!qV0nD1E`@WdR0?*snj`-`Nz-g=r6_orI9Jn(f2a}4H3a- zVk9gMZUus?i0(SgW|!lpOSfNx-m%CC1+p)$0n$8bby6>InE$167F{ahd$81oJ{Y(Y zrK!@S4z^<6pqL|O94O6BVx~4uEv{*IQ(T8;P3`g*!U_GUI2w!Y_|yY6_g?dPXf-)` zvAmG-N-3$dLtqHTX&6$8;mHiTuF$Nr_Yr9bY!JxTFKh@4hjp{#kUY13ff&LRnorfN z+7b`0WRuX7vu?j3iMf9QN!)fdE>S~VgMVct1=k{3d0K2v79-53pegsao4j

NyY2&wnH;F8&r3F!Z`F{j2~WdIGG_;2FlHnDsh(hH>|TU&Ktmt$}k65nLI= zxuTp&aG*o*&&lvG!S{tS(5J>SwH`}v$-ll|A1qxW5xipPQcAw1RhYh=0JMwoKQxNo z&K7hRd(`4wlZx=ZO=@VvJK0K|@VxEZ{_8?{QP@RYtAkoo-Sm^&!&B|=&K5Q~CuKUQ zvUh}!J844$-nt8Ah7)99YV6^}1|6##-D5oqwxw-i_p=rCBUs;*3MEXAlZIKv8|GTI z#v}(!7WDIF_`=NaZR8fC&YYcqt=;=er53!nNt5;u&1;_~@GkGSAIq5QocuHu_?)sy zyx6m*y1lj8mocDg&XcV%r!&1;>th|ixtMTKS$TS=`1O9j-4}!`VIe`mixVEfb9y{$ zmIpC1h;)CTP>ZM6rSgv1KE1U9gX-WUZfN$+szW_^;+tuU5AHD^rrxX#@(XC~N>78B z(yY%l=r}z!IRTmKh{-;suM(m1QbMi4a7C!`LLhK5IH@7DM-6a8lq^Fe&!s>1`-y0^ zY=CI+cvM>mzdS{9B4B-11U&>FGXUw86OZLQHXkd_o(y%l8ZkObpBGd<7;oQ;TZ>R^ zOHF<%LA9XC)eP$xJqbKoz{gm1-_29~Kq8Hu+j{XmPOA*zHWlVRuT6r}h;EXVrSE`u z1v}|TkE?@+@t0;C6sF`}H_3K=P8Qq}Jy?HB7z{?ql5CAqCQp2zWQ{a~|&?_L! z^Ac3fba3E{@Lc~#bY@!u(XiGu_g|LXznk?4|26B;W`J5_AgC>Nm=A!jF3JL^4RG^T zxw5sH0C?SE1TM8Vp{|dv{XVml!*B*Zpo5*f;xo?^g4yGDYeqe2M-@5uWIJ@SW42Ht zV5!|j>#G2^*rQD-l^qJDFN_MEGxi*e#jAM4X!_C?n4{FTK3FSa{44pvLkVU$4zmfL zjtBq$BKGDv{jtKQ$riS9{9`fSaYyzsMq-@~%Ec7H&bR9={pdDZq|n}N*R=nNPNx~F zb!x|+wjQxn=!{buVa4moO>R)AnO)kR^l}pnL-;)dJH(k|+huXNG8q7Aj zs&W2gJx>UpXSJUp?_QS%0kFm*1kyEN-#aBsgDAE@(4qcE<&M?&DhPz8FpSnv94b7q zqbRBWcqR4DLtWtu`bp;FhzW}eWrr7urptwGiuSGX<{R4?fKkeXE>nRyYmH#FA%dWX zE*l)+es2iNW`~Aet{Ib2*f1qu{c0F|j7`jv0!wocwTi5hJ>kdi!Liq{;qe6BXtqUb zL5-lN+ho^64fh!FYU!$Dk_$`-euKF;_pi>Lo@ve^F~%a(f|H0u`ry;)br0nIwZ?hHO%RscX2^C7tW zAvYV3rAq901LJX=hx>N=xc-LQr6=&MBUQ;8N`k0uAW&zT)vPuc3j ziHqjL*Ex^Br~7m>Kdu;Wyhuw?gDmAZF9lHV9f2qLl?2fn6m|bxMV|CKVpp%@^fbv1 zDXgJ8En;IcW#CwC_;XF4Qi+}6y)^xY!cBvFmTKP(X?H#zmZGOW>9>FFBFipWIi&Qi45tnzq=0$Vl4LkGopBr>C;<0XYHzh}3 z^c>yn%y?!BqZ*j|bi&2v`UD7~2DcyO%AZsPT4&oZovx8c9#t5ybKF0QyM79=j9xT3 zaO{U8y-?{L>hFjS)wh=M`jeA9q2kx>N`##UG58?cl=@crRk1kLUF)RuiJSgX{LxD~ zu|6yNMY&Pn6vw=JioS6uq}%g*O2ms{ip9e~g5=yj22W+{VdrzW6(A%XRfmWx?eC;|njr2duV|BXnSjH1iT&l`f z1|hD;@F{2Wrq`eAD?gT_7B)KZ;IiU5TzZxQZYw-QK&av$A(+R0BbYt-dDm?;j~S>W zwo$ybr$4Kl+hoSbi|&Y?66M9MD~hpnu2GvQ+_SY^{|l>V$p5jjv75^Efbd9h&1)M2 zdkQ|+yXmY1*BMH7X}Bzn)L0H<&G*bzU-GN;W1QS_%9J2?Nxt;e?jtK0{ycqKXr7 z7UtfU^dksyKRK4Bl3P#bSK+%OqzuN(`ETxc9x|+FM5g9+#U6$N`LzRQZ8cqE1o%{WV=}fH_h(2K_V^7}mc_GJno`Tv zO^KC&i%+``4Xw=u_oIOD7wYhVz-NSPKz zy-gEb_y<~ofdH2l9k3pDQIYFeWZ|L}=zy$EyyULIfmP);sXY}%N#M`GiJ_$hIiLZO z`hvIYSw=8$4l=syJ2u{9%=?Hkikxg76H>YGEK|ag;v%lt_>3^~a=D(Pf8w@Qov8#p zB~_mren7X{i>F_8D!#hUZtXU34uV`2x+Q!z!XoIN=9YAulZZ>u z+fxx$mE@MoZ}kG-dKxsIdFW1GeWQ5sWtyyU;#s$dJmIDwH#_f+uX3ptEyuHIe^i+o zKxdcD)%ck|(ln8)^GWaJl1gtM?$Fh+&x=_OfG_LwS8q&iSLmGUPV0W!ZRXa`uYDZ5 z;o7=EcQK6IB)0Iq<{&Snk!TyC@qx#_^uLZ z_E-?5G`(SLRqxt|&H@=C>dq2|ZO2dw2*4pOSq%ATtk3O+e0pD<#az~MuCP*cb9SBj zlKrOUTJ&)U%BfBi^GO2dZJFYF=AE-?4Rd7dIl}+-NN)nM5iU#$FS>7(1tHN%D|Ii7 zf>Sw<=t3C=YAL}@PY#a-wZ=sB|It#ilz^m^#@jQ0)y#NUOt@neM`}=myuL(Z;)(Me zcqa?*T-t}Wru0?~J4Iq#@-)RR7Pl0z9(f(JM$IZTb;0;j+GP+NQ{JIZYqpkX<~I>! zN}BOfzP>Zdl&9*wu>jyHiB!g6yl5H1Ks`?_g_(kg{r_h)FBv^U4*Vmdnc>Pb|JQnr zc~~24ZBS>T_SV*q&-2uZ3Lb{DK>1*ZD_+?NJU(-Bfd0~a`{(&R0?)UZE`HQePeM+{n5z?gN#c(_UTJ{u_c-tisLOt zJ#EA~sjVgWeLz_%e`dXXXBEL&M zR5)(F97OYpiX@)bpuQx$v@#0qs}KD%S@iEeUhsvin*t~Wu9*wSz*m*dl^=Ouy|r{N zDp+C5L*Y*K1Zgt(S*c^#>&*~te;LAeABDk7no3zJ*UrIBovXXOvbQV=t`?DLecfQd z4k@AIVznYfq#jhar;7jw5h%ksPjKbzH5J!)VP!9--f|^>tqmSA#LMBq7+!A7k83Kc zY~H1Y1kHQ>P~9wQSwI%woc~b(Heu-*h))h(^{|FJ9|{_2B#o(}e*oOlP{R*8qlX*9 zujLOXFuR?nK9ftid`%TMbE<=z2Q%K-g?Z$)495B?Ej$EMbGBu1tJd@kuLZj-m%y;D*%d^c$PU@3qcCB7` z+)hy;iWX0SkCDK58uRKg-rw+zJRuc~{UJY)^J*|4Z&Mu?+||MtqTwGcLriUttKwo? z5DUAz@0Kb5#jM3+y09nKZ+f(OAXH?K)Tr6F)8$o)Swt}~Ga5yE{f^SlvXyqrHfL8e zUDuFhVCrtUZ2RA&?i4bAqsP-Qmbo#G*E)V}uWOIFnZ-zCbtryU2#7jFnckKKTy}Of z0m#9|c6>`d$P2*PyVtcdl6$zDTogNJrQpdS%)PsQEAC-j!)2E-vC(1uML3YSe^J+D z^zCiKQ*ODIsi{@OR#{(^0<|Ex+|ofOm|3suVaB3PK2f?J@wTnbYS;&+G}nC9>fxWY z-C7ze{fa`D+k6i|h&8nz3ZT(yr&c!NwtD%GN*T~Y24$Ad5MFB8wL~B06I$AoCg2xG zW@ncKlfw)0T#lVbOwzC5we~sEWL@0X5$~Sz)c8DQh$6AM6zi0784k6`aHd84c693Y z+3HY4$D^;RC)6%ce;^e`5dQZ%t@A(dncEqG#HK{}P4~a5%O)I)K11Y7sv{fe-ny+H*^zsJ_Dls#v=(JDF`-+dHjIwmC$B=`EQ^nNChR$=M zYY}OY^8-Klo`>Fr=9zgh8qd%dn47mJr{63h4>riZ&wYheRD-Tsx&6MP8)q;(xnr== z{v8VM@^X&q<;zGIy^4VT3FW6efcY_i`WZtPHZ}oJUrpnjp<`a6IP- zwyk{YCSz3*MiXbvkv`WrO%rzhGGx8SK0J7H=T??x3KYM)uO@j9YiO$>6FZ#%!wOl% zjy9+2)zJI8l_U6=lBW5Mu7~)inqLMDAL(2pVsP>a#$eMo{;c5CDIFzQ0WGDmq-nd& z$J>PFrpM79o>t}3$o1!gaGz0Y;cDR`iR_1=bX>se88qz7QFw05@I4bGOhU%B_E z*5;;N2zUp4rvo4TGC-(ed?I9LrEkP#qlk4sg#DfSt;`U;6gA+q+L92*_!aK*0*3X{ zVF_J<`=8}kT(JRAADYx(%WAci8frObVu>-gzb#7K<{vy@8O2$!cA6^u1i6?sEt1X6 zGxqOiprr z3*f)E;2>(^QrPiBzg&=7j9NLQ`@^Z>q7lY%<;SOeDW2laZ_O~@&nESQPi2vNJ5Cju zP(0OrWvXpJD02WJsx?g(l_Exmrgp2BXeY>pqC+>}vejCS`0=pU;hx9!kVOl(y)hSQoBdsM z8QkHQsl+u2S0m@M9`B}<<8%g*vCdM!nFSENSUD_AHr^kc#P_@hL{s9p0|~4!$6XO- zamC_R=<`?`QcOz&z;6r>Q1ojrm#HZ8nLc8uG7}#rLwMsr*pdovD~1nEUdeSXt7IFi z?hbMXbS*p@V`V*_opB7}J2 z`%krUD5LD1haoFhQG@#HY6^-Wsw5jxgEOR@PCOQ7#?6QMMJR;_F6F=?|fo(&P8Daf_sZ#)?K!0(oz zueb)P&i-dietU|i_Gwmdk$P^hJNM#$j)?vZMnt(3P7yvu5zHv1>vF{a%HTE}_`BES zYjrM|@c<3Fk(lookkS$YoN?67(>k)7uV)-v$e~T_TVh8n-WplTw%c~hZhI&mVv;Y!)fQ7MhzTOE);at33Iu

EXq~EnEuOejoV|O)zdTf5Yf54ucGf;vPzi-07weKMPw*haevhvSY1r$dArUNviR#W`fyZ}Leu8R4NTOBY^;hm;j?R;Yt47OyVB)G zhwss-){Re>!`=jbT1zxqT3)|*)kxt9L(83wcukmRF3P0t=pRgl zN-b^+`r1MKc7*Zm$4%rubbc{H__UNkV^g+|9boZi%kQd6gNwMu0l*^hG#_9br~Ta%M=S zw8U}Dqf~h&WzyBDc#3DOfL7O#iK6P^Xl7|__1BLdDV=3z^!tT@`G4sLno=*U*KbJ5 zbeaS^MyoBE221!0YrJ0Eui|-*)=%${A6=V$vB>O?2===a;v_+g!?`J4wC7$7DTeJT zc83A$*BP9v`Q){qXYwowD|0-xu)5WMSVxgoUbit3Wf#612TLL~T}ED!T|&EnIS*gc zk?IAUwu&3q(|ASjSL{3TKUz%uD;pX`*@1)1ys3*Q81MjHzEpELYT3iz9HP8Jg^gJ+ z7`l^SN$u%9CCGslR}?G}qt`9b2p*7pGj3PBPGldgo#nQ#bjFn&&aCtbi(?z|&z$3i z9tgXF?}YHi_Wp5O!_agni@kr1zCist;&LALhJ49r_a5nNWNOPP0z^!C3(7}&Es}{k zL|QwWYTq_Jt3mZU@_psR=T8lABBuFSSp8J*yWB$lQPbzd_~~-yYTIcmdesVQlbK@qEa4dnfDcWwW3~vbKdmN zkW~?Yp~2{9Y_9zd`G>TQN&yvG^Y?~$w9PKD`lSdt9>EsL?MQUv4sbO7gTJVf%c2qwu{P>IZa^ePM zvQ$!Oe}(KGV=2Z}qxAv!(tbL>p}M8NlVbz_RmIVpAD5E#eu=LQE@H5eDg4v$^H1}9 zqP#2BI=_yNZkVWPD3G4?AFuv_`lU#&5ES6^u**246u0$5Z6I!I6|+|96714+P(cB- zHm>+!BR$C8jp4FG$?J8s^)?U>l4UqT>?@-*5cnt;Cm=9RkO9CX%mgs5j@VwAc81K( z{O1T>>~E4jVCVVIM~wd=mPBBK?J4-3817>*|^I9uS@Pst|!~lgktNlEt z=N@*7Eq$Q6Yy{8ZQNc?g@>`nw+)600J&pN>3lLsT2e*0cE@c*d$jz%k@0%2V?_coN zX{TkaPxo@u8ig{7&D0EOSpBH5=_GaErZ-dd@2kM@=ww3MTBHd2lO*Gp>=gb?(*rmJ z+fJwUl`o1_R=&+ssSY*tX#AZcq8^!ieOP@;L2q=xb57t%nO>~zxFa+o*16rTIYL0i z^H#r@ZnDdkT{jt%E*4>qb6_@0C8S8OOO1DPHHw-MW!Y-a>@yW$8=u52JaX4P+gE0O z`ZzTR{v|wUG&(#DS9N~D))6*hht@q%ukle!wn06P3R7+&GyqF>Fyjl3b=$5 zOy&zgwiX0~QVVXGB+pa}>X1qNx=Mr{A*3x1d=471I8U_5j@acD{U%%xcP{Gj!gohK z(Wy%+2eyTU)J={kEl5Cs~UBY zht=QChXua*Xo#uQb5@(&&?L_3-J@g*Y5I5i8j_@rcFJP?%O8U|nV7KXNwCV~V|!T= zR@3zfOF~0qTvn|AFU)!wHCyc-cOT@y8uL)g`={kARKd8JKac|ZnkLOh*|t@vA+t4O zO=TF*2PsWS!q3U{eC3*f(SM^!h0%mwvsC2egWE%5B$L1fHM8}5m$!Wd3m0=0NCUN&x%c%CFTkSD*s5RRG zVZuzEb^xHwrBWR-cJ+XkE>|FEc9ug1F?dG6|H9y9{s#;`SSj%4e@=1yE0Y8f24-9V zr!_r*rND(J#7J%>L4k@1Pzj4}h_Xd_dn5rr>v0*L*He+JEdY7RH?zm6&zKiXO3#xH zPL`nOeY@hA#SCU5Ev5A! z+asI)@H9K`pr2(ZdE!B(sMwvL+Lrm>VNkRRm{$y*g{5g&%*nIG2;Jd}C%nn-`)zE@ zhzfC|Wu&LQ{FeTvc(X?|Qw9J*dZ>-GueGIgUvZh=QGcwTq(2j{+|gXYiBW7(Kn}2Y z{jbUI$Z@{@3m;BJJsE@5`YBq^1#fdJ^d2q#3_az$OZKR`$C9Q9lLPC*_kT=jQ0Z-Y zZ*Ki-x!yq;A7qng%KoUhAc(KP9;u`%`$QEN3E*E=n`Z@w$+Sv%6-R(~Cy8;`xQ~6_ z*udNUw%y!mJF?%CZf2&&5jJ~-7Zpa0J1W(pPP_dC<+kzjGK%CDtjcLO-_qE}Hs6wl zV4L4gwPk~tbZVwjwH7qnF;X?y)~UxE?ruI%W}ZjD_6gW+LD#IoG@VP{&P2cf7Jcla zk09FFZN0L2))ct3i~;6OaD3>#sAb5sbKIIriwk~M%;$ejAZddMq$~euG28J1-~Pjpyn0-58FkE?T(`NPg=SX6XA^h@P=!-Ufo&MY-hF^*x&=z%VN; z1T07PP2hqx6s=j^H$uF~rN5luSR()1sw>Hbb|uEqJ1$!}R&y@!s0g7vt*I>MKP*24 z2nU~WHl=+0=|NALl0|<;p0k1l{?@t(mEwhs??uBMMW?b-|9T=Uq7)X9Q1&oK*^?Pl)_U?r9S_S`@HedFvae7yIa$tVUBAXiMkgFzj(bJvU~vHOla@= zuIc~HF#%9KIB91TeDCd6zt*|K=A&2RA<5Xt{T!k84d+}7{ADE*-3f}F!E1DYcHv_N zNqF&T^ErC5BNv5spK~35wdT905%S1AhV+=m*+G(apVv?i^{;SbJ%L_TVTeZ%F8~$r zvuw}=c6|Rix&s!gWlaB*Vl{gZMuFK=nuJLdps=@MSpY~?IX7qwlor|(oOufGJ~i(R zG#j76T~>b*ECt=U9Wptex3aT{9Dwb4)G`R$!MNVH$EFN(ZURTah&^fnoP%8}##rY~%qma{E0aT!|Jf zOi*63WdM_uq)1hX7!XpgED=eOTEB!CDXIfCER+E?4ZJ+{>UiUvqNt^RUh--!c7y4+ ze9rhm{@3zW0mTA&4Y^BygRha9X~*9QZs{ukN<)Uh#;KmiQa~Pzr&RUy zFNreSjT$D~iRlLfxi>|*zkHw0dfFmbF$jt78}tk5(+@T}pn#L`4*|eyVm#k;6V4FD z5T>Vwt`g*SMXQ72plo`b`G%`|K&*zXzJ-B@XS@Dw_k+1L&SzRlo$fb{dObHX-6gP( zh}$)V3ryI$fq~yfZC%C9;l@8>Zn{D_JF(X+B-i6jmrRI6wE*YN!%Rj zGkp__tcKwcjOg6pkq@4Z5;514;Bk)6GSwXX#6w-RndY_9iWbh%eOE8c6h_5&-b6N5 zN<~e4P9(`dfW#I^`BcBgx(Lw505w2)IXfN0@&n%V+oe%w8)4pDXAF9P#gZlC|H}rJ zMy$}Ds?2Ub0qdohld2%)Al7!F3txVXwLL$~#ex0=QR;6WI0`T?xsWrh&9}308j6$isE&j%w<=g^yBQyz8hfeW+fj$VTkpI0X`O!XCT0k49_SP z#+3)3U!iEJFwi}SeHC9N9%ELFb8d`kT5)`f-e8QoIBE8{Tr!{j_^JMg=Cs}FAgrvwlAQ$+wwbo7?=x0B zm5I=x-hnTAwC+R>8skUi#0rd$dwNel4uk7CD?fSlJ>v?DJ}DSz9fUf6?it13Zzta- z3gUcJRFo@vqT+I1fWJUd1i<2{#beN_;P?;(jGsz#^kBUhGV@LSgO@OS-QuH{;$VD3 zc=zKEM|#p1i!N*VdwYJIGV*?u<=ejVEVE77KDq0ud3&=8Ms@!3=U|3x0^vE5(fL!x z>+e^d7e)PD-{7KtMgaJUS=NP9+m|tPjo=%7Ek}2Lypq~?X+V_iL70=@ZlRU-$4pKy zgjqy%`jzFH|8=oHh>#UThQ0q;)VL_3NRYX(m}H7@n;0woijy}YCx)f(msril{ossb zYfQqa%4f&1TURw=q1H|?5stWgiq@&|Fv zbq$_aDqZB|@*^lyboV;?mr9jS?&5qJ1mhRn6_yVj`;nAX(YsOh!*bb|omA83OOPpQ zapeKS01>l0dw_}+8OxU41GS=%)t4Axhk*$BZ5EUNaVq(s@kPZPdwIqDxa|3rng7=1 z^Hb|z9juBizYVoizL1#miCr9*DHK9Wy)B6HA(O|^(nTN3$4$30xgOr|WzIHwQl38T zvK)9w+y33xm38V|5^8@n=HOg5pbD&7ucxC9x#`1eM0s6~>KkFp73!#%e*_XKTb2-?DqHHX&>&amBl@Ephz{@}4E;$`;P(IMVNp{gT)4_qZ7gY*W)%y9rFs z-1t&A598d+t(|Oiub5y+gYc6O$yE@&y+`ZL&{}FrQ!7?o7g~ogUlo-(hJ90vzSi`D zBYJ-BQ~D?8Y@5)c{(TTC$lic{@S49zAOKth)vJND7@GmsSZWKwZFAYbgdzwcIJ{VpX#&kLv?Jr0voqG3i1lrRDv$yaum17b6IBNtBFqPm`*qK z_nZX?15)?{Z%`*fo`R)TiLkjt<=^sI0vXzbdA{H`{RT8wH(Q4jl;&r~{8i$f$Kk=l zBA49vsXviL?#K+&4#VG0O36J)XzzHEM}NKf_q`RH`ixARCF*%g^P#r#>r}%hTx@Av zzb|%ToYF2PHKXnoG+2bco3oi4i~zq6MUP!I!&Li zkz{uDjGShQDkldj9ZGKtyx&=5v8^>vrL#k-a46Rh5P?uU&8 z!1j|HaEYA`2Kvru)`FsD9mCx{560YkQXz|)_*(PM9||)Du-(}aKNB3-PkH$N+fT_l z?RAe;zxx}I{10s={{ker?3Z{Ho4=L;)IO(7HVCo7nQLcxax+0*bX}BFR>E3-iHQU| zz{^#l4pj;O88w{p98rTX6|!XdjS zZf{N=PnGCsc(1{%t$LWQO0#3W^)eAGfQ+iPRn8+f6p8K;U0Z9p`g%ArmfoB;{2p_q zL~)o`a_ek@Y4yfS*A_WsYdZPdR#HNCoK>W+v@k{`aL=dI1~tv48A=hexPvJxveg)i zXuKjor}IQ%zsgD|8v3g)K(94jr>znVLNq?!5*59Z;}xOxSQrS{R|sNb40icC7HliKK z!_P-LTeQj|Ul85%Du@ZTakh-3NUmp{>f$# zOZOH$M5#k~!kNSk-;$ow<-Oa$bqrp>dJXR&35fT@_E2xL*yY^N9R*6klM>worzI2S zIden!+*$q=ewKvwz&pjAX(@3FAN*)chRWFC*S5IdQFO6OViN%_%RRmUxv zXLGf3yq@X%NM=CknXXW5yvDn26@g&!(hIK8D&K(3_|e9LZ~RAhPK)YAL%mzV8n!Gl zh`{TldNXR&jnU!VcY~kWv9atu)ry3}1nvWsu@QF=}h8z2_dDERB0mYP&k98{cR9qJDDcD1ZYS zA2uZa5C*`WYxEoRc@VE|(Y1)XqN%1hkY5@03L>^n;|Zy9ywm*{<2IoZ0sRKaHxAsa zdmL`K6 z`6>_t%QV|f?B0~BgH|-Bd>E5Wjuqv25c;X+s@0t*V^!IP4>ZGOQt3X88M{~!_j{MuFTuaZb;!6h zNviCf@;Q?EbmB>MoLZ8UlxVXZXcZR+(za`D%BMecdwMQA%Q;~eH^{cVP2yARRGrCZpJZ3lRYY20gp+Muyp`;kbBLbiRQm6(>x%!@bzPA_6l*EC_aFQI3O4`i z%u>32)}=#0SVqN%D7p;7mp5;6qqNU~o!bN5!lO58ZBddy8e;#d&NXwWk_Tl?Y>}T5 z25iC#%{>z^=q*UMG0&x2a0X}>$3J~8v{N|NR=I;7J_6^y@HO$DaQT?m)%B5ncK*rT zhwShloAkc2iVHPo`Viy&aP6<|%?==m+Ft6|X+1vm#+XCh@AJmc;zFde@XoJ}Hs!4# z@)rfX&trI|$Hpttbg0#hp0~bMyQ3;THciqUQ6tmW$4a=7#x0>bhXaR{Vk{9Yn(fg$ z&D=R@zwH#Az}5n}$J^f0u|ab$BvG>w;=ykvc05+~^Mzvz8Emt6lL-2xdSN^7wDmJR zg&|ccQB*g*{s#BrMX!gKa`YRb#_D-~5l%nnJ>5G8me-42h5#;TzLORMze7OJX*Q1n zKl(*fY)Fm`RH|A=$~C!=62(@`79ouhOYY(XO~G^OO`@vnkUrqmt`d`}2MKg-Nk) zw!YSSgYb|HxuW5Tf+r>yOS@e?qrCNs1gyC(oM($ISbSJA2qkZg__Cr-WfkRh z*p4%Q8n@KLxXc6E1a~~IcE-wCcN!-I3+9V29XIC2WG{dQG02ZK{J;1yP=#fuZ0+6t zQUzE0u9#0z_!da}cflVq7C3$txB+g{V8}S1SOA!fvhaY}9}erRUCushN}qkX^C>ru z5CC5xQ%m}>6|PX@7o&VYFlRet)|fXa?)s~D8hdtxt5VrLoD{@S#NfuZ^L$puOgsA6 zwRyFD6<#It=g18qf+CaW%3e5Kce9DgU!GZcZkSi~hjI*I`($^Qq_}sH$GlCs(ChYN z@VSQ1dgxZ(P;)Jk8C|02V|AOs%oDW~b|T3vFM^En*7-0n)b;G%!=*ynYDL$lSpQbv z*R+*lAJ5zEUsqMx(U01aH!(%VR3>cAI7qgoJ4tavy_)7+nS>v0UyIJ}A{MD3X5KuT z@_!eha*bkp@^M3PM^l(((DZ(1r4M^3q4!^Y;LCTld1iOYAR{p%B3xjgzOLRjyZJ(S zi1ri!)?VxgGF+dacu%ga#<&=D-vEhx&4VX5FLF96Z@r$b_X_4mkrB(tYEF8-I?_iW z5~@;lZ-hOb{4#k(C>HNNp2R(@Qxu2%Svs40Fyra#Vu9yInam`pTu`LzF>VwXV*8;J z(!=RPtoz++6`2aKe-;q;265^9%kJRQWWk(%_9ye`Z`BGhmh_K!;(&mf)btPkXMECd zyhXJ8J71*WUyn$ZTD$GWtEHcuCt9u=**9jmFNh@lgqbUqxi;Qv%ak84y*?50u|fu0 zDoL_tZdEwbAJJ*@8XEcLo%0%!Yg=UTQ6{vb54$CCIlsx9Mso6;9=^q^$t+_k@3jdJ5UDRDkYEA!g=7QJb6Q^Z0EyZAQfKM0|oy4F))ru;RQ%=H3GZ zgz?yxxU1*VRv^lzJlWi`GewKpQ?iy7^t-HY`G1%7#Up4mCzaWjaqz8-s)rfB*d0%yq56aO62&A}B)+ z0?eQVlf4ppcmT_`>@#1~hpx@b@L(GQBP1N>CFaClt2-yPU%*~Y_$zidl$KwddXupi zvo;tnkXkJ$z8T7C)C;1m3gQH5@|H_`1HFT$=gNKr&6Q!;%_C1L89vAmy=D0=N|HIgOhBeu4>!LvfRH~u`KbnYwNEZ!6AgG8~K|z|7Ac%+%s&tZ| zh=8Gph@h0HC`geey(IMBI|;o@4WXsyyw1I@v-h>nS#!;Q{0$iy&lvZ(i!tB!hHqz6 ztc^xX(8T7v%O795qI=N?#IP!Ax=Q?Z|6GgHjMRA|?VRc( z%~~JR4Gz#hJby_Fu|PK-mIIN#^Kj&r`GD@nH0;VRNI$L^?fPlnycn3nH@s4K0bEoK zTT2c3SO{9L;1mRz8fybP;?%>`3-UY(tuM5No zY67l>I!K}^?Rl+z@4xVU9MYpIT@3V>A zn%;c&Il`-2_v|~*;zRm$7p_xJ!?JR1zro2%NT)SWK!1ELBw7lvBvUgZwvWd0D;J6N z8>~I+Zotoliw8cJ(*7E-1{`<~FN*6u-A-X9#5e2gc8xos9mzUPj++gQtMMYfTT8Cc zu3H+j^WBC|T(EoC%` zv|F*#4*FAaanFD5!$PxFB_oITd}&dUWA?dTbCBS+#{+(&yAO6SL$*{?&52MNg9aKuJ#<})k$Rbt#WKc8B&A>kXkJ!oTM zYAZMk5%ifCjU;t1eEeR%+9(e%e5}hd0KFJlD7T--uJ(_X-`Kq+4tlnY=X8Z_S8tsN zc>;I>`z;{^v7u$u;;C)j@CxvD-)3%2>IUHQF#rE?dH9+3a9_=7x9Q)r9qs=Wh*7Xr zN^gz{WFDGk@P{assAU2AiC2@art0k^4z?;CQ=C=0JU+Oeineb=*C`t&hjV)ga(y3c{n@l1+Fr-Q9mfd{h&9Qj|(d-JaKJLoW)2 z|AINvBb99fi^CP$Oj2P&+l{5GB^(;z4=2WHMtcVE%Nw)rZ6u8dIk6OC(hsMFDYXve z#8)=PzB0IZ(Zn@`Y>wR_ihAkgZ5y|!3#66y*_q}fy+;>hq&JfgAz6ZxsM?%l-U`Uu zP{MRWwi))q;Oxu#`q^v$(0X~A(BC&@QC!n|pi|n`p-MFKEtM9x-9MidJmb_pxU!T( z$a?)gZxtU>KQ8;K-Mv$>I>4Ku`D##5N@94UpnYrA1gi;Rm<&IK&!45;&tqSod zKfomGPYV7oj4T8_-_vAtZO;UBu@RB8n(PdvaQbF^*=!$RbeE-OYL0A#d8R-o<|NNRI!()TnC51k~=LYv5{q7uqavksbcqQcZ{~7?9^N_H=EyCLWm@_<1Sv?r8ZNabn-dY~d#b?LnSE>c_~iWP>Q* zg-lV8prgu*Q1r-&fXnbaxp}$KA=zO2vf}coR;81nJ$o+ZI5H2t4?OJPFjF$Krva+o zpG0weaiIjwKV6TJ>ILzD@H?4*6~q7DNatIiG5y=_f1()P%ctiskJh55*jC2{*1nGb z;SI3ypFu!~1;`?zybbLobS0dT3gSf-da3Cg`l<2&-h?ko4k(lqzsZuV6&y`vhS*dk zGZ^t`SD@2#pxas5aLy}xsZ1UK_jH{K3GqwMHY`&J;4pO5tl z#;gjL&CZ7^REeZnSB*6+}BYSPJ-(3mzEKO&RhT$unp6yw3y-qw9@y zZz7EQlNO?a7w8HRqv`i21w3#T4OkTYOQD%i!A4=q}@P$4pQzD#&t7=U3 zwR9KEK6-Hk;?w%rRCa`X>FIp!aGq3h;Yzfg?)*ePl5pcZ=H&rrzemMZ6qP(hpX^$t z4IMo)i$v9BY-Wao`06=BjArt7eX#!1sh$~2=O{L1e4D*B8XuOIWTwQQb5|6fRME(T z6c}li$0267PE<909l9|hHS)rk$W^Vmy{t>QWIzn>vW{{n(S5)8Q)&t!X&mnm^hzEQ zV6ToH6&WD5C2H4Q+9SD3n6E8;gbC=Dwp(<#V**GeSg0B*uvV>DW!Xq|xkTe>#}zos zqffCyd}?i^S^qO9{h$+{<`&iK4u+;MIx$&ljU`Oaczi)f0x5~3i`p=bf?W+z<(nW7 zsS3E|_Dm3i37b@G!#IYz>^D4V_}BE5{C}CA{=xYJ_Pzf$AB*;PRz+O~`4ini6g~A-!UqU$iS(t5{#s)rdyV1+-0$WI}%=(2~L=A2y z1-0Z^Xomxfc;oAE#`OUWxp}YmI`Q<>KUYIHlKAH!2sKq!&cZ;ch4(Qaz| z`rKQSY?$sDj$}M_qIMcS&z!z1@^?9DWsm7HmY`?G z>vwi?u8zN@b+cv-U#=Q&R3h8Uo~85h!1pnQ3k9YbN`)}7cq4oT4=yb3&f_< z+Nd+@fTXKG;YwkFeP0*)&TgcPY*~^G*g>jZx*p0poQAnE)%d>C;&35TZ+Pjmu=%&; z5x>#8pBShY`e?JkdoRZbP7sr+1R^Hj(Dz0*whn_l0A7Ix5ZLBT|Boy|M&ef_m;Mu8 z!4kfXqt=Igq*fa=IvWcredpx2o`C|mhWZiuRXiLeK-z6TU|)*5cE#-|nX9V2dG0r5 zMET^Z97oiHy?xM5el$y^@QyBo3S@;SLH0S{y1#<4PMxA()R?ZN!#Qn#LO!UBs@(0D z^EzAsd9npA?Q=Wi(y%1!(bPBO_I+2-V>Y2lpm1JuwPYXHxz&?Mb*K^T>`N zHB$Cs#c!oGCTX;hofd{r-_FU&iF>_*oeD6HDo-t_cGg-zbK+b0ITQH=)n4lEskyrg zTi0Uvi>xaXCL&xCS9oJj_}$wcF^rM32sT=ykH5`AQfIn z^|m6DUddCk2eVohL!eyQUgSbili_{|FLtUf)kq09%oMEQTA~MN+B|FneZnp|{B`ldWyj~0-3fo{Kln}c^TY>KTjA+u z;$0d~?fX|Z`bs^0eym4-hY>Bwvo&RBC~_$4IN_bn@mr2W(OZu6;aBM7KxFFx3^DVy z1~IFEDsxtuSZNAFxg#=@_?g$Q;tq;2Q!a3`PGEj%f7+^2&hvfCYV*T;0+s2GMxVq( z=@Kk&Lx-<`r#aDkLP^|fX>`1mV{RtjWoQZ{G_@Ns;d9>XE}CH^#>3H|chDi$2&5`G zqI?{1aHeOXohJ84(BNbvx(?erDM(F<*-aq+`KvLX{NEaL8T|Aw1hD>30_#6*_OCY+ zlLmM*0px<+3H84cg+tvy1V!2gX5e}^{y*FQ_5b$NEf@A}{DA_`-{s7sR}dmAz?i|M zqrs=KBXXKGg3>wkMNec)M2a?iHN;(vj{B!As@{{o(qMJDQ{ zc#FSaI*p0H?kbIxf4cPb$O)Ib#T*ZHRY$WMb`{it{T1%2v}cq;dKUlanFVF@`gKLk z`mjko(D_FIRYtda3QIbT2F9Vlc=D~&PR~4RBpUUrU2StqT;j`zA0;VZTUpLdm9sSK zqLjzifg^6gJ&m(8<-c2+S$xr~EB=#_z z)NrguH~2Od_I29fZ4AIoHmfmcb9)ivRC z^w|8+eiH3>my7!yVm6i$8fg(AC??7~+n}6RdeLAzOK!+%eD9q50B+Vfkamq&)e}1- z=A_&?5SxG5dg|(#0_+e+hg#FM$_u5d)zAmu*@vDdo}S74kOLw>40Y^36Cqj43*swqi+FIqpUjc7t4;o2e2fVEtiB_v- zhAxSxr-`dwbx+pHcT?%1O@*cqA(O}ACpH$fGm}UKQgu`OTETyWd9R3hYeWc}Yb~A? zWGI*^J6n}|IdpLh;kVo8&vPe-g_T;I`4SGzx+hUIy+5HJ;Qw%vH^Q<{mL1Pv{!2jv zve16*ovI@(E<&BD|4=n4-YyN;)(;3=^lG~#r!sSH=@!=aAZzGNeyNS0#7K;76>8p) ze_eG@v0`)reiF~%@3$SlxhXxbJTEova_{!k}mX*98^0($4lDkg^I*xHT=23C+aaEuk)gH zw}p^HN;Skj&ExIL53pWme}`b|6_y0zRCvkGnKFyW!U|S(riPrRw}hA4&WIm5uBj3h zJDx)d2Ow9zFf`L^8(8(r-z))&JJr4u3Y9gzz@eQ0E&s)fwes{%sbY2PYmC;kI;J%;-nC~XW z!-~kqIay};Ivg4?J(&R^>QOAq}uD?%Ik zJ^K+LV)9)G2E8-75h!$JLxgT!yt`TIM2h8Zy&*nC0>c@vVo=d=z*9)lQtLnBW>8J1V#Vv`At}VOn zS_2;&d>hYn{X##K71;1e&#S2@L44Y}MRj$_QFQAoHtK9I3|{CA9j}fsM0@{q$wy#} zycH=WI(q6Gfkc6qqn{PD?`w%r`9E1%6NwJzF?wb9cI^#$4id}_nM#Cc`K|ELNvWe4 zJ$JsY7z8xnq0g4PiH)~z4T8>(ZeTOy()Y1f~823>#aJ>N5 zl>cO~#U_<&^4}a{4OmfSg=6DR@e*icpVsk%aE4tA-ijIDpdJP!TzV$QZEpe*mzj|% zX!otn6?_wV=wCjilmAVeVAWgO${sX*gn{;EZq2uM)&Gr}02E^N-~Lwiz!YfI{^%?> zj)&vL&kGnUw-i8F!(RhbL7UqO6U(X1M>=)Ih9(IemSuyT%fx~yPWUY+`h%%C9*(jX z093Hir{elx;wNC@jj3#WEpK(GRb@H!wqu*1>qdss1W3@~RAt{i@@QeY=O3V%zqAF` zgx0$D*x-^d+pA8WAUtM;GGoL~jINZ?CW!1-!gNJ>!V+l{8PH&OWKPO+jL73G6>rny zU{%EwPfrjU0Rr2g>K|$-g&tk~?+Ww$vIS}B` z53q^gW$6GX4`l84KFbEq*Y19RHb$(4DI$6wpYbEC&AXD zLsy;r9|t<&e!Wkm3NiLrc!41gNnh+M*EPlDpQ?yPpGsD$0BE2~ z){p=|ox3lEn5#v^?lpY0-QU}mhiH9_*~*9cZ#MvR0>JpoYMXz}KIwgoiRI_O;Ou}R z+2ItzZk0fL{HLYM6)0U#>3nqZUb|Mtg}pqn$vQYK&P3|PFjE-^l?biIB?!9Z(JW$N zMvH6zG-i&M{N&Ril=-VV<>eU#w*#*;bv}Cg)K?zREjIwH4?-`ZL$&}G;`;y0o%vTb z${!r5`aggPHrIImnv9|p3TsDk6+brTgU;1{Pt)b-<<|kSCHxBARuq2o4v+Y;qOY>w zOC*-+1A$9Pri@kZ_)UW#CIRTPK+hE?;CR_7oS^P=WO>sTz;m}S6Z2JUVzBCK87UE- z^qt28?9o2asc?rwgTpUVGs!036pP*yZA@pL-Z8$$t*A}i=n0s6qSZWsE}Ul@ybqQqBd zOKjC8E&)4{*WKjf;aEtrpH`X%+T4W!td}ca{srj;nl;u-t;5|a!JvpSv@hOlKE({r z#VudBY(oeH^q( z+?{iAE4R8C1(^6{EQ=5y*%U)vPG*IAh+oj0Q!VNG&3rIT`WtK zJ}QNnB}~2?dx{p+k>>{HjYz-6A+e6YY(&S=)v$+Bo=gf3C*hQ`>M?DyQAKHOihLll z8TjxGCIN5~b+zOHaiD<+I-qrfsJ>*T?sonnAh+H4_j23+N|5*{H>A^LiS+#U;;&I4 z!e@$l2~DLOtp%(Z%|VZ@7bLrR8u|R1^kaOQZ(;u2D$%nIAkpV_woaBJOFa2}Eu>ZLrMPB9P=9GSanElw~3k5wrlz6yxr&eZBj~1NX+-oe0|NP>heU}%m|OO6XmFhRH@;K;4uMR$igv% za!R20+&=6Jj2aRAV3XG_<=VoeRBw&$yc9)B0?tLD`)iCjU!Ib&&K$Q*`8>({;mCvbkhYgT-Lhyf%41yx{g{h;vYqEw z?4qG^aUDutRW~5X=ld4l)3L-gaErLKxQLapRzPb@(qfz??>^4CqtXVwT=MvPoJPX!!I;85`=^K8MCYTt!~0l%$;AHP#E?W1{jkc(>^AkO&E z^?#N?SEAq?hgSUDWDpO#{_YQg>yJnoal9x&-$L!uM0* zF4Z#VVdAK3x5)-TLX^TEP+fY=+->q`BkvEns}u!MZT}m`eHR*VYxQIG1%NzQM`|yF zdWY}n3>AmfaN)&RJ|MdXvy0WDzM~@BOZWSZEVlkBU&k%fF*^hWeMLZH z@2nT&m?m20%Wj`L#bjc79~cFSp8-0sd)a&%%ddUCk&oXmZ%9|QeNg09u8vZ;^SxWn zZKpN|KJ6xwz@zDHmhtQ5=DR+`o!pCaH#D+WICIDSsr`Z#h?vN!!reIYN#AZ?N7-ks zetff0Q@g)=#2*{ZyN@2uMaFh?XChRegN$6O1d>Hx$Lkgg`*iluy?1_V76x^ur=_2& z=#svXoeI@_LKfN;ZAnpvQ!Nc7gOVqv#hwMPpVJy~QuAz_>mRmIr49Co-xLtzx`xE8 zzVQ5FrMY9HhvB#5BZ$zJ)Br!6|-6Q;Nz(Tw62CtpOHAf8)?8n5oQ~@41mak3TN(0%AwnH~{ z>^+vwG?Y$>jh?yhi{m%k7f!zyKx*dTPffr3H8)mvAK>4pP8aKMluFb8l;aweG!eFX zdskhbHM^x%Ru-G?1O>D@OPScoh|QH$6Zb?B&iV9o8DiP&rJWpWHjwz!VrN&qxPE7= zAEI%%H3vqE$JxaPRafQj1?%MFcDQt)bv)t9u~_OEb0at8yVBxlaj9|-ufcOP8S{H7 zNiUbad8x~68z*0%+1!ej16_z61C>*wu6GE7y7)tYqz+TT8iHPoo9;HRmVHcRQi3gW z_1So0PxF$f=Nt4NRwBf<$EP}94AgOx{>{i1XS zVwaZq*k7qN!`R9msUH52U%=vbe19spD8hrYmW#3A4w`l_P35Xi5#VY#Vn%E}Pkg1j zMNuS|+#xI|lNRJzP-o?h?c*Tm2b*!UR29R->=pLC91zk?XH9L(hm_^kEk6}mQzjjD zoSE`6`ogQ9RPun){xy3vVd|j*_|?UD{h!*tA(m=IpV5M5HVnDh4oUa}S)B;jzoh)ml${)>;;^S3WKAA$6Pfk8se800)hs4f^VU?Y0JYxMv|&=z zuW+ksI{b|_t~YtTE;Kar7fJS8aSP<_;c`f-yl8KOysEKvt?(yIRd&T;RSgj9<#}If zB7evuEQnOG=X&sA!nVsX@R~ zpn_+^C!mPCnvcDlN0YAk+$l^GwU1Ws`9*$N&GQTnAZ!I{uTL1J>~qT}gLJ9h0#m5i zFM^XY<@%n2qvDtSE3if2b-r3L)$YwY=wRm^L{&BPVPW4xO5-tI*LVkYXneGkdmk_jLIY=S!TCw^1=uEu1&1i7@Rqe-xJ;6=9j9wL{ zrbi~WD#>E|880B@963sH%8Qc|b)6|o@JHGk`wL>L>7nbDqst=Ogj0yg2AAoD_c*R4 z#&7s+cy3;Gi(7)xZuG)zKUhl))b0ivT-q5+aRnVDYJkRTU0gxIv{es}jZE5VD zI{Q+mWoORRgP^2tpj-p~?{bx`0Lqp1KbI?dPKvq@uyN%t;%pW&88D7%IclNWPr#O` zw5Y&H?OOPUP;kc)C?=?!*LUGK2W6N)L|X1+!bByTX5C553E($zkv-ZwrypNBU{&f9dzT(}Iz8_iM=c8$oAjo-c}58lsvK-5=Gg%8Z$RC{6|0GGF3nbV)b%cR7E z8|8}K_?A{sli%1lSph3-KE8F&ZoesyPabUjPtxc)A^T8`S$_9c5rOymdJn8`HtT0n z+}{D5CHuVhyYmolgvWcUc`!I*oVqY`&$0^4cf5*mbG~)FSiK>< zdg=M4;J(8A%J9vm_XD?c!*jG%Y3VAS_TPt;4T*6ur}QhtrDi?yRe8prAWawsEiVRI z-bAhT*o=XGR&dnzKH;3^=k(S~)51CG%xLq^#H-KK85@;qwlXx|fLJlew!%PyPKMR#fVyX}KzMl7JjdtaIQ;u?IZ&?M?{}I011Dyj`d&@&_XpbJnQZ))XYfi?BW7TYM z98P&hSA(P0#3i6~?kh|Wg(a^De$Wz$UkubV?!zi|1u=9*KdiE~u_HQFyPYa45zrNT zv%uZ_bWb=;4C~N%lJ$cQC;01(Y?adF-6Mm%gEb3ynVYNTAlj7|i^-3{4U^`&hAY2= zjiPls_AS`nb5mtC4vbGIZCxjdVArNTa}dcAL~TxR*D3))#Q$Ko`zo>XR>4mm7@bAD z+*}OddTAY`DPdenc}HJHtLDD8DR$WgvrU%0Uk%z+ckuk6Xb7q)FGl|+ftTVzgzt<~ z)4Jr?VZXBMvWLgqPYUtU+`m=b_funY6E%7hoRu+5u>y_J##X&)H;d&+^GvEE$7G;& z0_Ns+>yMY0@PQ70lw(sNk4){0xlAtYQhvJD3tDWAcwO8c=rQy86z)HDGOCL7*j?N` z6s$u1p4X$PO7pGhGwy=;T8&`LTizyaF!<%zk~?tP4eMx_vS&$adi3LDUjJEpne|3Z zm<|NCo!jt_m1<9fz@tfp$WQ|02jp^f~0h@;xOOx3+K19lwHR;?_=DU(7ErDGV~_ueRY+ivKDK91bbPPwq9w;#`Z z>^^S>iPgRgsf-sVYY{)v+X|WtZ3A4(7P7|X0%ItpN_(xG`BFtj`)hW=uVKEbGo$r_ zm0M{)C;Udb3v6intRaLcDWtv&il{P*Dx|$!NScpHE$xkvw#Dv0UT-IhuuIEIPJoZD zcStXpsJ7oH{7y13w6<5^qIb3ceiV19@;K2fV(8qrBTqfN_xM3rP{G8p9`2Cs(J5e> zy}euW3q>&j9{G}L!fCiLeuL$J#cwc~+4TMX=GBUreIHJ{lg?Amz?a-(;2EfthfeFd zmspBZ4$PjvaoI6jPP8pX%8c$s{0PltpQ=l#VcVh(s>agy`9ro2UUB7HY39CiB*?5! znX-L}V|`hFnxj&dgt4G8qGR2 zy-CfY%1@P94kEAXUp1EuZq&d8d3+uhp9Xo^UR0Cv;0m8(8wO-^303B7d7LnQ-wSM!R_UIzN&$-ykKy z=v~l{s`d$biJ7DhZW%#gr-6XVyOYeI@e+vj@@7)I|B3vU10#X(rnSo;+BSIC+3xT?8E5P0@4_*euOS+wzkfL9;C5PLal zTm}*z*HwRh@1i%F5^-Zn)k6Bol48S0di^v2uATF>-5Rsmed#WaNmzRJSzoJC1PDJI2+IwaZy8YM;6c-04-u7et zT620~{5H~cN`sFvAS;{VFcvV>ZV(kr2#V>;zgD&>911H;3nqA{%b<|QAVdhn!efRI z)F)N#OPXC|A3C+DPK&HTmJW6Pb_IR#G@b(e+;sODSaPS^7IKi#`Qf%P>w2(tCzean z?<8}4`krcPbdMUDkKNByK~$%$`olFqALI7ATpj>_4A)(O#q?}tycop0{?~9S6{PJ% z#krvj3tc?MzVENkq5VfeBok)zP*GFUl6z2JEq4eP4tE@s`)#4`Pl*020Lhi(TD$>* zE!aV!Ce0fr93t$kuS-Az)rdpgW-QzBrO~)k?z}Qeh_ugm*=_=gdW9uh77zR&-vSwv zoUKC7@AF{LV1n|wTM12hl-4r)M{%&x6JVm*)~5k~MD$A2=rFRq0c@L)G$R*8cnDsd zEizqC%1+(4w*QBk2@f(o8E@f}mHk<~{oBVJ`(<#o|I1I1LFvSGMVzrMW7ghkZDp6s z^Q`YzQ@4c17xTOe9XzKVOKPR02t8cM&rsRq8 z`c|lkfKR}p=J8>_J@UoxQq5;Ikc4fw0o4dF`6ldWHMU=%XRY zbZrFDO;6)#vF?+K3O&2|roxDvJcG&B2_H4-7jq^%-ed=1xj&)y@plMHw3%k8pnCIi zyR%VB#r#fsQequnUMhcx-AwbX-Oyht9jkx=j2MVr7P!3NuQNY@TExGBVgh!xo(m3) zQN(3>NGcQT|Fey*iCl88{@X?e|9u-3hJf7g9rY9T*w_K3l?hP6JN!`dm&qcIci&!_ z7VB4IuL*2?gI&n^V^shad42WkVBLu?$ z-uz9L^Xhjm&MWpkr+IxVlbWg_#;3{@U)WfzddHp2J};#+q1L)$RTzP&$d6EaqZc75 ziFQ=WWxom4u$}tiLhCvs(>C>pG1O8Eoll>RB2?I8fWVmed*{ zf`12xr@|bo02)j>qV}Q!Js#qjXCz=dM)hyg5R~%tZQu?0xxwVR742MiHDS5ljWgXQ*}8v8HiCSKz%;dG(=a2F zc+GSsa3*i;UBtIlg7mzYLsGA*e%Q?DQjX`s|^CdODfNDYx zi_=F9W~KsSI_k0IdwTCh<#y#jYR7%06OK6rCZ}({qxgw;l9H*9VJd2eBupG9hyspl0sc=4@ya5||>qPw}FT z9HS~p{iygN_-2SSO;fyP{au0XjE5~m$IrjAu`H_fd#O?pV7Dc8GG$9Q1S2Tj19;4E zPD^l-(_hqb!ED;U*|KDEN344Xeke94AdgMIsjmxjiLk&Q@ZdD}vtHz4q>Hkplt=RL`)eh{oafPpW9ANJ>drLfbU5>j>HliUfLHXDap%s6 z6%%s?Wx)AO`87wwFC`5l>wGPVEBNicM=j%HSA4Bz^IEm`l+98;a6$c<$0By*i!eJI zTJ{oEb|ixg-oD6_!Hu1ea!@?p!QTAMdj}7%d#STmtluIT3($UU%c$?undR@m`L2iV z13gp@^bZhR{S6qj(41eAf?iZG4iW3wuOj?VL&@hWyl=1Vz3Dn&NXw9LEBQyuOI1N5 zyprd9xaQgsx2-HAtk!SM{lr$C7!YYicYErpp8RTI~$d5xj+lP77MGnX= z;I6m@q#e7~%?+wX4X`suiFf0AJi6(eWxrbagvDMjsBY{ZCSOJ~qCu5lVtcfSJ70FW z{C@eUONWoMn;L;YY8Y}b_$bFSf)V9KG2179zp3_e_~xGA+xQPSXvl39mmZxLaO*|q za6oL<=Sole%@S{-L$>Vjs&0Aq#A2bVX>)Q5PM#-Jr`qAeZr5pX^jlVw%G2Vbircp& zwfxyU9L&O#a?U(*vc3z>Q|J8w>gV_%_lVRtQevVQhy7UyD5b#-r0J&z{Fw0`y(8>^ zn7kn0)lcxjquzr}xjQRxgE?F<1lAIv4%l8 zf3q)@um+L7oOTWg)rHq2#Xvyz^4mk_U3mR~^R3a6$!pcteKe61CY&BjE&3sCu2dZ= zBbocEWh*C+pDX{WCg7yJ!_z%zf2Q&sJqmYY_n4U6H$+1D@WKRqSg}e1&8f@apV&*r zbY>gFk$rW=dUsWIWD%Gw!d${xs|2a6=d(pZd7lG$Kd#M8*jAg>bXcg&zJ;0XpN$RC z$CDnzcP}@Ju;xSH@tM(TqF$Pae=@BpAI|PZdG=@oSJgm`CD=#f2 zr8B!TF*Yv%kxcrimys^4@dJfPF)Ck&alL_(6E1Vd?n_3cIK$i2J|zO%1Y+O zwjinp@4agPQaZhXJ5T_o$iqbE3pw7&9aw&+9|DY`niv2aoW|UZ;%a=Sv9^LOB)_ks z_#JhR!UXP09ZPqO(uQ-^%64O~s_dCNd%aHT2p2RS=?v4C1$f3Vtrp0*L!NML8YuK zPOs*rml`3vzuV2~$z0CtcIs&qVrTO-x7AkVwz>VFll2M6x7z2}ht&e5C(|YT#w5M2 zHuL8x{-QmAt<3%y+7SJDXR9y6`n+-ysjt)__+7NZx{mS%(F)vC0Y(*HD|&em;o%u7 z_$e-1+DiNbH1NSu?1g#2|B>GfbaTtn&-8Re7fm!htMc1Xe-gvBeLc29z1=o^3kc3e%x+x5wt8t#?F%%D3I7BP zqS0O4wPw3WkIt#BgSAU|HrraTMw}QPOz2^Zs5+_TqYTy`Uj{&^`Tq?<;oLxqGV95U z-zrg-Lvkar@w8lKW;1pnD3@KawMm>*W8KwF!>TjF7x(SaD=_qB01PGIY#bkK0@kv! zz_Y(J_0zcQP@#~hw#DTqad~j8ezi4oyVUfFVU%?WqqOCE^U|!1)n8&)h+W)*@?sOE zF+_|5cJhl7V9&Kl8LI?bXSv&=L#m_><|=OBuO?hIiL<$KeyX569f&j8Y;?}-sEDmT z+H+Z@bSS)Q_DaeV$$(YLaA728&gA@i7$F7naaTAKEmVFfDj-dRPIvhGO8tRaJxDwii1q*I|FuHZ)u?LRax-9 zwQ+YGS2lNcFIbj&y3i^ED__3pb#6;R&YbM|ipydJ-6Rx+`uaL8SJVu8p5k8Rg^mIVVOG- zi=bTgi)nUKEdA;o@F8&oF{N10MQPlrHW}gm)Z!cCyX*3#FkdHSZy{8a@aT^T|2ENT_xzu6XdJdMVo& z5*|Dq?y5zoe&gFIQVj&CMdW`jZG1eS@uW~>qtJBSLbU_O zX38@)+im-|ccxL`&ZNuGK_gh)wZIpmmUjB}RiK3qnUK=0A}o^JbHCY844yWvenV*= zKIK=JxBgL7&C3V8>g9t8^py5m78B!9CILvOcsZP-SEZsB3zVfhyW{-`+1ANq;JjhB^fNHHyZ;{nQhg60sgJ$)_AvKsgg9%G82oeGtjuPvNr^oCv9k$ zzi{|sireY?9g1#}Tv(3bPzy?HK02`6Tcx6jST=xG`qp>$RZrJG?bFpnAqgR-dQzTo zLtmwd80pOET8)as=R_4R*rykqJC_Wi)Kd?tab0I0t!2ZRH1gpPnh3VighEtW`hvG! zN)fy6Z%Hw#%sTRscRb({{)p(Ng4g_jQvNo6*Pz_#2ag#p<~y1k95E-*$7|d4P)*9tXf{r zD`;84U6n0hLkE!FE4>9WtU{Iyt7G_YU#Z^dm%i8ZH2fiY3+!QRaSQ%%*$ zTn=$qDaN-NMba3EG)YOf8nXJBZ8SQ~Afj@lV&F*aOpOu7$>j2}ue4H-=JE&pA9AvbTCd%&Xk~N{{LL z*{y6}Ac)+DH(z8l-GM!u6`>cu1cRCNQ~imfb$rTZk9O0o_dX@%Xf`8C2Ig(FFe*?H z9S4K%S0AFqyvY2D)u#|$7$G}7u$Y$DP8g>=;(gO~kK-q1E+IOj80bYs`In9Wr;_u6aX{qzLOjU&zP$s05G@49hZtHSkHxg|*NGm6 zLh_(X5}6LM629fWr_aM)YzdgZ@Vd_ZMKWNt_QvM8_MW9!S3+>(Ik+(fF4ka~^6H3O zVsLM{1|Oh3{07VM5)R?EQAhHm1s!CHj|X%YEU-L6;Qx}d|5#L%@>a|h z*JLRbz9<_EZIU{QH-pB~29j5c1W6P6OE)i%0$2KSf=_|Q}x8gH8Zk?ES5 z`eFkHC$p?ru9v(=W90Piavm3uwH`llz)UhfIJkY2Vd>E6?1rfO1=XGE*FZ`G*Iid- zhYiS)T6Mt^jQo7DQOdR#;ZtIv6pHgyDUL%(TMYE6ig`F>?~hp%S1I%52yjETMa1Pt z{+&vD{?DnDUdd4qRqS4jSqbOOq0RptMN8O&l;6RzySf@IBvGpw`=@2w`whF7VY_BD zvDCww!GGot(cb83SrQSQGXOa_+@Ap5d})-B!i8R*7p)au&S}FdPx%u$=#W{`k@eXdVpoRU?))ig#Kmbm!xxPjHSe$-(s_ zML#pGcB8Xfzh^0uED!ect0n}6?}=T`>}vXk39g{=LuEP=wfQSfrrTUA`<20WQfuDM z*#xE6*}dv@^-k2Di(1vME-p%*Fg!tAqxqV0$Xw1_oeO(rCy=xfrH9qBB2}8su`ZEA zQer5_$bvr@9PRXGp^O`8b@aBf+I!Kga?$zFc5^Qo%?!PdeiM|HB2PzwX|OM2MdUzO z_1t-f;IDHS$?mOI40zlE6H1X+o%cTv+3`3MbzFdyA#Cdkx~T9F0%9Dk#pbi0BQ~?& zo*&|e3jC?1AB)ZR-sW>hMlmPc z8JQAc~*CynRplm@51+~I3M<=ZJPzLAElcmEcGL9^~C%P-;7f^{;Kf?H?15?6Vu zxe6iPuZ4lMbp>w+TBR;kk&-iOF7<&i%We82|I&-u_k#3@J}|NILuN_8k!zEJk?<)O zUdiMwTe=LySJextg;4Lw6K*|x>FI25xC+Bp0a>Sttyf#e-NsQOe*>PnP_SHB3Uyz^3zdKFjCg zMu*d!ca&xW{ssGvSpL%GNuZV;za!PH9*&&*Uj>W(_XR5`20~?{fw(060RR_GAOqq> zR@y;(7P1%v{_+YhDSOb4xcsJZ_zW)ArZq zQ-CmJa@7>s=*dg;rZ7wdrA(PBi26bI;|&t=d+m5t8)_l&d%4>!^ZeJgR(U>>ppK~F zTkC#2{n2d6B}OT9zO*Mbhc0C0@#{1=fBBMUp&#*l{?@|iEBTvMJ6}3Qb77AriLwSFtMj6)uX0kJGZYE> z?1>tpLqnpd%H1c3HbGhF!u>Um!v5N4Wv%6NTMu223(OoB8Tx-Hd-Hgx`?v3Z5Gq@X zjEp5z5)D$uWEmxCLz^vYB*{MZjIo6@*+O*MlBDb-yUE!1P`1f7ma$|T24l=(?oa1+ zJ?`K2yRZBEz0Ujb@V7r^-t&GR$MJf;UdN3RBd(ABwnu>=qR(*!d+a$LP}C3%wD>Fr z(5WpwA9ek<8-jR*SNm7M7t)Qw8IhuOd$R8=Eo9>?#m;MQj^De}EiprS$gJwR7l+Y) zJiC3l*M4?8Ww-qD{P#O&b?LdG#^{&g_kt#+cue0SZB7uU+(3_CVuP3v_SM~w{Z(h4 zf0L>BkE6gsVXpLoeU9$x*`o=v1k$slM5@tWnABO#H4&hpVWf z73^D5<<84lo2SvgrRGkJWYts}Q_NmCr(G?cz#CKEFDpRb{Nh2PAn^EBB7uiet^teA zz;lPJ#DRE#7k`%&N^=1{kOex#Z2*|>G zu#`jr9?CI*^BK}VYg5jYcs~L!+dXj8c1kY! zJ^J*h8U4JMed>8pqPd9{3-isY<*;uy#Ots^i2ABV#ZRTxOCfyhTy)Fo^IK_kmUGnt za9nOn$;{lYQ$YOV7h}8ARv6@E7w-a_;jr7PX*7M~l zBaRaHcz=g`OG47TRkZYA>zmC|vBc?qNlnkLDp(Pz63(27LNz*#O+R!^K`QukPQNkw z5Jcu$QUDII`+FnGxKzVJ!4<+Jixq4aeD9@Utv0e(_2Vy4JibvpV_{<+eUN_=LmuxR~@OQ^nk!P^E0({O}9Uh+1mostgh4iONGzB!4-j>6fhn)^u zqJbVM4s`c zNfTw!%0th((g&00-jrQXPUfrd)zs5_m*+39D9ZaX_O zd35e(j3#3_N`oGp+7;H>02q^*4}5Pizu@z&=ZK0OtxJeQ^P}Y|`=$$CtE!<4d4${- zr|BD3gdu%FCcRKQe1z9?H;KAF3GPXpZ z>Eq5$JFbmR7j{Z@yLc5f*WpISARR|0rE*OtOU!gbc!L!)M zs*R$nJ>LnR)+jH3hpS??A!#L>r zqrRKJxLKZDC)7+jkeDNUJ~e#ae5e~))DH0%+QDlddl)-$J9e9}7ar2uWc_Shq113U)@k1v%XEK{#z&>}ilGf!dPV^`9Wl;|+ zm{|QhZDRg&;Zt+D@psLbgP(tp4^cgQ9OzCf5eCE)T`zt^)ZkcXSe{T&7d?A|h)j3g zAXERM@@1%R-iE9S1$eN2=9f^G##YNGH-XFoRUTcz`e$SafMt+oy?(c!U> zasdLIlaYg2m5OP6@|-joXEk}mK0TnRDl>0^ z;7RBwGcAf}cA38>xqYXmd-eO`s^5i+dWj}pkxZ}MR7Dk>#gCL|0o+p6jcNCKmwlE)wfL(3IfjuOh&E>B%l)4w)F=Bh?gQ`U@31YY|w z-%Hdh+JQ)baN^sZHFg03A#7t~Pj;RK-U{tSd9B^BZt?zdkEUvq?$|5s+Ess`%YOFC zE2~L)w8LNgpAu}W#Lm}GMGE?9KNmX^jwsXHeaWS2C;nl==Hl$SDl=Cry*l)MN+kJA zfz6@Sf-X(%Ia z5=N4ySbNM|m(Yw#SzeLFmk>Rh7b?`5qd1|?@3}_i#oBuXjYFS|ej-+ubYmy#uUF(s z4P3Jcn>fpQ!1IRD(*mF@m)j;xkQMnE7>&`$HP2;4ysN`e;X34Ks>=LCe)jTL1aezm zBSpIoL`64_kx8 znzGZwQ_o`?A9)>p)PXK);Kup8wplVyoS;b^QaJrW^Uv$e!tNd*GB4{4yLoHyp%B}% z>s_rj>h%SDfh%a4>-Xn4A0QiV-WTSLD6&#apItb~ty@@YwtYx@?837}3e0vcvB9bX zdOh#^V*YPf<*WL^+@i5ohfs}eUm?HW_-?Oqp>OKH=OrHCA{CX!9zGo+lT36anW7pi z)2}c4_uWclsXwf_J|cID*Q_S#Lr5yEv`^h(MHSfk(zd@vZD#9KN~NJdPx<}Zi&b~} zhjHi2FQb2^Hidn#F*K{^jGqaWu>&ISv+|{s@SJy07cy$(;+HOLzQ*_=SFNk#H+ySZ zvIo`nZt1LA``=li$R;$a*U1ZAG>ooZo4qhnsv#t2f;T&W+uY==qs0uQm>t{sxhj51-FG!U zBzrgF#yRy!dpxYa{Tg#!-`d4nPJI_`^qF$lZv(q+=3p<^j`qZVmT}9gF$bMiq2zBl z4a8u_2yNso86tGD0LA9(cm6s^~VJ?&X-B&+mpDVl5ua0o}X z`wO&4i&Ry7sqFk`jQQ^&d~93LE^uWY{%==iF@{d!W~;D0?@6)rS^tL}q_4N#oH;T< z2731(+#{|j>iV&en7E#EQ|GRf-O0N&X~yB`6>{0S216D;K)X+B9y&J<%oTET;eir82%iA24NJ48#1R7Igt#PK%U+paNeYm;zn;HPXRJW)oLu(gjvTeDg z+ub}vTtZb)^2`cdd8Yh%MP+_x>uO>4uYI(SKnEC{zo%gQAQwng{`P%3*~>$CZ+9!J zD+!vs`6DiGuD59BA_;ib!;*Ea3+;4gSd!=*2^3bE_o$Tb)}s{FeW#2JQJF6mI|iZ( z5w+)Q@?L8{UZA`haMP|yNnpMe2-m1ts%+Qjx!q%E(XyeN2nCZ@}@YK6eQAPEUR*K zHmaDc^THuL-`+((tsSv>e1Js{i>_bA_T&Z<#`10F?l6z)Um*#zUiJbRgMxKIHz1ZL zvCYfA1sx)LGbFogh#Kf%k3Z)LqYYHa(tIA<)O&`G_npuzazuyf_uK`4{aFw!5yPPT zq3(MBH+5GvB(*hM32Ps<1=DS`&n*7zMacpqeDd9$m}fgH!BPbbo=W|-;688S1z*zM z&dcCJ_Dgoz-{KSb|2WnEX>!WY116;~{Bp@S<8VVa5oGJCmz*xZ;U)^Dwe#qp`9cI+ z+ep2B^l9_)?hW}{c8Y{K=wx2c4Gi?HD3}Qyj`;zNizSM>A|6L9%vf7xmT<)DTZ+&+ zq*TqwfS5wI;U?tQ3j|$_NNCkMZ!lyb;-_OyNbxbMM!P}}${k*4LM_IO7iglq6#__a zQm+-3rCv+tyS3?zF|?6s4o|^^!+2yx>Bl845)O-%;qw1tUNYb-2NDbObIt%)8&xcol$+^$ZkOl>RFD-=KKD4zNxYpSs; zTWv<`6Oj6L{-a`mWJE_Ux`5+ymjj7WO0O`y=0s(1rD64^P zW8FZn0s6=+hbFWT_EU{7Sjo-x$c=O_{U%H7#rZ0Arw;X~KEBaMV)UXk9(wCdt=<5* zGPM=sU7;r;q<1=Y`mC2enX2?=JK`w<*Zz1h0pZxJ!&pdA$ZHAY)U}!>d_!ChI0#}* z5E*?b%V%I9OC>lv$b~ICddK%nMjdit0ajX|;I&`=rrbh9)a_>|i#7R_$}Y>F!#sPH z;`4+k1Ic`u_IVFOJhdD@l>6;0a4%djCa8U06haz54$`*-q_7dC=#4;jQ9iDBD7m%G zh$w416k#Zcjn*56MW@OyFV_Yf8Q6|C_gOfiVmCV?_vmY|v>NQ7CDI8X{k9JO+I=U$ zL2?41k~@})*mna>c&|-(3IqZ&=-DY)8gOMxfB+xZ)G`l9_B?w|?A>V4^zs^lN?V>J zmedCSSGd{0>+a^KT?c^9^ZA!_UJ*d&O@Iir&&;<&WUA{c4wHI&pfTd{0R+J!MIE=H z#%h9}Yy-F7<3GL9A-+wIOAv?(wlT&pwAjjgZALQ!q~IJhKPZ=F#2J4p&4`o#HIZSe zW}S`#lG(zyH;kAAyJvNPRmupO-jIaYy=W$vDaN zU~G^L3I=@}TW~XTqP}~cEfYlJLClbU9S?uRS5oVIG;1Sf_U8g8UWKQth>>JpGCEsp z#ol^!e|T8aYq68dNYRoQ-)&lDF83uzc4{@ zDMf9y3hMOcTBkvH=qFs?P|JCNs7@XmSAFw|X#u%~sY%`>(_%&V;PL0{NEqm&5kZ-j zDgZ*5?TYZO#^WP2N)`sLZ2bu6>3@=GBp90=z51y#!!K>)!bR8nr%jJ?IjNSwai1Rc zWe3wD(`zQ|E56+7vTN>qXDN)=6_RtaYvgA}xMKU{_)3dJezM*I8LYM>tJA)(5HZ-F5H^(z32X9KXJ?aY6m)ALk)E|&f$vm_~2G5+3|U)4=4 zU^&tI#uj+5cNOr2&;&r3I7P~rm%M&IGG{WAH%^O4W~KLDd*UO)k5++p`2{BXg4cf1 z4u-(D>&#M?AxOKIRt^>4 zeqGrj&bsd&P4pUqnyy;Det;th9gfJwOk>3D4rq)jc{AGzE2V{sZ60nLOV$sWqzkS7 zv`WyikJ2uxKV~syV&f@&v5EH@9>dC3a4yiE)D>zM(LgPJ-?$R@4J;zU*cdQ;yc!Py zy~&bXI=CYfF)C-g?Ky!qU6cO|6xTuY5; za`Wqgy0HFJ=16cI2sfiL+B10<-=YG5+?j)%(qt9LaEL_)Y+E#Ra z9E?j*hv~KmOg0pjsq?wGUdSML@H~J{j(0U4Dk+@s%`?!5KyOWEriRAwKcPiIVR5Lu zb30MT+8<5+s(dBxVjN&4^eYur>rQMnHbyPhl`PX^_nkJ2l@_1ybrgTTBI`Ev?pACz z+Wu$Wbjq!^Pz=7i@f_un=(YBM{Bv(af5g{`z0B#CLdEM(z}`=MWd{|mK_(?@*jfWYUwS z7Xd_i{Du%KZByYt-ZV-F0v4~hwCg`UBcsjp%kCtfzuSqb!b};}8eUkN-J~AsvHb~_ zw4fbfsI^AN2tq4+2`=FufsOu1nZYwGr|MFrj6g4q_aOWxB7h8m%i(}=)Q6wLJRkP* z{)T>`Cpj?*-lAEe>h{lhd{xIwukk2ay>wHIa&{FCN{*3uuI@>>w*5wYalTU~v2shV zy%_h#*IsNDhTT#{*;WXcqX#Q)V5@>2Y5TnH8rg5!yrvP0`pHF&UPf;WT+3X3o-vbQ1{G0b+LhXz!jY*IA@@z;>9ntdE1+n6cuF#W0YJViq zBTXB}z>X^fMX^^iGL~8ATXhe}4T%SC3a81`fEDnV{Qqllo}M*w1r5A-~l1 z&MBjUSDJP!ex!W9K$kH$zEA$!Mmr<*gRb9k;>g_t%$G5fUe)IDnu~4xx7FcI8xej% zEejgE&F!5R;_9QhOWelhW2G#aZs*VVz25u*hb;Me&Y||rGG7bT%=75X$%nO+ah#w6 zC%VUK-ouM)N{H3BoNXG|@nh8y{perUtN&@X^A{P~{+_R0^Y3gTUHo;rL^O=(0*%2jP9Z_@Ke!dzR2E~z{0!6Zwyei=-2 zOT(IagS&yOrMbyAEjAZbVq|?-Z=-aK>|*m#h}dgES)oWG9NG-bZxS&nL2ql7e7!Lt z^LmjhgzuuBFZA@?Xnron9)!peed z7fQYwpET|IqgY|HerH}A7<#_Ju3Hql2T8kd6=*xGl8&ogdDamwRA~8^@62Gy4;+jj zbUow#9VA)EZx9*Wp%sRbVrvDL5du4dWY}K&)nLqY1~O7D0zbaHq7|5u2aM*`;eKqK^;$XO z=g36x%Erhyyp0dr`fs!He{!M|A8M&)e{-Ts|CSTQv!c-0O7gw&%^S0GJUT9I|58UVv;Yu@ zY4u7ePy(#!)l;UZ-g(iN%EWPV1B7&CjB7$z9sr(LMw)_e0MhfuA z-(&DJ0C~)?QNZEJCEB%I$Y?bk|#BhGXS&PZZW{<8g_;v%aVu<6I@b%5wovG%WP+o8;%rt*=`n zZ^FYYESR)|udz-R5)bES4Wc>XGWzNS59ajZ%=n4;c4~kXwT}>6wHj^Z*=74Cr@QyZ zFtE-m;9XXmhSDq-kpOxrux2Ufz!ee;5Z2AibDsgmesE(bHZpwAXGf|wt;VOkh(5yd zuV2|Kvd?BZRP7iq?1-Au%jg43jyTse--65zc{Y`8&RG~_1m*M1_8-a@!vnBr8R-s09!30EkdCvb{+S}9Cj7i zkUyBZ01Fc7uDr%ps;oAPS&(*Xg3MCDc;$p_n+M&* zQ8nio%fXY)J@z>0I=lxkUdVA+nhi`SuDhF!eUH$RxSPi?zo1|t{5kP?mFK;rif&UI z)p`abz_qz`uEB#~-t(6!`=s5 zLubnw1ewy9o1qD&s~C`ek?V!=Ya4x@|ym*@eD$23TZRJEw9w-P)u zJ&*&v9WAZzy)qD4Xi)1uMos6Nzf>GnkQr?E`YU0$STV(|prt%NL&%C~JlX|MOm&U( zoP51Ex~4b-I2(NXK}2RePjtb+*=+nMz`Hr9@#|N#CXCcsY(MdIEzO z_6}pBgb|=U?QBk{Yha(o)L|R)#sFm08Po;6Zsp(Y-Z6J&FY@f%lY((a5>z=RrQnu; zOSO83CH>Uq;{>>}$Lbr`PTh%2&91Eh+(yFJyLtx4wF0IK&Xr*cSnt8@N5>n+H%(h@ zDmG&adS`XpG*|`h$*t&wVxuD?&+%(p`HEXk1(!#$;}ySYwo=;dX0PcP<5cl|&tNvn zS|(O2ThYxhm9C5yZiF)6noz+UM0LH_f^<)xPR*8rqYdxg=)D0?A!X{j z>}WV9T0n#)pxT}af^~bO-;_#WnnhJKmP}ESA#>52o%HMPE0FoZDfq}KU_9=MV<@pP z9FS8B%A!BgO?xYxl7e8DU< z_X#um6oB$_``hjbL2M#U?QREW)-7jFJf8>qw21qtD14)j{HRvS0&Md$|IId!yla(H zxRkj3?~I?=KgQ2p4R#E3|9geWjblKB#C49ov+8_4+DEFYJ7n4XlqnHeXqgp>SaxbqFPLi@E_{!RGn!msQtE?e=DQXQk@qwo?nai zu|9@yv1_@EZMJU@&h}$u6s-o75`Ud_Eu^3QlLhR{|Eb4Qq=fLjlQzEV@m`4d5+kKC zS+21H77w18YU~U|d)|AsZ}kW;1d2eTgbz&9lXQ#j*?QdVg4AEB40)Pm5(BhFrtH>Q zDo|v9y~~U`N=7A>9d6Kj3LDCR4Ma*jb*j@>xBIF(6)9d%Q-cZd@YF{Sl_+LwNNJtg za9T#MS~qMsMV0Hpif0F-SYkG=3DJp&+eJ9=q7d&NqtfHtmFE7caoH&{`g<1DQS{G4 z&(~hFcNos&w{~+}ggl|7UdXcMnA{axI$w1aWl@X|&8aE#5Fno26{AJEtR!Leqm1Smg)$rKwjw%Y4a7F#U7(dV$l6~pPiu=^R% zL4mTzhf9|}X4Z$gdYieZMp{l=Nn%)pS|f8Y6yGofEtG`?t6PNX= zsY04p)vkY51IZ#B6hlXTicB9zJ@3oC_ikb45_jJ1z>iO{HqXq#-3w0aS&()aT zwt!nUI%b-#o@dgIf$SlkZzvsk+GpSmi&<(&gX1=&oT5tj$PAH+E|(RoLr?v7Wb)%G zJ0^&=-_b9PtK1Vbo(###J*ivP->S_|YY+US>8g=Z89LELy<%aU;Ap#9tz8MMjuOYp z<`G~iW$IAQ&5zY1r>#)j@2R^ze~w>Ju!0oZPmoAD5W>EpwS~m}&s2!_BGsQz4k! zDt3_iV;YZFH+KBN6)BY_%~_%pepZ;&s(yz35pt8+l3#qWA!x6oKH>_dzF1xTgIgwEPj@+f*I{^YIUIB3h#UTd~na;G^=? z&LU?KHm!@3>rH!9I%im1Ry$9F(jd_o$Wa5f6G>g0wuLK9su+i^)=~eXa6-!+M z!}jD~voX*&9hkfm;|G0VkCD>e>g@bVKR8kU^r(HWbO9M&Rh|K_Fm96< zwa=C&6GkyU9?^b#yWSy}kjiZ*`YNmU+ewMzvzTMB0JQQUoVy~-c4_87NPZRYOc(!i zApXA9Anx$r7vsO?;s3rE9l2}^gc(6xwyc987&>4hHew!sj5&;Pui@M3aL?xfhLqM> zKuCF)_zO0RI4-Q?cXw?*6kyP{J7cgRaT%2rU%J1`?<5A#kxrx#8Gc2ldx5;7eLzr? zLuemQgWs34lVu&7N9*IvMDJN71Is!>=I>A=w0yzaOVB%Vo-#>@5BI(0`R@Bf&wo|F z*q2{-NZ_p+?=@DWIGtyr|I=Q!{^=*}CZn$m#^2{ppgXpe-KNO?BK^i%akz=jR_Ah` zsrKr{5#S71i2uMw- zxD}={l@$75xh&$wV+u~)$j%pm*Uzo5E{2g`#5F1jJ&m`gf zJ5~E|I@ukBBJFcqy4K=^NX=^ZcwZu1_;@<KQoHA+%82{j+ z$94SMHD2f9?vzU81y4nxVvHc3_fO|h&IRE!kVElaMj)wJKxN+Hb;&&F0Jw?Q4&&*4 z!y2z_4E5M&b*x;3_x5uw2TcnwBbn13qv_3~O;~|<1E#Yoey-NeNX(sD6*5G37%?|_ z&4rYdh9A1td((yM=$Hu>h*@*kb{1WwHrLAwiPb!98ZiBxS5vTtd|u?2MtfC1v0Ehp zu}R60%ZXWUS*doeg*)Olok$4~1)l&r1aXaSd%Im-PD{|UxBC}ZiBnmAZ93qJZ2+fE zAvPw%VPTzqEQD@76vymgf0ld>pBLIK&)O|{)N5zWiXCnC24WaG{=XOo*X_7K#zfjC zwj6N5(dWy74jlaTKYDMDzkBa(SRjEJ_=)l9eB*w7raeoanNsv8ts(ILp4QMO+;!!) z_F_=nwEM0E`#IopifBs~2vHnl90d{wZ9OoD!K3nGspA2cPNZ|IkLv}^z*X!Nm*z&J z3W?%xA~56JwbdOhU8h{3gUP2bfi*T4m2K2GMGrX)qZ~2;hDmMKavaDSVQwIdiFVlw zT9mcJ#J75T5S|h4pjYgo!i@RI5Wc(QG|C~f8a~rqNN>F5D}iA305J+=G^ssKJBY5~ z+2PZC;`h;I8Dk4?6|J?)RePgfgzqZ=K{%PW;iks*a)B&=zF z89H>#G=6yG#<`d?^)zdEPgDf}8a;<>J_i9415kQgQ?V9@ZOW2>bq9PF*RS?C2pjMN z1ffh>_czWub~qFAZr@fGzlze2MG#u8g{SN!UXh07w$o2BgHuv*wfhu9 znk_RUoP;LxhAZ5f1Z(F^dyH;NO7Hq))3FE(Vs25D_aLK1-(vx-e!e-25yreGG2?-C z6|`A9HCj=G^GR3xOEDO8Rq`7n?DFtlWX%5EawqcRu~FSEV>ihg0WEr`+v+XPZ3V8h zgi0W*_r^vS?hc_59QRp?+gk3)UJU^kM{OK7uaW~~5}WM;JCI(YK%YkGI%PQD6K*{p z78V65KzIq_k%tpM*hs)du^nx4)UW4){4xdc0LZ2e<7_xB2Nc({X=Kx6Bl2}O5ObET z%m4oX!hii7kjVOuW&u%=Vrm#=XMgG}463pSEw!I* zd73zA^+M>E-Gm1KqnMR2D`Njh3833qnY7j2IAPMIgg%;PL_;%e z3jGv0gOe`LDQ^xfVN3CVA^uWZ_T$Fo$PkR4pd39u2AHR8$-C=0-4)))U9abR`B(ng z)O-&Im^kUp?p$_$S6KNgapSt8RlslmEB})ug1Vl6D{v@R+am*9(&7`;HK7eA@gmkR zxYpDd!o$*nLN>-b=uP#Zh5TXM1u>0Xs}?Y7C=SUac@##XIyV+!Lg`y`)kgf4iwfWi z-hBH=V&Ylc;k8LkGper-olDlc8uaiNNECqI`L-1b2y?*v%R6_;H5uY+{ho5j^v$MX z#9rE2;{MiWUTA~0h!+}Y5{;)_@|!e21nH966eVaR=)XcwK4m|5q-;|q=yG1#G0pRN z#WTxgzEQUrZS##wK&2@OS?$h^K~bVQv~dFyriX|Te%G6HJEChc)g!wE1FDbu%yJbVVMsjVEa73_h%1H7{}D48DIm%Oa$%ql4-Yg0fxX6 z7?G2lIrx|8z=rY>`75OhH$az!Aqu04OBz-CJrjxy%H9(Lk}>P@X;I=(Qu_$cmc@#* zs-L%V*QjNo^ZgWkxwzFYb;qY38cb;ZhkAa(YWx)_R8l4JA&^G$>hu%SYbq zuk`bnEqT?iW zum3vqANihV0w3KT4|^nfGx#Z~l{`MEHrt`?cY9Cyc0bxTN-e7vf=pJw?%T9mwB4zRR(ec8C^VI->{xE zg0ZaIjVwtpszVW4u4AX&D^>$!Oa&MXJ^rkF#>&lzbybVUveOV@-*-(Menb~V z2_GtUsoVS!4CQf^*4~8?W5(6L0Od9W1nVJca>omVusL#&tgKm|iLVxY%nz}tInXD$ zrtC{%J9B@i;`IMb6}uN?opXEipLw(;?l-OYy$(aN+3=-$4j)qjFhw6cLSU!=uHW^3 zN;u3mV;^Qa{5>d|{J$rJX+&q%_L0$ydX9KI_L#B!68^@m+rtFW!DT#0sj(UmX%kW1 z+CC-1js7buqGlsrtuxG$k+hxA9N~}TKVHY@>j~|RQNgRPYEw&!m7cdRBx*YdUM|G* zo_LbG8y?~U@;73MbmF-t!?Xt-U_6%biED15eG>%6ynyCDHO=Q=CC9*>Kf0d-+)++d zK9E>E-#sHdLFl06y`Jy|%;PxXYT)t^M9 zOY1FmuF&jD8`|+}_`ww=&pOLw6|?P`i{9W(-AIgtCv*x@xj3^QQ(P#a9aI1eviPL- zNRi9Vwvlcs+2>ld(LrSXwbm4I>-~37;fb>7OP5x4+rSVyH;n1v-!GQ(yBq9IjiBS6Yh(%r`Qc*jKbYN{dXoKjKSaSZjDvgc zBX=!8;wSTD(jv#tcJH2@@YteYofgx5&7kVo(T5AOnJ1nQnl=Vd$nL0M`g)q->(gcXbWJ9rreR~>7Yuowwn#_o`0=dTdYkKBNfb1I$PTzkJ_ zP;ECYPWA47#!CXmu@=C?uyCr(A4WRTEgmBj$O6nJKzO10#-HXyAY`7Wp%0K32PqUW z^TEKGKhop+f0G_FVA+m?af$z0b^HmW)5HmY_+nPa#sD|a;YPs^dX+|?&wub@$?>oj zZl712CXJ2IalOEUXuFn{IG3KJsNS-wTVi3^^vZvswGFpD&EH7wuKh`-TXh&sFCpx^TC1 zZ$w{I-{?)gEdLW*b9_n@lYu#T-nT~d27GWe{lhCkZEo1OZfs1rI)$Wcl6BG=DsVhF zvUu!`Y0W@U)+mPCkx@0V7q7`oJPLELiz}mZ``~ssfID(tIC&=`8HXr^-LKJS<^yGF zPCui?*E7pwGVtN#`KP@$g3ejw^5YV9Y71-<;kDB`0TB(!FhmYagvW-Se@?uIg}NnZzpX9Aee}bsDg5 zx_Q$AL{jbpp3zqBH+dieh&J4}xAXsiWhep}$XEYCc&9sSl|4FC0xWDq1FpR#5vIsK z0L4rfY^6qWMjW->c*IeUz2bwFkfIW%mY}tBZ@BCEf}L0gbx?(qNAw}k-imkk&qrxH zI8E>?%Q;s8`DD}?JWD2v4@mJm5%he=KG+xC)Gpbv7pmZV8N4GN>0|tTMoJ^%zYf+Cs8 z_OZqIu~()CLyPs>lnn3j-a~%Db*x)FXemkjAYGf@)Fjg^0J2(D-MgoA;WKa+flF|E z6b1s!`U{x`QCMEE}8CQK~E;}|y z!NK$Fr)?ZoxAY+-EZWN6lH|x_so(_)z(MzEGmG)@lrifOFRYx$lppnQW|C6#%u-2C{ zv4{M87+**Qn2qx|h7_>}K-?I>bDa2m_+LE7fkS|96PzRvGR7SA83HclF?SR5tE2&a zo*_AqoB5-MC^PSFD?*$=2*GTlZMbFwT3c}=>+74OTcbyH-D+z2cCj3X%%yl0(2B#Y zOI`_3Qx@(NeF>Y{9w$9GJlmf}C20zGL0jZU})6IR#7OWTNiLV8{AXjYoUP18kg zu6%$|teXuW0a59C8!xR^9MQ8MLldR8ohy&2k{Thi%VD^fy@ucS4!*S2{6&ZiZWRoe z+0P#?@s(~8n8OgzDH(`2oupzIUy+?3S*8O-Ra=R&La>~(+8VFh) z|9nd~(q{Z=snjraMGLA&QoIvLPz}it_3#ZH_z?5I*t^O+PdV7lUvI! z%}C5w%2WZGc1C?#xLbRDmq1T`+74$F(bsqMCKEaksYm09dVOQ1q5Bl7x9(yayXb`L z5rlobquYWkcC!i;KO)7USQ_wrir1nh8dlGF$MPf$0D{Rw01!O?4}jo5!Cg202@s5+ zkFjTf6iN#;SA)z9_1wAhpMfx0#VchVfHert%`5S$=ccy@=7pw8h*BB+y>y+eDRm&A zrWUhNe&aP}lXUMiv|cY(YQjv45hvK&%7`~FaY!IP3E2p58v(V{F7CiM&G19a3inI1 zkAl7aoJjSkw|d_&0a^R1ADJat-8tKR{LLGoiPi;yn!)7lfjQ*Hal^^ZWNEKg5-MGd z)uOrI7fFMkP`a-#c)Nlx*yr1ojKV#C#Nn2j$ebG0e|W(bZBmx6vYp?zQ|(aluF0-o z6(jb!3J;hzGqhRvk{A@jSGHt`mjNryb~r+gVzkF}PT&9Xr?p;h=_tBBjrD45)mHy* zcH!fp#)b>eP76CUmoaHikHI?Aa(G;Ttq&< zpWBO;XM7c1X&))2RryopKF3GgmM^7@=L+hiMP-?J{_Oa{vZDr!-!#8@yZw^)C=c8Z ze_e9#a31uyY>J7w*45x9C)2fWQ(?0srvq$KUuf;@p8=K`D6p?!5ntIQApYu|0}B@! zxizNh!N=+23Zkzv!UyIxheTq(8-#b1Py2jjR6es<&D-x*51ddEp|vH-CH?tl`|x%@ z$1y6-0?tgB)y*R0J7uXcXFixFvmR6_O|!6pb3fvGxMz-Vja1!x)U9<$do}&e9IZS@ z$lR@N9@AraMB_l=-eO0kQe}{#%wDS-e?6bML>-OrE~QgdeNU549^n);0`g*=0lm0- z9oR>k#UlSf)tCRl$vh2AdvgB4<|1~q3&Q52f8(M(B{+`y+0jgnkTv zl$_SO*Ys7CR|rQ%1b*M@TX1Aug zJ%ue2kG>l`)Q+GooW)bWf7qDe<@jM$h|j$Xo`6E(EeFZkb2rjIO7q68ajL30T)LJx z)FB5R=#Y(07^omgmGRxj7T6H)j`&`#9Pw&L51M9Cjs=TM3`{QiS@q|#d%<;Z4GAB{ z*HPb^yD^h<)eXvS8c%k>CBNHY4r97f1Z+cGY=#I`Egs`FMK~>DRr4I>LHJb6&#hV= zq+%t_?4#G>%1y0-P(fvg;D5hdT2 zR=G%~>}fUc-HYQ|kc~ZPsQ=i;s8FPMgpw~^+eKH1j1D?F<{Iczs)_K$9I2um(eJcSeivp`&&LJ4Y z%hh{**t)e}fcfn1zlM1M^BJ|$H~_1*Un-cXJsLmf&idN_$9d*i_sMMN{sgSz;?(UO zf!~<*|2Z?p>o*`bW-(oZvw>Ln4}Yaa7=g@eT~HqZM~mX8Hbp!K2lv+L8h|9Cq14bmCrgc4M> zVF51-^UXzV!!4cHExMueMQE~(=nB|C-+cGVy^rS#F;f|rdGD;E^##d!GY_WnzM#oo zRpPbZUmM@`)OK!a*|`~zmoEZ0Evoj&np+=p0Wjk51#cC*nzE^cYJ3)KFiNr;YdgWj z@Y$;&1?({~%RdR`*$HpzH7nY9y@)^a?_}(Lfj_#*BbVH6Ijks9mOasuBY!y}Tr1*|sWb$`GCJ8ze)F1@Q`&3uiK&1U{($jq}(a*`#GaFoA4 zNWayVVtD_);jLNO^Il;ElAffrV{ zf<;;L&9}j%Y@n7r4lKLyZl3ZkScJY4w9SYK_Vq))Ij%qh97Rtse@NTEy2&84A>s{L zk-XU@$oZpWro?QZrZ+T3z|+207EXjudI^0_IE7Y?Joy8&URCl{Te+d-)PXGHUpk&| zhQ$T6R7XUe#?6OSqXTjj*xx*CF0d`cl9Yb458Jz&I4`kfjk202m| zSl!oi?VN!1-Gvy~=7T)Cm&Y7K`im?j4?i|*y_Z^0R%-qm?_}Aal)R?C!)>zbO#yn4 zToyn~U+@A(;WKqBr=fQQ9N$grO9#Oye$R^(7LpQl zuvV6k4>X(ag0a5S!n#k8zjoX*{GnBKJ-~_MShM9GiKx9IO4|T>?U;_L&xYr;Ou4Wp z1%xDu1W#DOBu%OuYBLjke4lZt#`yWHH$(x!?QW8>Kon1b_q|Kn70TkU)|reS6+Rf;#N!#7S^~gm#PWnx!HP)!1qiG29%%Dgb0V@C{-oXHvXFh&mM0?DOvfqvHaZHrHZMyGAbzx z1wA3)-IFHPU2+j?A=N)P!dNSoth1(Op;z9Sy>lE3xnUwA_p1M`vEJM=#Fe}|E4T}o zMw=69A$sov)<;gL59IRM0jBYH*^`#41n6ap@mCUlYR{HuUI`?OQ^hJ)VvGsH>J{b2 zJl>4;U}}D{pPc__ujogu_K^Uoll!L|T!0a22&GQ5Cl-AJJQ^F1YdPA8>v!&c(43nd z^u!J066!wvRW9R4gf1==Yd+Oj%8?jMf`DGfd;zkA(uUJqHaRb1rX1|ey!oPkEY0~*aDzx_meGQxAp3)lwwjW;~li~Y8I<1*104w;h z)zW-MMvK>HJm-YGubjy@| z#>Qubl{O_Hk&qD2QVwT%?WM0;2($oeW}vwv)}+eXHJ;+QQ>~oo$0kL&Fq63wm<71+ zZeIz%i3C@_np))37AG0ykxv>|9@CBld&>U^J+HAn7;t=eTTgtsQ4%=VV}Y5`65I7M zTab%Zsa(Ums1DUzVb*c!^xXecSbO@O6Rt{oACKcW31}!*ki}< zZhraY?OWm#k5kY(6BBhz+|D(_yeW!wUi!hcEjbYTFz|C6sB8aa%66-6S8qKq4Yh%Q z4Ay13Z=N37olX^3)%_4>i^?UwTL>w6Y9PIMx#*!kxXs8m%&HC8u5P6ZtH25eq%I2D zsqc!V;)!w3E%wsyl1d6$*Q=&!GHoH(O>Df)kVkUA;d=Pm7dVpvB*%Jk2aQ-+(Pj27 z4m78go5$klgOn{GuRB^{?ceDW;3ltC=f07OL9K(MQxY4kLTTFpc1)W6`&7)S4xZz~ z0u|+H&yzfona6&1%kO+X1=+lGZz1dQUaX)^P^EQ&VT=8}wY5jQGRh5X$alGn%~)*f z#%Q6ZS?!obM2Y6yuc5^C==FS#?y<%c-VmP*8nNeK?>WH82taPz+PJShuLX!L@Z^{; zz_V@0wgGrBn2`T~2XkA|ef%Eb?!Uvq6w`o|0Ti(91Nc(A^rlA<7kdr^n6_KW&$~FE z0X`w#K**sP(X-%h?@J%m9l8WoE(nWK3Pq+t9Xyg=%zkb>*OFN8EcubWhb;kzH=RjBZfF6wECGZ4GMHzCdfL6U!AL@3pyOiU^kJ>2B-DQ=813iq`_& z1MSVt1mcMwI#ulF<}w>=QT=oDXQ{hGr|ro?5Ln}Rqv)E#2NhDmQzd==ruGco&{`{KS2}yIg1QA)G1v~*ZN6skQK1E z0TLAzl@aar0)15rH19YG$dNu8$N2K0V$AyIn1jB`g~sjPha3d|#0ofbOuQHsf6`{U zHS5?Z`_T|OlkPM>)mU@S(s|EfN?~o5YtA`r`o0~Q;Dj(RsLQ- zNe;w%45Sl7QV)uekB;>uf!@^TC7p|T6dcJ{6VpSVw{of~Fdf6vxeZL%Zf55U3Y0M( z!jNxE4N5u6;)SE59J!&w)s~3DR76BQDRW!v*G6j8Y{28%Zo3EO`4(^qK@ZxaJ(jnWkcw2loIlc*ZeTu zJ%+U29@uEWS(P=t6Z#qFXJQJdK!0^l*#kLtjRa=)ex#r$5X+<(zPPY1txT8j^!Di3 z3+w*@_Y|mvUt(2A=FnqdWx_Jp3r-&Ml>S`FacaAh@OAR%89A?c*^FxCjo!C%jHAM- zp^Wc60W+CiDyw;Nk&=?n;^lR=)`T`c_4V_|k7b0)4{&0!@3L{P#XCbS*$e^Gx(6^Z6;f9FG&xoYu<{#msfY z@4XsvzIRGBwZ$5`Q9x`&q7%A060-Pfom7%;FU?a*cE_y-w;S>J_SG0!HrJ1#H z=f}WMcF`KQ6Yx5z(DtIQtbla^u=PdE;R6S4yj%)@m)*$E7Z8J_ii$IyHZ@0xcHeZK zyyutZCx5pUKnVkC2h|+c2BA%^UsHchiW>aZxWQopO7z8SW@y)rN+}AdM-r6!9aP+as5O^C2HKeSPOk;I{Q=e`VqR2MbO>0m`J^bSpy8+@(5XOqGY!x`0)2}W7K{W0 zIwdnotNV+`nku0v*TxsxjG-e@V(P5#O^d!iBxj-XboPy5 zaJl{9g7mh=vk`@lN4ThG3gk5@q^mP~Oo4t;%=-O-NN{i#U1=fd zB7t+wa>=`xb_i5$yP~7s!>tZv(KPr7Y@EJex7gY(J7;_lJ}zEf{8F18*-MR(l*pm3 z$%auJT-}B9?F+twldEHEUf6m9$tq7)xNt5l$)R9%_7S1k5}n%=1hb4r zjMU}=zA=D$c}hKEOWs}#z?OqLHB~wAO}B&PGi~T02?tx6-P*XrNV^M`pvca|L9E<7 z?;HIU764E_H7t7E7S9-LYCVhetG1RkLAH1%t8Vt?u&;aE^`ukh5@+j4Lpm9G0XkbS zH0<4OCIGTLKFu=-GxqeHpLEPN4+K9Ng`b)zwRhtRrf@^x=a;xv5M{L!7MgMp)gX2Y zXzk{t3>sQ6009BmUo~fnw-eWdHxPyPjW%d8`{v8Ws3ze0&``3HkKY~-W zNVg`H{_Oe!Y|lw(SqbQYt;1rHI^Q7ZO@`;14`4%4p7%z3n_L5Zy^1FLR~W|HXb#HK z3>5MVCV~oVIB?ClD+fSK%il|Gpz2|qU zJ`ulFb#G8tU0Gjjn$xno7nnS=gpFz#13Xkrmxg;w%o`vQ+G3IY#$_X1JBFI?8yEBK z7e)II{MT?y)p9hk)O8hzRKKJ7M*XATg&KjNTlw3}C+ux$k$a9eYOyIi}+eYA+wLtYS8GYSHt{U-MgQHu&dy zEHy6RN&vuVy6$D=1N_0WX56|@7@rZ>$BMf`e&Tc;ER+3E*93F5SA~v-KxpeqdyqNr z$e?P{!HFwRyihkzv1A+71JxBj?z9W+Omutu&lT>3pMsc-ziZ3XRVGd+1=eVcwHt*0 zu&Pq6`tx|iym^-PssmjEpnvQyd@pc@5TMgIJSqt8hSuwb_5k1%SvkC|NFdf`=s4T!D zUh!`&;{PP|X?S1m`S$Np`mzB$AlnPYS!c=wWW-|gobe9NVk>|wE^Cd&k)wt<%wp09tXo#?1$$aD&0Mri*w9Pt zw;5od(4{|@@+~j3iP?XJu6FA6tp`A=H4X{X&n-jKId_Tg>TNvlN-e)@${fX~lx2?J zMjxR*IE+LjO_!}Dm`o-Dj7nX}43g=-gxCn6(%a|n-+eDOT1hkv=6wzq_@K*5juDU` zd1(?J%o8{o52ygZfK;xd<8O_+t%DCnk&@&EgX_h~$kZ=)?q=Ci!}krBYlG2Gi~@!# z0|u#!A)~gf2mADH=^gA4*OFkOMq6Lqo(N`tIQjC(!5(4NZMlibN0+g2AB*O%FLrOO z?xb7Y_YFudu>G#_zH+gxAlIU>e4JJ!0>nQOj|ZH*ot5wztoU=$4x=lCoxG)^?^?au-9^C9AP32#|=Bxj?Zxc0Tp}orPv~4i=9Pw=mV*8Acg9FZB(-i z8VL8JZYHqyXzEiacVF*qkDc8XfY9zgX9QxRI9gHs^Phj*>Eh0iDwJ5n2_KR+j(UO7 zgHfGNBOEca0*83Co;iR^Y|CoC-*16%_XN&2y{ibxOds)ytqQi3C{^_+*Z5u82OgPj zsKi&SZdscZr4Tsl7{xQrzJkNvOdaMcC6C+N4!gy8ae*BN>jA=7U$GQEa|HFEnBudU zDu--OQ5vq%GgWit1??S-R(V9c2+n6Vt@yZK+gHg-xZdzSUUF`_Z-Cu#=;#`jw^P z2@#$2QTgc7+I7cA*-L?}u26;{;+TXB!4g%A-UB`F2%Hm@?N#f!A+x|ngG-Zfu0>}L zG&nj!O>pM*Y?OnO67iV+ZAne#r>u!-som!y;qI~bzE@?hx_W$7ta@GLo((&kGD<63 zeFY5?SV$8uKViy`P>=h~E{iTl-sX{@HcBI?7mT3GQIZ#L2(qGPZmbcasGHZ@R5%rQ zKoi9%vi;_-+0TiaXvvM;*oj|Flpiy{Cvqdo(z5zU`bvx2TX!d#l&@gAvOPU9UBn~Q zn4Z@{l@*S7=uN`X{Lbp6N5-^y{kQD+zs=Ka9f|cNs}7L&q~lTjs!EvU@XajDyluD5 zba!^PGd6AYI%fq;ZRgAEC$990ks+A?#w_kHH2FYSTHJmwtzoo17o_$lWKx%7O%_EV z6fxPJI|sN!k0n>kEhE+QwOW9!Z4a5a9-Zk|`vcRaFr4%fO-JTWcAwz)CSX!iZMn0P z#Q3)7v6--_eT7YA?ZCVa(^+{@X)(RDn>E{sjpe~Y{mp^Cio>Y`66+Eco zU+mnau=-!g(~jDz&~gcs|FDCU6`0ZmmpZ?{yn{$ippWmYjLVCD0;?U5RPZZR6U&kT z&&1U_K&D^p9uQYj?2%umaLYz{iV5K@dW8ztMoV;%BD7W$J;-I~jUAhJ!y@8iNDDZ#Fg{i^~XmOvQcJ|TDUDtcS#Bu+2uveHNI z?yF5)pz6Q7Mb66IQ{qlW_w1e)9m76*1xZu(Xr$b1gy?vFQdIWJaGiU{?iH|U^1?q{ zIB^X7L>O7)IHK=7ww9L~GZ`N=8iHWV7^71w2EW%f;1q_g6qR+Iy*=98WU~SN9GPr# zS68owQt)$DK0`|VFFF!6))C0iyN1;fW{HILV36EC!Iz^{$n`lnTzs~a99#ub)zurS zP>!#V^hYe-P)bcgp_#xuk~^xH>?q@?6ckkXp4C`l78TlDe8=9&bb0&b*pZjs%MYY{ z=L}o!fYlk8b)-RizgV&^OzE}cjm{KS1+B|p$Dkp`Si+Cg*l~f?+yK{keUogVMrd35 zYts_+Gn)#N1kt5HN`CA472cM6rNC*-`%g}z7tICfnfA#E=5x83P$V3Ayy?@a>iyr$ zB3X@`&~K}Pmo^{9BT%kaENka0|ABc&yOANjVB7%;vr=WNIB(A|~& zfW@2w=QSOJ%-5bY<%b_3e-uleo~nVtZ8UO<3qN=m55p+f?_%D*>qS!1RMt79qpc;Q zqK#2(vbr($fj8uA3^Rl2@qT}kS%EN9U7fEw;_{91WxVOi>{N{pElmdr+@8Hnc~pn_x4*!v8<=GvN~?v(m?ii1M`jiFXgi4bNH(Kzis0!ZJXO@xk-Dsk*r!1 z7D&miG?=C;Ew&YF#yZYYpp04wdeMocMXGL7@oqktH}JetbH|MjR+m^RW0JmJUm71u zG=Lks^n;yFssD8{hY-hq16jFoHVl;?YPt&yd&I&>kDIh+qJmWSI?HuHAn=^Ek?O_^ zl0rAvx&!GJuIwmU$I6pF#fNO-85S^5AQ~{aP}AW;f`QR3QD}ZT(sx(UryqitbK1Zp zC3vCYqQ`qsC07S9&it%FwU}1N}6M41RHI`D2OO zo1Kw!I8V~9DbffPe*B&TO?+HK`*fXx~6)XZ{yjK!~-?r^2QLs-;L8XhkWlV=6n?h zx}xOR1Wm0eQ8ldD9OxQWmDAc3f-Ki#W{;yYPB@fIjpq0^-mGDX>K;lw5uTq$8=Gj? zwE@_{UalUVVy zflXzzc@3F`#QbwDpM+a7w%a|Jc=~aCt#wL**3ZC_^0cZWGOT#&`XIqclUr6-`NSC3 zTD9Z^W+KMB^8jKR(-uQk*O!abcG_60X^xFKG|yK3Qe4JQY@|1);Ir}?>l z*pw+k0OWV@k^qPuu=h8OBMdJ1@FuF6B{}8wD|sHee$Rx8JD7|%wJEUkG$-Af%o7t5 zwD-)acz8UZ1tIhu;uBfpHGBJr+1B8l(Z&Ybl7U~|Z)(<3lT>om=S5ae2%zA@L8F0J zs0GCFigY4>6fY#pxI9_unFF+FV}k)r(Sv0O-4QsvZoh9Qz|mVQj)*XV2!aq6uYA8> z-pN|Hb_Fpfub-4cs#wswG(DcQn7rYZyGNOqFe^^MQ@{1h4%sYpOIF0Sm8PNZ$f&|b zR4F;uV^++MhCbcy6H!J|sJ&~WL6oByqU+q7iuHl##WLua%hdY!N{|y?oB#P}y2|`e<|YS-YlBj}(;%^0 zL<6ct?f<4)e1yf;#((TBpJv|n|9gLgmGw+8PFHmwIXXHgv&&q9H|`Hijn5CSY?`vZ z0}9ZA&xF6$C~(ySMaP17`r^uYKwisZh(?#2OU);FIG)}bHI8~XJ|O!+5^Umgm43YW zPS=6jDloQuHgD`*{`-pA8`Yw;ZpVp&!8`H(17M=IWUs}RZRe<96;k{&?CyFJ2)z7W zVPy}X`ZdW+>S136KJUJlD!Mb_D1hcQ7Mtkv8T4DQsG`S47E`k2>=jKXXa9Z*w~B2S zF^h%RBU|KF`SEGPi^Q|G{w~66Io;aIi^otu8}MIaV&v?^rb0Ydd$gJzMg}t5Ajq>7 z6cP5!3QU-4Iz2xFgtD62NE5d(!uDmyl%IH=!#$rk6IpvI8iV*J}^W@5Lb23FnM~8$*W0Fl2 zdJZuPiwo(9SNCkFDteO&xp-DBDvMP{5v#1Ey{?~uUWKO`iBn6T8@<=pkD5Fy^(vBi z{0mhp;U0nJ%%`j?t~#cHCO6Mq@QbY+3oWavcNNa(1KuT;py zu0QAQ;S`LvoDQaFx`l1M^B&K`wJ0jK1j~;r?M6d~gNERnN|wHlif4E^lyEi4rkuT> zW4!IyZjTaH8mI1vN}a25KfeDvRsvv z#THd>B?UOR*&r=O+2hDg?m(@t+D?-tj+!*?UT6vNU$JZw3~Y4l|1e!XGSp`pmuEKK z`Vq=%Y)dH0(^OWge`uMe#u!)Ak1}I%pe3SY1{MgQ8)B#p@M-k^9>=wH{c$c3dACx& ziQ}4YmfGCITT0{~{`ec%Q$M@9n$Jm45oR-aHkU0M$QQS{?PVr6EQ8M66xN*fG+&SN zp1CmNJ8JQjDwIK+q264XIGc>!#879R)q%hj&4|K$RGXK=r+|Sw!y2W@So$%aj023m zhG7eYYLNQirl$S`kX~fJ-%0+aH2;kURP~YwZI%RK+vbkWs$>zLEau~y8V`c+i#WKwC@zkIq{(~4`E4Y1~wF+RhPdZ zL5V3k`F);8dcpBdrC(ra#+vNdkKt$H@!^|aeq36WWJwzPM z@L6CYSUeR7DuC`hrnJF6#)L37&+>ql`>aTSe8$V+-GQ_or@jA!<6H}q1vnz}w1|K%;g1WLW!&_Hu9u9`nQjvt#(@{jGf`9OjysUr6*nv5r2 zBu;$&uw7&VPesFu8GN~TcEL^UJxZnaRfH3xy{dNhM>JVzqY)uZKXeN0;Z_-Rs5Z54 zt6pCZ>^9r4r@IMRx+-=y3Lr9`3~PBJ0MfcNb9A=qb3iDeVAPWl!qybjKJSq7qH_G3 z+g&#=r>Cb#+p{UT#q$t3)$&H!t-fb_eJqDYxdiOyDZDDi$7^xG*@>E-v=}S z)!Fw3<%e!1v*8948)WKbt-dU5qqfUxhxM#FKEBzO>5AAsZpg}&M!8SZtcrJbK@P{= zP$`N<9tnfB)r5=zL#jO*_4jJ#dJ6@}cVe<+Q7B|QJ>ww>y$3WOZIU3;2Z=Zx5D`!% z?KynlzC_yLOn*Y{_x_z~%~qSC)R&gjBu<7*mhb z6qncSd)1M;ht~8mc;`wfBp7q&jsD=-q5zw!fD%fV`C%)mp45T!98lAc+%a z0$YT2lbBOGlLN-=SC-73d4SS1q_!ay4ve{TBWhp(1yFX9k3e;G{C@olwaKf1);fwi zKEqGwZIASd7Bnn;?4*aoKA#ak8lyzvS8rUJI`^}S@IVqYkZg`h<_a5~1=XGSn4IzG z)W<+qoL|u~Nb(3XE&1L$JS#R%BfzH&Vje{7J9ghinEwM^b;BUmCihbk{lu_EE5A49 zcCof9GWd1y5eZY>MxiLey16N0#u()!Y-$IW$apqs$_J=59^^OAnF^PhpA@+IHNAsA zKxBx#<^k!*BTNvx{iytnrpy6rK@f=;ay%^w`tu>`z{#G&^zO-9qlHzUDaS`kjyLZr z^orU{KZP}V8$s>kFMHg}U01n_Yufg{2rsJoj%h&PqwU{{;lgEb@apa7-d!h1I1jRF zb*FhrTA&aNY%y}8Ldzb#sZ8s9E^H$pcDbrBu4Y|kL~9PduLN331`PoPUW?M6i$7VW zWeJ}`zt1{4cYaQN<=dFjpPNqW|GnwBynJnw{*#-|bZ=_k4l->C(gL-fa{`{*t|*Cl z#zS+}?ShBXS!3c`9APOELUIm4&{wV+64LmGhs3m=O@Q;p3T*Uk4vD1${zNOkI>-Dj z!a^T?x&=5>SCY~4Wi@a$sbqYKjNZ06j2A-NN+*m4mAEC{lneKNj2JYbNIWNaN zyDHWeQ8DE>4(uG7B0pUeOYIBySU!*j$1phWW+J|8x@3h@uC&n0+WL~oR-;pnindvM znxF9GdV{?ftn!n#r3eO+#hj8K4_F#-O5&lcxJIH&rb7+sai5oaTObKWCDtteZgaBN`NsEv5-Snqwady-98c$sS8FR zG<*D9dWzaE-%VrtyBwzEvcM^vCtC-C$qr?`LA42R>z+t|h`~R^$Si7J-e^RgBlUiC zUHm5N!$|CPIgnh22J_6@3dPd83eGhc|I`SsLbybILRqQGaa_NHYi;Ta>2 zI<+VU63{2xO1pR3l4_U& zVSv!A!7NP+4opkX#;>lo{1XZCe@TFUTH4ZoTH3{bD*;M_NGk#$h7riyI?Y+Ojw1{W zhsgYXS?b5%op*)Tjaz5^<_^a-`c!LKun^2}I#)p6zI@6VnilY?hNx3ozZLEjD78lf zi1jNK9+H^!n5XNa1f?*VoxijPuKf`Rp}ec>(6n%x98vqWY0q?@ifG(f=H;-yb@>d< zzbwWhg0k6-j=67VS9R@umbbzQ{3quPp+}#<$g`?av5|5uTIIAs4+R}uH%#}F@*xu~ z_Lp#B^7Q&@gQo7fBAQEVq3t-P)_eJAz#;o!@XGA@`hMrMk*5fQkZ3_&t!39~;?~9= zb)Y%XO$=pWFVWTvN@HJ(9-3>u&8O)64Z?q*qRQ>smqP|Fl~%JHVZc~MJx)Gep=uAPk=N?20!5EeUy69Xzc z(Ro8NL#a$9zuXCC?7fXtdKsceG&X&y z9~kXT6N|0L(u~Z>|0o-`WHX9*(lqKtE#|t59;qUHceC$|yL5h1T<)A4ep`D=fT>ZiWOtltxcOPa|8ihd%<@-MX;W%d1{6`TE`&Y>?x$&#IqG?j$=yE*D$c;3&g zyeLUfK?aDJuFFw3sJp*}42Vw+kqKepDrcRt$G7L4P}(xpC?;mNmx>&u$^38qIlT#R zHT*ezKu5tGrpOG2xUw+2tE1yO`>kaA3|V%r=#Ddh>qRY!?cc%wwbtClh5*ga6bVpN z$Q%!QowT%2;6Xq49p8M()9m8Msr>+xsxteb=#1*zSiN$1WcN3n7 z%)QX^9eK28v5qN}lP2R%fk(`eo?jg&aDG;_+|_{wD}tBj_IGRXHGwwPy(kmKZo?m8 zftg)K?ara0C&J=u!}J3;aj&JT0N0VQZmD5B?L|V6r{BWV?rD2IOq#HZ5kj_y;V2eC z5BC{4h)SN*(+p|}d?up=zPGug19tLhJ`RgCRj7trqA;avt6FOV`f`?WuZ*QbTS&)V z$&U!RFUWfdJd{v5=IJTH_d5Gwd%BPtG29t-BhJ6dlfubGSEH^vMOkZayQBPWmvzm%drD zZce_YvB_ia+2zJ`E>l6$UAB*kWpL`i{IKt`SK*oEDWSSD*v4#aUBw%5!;+j^xe;2R zwcSLcwww2MIKnnZ=l;@9nu~&)Gw-6qJ#S5ijA}H$=*K@4ntL)6{FVGGi0Qs5LOtkD zF_6+sK|1(233~dyiVlqHlr5pBg|D6p-<*xrobpSGDpt%DUvo>!*nZW~5B3aRDn6_x zSQF>gku@|F#S2wak4X3T1Km>x-AZTqg6`D-f*nz5FZa(o%KEqOsLh_b3@n#oC6OAt zUM!<1;e5=4KF@YpWj5qEEk-fG&Rrhr8+((3P+IzaFFk!f^Pi?-^}m-?x-)?RT<-pi zy*l$~o#z!|le2yg*BM^=tT2e-0thMR#glBt&_~K+9xFqByF(T*no+!>lDbfjGGK{m zqkb+ER1vecjm{N?M3p}*S6n$gw$FV@d>8zyY4(Sx0&>YM1N%NwnThaXVfPLT|$(@ zzS(HxBJBbMI3I+o%8hS-+vFw#gpdjUpQ~N+CT|y0`$?G|^AK1XJp^j+%V*)W?!vGu zyYD?~S7w+l5dlE5BdK7kIg@C0J~*mRoUJMVTC6c2 zO}5$7r4{Cp?(vc3U&eWTuR4^P{F~(@hDxPh#EQHO>msj$nNo#I%l0=CUKFB5esb@culMI z?9Wl8wzk$BCo7-qnXBhd9kSD-hU)lO8;yqRMHtyYN1p8o?*~@dZGx_?UuL9E+()}` zCgAzZ(&pL9zVCv)fCL2_oxPJ^DPA-Vi{Xb3|;Z?Ff-Fi zMQhBOXUimUDfyO>RF11l1+vSe#$UClqG)OMj*894fXh!ixN?_>s=Pk|4^J4|OOx4~ zp6(&=UJqr^o7ec%cg86Cg2HrPCK){w7H%=<3+KsixSe$cJK z{}GI24|b`M2(K;1Q+>R#Zh+4*)BPrAR?-UhOJPkr0QTZYM>h<|t} zDy(8tPs)?)UDVNi+%S*eS;<;0oOGJT?*rqDqAe~ zKrow%oW@l_jTNgb(1lIiND{AYSqR%tmePB>n4RulSFGw<)(@83G8%kzIzOEc^WS$aIl>JUY=6Z(I8-lUQ)W zCMtaOr?$A5K>Ln07Q%D48S0r&8~q?BngIp8gD_yeTKpk5Ak!-y zii8azvd5t1yunrZGqQMSqLOtmo*hlFvA?$^5@Xzb@AackKaD=c1jEF>_4zDNpaW=t z2%T9YoM6l|yZyx$?c8ubO23vkKX5H3(8O^I@`*U(06B*mS$zR<`Cdb*DY4tDtxYIq zw~hb!c&S*Ni*{^8%QsKe5hzF@-d+7*_8C<*M{1=MztYI?LCCgU0|u5&w0hY;lCqr` zhjwwAo}fHZ$)TDL!(Lca969@qwV;R^2&ELPWp@V}$UzgX^Hr+;l+{ zIXDDC>sjv0Xtt0-V;^Fq{2$j_l3iYeUXk>VNq%o+D=p3-O>9`;dBZ{pz$i0e?#BC` zXv-P(IpoV{pwFRgyeiGTGan}T4-4zP8ETW4VKTl|2lWR5Ef3O;=)z zx7+*AIZNygf|h6av}jnL`iC8pQP(d$tv3b(|F!A8KoF~2cSlBrGkIUbE?HJ?>pa+_ z=Qq>OA~?P{%Xe7kLL({SvAdU?@ygW3IDX%Cg`6|pF^7|R zZj|9knYPfFD8UbitEm-nS63s=&n%T+&RwcGpWrQhdKfxgKx+>gm9io5-Mbsl8$$a% zl^(dWK}KRu(mpOt;bxbhSHylD9xG&vgl*6Eja9u$FpiIT0E_$zy@VbWA5(J5FNPWW zx6IgXG`(xfA~U)Y#!@u)elH4m-Mx(iH+Rr&X7F_BKsYkeJiFEbTDM}u?5i+Zj;no- z`UykyfwvnD@Cs`qVK?I6vhUs1oZ@#uxa#fBV^&X82e;-t@49*6ujv}izwtKZzM!?8 zrIvP65TNU=w{U^xtk)YJ7J`z2`Y=|aF(f1TA>(64oNxbMhCGH*F(&*pi@}sl{Tio! zGIws((J~SD)(&SRvEqWL+ufDK2Qg-Hl6#e}Hn(C8?c5Vf6AIa7la=66Z8 zvqzUqkNa;SrRj)EmNiWsOPiU%N9pM(kR%A_?1R6CFv01eOuA^GI`z)k4%U!!N*+y9 zTmIYcO^r_scMs1-@gD>6ai~Md$_co$L&>%SrcDWw)7im^X7=Ll!UI1cQ;R zfWgYp-CfY<54xj{_LqU&OMH*aKkInfOWYfH??c)Fb zaCL=JbwWV*$a(F~8I{Fj4md!)q11quk8qKBK!szUv55itlg$tJdRIZ0$WSp7EMG*7 z^!+xo*>aq137U!I8itC^EjnzamD`thRV!7*FuTp<1Mx=^c`p-=thKb%gg96eOLLyq zcjFa#gTzLxiT!oM6Z8E~MW?~8mdY(n?w7D&J#P84? zqS@Z=3gqRcpETzYpU@`_J;v{Yd&MD!j_x-lse*>Vg~8S$A^ArW9C&2qPUzBsK6~zg zh3e$MP<)v!OWDxvZitAlYnw#SB7aCzd0NI|>)XJ{q!1OIt0z~v?WrCx=G*NbZ7Ml; z(E(ez3OdPEjkRTcWoL6%H=i62S#i0(vf+VTEQeMdJg(zEUB2+D^3$p8;JS_1Vnb904I zB?)@G;s=@_#rZrU04rAa$97sUwMyqgj}aQx+k@jZ-FG_r=*ubzbW?5iK=TsDZgrER z?(#2oqBV5*bbg5cKMobbfA3I%Fw2>&kj+D3qkdVwHNafvO|hl9R{;Pj_R{-t%3&~X zg$o3ONV#u5bh+Mh^LE@#m*;UxroJ4C&T($S32~~FsfR@s*k9}u9;5zfs36zRCldqB zgRj?t)hilRZi(>AE4^Bft87n+!W9vU0#7^pdwQ;C@Gk5_~?i%}wFcr@l2{gwe$9t$PABebZakR0_A(D9`)M$t-Wh zF)gd;nFlF?UT_vAmpm0$K92o7loC4VS$cGIN-kaorb$#Wt)X*;wtxTRA9q34f>k9f zn~odu8CmVRfw_IqnNL$~#5jD4qs}>2qN_{aSD01|VudrL%0oHpiqv>iR#V`>F_`KW z$;L*f@_ZOb&@LhVHSk*ZUG>ho7;yNX-N`1a$7=Z8L@{Vv_%&Q&94gXn)F!A}=(M8y> z-Pnu>BP8jAmMx*TG7fnQfb#GH+iz2Pc;|Aq^U6gs4!B3+27nNyKrg4h#=#-8K$B4l z1H%-_P=+rgZJzRlDMxUqHH<)1&#XVP>DTDv>ez%4yGI8F6F&9%i95hN+RHz%G`A<( zx+IrROpUacbkQ_Hsg>>??toxc294kf>wF{tdR>J!~)fl2AwoT3M0+e?RZ z#zp_9gJJ(EWytBp8KI<%CXE31&%%~T@W=&O6+;QTIhS>Q=lB30gzh34UtTT}Tp-eM zpbCpvr_ZGAmNh&qiOrDWu1i{_kW&I;fa&KHdvwjdm^VaY;`A62y}w!+<0nQ|x?qqL zoSX2dYig`%`J+$fD5T{8cvh|wCRVvIGHlT(GJ3yqc`v$um{=w;#_rvjH3rwHz{Gwn z8f{dh09vu|-07=I#1Tu!dIMBxm`s3>ifOd=hGWO6bm-O7O1m48N|r*FIsAq;AJKfO zht}iVWTUHuZ;-UaUpsS6o~lE0g~=2?)Zw_c(;mEl>ws=L>%AZpv_tio;ih+W1Dv4P z3HQd7Uz_?}+4-(hmH3dNobY-q#>@Wiu`fwcqNc{M$5X`S2R#U6)3ZfD2{M8$5n?X+ zn;?!_;)6zPM~-+1B(J|S#I36sYa^Q^%cqw9Ha)I2hfnF@@-Q^B>6!(Xryf*y7X)ER zxvO0CG!y~bxqGG#5?u@oEL3oaV7p$9sM|JarhmOE)WgH=lvkH`7?XX4T95+Fq>W)= zO8;royC21Yug7UcHM*MJ{q5AB9A#x>XN2I1OR-{(NME}lY$?axvwH=`jfJU4^RwMu zxJbyR<-B6eT~)_i#rnMtzjJ7QV`ehg7<9khz{E3%5~UCQUzELPRMTnO^&LcI zlqRAC2t{O+QKX544hjOJf~bsu5C}yDfrJtvgsun(p;$&iLQxn&h8ls8P(ts7i1Z}1 zP$D%11VVrQ&UL-(zTfA)%Di7(OBdh#bDqb!_iyimj$Z9o$_MP}lCb=u>^-@Blhv}5 z;MuwF2~YfAl4oW$bIY-T2v?Dn?mhdu2hQxO;4!EA_An(jg9@xcbJaqD>Tc*g3RL#6 z?|Otwc2xdzdgb_etwoR8sYA0d#)4{RQVgmesq9G{HVEa;jJ@3U@oUtNYgGK1!C&cG zxKTYGZ$HUNhI%$VwGUs5K@{nIy&lXfEUUlk+=(*JHmezGqF!pg!^fapb@4j>RHCs+ zZrG`W^h*I2`c=r;5Cv<-6d@MU$pSebDbpp(SS?P2;?8No8d zK88_$3SkHnPxgAgX{=CG7(u0I26$Y4el~;lZ9VsG)$&;(^gv@+r1!^k?O-_-ZUa12 z+0xI=pgPga%Chj1!ur#BdxfAW&tOb8Uk+Q{Xx8oOB@R5-(Lm|h?pEtwEij+`Ne?n{ zW>r(4|5TmKKzH<%K6UO|J%dWoEC2kmct)&UJv%ft(c4_ara)AGrOXDOxZz*YbJJ@} z24I~kDjq4QdHm@Xtm&T`$;+;kM$42V99w}DSdS-i&`PnzI%7S~Q*nI6dUu=<()}=O zw6Fc)WG12CCw+2z|L~X1Z6+|6t%nozOICrotf{4Ocb>SQ0r%|HP3{h+;#CW8JSa~+3 z&Igu8UU3)oFwNF=&f>J~-23JR2d{I?I7p~J^oURVA=k-cyODo-ZS^$EE+(Lb zM=l3~Zo#d0v$qxjRpg(~0bxd(r^g{;9IjPcjC1(diN=f+C~>uklxOWC%)q=ac85?u zs-pAHKmHI|0kyH0;HY;iXH@#dm@joe@cL*rZhm>mH8P>(8SaAu}g1iCQU-sbi%^9kh2u_*6qjS*$dHot-oiGT<3g}UBf?`~tSy=r!I zMl7vJQN>6vHHF5V(#e#xY4mr@+4B(2$b9azcdyY7f$K%x)mweJlUF{%%~lEJtJ@6c zwOy+U15BiY%KQEc%4Rpe-G&Whlx|EHtVqGlCW}HZ8EnVP?^z`o{`D-V>d)NhL3?y3 zC8QVh*6uB9-OCN%mGk?2bAKr`yd>>(Zn*5+wlVW}%+^NR248b5W(!RXcMqZNe*w}O zvgPQ1oz`&c0VcccJ?{QvRydDs?ZGb=z8vW9kPyHr`)PSRB~_?>*1~LlIX0>_>UK=7 zpaCKTOjWL=qz6p8yVm3T<5Dyn+$#zbRg&soB?ov3UlWj)D$L}LFNGhvoB^=%METZ3 zVPb1jCXuY#Lswa7Ac_RcbqD(0e8kp<1ng_>UztUHG0_^iU^oE55wSx*`DfR6`MRF7 z>1v*PCm8dvGsQn%af{h2Q>_m75}B8@c{QfCB_B`>i}x;H**%vtX1D!{0j55!*^bP) zHu|>63KIWl@cQ1Ia4@r3c179>_0S;@VP^bVebrP?ZK3I~0s$iATefG~MKSfAB=)rF zViyjNI04tKS&DH4+jY^D?z7c_Nlpj)UuBYiPI6DN^FZwSzfW@e+JMsd`RD_~HNj{7xd7QYj*T5p z`3qVS4b`Qrrx_oV!pCg7qAsZvW=)g_@LaHzp2%{0Ss1O*;u9~pFE&EvpKO|FE;?U+ zy!t#D5xdyDw}9u~ZO7_+WDei;PEyf^y{+&|P;^_PY@E)sujbIso~>Q=;JQEpCTWRp z_NE?7rE6&11GF^P`@G51j z;}vA-q)WiInhPNdK0Pa^M{cSLDP_%eX0fLp$8UAF_C50YrY|E)W(?^%sxo_;`mS?> zL%1!u0$r>p;>lH6d1rFQs6Q!VHh-A1r#3WVKyaUZu6bZ{T{o+#q#5p_4g+VNWX@>S zmiOa!Q;@l3tV+~yEfW%H5` z4yWd+;u=ri(Fw4{52dGM39x2KW}NJ_jUry6V1{@MoMdScifEQB*gWq$SGuGKUTCqN zO{h)TJnC8RGp(q+aB?7WZL4Cxk)un#TT`;3si+4Eyf!AT9CHcli!eMg-T(!z2miAU z=fMOI472*#9mRWn4N1|p9`qiY2I=ZqVRG0rF8|@v>yo^+k@`QA{qX!4`x>mTiU39( zx^*IR$WDbngy@2>bY%Gp(QE^UW{4sY)*hj**F&^=-}V_m4o)IZ^f_h^jrWY+f6m@f zh<2D11??(=_Wua8@AsUcfZG(Y!W7^gVI0hDxuM8%L!MIpys_Nmm;E9JsRu#r47h2f z_gH#0K1sHlL-g@LGXzOm4wKNl=LWuu?IZ)J>HL$%`Tw~hLRImj=71O^?^!r zq3P-Z-IB%W-WHQ4BU2(aW+|3EP4U}azss6u7NuWpvRNp#MIteyhL#fup}~yuE!bv~ToZkACT90O3j9 z#qV=Q;XFhRPs95l(0H^w?pUa-lzS++N_l5B(J;jhPFB+d*YtpsC|Fz0a#P@CbGn_2 zJD6P`Q^;o0Bxx;`OJx!lT(t$>CkE~`i>Y_p6_*vZ>ZlUP%mxQUaDD&}HK-)MqD$rA zAB!s5pk*tNL3VBX>F?^2=pg{Hs4AJ6&Im04jy@F?lrn9)@~4xiD|F5yD_ruWF=;QD zlCmMRx=1awgpfU3K@0noD-g1^F*O1iUY*)>kqj6L%pXeqXZo? zw+;1j%$C{Ilq2Xpa7GNGWM=OhLZ=>n5{R*SFWM+3+>$UoQ`^^kPm+ zM`VJWhR&zr>PP_C37wtZx#Ra!UDTU=w*CdN5iJ@?Vc?Y{^KqFPvgg$xp1w%oiAeJz zw&M$jJVS=+&%LnY?Ip`+cgHCVrpZgJr6+j;zKKT?O1r~$5I%{|16x$(FX^!=Hn&=+ z_kmQU#1mNyC5?*9d4=^Ki``ue4ENL+I~`w=c3f-M<@i9_7Y^S$NjScTe41 zd-eF$dmj*qoP-cV1C@Z!^WWp&-`p;o)-1*kw3KPCii39F%R1bkas6b5!kz2;BHDMBqTNiox@ul>s4!d5LrXhTwz%1m`+nG~S(lxWAqO zDD26g$|Jt=U*HGCGlgQ;W*T`TW|M58ELhsO$MQ)OXW;-{vNswGK`bPM+SB6Jvhs2l zjqHn{^8``vDJ;aBtV8xa3^iEq%Fe<1bHp~oj$elBdKv`+6gI3ms%E>AeJ4MR9u=i8 zNQ|jk-489*^2et}>F>@)RX>20m^S+2X#qr+Wr~HlY^*TZ<*^11q;^J%NPDSY>&h#f zi@z(|Y_n8SDlWVJv9jfjge!w4L@v8`!yJhFDB+n6+K2sM3y|W(Y#aLwvJ@$fY!_=G zn?;#^cnobN(v>pw!q4@|CqWEoyebA@nSh5xP)*U=4Uj~}dEp77^TokvXsx5QHvB~R zu@2x4asssDo~<~Pypc#bjv2d}6`7ENI=ff5)~KPJV{2dN6jO@DmJd04krb&r6>VLw zOQ(FVDXukvwHqgj_oRbk(dLT}$^*PSg&nthbmKc6m-JI|s}bg->*QgT zlFIGQm`ZcR@DS@L_!|tTrY_Im84ZIn{!mR(3jNgK(j>nZO+Cz` zzu!?rUWl){5^JeS&^*G-si%aOsi7kodfErYGeO+7Ew>q96c0~TW;yvbYN^;`2RjSX zT$@eS!*cJ3ERK(=K4&-$jcU<)es`O&PSclWw&27epLeLhjpK9@hF$8?6iNo(1eRe76ZYA=c@r82YFt`< zY%qL&_4C){p>94*Q}4}fCr;1Ahg?Ig;93kp-F52Z&aC?T*JkF(gY<+N*yLttXvrfh zV_no8d;D8F8L)!C9hT){jRC#T;{rhtp(EYE>^`p$KD`Nwuy@)U$?+fN4oz-5hA-^y z{<*#Jzr2J339;fJrHgpa){1+Z_oe#(jhld;`0?i4AKJgAIhJ+NTX&>-QUSz>zhAo0 z@(ifq<|(*kuaINu7U}E!^uwfZhznOab%gl+Kow@zC?E9;g?GH8Xn; z5%?K-vsL8Ntx-zTpE2OckHBxK<^Tzn*p!u*ZLQ-?n|h?!a$p?mapLw&tw*0S(0cSy-&Za0-cB*$>P~yV>8rs?Z7%ZI z@ztC!n$b!!&aM+Y5e@l&x+8x#0R3_kOI8;GDTf{zXY2$U-=dT5bgMN(Ko<-MYOEx~ zQ|LC3Rs(cKI!=)UL?E(Oyj|--j^^;@ccA&x42e=kAip{4Jj2YZS2gM3LA zRn0qP4&@rBr9kF_nyV?iAYl%nlsAG28VApl4ILx5U6^K^8)?~TEMj&*trU>_U;Y0i z|35TSgiD2I|C49n_+#qdm)&NwcZEP>p^uHn(I6s8Yx|pFbGex?uX%F}6wkjGHD z$56FhIpk-D`^7};bl-=TvWZqxNR?|64d}PCx0D`}I_ydFp?JT{9q}D_dNNaQF%b(S z3yNP+YBkIt1MOxZ^;4y93&!3L7@o~Y+9=`=mh`#(V{tYSyC4R})8M>=iSDnBNu(Ep z0czV4(s$=O6DTeL9;g_VmgR?XBQUiGTgz+qOO3h)Ys%it8}tolx zq3r&~F`xq#ZXKGd^(2^bc8C8NulAP?sqfJeue8nTHmB2m^J7PrkJ!O%M_$RMGE~W3 zPLIE@AKH&tt2XyqJA!Lnw5}L$X*`rvY~J1Nj=G6Cr^#(d zGTc%}FcF!vPb|H-1bHzDTdz64*&B2>qwmkFdRPOW^km0PL`7{@&P90d1qtz!c2>7R z1~ID=yi3#Ju}EK}hkEso~AXIIDH_F_40}$nQdp=l|QHLKMLGZuu2pTYEZs0zX&G0f9mA2W3?JCszg-*E^tr`{%QQ+(QNjNwiU6+iV5=8OP-P1XZ)lQzOu zGrOa9HD|>eH4S;jnWHAe&tU~NV~12!YGKd*oQBRE(1ND3&h(dY$`h(4yzR#%JsvdY zQs;Xd&s0mx#0Q-922+iK6J&?XcA6wAhBMaOtzhj94g$m5El)+T78(A3&I?M1<3GF! zAafq+Vj%rxd}qzNFvZ9* z))RwdL+ve^2T6o>HyHFj1edy&5N@ZJ$l?Jd?>SSCA`h~1U$G7$0)^)lp&yo5H(Dh% za{xs7I#ctm3(dnf(}L!*)g8nAZY=FJq_9u0zRAokB1AHLLjeqsa_Y|njX{F~g0JxC zlzDKOh*Z^!kW>%?X)utqDCa=yeK;v=kElAz2bx%ZfnG8tJFHpNt|$PfS0W`;jg!qi z(|x-e#kgGsPi%3^#59G^asGj^Rc!GaWZb0Sp;{7?aLc%u|EDQpPjxnB>jT+S@JCZb zSc|4c(BDvN6@I9-Dmy*tqX0oQ6*m?H=b*EAENjzQ>){B%iy&)Ahj?EH2O4^3&9 z+t^>>cq2>@w8Piu?>)%BJvhd_xmg|7-0+q48H9!BhQzmUrK_QabDAVq}!IA6})rAC|XkJY7t72!!m{9GASeVFy@!7N!B z*FOut)lMK$rE(d~A*_V7_GZJ<=_em^B(F&!(uV-;jA8rStu(1tVzMQ!_+eva0x#{B z&_Tb*-!{iUL7-)ar5D)%PbG8__6F0Ez*B4h@J(TU} zMN0{)kDSOqIiFW3t-oUZ7wqPXjQnaHl2a0Mp`7~Dnal(46Z90tuNtoGe{qXi?RSgQ zG16Z%)%Qofbk@v4!T{4?os^Zc{q6=6R(aG^n!TwW5B4%QAMu-EYjZsr+T~j#ro%Fk z#3Ttz-M)9wYA1P?fOm!zLc6Qe#|~S{v4r>epq%P>F1JrGAFNWPMzuiP+1h0V@!8IB z>8j3`q5!yC{$IgeAhCe>JK%131aAbcdiu9%H0XXLN1LE%WSxnO8w)uyj(EUZ*IizY zg#(C(-^hz^X1({+6moR5zWLG#&P;VALNJQ z*r{l>TM7bjJqV|MkufEbl$0o}0K47E=?Og@kH*XhSyfJxtDoNn{>m@a+vvMXKCnq-R&KA)`h7#qzY^Fi;tk z;&0`-oKPVvqd`X-lp`*ne&>$9Wx>Rf^tFI~BS+d>DOUFGEv(59*OC%-2|WoqwHl}m z`b7v7Mg~X^Jk8#kiHhu4F&LDqwsZ^e zK5rNC_WdwQNY!vAl_cqNXLcfj#o^`3dc-GUJlkw`$4z z0$9{}*O9)Z98FK6oVH`=JkBeF3}!;BYY^3&Eji0Ucf6;}t3#RSl0*}4?@_gQ%Z4wW z8T{-0hNTjbrCMinmd=h}Ao$^JMxiTRBHrmy28_Ndo$Am~wX0r!c^aYKhnd4azZZNE z$)o%>p;`E{h-X#oFVKAmvls}IMs2UH0OISJ2!Y$vr%q`e#rc(?lFr{%;n-L609_90 z*mt=!rpJAkp}d6dvyvmLR~@FVdY3s1q{GUHr0x&h2}>!o5RI>x*Srsx>=eQ#zv;qC z)VuHO3&gNsUS0zdJ62x#iJ2je@|;I18rAWBx;ci6GcSYJVRgy94bv)!O#YdCd*aCs z##?yq!wk`HgPGwQJN!I(^9*la12WUd2h*K-(#3d65`9x~l)Z>ERO4QH=N3iO`#4Es z*uB}7Dbi><&N6Av3I7q&Z;&&ykFE7tTJ@YN@LlXW=c0o2?hIPb`{cIJ^>AFYwh;3R z7%oMIu^yC3DVr_~_{8x>NFDvueuFLrni@RxmN#PYFJHYnbA4zoe1TJ5O#6q}rEQuY z(!UGX>cz!(w~fmy`ir-IDU1D+1?SO9Fy5aR&LZ>=u5W^=Kd@>?RQ1W8}BCr)80;ybTH?WNI(!2nkK5r6|c?ND=czM;>(h(a6fyt}@z`GY!zf!>mKL6y;k)F6ieBa-l%k%Aoiah^gjyg^+wT*qm z8|dqEwNeOT6{jG+nT_LQgQuFv!rnrhW!k=yNBGypdGmNRRp@THg^Os#;sjqKROP7! zjiL4Y4Ua2y?paXJG1gK9Te+P}<1%xrd zSLi(~rpw_0M+Gjqne=I7|EC}VShDmB(y;;LznO_?Rvdidwp@&g3?@=sXZ@b7~} z+h>e%pXq~&ThX#OVx@Mk7#u^XH7nj+r|N9PqP|~%(uOB{6$}tGZ~6^HdVglXs%cT+ z)KfO9KBdCw63J!Z3{?mO5Nf)=g`FH`Gh?lDL?(e!S5dZSTNp(^N2`wEG{+(*%mERO~W| zxM1za8hjv?I;vNQ;n&PfenVW4Dr>r+k=KBb8c;~uKNx}HM)84aw^}8hbcT}{$-KP! zaX09wb#mI>jLCU-MtKr2nEC$CVD`^^!53!b=s!-h(Eog*aryTty5R>-;e-#90FzO< zt5n48&^t=QpR-;rGZ&brwHPhq4?ZB2*W*1quPBgdF8N96ddp?)PX65h)vcD3Rx@uY zIDjcn+l(A>%KbOQ zay-CgB6IoE`Iu{~K6QsmQ@#ee4)j|e&mB?6Rl4mxw`ZLuV>>bM_R}@+!vV zkJzsHh6__3=nTSIPhMoVi)=y3$HFi#AAct81&ulb>Y|W2@$WQ6U!_3yqW;^*p9+!#TFb2HDJ}?&<3c)8zDFNrPDqF2WH2-5lULI7TTb)u z3*;tnd46*m%G9i3;Q0 zpLjd8ZwZ0YR+S87i8~*c;5=Ufkd_~)w3$zjmbyz%YcE4-N8H>ICVH4^BG)H-0<+(W z6iD20YKckP^ciiYR{uOksnU=aaJfX(QJZVmFSW^lN^QQw(mLYy-}^-j@_|ft4ng+w zCT8l!x0lDsTt|$HP4`3s@P^#%H$3dKS?r3|_A^RieqK+jQE_|2;_67E7qdCTZc?1g zpq>9!lX*}5f+Hzx^Zj0cb&U|6Uext}1p^HKDqf(^1H}tq7LZ3B35!H84Y@NCEkVR1 zzUm`DPISiD5OVymZmJMT+o#vL%OV!=$1z?+4}}*naDC7C+;Tyq2Las6q=;G-e6SuE z@&J0clGmKuQIW;g$4jM~(w>JpIh8j`2kg|V+rWK46eS82@rQU~^X@4QY~*$7_>vn3 z`Gad`w>9{Kg+Z{s?WGJXsu{fji&q!8*H`uHK!7uZf_-H+OM0H1&1OQOQl9R;yURL+ zEzw9rgkuuHMbQ8LcpmVoqswsA3tZWsJSPg*3)-JnFE)`L(a@qeLwrQ(7VlTxbho<+;*wv|SsZc9t-6rshkp~)o;y{0+(E2(38q0J<6 z>-PkU577ar>_^5F#BGnvbJvCVC#bxjh3$-!27D{iAAHjCyD6}+rNQ;)>IZ#R$cr);F_hD%;2PhH=@trniT7NBd)<{U7D0Z29oJpc@0!v84}^*=|} ze;&fZIpDn&?@a*Gz7AvPa8@{>$`O#)7nbfNJd_iBo1m*hOa*_?_YIAbny2XD>xIcQ zd9e`uWT$Hh&028)vDjd5xEle<)Efvpv-A|E1Xn9^jM9hAqRrDALG!meiT=NrsvHbi z!vTjD1-SX#{cjhm3TT6To>1PFz*6E!5ec^pQ`6i-Ncei#mzKlcxQf1@LXQq}uDjpn>|yUU*Vkh-y>lMT z0K8~e5C?ygBtta@ArEUxT<4gjQzCz)I{K0`j)W9$*?<__-szQN%DAuqziv&$SH;yX zoY90MKbXEvvJ+-(o*T`|lx!gpff@+*8Pi){Tamp66JHbCG!t#*ab7>gKJiaq7v)RF z8MvYs93HO>Zh5z(kvTJohMbr44+Mq76EsGL=8A{PD7i|z=djem+e`z6KG@dR^-a}7 zWIoV!B$iK4k$3`w3<0>$J=0I%5%IlFLJ#B>w~h`k4{@|x@+8qbnu8sdn#BL$_T7z9 zUzk-%YohMZ%X%4=h3aFQ_q~pi41lG-X8?xi+XL)F8T(zJDq;QZ_Fw5a!&dh<#g&G#mAh-@9^s$X0ZLJ7L~btv@~|)F zuSx3P^aD3?zcwgBF6#>+fz%Ltdg!kk>(<3-=YC;5mdquSsS^x zR_G?%N6uGB_J2V7WV6BKL!yYBOe5JQSfKjj{@Me_WQ$U;bn3U?D?`Ec zoQbBKL^5X4EQu=(A=_d}cy?nIfd8c>?uz*@u8J>|D_dA^EAP;)GdHIwc0-H<7%W}z zijNxIh^n`+{N;6aLdu|v>?`@DW*J(bi_`G^_ajdCC&v?0QOg!tmiJR#U;yqb#(oMz4atP5)!oIXbnE!mC56wzu-pZ)G5mB5npS{Hm?tI{o+ zlA*Zv*687$m1Ciqkn0&DPAlc1H@nz^n+tqlN=>uD#(`>?g+`&Q3MzkeSy_5TVe@y& z?TXsl@&-Dvxl03fFncxXwjG^*qmcNBAmm_3F*|%2u14-?8h>6($yD32SDolfblVaAxK7&NnU?+m zy8^_+zZ=Paz^>u5;IPFS1D+SnWxUisRUz(WxMyBBzj=8v=bFmFdMRWVWtz$7ouWc( z>m`Ypw3$xSDy6cxOjjW!(4#qppFO2k;*y?=fGL?3J|}4nCdTXGXG|jZ4;R1IaF@VF zWre#?r!IA3{+4`+br<|@xbUvXs0LlGY4g-Vo}BYLaa|S6zcePa*d@DN!yNsg!UzK!yXFT#N&jfyM)Rr|$l8 z-|+Wft5Y-q<10!m+cL17vgVB?x5r`PPdiWc!pj3o78gM8pWf?aES^AFNr!OT`>hXK zCa$H+|BAFL(Si`Y`ChEV_h(w61vG-mIM_V?3$BU# z`*2O|j@jrUs1D8A<>Dc814vWYRV+yY*jsU}C^O+mdIBZtHpB+kOVHtWBdYV+Gonf> zC*9UNB-T4zm25o8YG4{rt-al-gJ;q$4-XSbE^{?1IXj@D%8#4(RPJEcT;?j@@5{ja z#n!)T@&^Nr%KPNiGw{a^3Bd=8Xi;TUA230{Q|z0|?}>|9+84Pr<%j)8Ddvtofjwm( z32${^YRujNGiGF`{TVHe6PQ`AyJz3GH-+;jzDMxMB3c|>CdTmWKSW{$pr?hhwKt3*fC3ft**Z^+$ zopZN0e+C(TQXjMv^&$6no-bcL@QH~+nG4u6h_5X4QV1$HYFRENf&|~+)!5tWA=&!O z=mZMPH_F!M$W}*Plg+i=HwqgL(@!w4N;^7|j)CBU=4N}7hIFgvfef;uSen$@@4#N) zVboKdtvG57muVsolpDR?d{y6KjgX!+ zh-q?7g0VNdlOA54Y69v)%#Rpo33ITL?fwSNXyw;A4`mDT#o>YP!WD}O+irKdjTcT< z$BVJ9$k;2{+ym?e{_h7kq9DUY`(MJYwXf{`EM9y zSBmsZ%nRKi-b;dt<^xZM%h0ew;$<6LcEFQvNqm|80Gwyp-)^v)-D@!4dC|=G_I^_R z&}zS@bwBV3mRz#rQ7xEO-~n#BpQo$51dL~UO*Sz1`oc}!z9*Pi8INFHeHW>9{fos? zzGuWWhsw-u?mY1# zmf;ku<9s+mc{Cih(9{zP>6LkvV1j(=H@#E%nW=ppr0KKFjs3y8=Z6P#U%Z`ytR#d8S4M;8{nh< zO@%XjI%(%48VGoXZ;V|dc!0a>ZFwH@sy-Gv_^luXH{nCPyft%m5`q;*&$x^7CkDI> zX?4_2_Bz~IT~5}3-OqoMSPH!mx;>?134<%aN5}!LGqY8;Hj1%5gxZ^RmH6)`2a?ZN zZVK(L9XnOKMLFMZ$@5+AG7!xT0nZ<8ye9+t#L^9Jx`yKqi2eq6%L7qp<}ysY^>FU+ zvZTGg7x%Sd`17>{wh2;oC5vxAH6S5%_%~tQwPYx}iKy!L3M-8$3Sc>Rwj0&DDgxhj zdCX7-GcdLIgl6|UC|uy$15~AMdInuG)(vPlihGoAj3{9k!{}_NYYvX`+W0%*G5+t|3A;T_^~B z->4n5?t5EALhc~ z>@{mw8W!x+JcTBQaiz^FiW8R`D6xng>D^bIA$F+JD+-3?U$$u7q?zWkXP2BWZ+)^X z92$5~;#vXi=G9BFD{468w=}TvXUN9b=JshmQ24Xkq#bmXfF+P|^!=|H$BWqc%D+X% zzcE|^qd?=j37X(NNZo~T2b0g0k0)ivC_hCmMmIJ4s!lrXE@k63C3uD1+`)}oH-|>w z^JSa*1-@)4*A4sUMXBrIY8Q9lcHtU>{Vq zP-4HBhP5UK%@9AaDA^sY!NbELSd&luK~WQwR$qrc&)TeG#;++=zzn5^4F(fMJUSCB zq|31mm|n3Mg$zk9O*%=Ri8q7clyet{6cf{T&ajWOLh)JY7n=H&vMGrs=y=W?wDdOI z=j-R5ciiz7SpuS+|6!5VaoKdD-77n1)C(;gUssxOM?&*4V-AT2z(1FetCOe5&j+iY z%(B-x0m>FOVJGWwp!N`Bg-pn4NNCyWFAV1msfA!V@wlPpA;hh#nfAq5@ZT_SPx~8T zt!FbJ&Ql)pD~*r<;y??y;wDfjZ(;bgyKXw8nJ-KPvX)R|H9D?qMj7T$W`C!d;a;1K zmc?om>j`*#btP!97Dpj~oaUAe1w;Wzaz zbjHc<;WZ5YrM#scpnHfd7EXssSD#1yigXR2?2JZqT0KqB+3JuM;*}o-Isth5fHL+OFzoG)S(@L|R?x3T+!M{usSQF>P9bXlFq7 zL{-Efl-yDLI+GWqRebH6B@dUeZUch-p+40QH0{4(!yOo)jBmWxEdsmuzZYbb)wm4g_(9AZ{ z1cl`6(r`rx|G@EqYq~?Cjc~Q*c&>IO-Hx?+;AE$AJdSbCnA5_qyek8ImuPwavDB9hbW- zL$vV|4;n8u*eFFP5EfCRn zu$?D@y#iLeHdc=oZ6KG;dEVs=Kl|n;x{`H1Rp@~l^{8L*J&3g`DgVW59jBYL4 zIWC3YbJfO+wrs_#hrR4BDc@ApVIcQxl$%Ku-eANH| zw6L>Mt-Q-^(bfZ_Jl9_&?Z9wzrh>LPqd@9$Q+Yt1cByH3rj{r8id%U$zF*+3i7=r4 z0a&}HYv0kLgoE~v2SsdBJ=4|0r=Fji$us=pgzJ~J&UK8^qPM&lV`y2l6{)9T>bUSm zQCLku4a03W$rXI;QaDjIhKpqyb!z-929HmOg79fd#?GR6y*kiWv_OGJNI;J(H}Wk? zbv2&Es>czCsOAJREf{ve0BqcaIn#ZkfMAb}Q9--PD z!WO3TPcma46`#KOq3>XA8xNcN=e7KP!?J7ciL0fHd9iE`cihi~4&EW;9`?Kml&T#M z;h^ZZT5X@DP!BE+FoZrXuGZWCoGQiHEp6a!^uE)$DI-C^Es4bpHv-~9Y1k$3HAF`0 z+3t*!%%z&JpOLhf(Q>whMqyM9!7F8}KaPsBgAQvCZ? zrypBKrq=Ny^_~BDA2L%W?5iqIV@vE-tI{qUYXielK$lbi-t4U9oS8Sg?e%;D_GxY=mZ7wN3bQ3U5_r#hNvu>zA^)=5?A{ z2|ZWEHrsjFLw)>kbG1P|#F@Re{-hUZk+Id$RyP3;N-m{L$<&-qWaeBo{M__3soD$F zhDaA@yi@V!PB>ZKr2FVt!^WF>>YtOGkJ)^Fo>q1Z50i2joEf%7dYbLD%V zHU_Gt$4Eie=%x*=WKwGKP~xENrQKWTn_jALS9(iX`o72RW=MqM%%XfwAhs>x%X*cb zVu;W$28I`@?bsao9&Yzt?YVQ~-QeBjaZgRtjSkDxhwO>S7dBnmPGn4ensfE?)E84N zJ~HB&LMBftG|Xj+&q{H;Tc7@kP+z_~R2v#^%dbZg2q+m~B6sZnS%1?_=Kb+`;9NGV zl-AGupz*f7)|V8Y62Qc= zvkb(`uUD^@L}pX?y@y^`Y|)J46%$!qlLuOn2wmE*ax$R%tJK4hx5xrt(EC_pkT7Vj z(`D|;R7^FnaO_E1wYzfIjHKi%p9e*O&d1o!SJYVVbcXnQH2FXYCZcgOCJgeYuj^!J z=9lly=`nMOy1(OfZ4!P4kN9eEwLa7%#OcEx(hBzPhhLG$UpxpaJNGM_qK z-2JE;-#-|TkuS~f|12QOY?7)(NS4I#SA;F5OSu1MAT`Lv29u9MWs^hF-aK z=DE|wz423|B@6}_blXxR`6+nBN@a@L< zIzZMO`J1vP@aTJ3!;$-sP5tvgj;nTWwH62mkFJS=hT~O-dLI9R4S}9U26?(`$|)0? zk0&R6!(t!h->bE5g3X`vi4qZH<`^MwBK(!Km z&_J#he{8<_S9=oW%85n#e`8PLFmJ?`7$m}`O&1tI zA;&d|!!N#kxG-~%XS7FNtO(2(tG~S5yzIa&u08NYPobQD@Ij*P134?o>lY`D9~cd3m1)2@5hp;i8nO*e7G&pBt2=J0pxLWbA`J+)>j zlkHzS80eE?Oa~Rr_q^Q;1IaqdbB!YQD^o86bh^ZW;=ZfGUMtqJ!G0xFEiUrnah4He z^3GdZsGt*4@&qsxk$Rj~Gk>%N-GXs#)^Gr02z0%N0{v^48Q?qsX+FV)H*25%V{zB9 zrF!Tm<6AAwZwQT=gKoRWELzT!c5(E;zK$(p(h zGf8;P+pT}Tq-L?>|Jt3j4J<|kYDH>_fa`BE4tP270wIprtN>qW9KWmAQI)Jk|H%x& zc(wb?8K%7_5TJQwHEDpWr?H4BVxD+Y522+X@h>p#m3~FBOg;bBa)&=k11`*)_8P9* z8o%{j6dQPP4=A#%3c9}jw3f3L6dG)gaZ7>%_A0DIae=*Zga=GiCQD?+J)BU4HZz`( zxNqDptjD?XMat@jc+Po`r-L)O?<{vt3l(!V283qrB%K|(k@0NkUg(aO(3C5>pv(g1 zTjJA$yXf+@L6(f?`bC>38sH+EdM1uPUNscv8L~aWoOyC9?9iznnTAu~nz=V1?^$41 ziB>?q9!QJ6gF1dSxx<3|N_#S@{M!v^_mB%vsw(VTGV6-v=cE70#Cpq*og(Kux{i*` ztqbx&cE%gUG|8<^Z%!sF5R%*RGp9urd^1TzORpH{DD@mAb4iNu~GAyx`L^*)g!jlJ(RkhdeAS@8-yvXr(~ zQi9k$HrssQ-R{cu;hGg;ta;sZ@3{gBX?M zTeeEJEF+S{7)Ho4MhOWaM2#gXvhT}SX2`y0XU4u8`#Sr~{pmXAcR%iP-`6?ky8i^@ z{dvD%ujjg$$Wcx4^8AhY;L5-rqp4&@S6wj@SNH`ec6O{mPC7aU#8>XK^8LMvYAy4J zM#7{8VStkuK3lBt+@-2O#hmCh)m<^fH*U9V8?y@8uut}KcqNmWa(3^goC0-E`ir0Z zWVxkFk8WKpO!|{9(9=N1L521UFYle9GGSb}ChzV1Dqx<@)OjJa_M-ZJA6M4eUg;M1 z=GpCR5xxSmE(n4^Phz#jeY>E?`0`8Gq9){$F$PT(Rub9?FJu)-yUl)4nf+m=aR~wZ z6;^Ki@$D+ZqOK6pa8H$Nm1m0F>rAV}~!`#ldwhaAUJ z;;!yC?li{R?a1HbpxKrbms~-C3RBe$%>i(x8@`;3MqbX(Z|dbe8^$xbD6NNq8dw2l zSNYzv_Z0039g{+sk}`z@vjSD00MEzCg)Z8F2Hw_n^}Ma0=UFSJU0J@FtDcr)xa#7~ z^j>b}IJ7K%bA47NquJ?QrEwtqIm+z!yIu5OaJ5$0>+1@hE_M+sGDxiG?%27Ch6l#t zK-YP&b99wOm0e4T@3R|CU8aR6B5%IvN-mJ}URJrha|){^QErmuQm6@cPZRJQh@Pq_ zPsX%6ef<`Wu#Oyk;c{6N^p;+yK|fTF-*RCaO_0O%U%@U@9$5GP_wh6TnM(OxaHPET zpX3Sf|Pd;dW$Yk1(c=&ptCzvS-AJ}*0 z%rw>n`@U%Q%O@^gO|a-}(hHo^tDbCeI@+_dGBCgC&w_*kd(LtF_~}O z;%AmZXq!o-A%E58K?HWpc-*_He%5~MS`l^&6m%chOYbLTEd9?*fj z=K(EV?~R|_gDeW%^w@MGO-uP+g! zEAl1Bl`npBI$Az>+;vwTD$|ByrYLkM2zY%fq$Ib!mh|nR3d-w2k57wsCvqY;T_W@Z zV1e|W#3o;k*=yuQbq+!C^)^rbrmPRRipS3Mmw(?c4OMqxCnx9NIrl7?$O__tudBGJ)KJpU5~5x^Kefyik(J zynWc2G@d&Q(}8qX&ZOEG(%59zTN*%tTc)t*lfq%2huCQ^r4(@2%@cZ^N^V9(WJ3FE zpVntZ2gwvsJy=@|poI5bqMR|$@kPDJ{n)bfP$x0< zY)SA_S~o}UC5iRS^BxYib{B*(Y~LexN3}6%1&WUhjFaMvs-yw4svbn<3w5zY+tZ{b zCmGgL{#-t0ydpS4^1ckY>L7-4Xs{WzBszG&imGdB^4~ZUjTqOwt*z#b>|5a_)P~PM zjKz{Qkb4U4KP(h?Fr18N`+{dNl^`t_VeTPP+jey}+Ik*zD0M(kw=fF|` zg|En*QiK7ONP|#;G88m#Hs3*(Csb3$T4He|bou8l^p;lnuKJrP5j1Ma`H;1odA{r5 z0~v*=ff>8ez9txdWI-Buk20(}Swc=RcM?{w=nI%5(~dSlFKJ_kZ`wCTWJdSkU6+e_ zHNmyc!A@>(4D-8nu9pwZ!>yA5ou<1t;Me9tQ>UIi0ur@c|JOvV|G3gt6aP=8$N!RS z&%Oji1Oi1_C5>wU!wahKzOBf;4@lc7uF#Tcn5x)cEq{3od8!!WFi)hjG?IHH!6-#f zYc;*daK1Wwf_&t4az?jZKBX%?6YPQ=$e5zJ&k6WPWpS&Ae=|>0wHI98X^}(I^(A3n?C#2KWpB7h?&ci|ez!lHdgx&)SG})I1cm5G|{8Y%rDFGci*FoRad3wR@9xbk( zO35C%^sWaAp;c#R922*@P6xnst-JgoxZY|1ncgO%J?}6w&)iy#!N=7Xb7Olj z0YxW;PM{qip_97@ffS*gCIw{n-NFt^-7T%9=m6PI0w%)*WUaUU3=!6z+pl03Q9}RSi!5c z!^RT(Gfm(TE_J0cuX~s%w5#fPmj^#+=L!b^EGVLR#{jn<&mZXl*Cb;<(06X4{Ezma z_5Y(i*t5VG%>Rjl@%r!LVCuI2AXcjaY%Em_1eyAJ*z65Z^k;ln@h1ev{;q@{GbQtpDwJ=K1Rbw?(^A7365 z3S3IdM#PQ-f#eysMBPdyp&CN&;zE2NZz7o065+bmRiF`(W?yNWT1%W%f8iikF>sJW zu2nrK@SZRuY=qFday4d}BDO!PvCbq~j2tN>#q+os74>lNn%kI`et@1pKL`5%PVU;D z)rmNs<0`y&T0yo%92Ae?xhPak5^3HRK+O4pVxqKlGwR&`Mso&jn5p;1be&NMvSxI} z4o}Zy1b<6WDV`aLxVkwK4hM2>f1SZ44?$E%PmCCg6@4hQaJA1jF`j+nEQkR}MvQdVW)y-Us0XEDk}?nU3S8|5Am zI*6&KspXPqNjgEj*)yKEwyD$k>E3RB7Ng+GJBzrg^RRW%2O?ygVAl1SOD&+E`MKVW zd1iU}W)Fh{ovrk=iU&t?ia%_ksBVkR36#aF!)7w0PCSQ?+K!y^*CA%8xg>D~b(hO5fTov(S61;vuiY|n>fsF~f19p*3M`~QI9;JK>5ZKpNW!Vsktr9DAy60Q= zZ-&u9>&9+0yPv(;2Vk#JH^7%(f|VhcM3@aGc2boJ)uSU;mPc}HlB9xpN22oz+mp#1 zN6iA7x?UmI7UqRV_t6}R!}eB_O8zNlm2`dS3n#qnKbzyLZ`*u!Q3>-?Td(djw}lOv z^vL*Av@?4V+JRP6uq;wWYMtFe3g}d|;F#bPl6Q>PsP=Hp!7)EI51Sjg#%J)``Nkhm z9RRa(jMZ}zWf#9$y6S&SDM{!R!L@EnNptK*Q>eI`cBm*G*?MIzt(eqbq_kE}T|h63 z986Dl7=Gt8NuSMhLAV7xUB7R;&HjE>bn#NgxaN)8t+Z%R9uKHFo8Qp93KDRipW~em zs#^!N_^POI?6ORwjrK?H5zD6maTu-%>O>#}=ny^Bs{6CD4jVW(DD7tF0IAd%3@oNy z8Ut5VK+*#3t#ETzvuAfdi!#WwJ~m)^xV*>qx)*IZe?6(??HsT49eH&(WV>*ti4FZo zP+4i;Pme3dx#cNqi0tnm-0$tHAXS(DWSj0?Y^n9*{uc1SF(x1bE|8aE0{->h@1n%ya=hPC|r>hdg6-2NNTSIz~61_j-@Ckvhv8u zmh8#B%4y;i(QKZjZ{zApiNAocZlcQ8&s6enT=X+ z8~ZDccWvaIqkD9J>K8POx>v~iXtgOYT5dKpHXD3?RZNJCtDMyIcF#4YmZjj^5VIQO z>4wOvwp>&j-J*37>bj;69eM7$NFb7F^?6E09CO49lF-fx88aj^;=!k+d#Cx${I#X$ z?NjdUO#SM;mJ=WZ+99IrUrP$D-_ai68FLB=3pI$M=DFM8TBO-0MlRv+G%RPG92ZA; zBHwuxgsnn^l9t;Vep#i7MnbQE_uPvJ&wA2p&P3a!+{6Z7ga%^ET8}&Q*u}smep`CT zMK~!A@YinXE=r~VX#&=r=^mh>?XNwHX|Jb{psmsib*xS~?1u2L6uwC7Sz(0bN;4iP zIi&(6r^oduOB-mnx&22YbR^J|aIL&M!<2O_KeY7#;ewq1#)yv6?jYZ1o6Jp>*P$4( zIJ~wVMWDO)R9QuWq2GuLB@Vx*FuuzVQZ~_=RQ$;{1mKSD@DTUEP@Xpyk$sN`3l65A z7dQaE=CcE=PYy!HMyMz}(EM@T+kv||%+-igrwm4&@8P^&%?cr8YH!;$Hdwq{H8+OR zK0Q7GBhJriq|!>uvTJ5WoD9@F20!h~y_!6{B@k%N4?57T3t^J`1R`Fx&jNQK$#6|d zf&Y-~JED;9w3O8;9oovTl&aI;*tevO>aM7JR~(>vlW)RZKS$syQqPN7t!)j@!RF$_ zd5wG!JiZdQ~LQt)P|?i`vTR1w| zCUA;Q*ClUaqee_@HqF=%w_j;MmLj;ERv4S)v@yoW<0n^-_)l;i+hw4BZs-JZONp)w z@_%(hlPO^|GNspQN&%?i5EntmZ>F=dTJSFZbcz%TjsCDD@ntGuZxqD}hcSdU0(k1X z6P?4GznDv&8QfgB4)PnA$)&iR__dNJvUZBT_&PqDPrtx8ueuqI6y{nPnY2cC77KJm zrR}CEi)4JlzMX!)dxv-{H*mWGUEE|t@$sNt@H7$mblCT)J3K2?6E@ZM!v<5^t~Tcz zdqsWlq6eVqRELp6D|MOXtLrN-p@+_Gnp1M^UW?zVEOIMZHpA`ah^wJw;PcKYR<<2* zOh8k%e$;2>Ku72OY{-NYf-UJ(B(JECv1y_wJ~TjZ#uG=BpZH92eC-v!tFFXZV@N%x z^w43xuk~5Rmy??uL8n9@!-k=oAiJDLY7n)5+HYD-@eydCbMHDRU?I)QWQLUkf2!4f(mZ+@;w| zuqs00bf)6N^(DLyRwTR~zGNciN1$-?Et(E5lqO!YTXQFvNF-PLhQgzq)kV>27Mb@A zeU~e~!Tam=B#^1cbq>z-HN{^|J1xn8${_9DF%GO?DZPIQ@a-ns)qlQ2eRu;7m9kEp zX?h#+x(pT*D1Sr5rq}blaz)e3RHRO#OPqegipcyIz-OM+VneH}{%r%B|GeFDD?9`; z>?M5%xeK7~!6nEx>z1VGhQUQ4MmsM(chih;@C_7xQhSo){#3yZsD8f&RZ5Cx=xdvh znXY8@P-dHgYxLNvy_w%O&^l!Pr*)|5I15WpBfioa+Q*54WTgzdi=I0g?qEqo-2)9* zg#S~<16&v_?JT=seSI!^kI7K`g?=8GHR3>~N(XMU{d=#2My+4HX#*l9WB7Q69Nse$ z2GU1cGNsh)e-X2wmocm-=0>iF+3s|K_W~OkrNR~W1&JjgXotOt*fV)`S{mvL50QNe zFY4ZZFpzuosi7I~&WrH)2qiUyr+~N1Qdn($a=#JFMM{Q(`w&WZwxRq3*yI(G+}du( zB$_(3yW}5U8Z;%eFE~Mv3r)Z#Q_XDPq#5h)T}*@znUX{|M>HnyP? zvGS-x#+K=yu3>5)>{#@RXy!GPm~{I3yt6`Jm(rRby*x$aTb3f!A zjn2naz4wt?NH>l3aNQ4lFvWa<4bikfc>g;GzeK1~Xy=d5da@Uc{u2C}lsVck zp5-F&Oel+a_OJ_1ig6n6^3nOBkZ(h?ThC2km1^R-qotg5pw}v$_~wk?)1oDy--`8n zi*BuGtfuCB1g|76_)KG_vy_wG3K-sPKy8SsV=JB4;+_9oa_!~q*Kz_OL9}~N>8kF} ztHp7iQeoapIPjOAQk{ufngh>BHMre;otTAdDZ`PCC-!gmWUDAHuBv(J+InzPd zWxK{70218?G=DmPAN26&?nC6u96d+{j?Whfq#M<&9Qkxl8A{#CUiEx^r= z6>U|A>@e=(H(J$7jnDFUIFSxbZ?}N`#?BK2Let6UN_u0-*F@Q0sK(IoTQ%(&pR8gs ztT7tETCpRS((y}8W8IMYs93t=0IqXoF6j7B`zcGp5+ec9N6uvMrBT!<3Lb17pUEbV>u2eH(`1&NP+OVteZo` ztH4QX!83e=d!jm9BsK`&=&BGlw%xAjyc2(8gs)uqkRTS0+#;mZ&@L>DZsk{tte8Tw zz}o}3Z!1jCki#ALW0VDsC zdzQaqw?V{8#^_8Ml{AoJH&{%BtrxVm9nG+gEM(}hs%E6_h{z_9x6;1eO z7|R0^Y>^B=GPk|ttF~!feI-F6|lt-RKR%F%%K1HzWYVon?GI-jhPp?yzS&#QjC(8!R ziw6p#k|;5}>QIm6lex7q!smuO-1f@b%bOE1mZvc%K^=F#Q64}OuNY6dBHp@jRH>I8J&7@bo$iXk~geE#l2wY zOf-CGBxzI#O)t~8#ZN(weO8Kz_=mYfF<|1kM?itEjbs+2tvs4(VqWs_H9Lo2@ZDx! zo4*6IKMQ;#u$D#7^l+l~l-$ex6wv%j6Iol=!p)(@#}5Rg@xpg)l+8A1ubM$u@tj$c zJ2{p4%s%XMUlW4E??H2Qm!9$a;0>zWjUDonOMhehElYERayg>wbv0o_92 zk%A^*;be#W8R6O(jwD0smp>yM>c5O|fUN^4u$r-aqCrtmlCX?rx!jmgvXUk?&NlhdBDHtrfvV}V}MMYlz{j)@~8Qkjmt z7W;P>W7KZ{c1ngis+Ze`tnn7MwaP;^PkVt49$ich47D{<}fvGy-=kYIo>sGK*i5yH$O&5PMfN zxXw%l?meDgX>^0l>9~n&`@Kia_J5+5^J#(iLxSc(=b#WCN{0d?nD_w`^Gn`wAV%b| z(dPS&?oTb(K`g8Nd{Q)MP-M~T=9VkX#vcGP%1X_Uo-;kFH7f+q`~|xpOt#qb_8*i` zo7(DK4N?C-XAjyuX`8R6+M5|$Y^+^^8-+izIgcRRw{25uJhDY*r+4UaR5>HQYR=9SpxaeN&zmC{LpE75O8Xsv`2EXe?A{mtPU7NO z5+%y}0@ILWKR-K9UTMi=E$3y8wuz-2MB$}^WfblGzZK>s@83%| zycuLMvYqPz`VCz09Fw`g33~=;*>-38k=b>dtj@_#(cfu#X=J7!bd$B-y147M8PUW3 zzt_#C4AYTg0|%ol_%kT49#!IBZv&PTU>nGWQP2{=ehEnHPrEVXb|&5$7=@iD-+8*Q zKG$++K=UA<@GRCvG8w#g*Pdr&6K1#FVSf?AEDkmqzNGuCC^J%fXIiLaJxFy^cf9@u zBA`>6UsAR`qy z?;FdeUbXiy0cuS)3)mUJA|M46%^%y?;O(dmK51K!;7V!r8_3)^8y<}jv}}#}CPfd6 z>&#mg2|GIa*cR18T(*;cC5LgbPf@e)maM$%`+VD2l-g8K#Vf(8OSK+tILfkH zn9j<>NsW6AMeEe8K1@}zvUiXWX6A}p%CbJCXv|s@36G;?1^b6-s#phVHxn~uTr zlS>gLy??D>MkiTL?B7&g4s1}ebb}4i5b^u-9ZNb?#yYLL`KP}K9drZB?4ceY7Sjhv z9o@}2`h>25l3LHpt1vIPkcN=hQMjQ5yh5{h+Wur#*H@f|DOSAst$m@jkJ57j<3xQP z3<-3duKWA))JxELwYyVrK)W);cr_L_EnYg(oVPdor`09k8kGJ{is4DtuH5#^Sw*S; zX++c3jCf&Kk`rC9DFig4{c8wg^C@}_ie?J2V7q7zwe6i441^cDjQagM*AWC*`<=*=zOu=4c_B!0k_vuc@k7=xhW44#C zO>xASQPyrI;}O}@t^dq*MbpaBI>fRwqOB#fs8FMo&)>BoSDp{cu-xNQx2Qrsx3ibP z`~xD~x2-$Oe;T5K2~;b1zt;VhapVTddf%V4nFxeYwg+#v9hdf*+pGayaICgyrhT+l zQC%d&?>omCa0+m5XoN>^-LXv%(+C?GH=Ht-;H9ABP@f8PgG3DG~ewjFH~a` z3&E1qpR)`AlVKi@FA(-;`L9THO^F;lBGb41D8~7 zEo;a3r%HOc;WK4&0+JDNxTs{O!|O{npk)MmV7vB4ppI05k2d!?pWu!7*czh+b;Uzj z;^%v!YF@e74BuaS*;U@0_O=whOzZlFnByFR>@$@#92{)x(O4|e8SQKMIA$?@jicT<;7~nRkgK8^$X&$);1xpHi8+H4 zK~Hsz%7to@`E@hj)HV`ZqrwZRlOK$_z1+Sz776Y;BSx*K2S1*c1$$mi6!F{YpgA}d zWy*S|hc|v=aOE0In1>JWT!GjEkU&$8eqV!Cq>1P7m(C1LFaxr;&s_kIf*4&_T?#Pm z^)s9m8 znxL4HzIvgtZu}lm80c)RbIeC+HxU{i1Bt>TKUR%1A`FCnJ++WNYQ^aj*` zs6eStn?p?1DJnH;?{Bo)`@sEd{Et@Fnh|pfmE^+Ww38Xgc2Q)ee!EV@RBiEbV(j&5sJ%zQx zY5PSP_R-Xe{+>pQG2qGMW#Is*dI1y^Ud~W96k0E!0Hc`JzZk`0fl=(^zcGqYSMgiD z<{qG!UOGC&d~;$DP;QS3KVpm2*Ajjji*49@n%K{LIiL2|4u4ju+uPua@_}mmHqHZC z-M_3cB8l_F(b1rYqtS@+D>~s}5P4B8Z*F}pWw4|3;xEC^jKPrd#Bae$cS_nm>CM;l|{X&+y3$-ptCAlyi=&}9Zm{GcK~d1EPsi*UhV-q4@fHp$`*G+AjZGo2v$PyOy>oevWj z!(HMzSlrIlF)6qT5jSZSLT$B~Hr!r();?j^)+qrubd~+jc$4iqGBUMG2cRnCQPk_TiNUATR-NA)|BSyeD!>@oLIhrgL8x)aP#|SJ&x3#^aecG-%e$}KX1>+ubg-5M^|=#?V0M;u z-8Zyuu4;d1XWq`bFbgg!Yml<~E$V}Z7;#gjqNf-0+6Epqk|_$^F*w7-Ife8d$+Qd! z-nHD8BT$8@>*yWTtl?(%xmk@woIqqRcequ{u6^g1gBv$eh}LeQSzXPC^rg#Vaq~Do z1t+x($jGJa8favcL23`NIF zb(X1OKJcE?#;Sh@uCsNbSK$7XDx*6`n+2>ykI@yT*z@>J7AkRy%nIyd`u`LCuNi{L zihC_B=JECPQ(>gHrHZU_GhzEt+seRq4vgLVDUTg)r;f#LNJOdZFgC^6_u1lX-&MLU zK+QYMMek@0vIi+Xa6lpPeRH$-I7?@@=Dj#jBhTDrGst^lps`1kdb=2A(hV@@@|Cy6 z&G_LGi zVf>(J^67n?NYKppn8Fy{Vm~#pcnFr`odI#@R1?=pK!(f5o~L9*qU1JE{^+GsrTwUb z)8DM;4J73eXW=CLoI{a=P((6C649jFD&94HF;Ottx7jEy@HuJzgw$zF@aPQ5S>AHka12l!%)rZDvGJ%+j{d=y zek*Ht_$KCf*MI3jqUN<2`ZcnUF_*Rl^qqu?ahlb!M zzsqXwG!_HE571m+_2vM^nZ%_j0AkG=E4>*(W3@)a8vW*lDq7dPlw|5CBYjme5=E`jvlm{QO7a8#U!P(RqPsF4>*SHX0mlo7#rfCA>-w0)e;lt~Q4r;x16u)bMZVop-Jn-A*WQCxo`#8K>6JiW2(x^;`n6KqaV!WM)N)2A+3PFm7=wv9;Qob zj%x$aw!b3_bB2U0wJ#XW4yP)O`l%@SnnDq4nK!M#f|KsqITU&$)H>iry` zYpS^?DEgL&yoR0DeQ=w0fb~6J&@s#F5MsI1wTfZP+&gscM}YUVBSRI7AtQygDLHe= zBPQa3@RrZ!z8BXIEUoAm7b|CkG%7!ELF*3j0%vA&plA1%GbXTLDF-#(fR%Sj24d<5 z0(D_1xv*e9>1bA=IQyE8R*3m;9omUMwUy?|#x=-?(3M?1^Ke)c=S z_E=$F-3ayYh_SSFp+R~cy>0YOBR+PZyUH8hSDdfuZ4Z{epFB_ai$_Ep{Uged_*+Wl z#?B?83RI(Nxv6ULqe~mn&{VOBhs&%h(($)_m=LawKSx>9!hVx}r2Y?hJ4h?d?>J2b zklUJnf!sC%eENS%G5$wBeHQ}6$caRK+XS_7H{E=8@*|&ovPOX{qjaX#r(s>T!fvLa zz1SG*1$VQa7Oa+khEohXkVe0R$c*zcc+|?BGiKZ{Cj3wC<4P zq6n^_K%RQEzYpk~{OU(9ps6KZb-B69>>Pw?DHUYnUx2A_&f+;O0@2p6wyCLhkv^Oo$BmkY8{-9#vr zA4u2zSU`z$K}b}udM*ls_eVGTY+66~Dwdt$2L~+2hQSq_I^@)tYx??bZp@uy>H&AI zF$Jr8V?;sc@XToR)Vk2S{wpK&M64aQH{{aD4$&RiCWIuQ0*u3>Cs)fn;^kYuz^kon0zf zT-5vQEx&FHI;^rcDIs)%&u1sys;$~1*2+Ly=%77pJdiY`47CW5Grk`Dqi{X8q5Vfs z9K-G#vGr5KWKlN0zQycHwF8e#qHOH~#O|j`t~Tdy;3hk9Qd<}c#)edD-tK9!oR)!v zI|x`#Wx@tiR3rTOL6iNb3og{iZjYYADAlRNYC zs!M}D!s`#09@(xy>F>vc^Gvhuk|Uf5RQaNa!uWp}h&$5Ghy?6Lu#2c8KoZ1n5gDWR z#@7#h&+J*eft_xc8IQRLAG3J1d(I7=kc_Fii2|Z4Y0uWRIj66Cmh>Q1a^vsX6zGja zjH~C#RYP3zn)BpDw;k})jT?+p(pTu8QPvmDY-(I`ynGq9hfdkZk8uZV8jG*(+_h`I zNS-CGMvchpN-GA0o20Rxq|vlqIou*s$p`5*Mkk%FH)e{{wP>UWgFF-9j3T77jLPBr zDmEQeycu$7e1xPI+qp8O#`&5GZ7zAee_fFfqeZj*f$X6)pBx1jtAN^wO z_X9QkhFNy6resyAM7_D*!70W*%s(YW3&9K%5||YgeFp;&uW}I}SfQ2G-^l?odCt<1 z$VBSCnqt!B@taI$2A%w0chDCv;(AT~Nv;1kU>cSMfN7rr37bEP=LT5vXax`Fpv}Ui zuaNUHl^`FkjavykdgI}IYavk)8h0Oko@twng0yg&1Fu43T<$%5)#$sZF1!4LHriKH zL6@jRiygx=$za|Wz5^jfBKd{t*(YUC%~Rf_4&txC`C;!yi}A0<=btf;1bGu<9uCeK zKM|<>nppi4zdLNJC`kHv7}Ds!jkSdfcE;6{i7aBp0|OP=U0^eCXoULC<_!L5SzBED5}Zj^bvVx)*Kt13eO^NHhNTbk(a2|!z;<F=dD(X$2iA5FJ=!yn?ELZ7eoLjO(fEA0c0w;V zfH}l}Miwuqb4(_8KxH%$9l&VTIEALlgOJqZ7+f?5;7-BHH*V7{QOxmb*R_4DTkq5_wpxe1!=avNy2JGb!E1u2>>(0HA z{iHx8i=AU4?Dpncfjl>gIuk*-4vu=`L6r9R8@hF|1oiOx|E6F3^JvQcJNm_5#yA`G zPmFfzS-`I2!dRgi;#GC8|2<%645k>zRoQTaejb|K4lk^?}%?=z~nZQ?9F^B|603zuMD zFoBVM*zj%}3GbZ%BYK?gNJEtv2H9@C>R5A+A)wmJ6ORjU=#x z#WQsugCJ#WL@otWdez=+i`ZZ+md=sG5$I-GJ6A9~5x#SzN2h&f+K;b|nKP{I_HNF8r*L1Y7CFRlJFz#D zGkLA)lZe?EB}-u0?HoYp5J$BONL(O*Zz0G8{<1_Ic7*>@N?et3>Bn?L%{}Y^&r{}4 zOy`|^>N|W=dGS52IQ$MmJuo@HGi88KdR(v*)B?75&=dSNfom%_7GYJi$BlRw@$f{W z+~K(ex%zL7>q!9~8cU{QhR!HK}57 z=8aUI+40Nx6FRlE0{;NRgCm`_k~QrwdW}Sse0S?{pIrdZv}@pihPYhjP7LmJmaN;T z{+W&^oSIbO?@hl3aNgqe#U7j(RoB!BJ&>*XS0HS*yB?9aQcHLX8#EE^eYohAEZ%?TDOAS5}S{YSYSV{)B=g(R?=^N&KQv zvE$TNdi;La30`CQDnBqiFd788Y%!ORPN{l=Ls}pMI)EC`wH7e&;nwVvb0$k9*@4S^ z=g>0+Dgu9q0jsfje}}JBEVJ!UL*3^dr?QXw1K`DHt|CXgvK*s1~VBZwiRZqmX4nto#EcjDE~Sz|cK+%h zJ4JbPrT+eh0|2oV`xl7qAM!ln-$87h&>LyFG=guV2d%>l2!;T~m|gOHqo!$fp<*CTL?-teB}lb(~w*Ue}b9X(>#6-GZvw+;(u z4Viwn*fzT8`%W#5x5EJY7f+TUlSs@Cuoa%WX`d-Zo}R;rqZP3K7KIB@Nh}%)2Qd;Ec zLiR20to5PntEEI4+8RKfXg3ci6or5)|1%GeWpr;ndb$HlI zcIrPRjc)si5v`M0b(i4Mm#jpgzj}UA$lcT32O9f2HNPZs=+nm2l%>DP(Z7O1*S7`s zH@DL&aj-{v>stSshl*G(rZYUX>Ag10BR7gI5CK7oKhwNGH?+*%ILBkGck(lPMP)pW zH&htfWEeWg+D^Q>E%?p&@j^OJOE`$?%w-tIn68Bn`@|9VBoBElEh?^d6t zT&>1JOUh^t(hB9zTBcj9O)m;bL+&IaiSfit1G&fRm}JeVbT}$426D=3LY#9e#};?& zSdDJoVZS3bZj$oU7pddF)I{++VrLJc8u|cRo`w*8xp+nZf!Z3X_=9m=AjZIc8xDoo zdgZqIeDTu-IBjdMmM4WLl{I}AewUdhh`h<3GeO)FX*MR-jdg6cHK*F5KqDAMhg@WwY`|32%hd|-l!@I|V4i!||*Ztk&bL>a5SFnxM(<0 z(0NVim<4gsj+8gPMvN;@xG(9_>%!pk2*!wPec~nnlxF!B7giu&q zcOGwz2an`dxNGDqC|k(q#uEj_BCRpwqR1;1GZ3Q=zq43dPo>!}Cy1}G7X+>CjZF(0 zrwQ`hNSoAkE3CNG_1~29z0sg#&mc^Hc&ubXLAG*4p{R{c60iM(5dJgO?4q}9vA}oVb*YL07q; z+5_o$YtP~LHOkIiR`7zt_F^8Hu;jRHnbjEL8TELt!%j!;jSoWV2{Y}l&rbbLnd;-Y z6MHX^r{-Y(UIFrHl_z)8wPt92>IHsI!sDclP6xSvYpPvkP31$o;)0ulopsta zpO&(4rhd6AUfOMGV58brspSQPb?aF`StUFHb>}%G(HqhZdQ{mCCSw3YrFaMf+>aLxrSp=NHuVA{y?)UV_&rbUJyMrOe2{KN{uK$ z5)sW)!ZA^SIjyaS3y}fVWdSF%j^5GQ?&!Dou_5^QF6~Ky3Waa`zBUB*f`SPssEq~y z5YnujG`m9uY~|X2j~NhGZ7d6z{HKYI{NI@97=Vecm%XO#zYma3w~K)O7n?@`q^#%) zB$vCrjLA=oy#e1u&Zz7`6Qv-?q;g z;%@RxB&qKs{W$0#!4WC|`hIGky`lYh?V=29OIJs5X}qFV)qHHWx_wq1cy+ZFu9uBM zkmcwONwp(nU%ircx{UL&rr(eZ#TA>Tztg4PN57``_nJ=Gx$|InEZ+8X|bd z(hds|w|rcQgFlAh_yykUaWh{go)H2QxG1S>Bkqlheun&e8*ywAkjWgwb(^qdC`u!_ z_!Bb(7-C}91T5l`=zqsY~}P&|h$O zFAR;!_MO}kK+(>ea_b!9nRI%)dYfGqE$r1E%#A%YPFk8RyGx7XMR$q_iAt!!O~jL2 zXA>kB@?f-t-hBtpC_lqubmhGU|Db9C3+|=YHRlOGQG2wtXMOC=Eso zd34zS+J*sY|H)iRyO=or8Pj{@17bF|IZL8h^(*jUjm|%8RgISOC{uN(U62?(NH}{9 z_5A;0?9Jn${{OxIkx0^?77TNc8Zr z30c_uj;d;2w}I2tEHK5)Xh#^>pq|nWU0U>auA=wso?^P+jb4#UE_XC9*7~((MIO@k ztw&SV`)Vzn%UU4j3eGJA4 zG;&~*m6M6boz$iSS_8$wj4nWY_!)$qQf*_;yLIXc&`ER}QZc68A*loCPWo&>e}WuU zyzSDvgqeB*nDSb3rycw9EAom5ifj$VN=(*XqDmt~M!PNy$X6Fk)hAM zo;*GUA@p2|Zm_*}Zzx5^e2vUmrQH5z_BTGz>&W{K$SP67WM*%-M$E0CLYYXoFGej8 z#{n_Pqc-L*HZSIX=dF6_o5Ge;&tMT2SgQ|^43jVCCsn3Qr5IL>G!g00nnU*^CiiiM z$?ae6$7It+6RZw7z&*{od&fRyC3`s}%(X=A+S6w!!i>W!%dy6q!>rt-zKt-?h?>LY zyfj>~TB*z-;1P?h4P_=fq=~eQ>M{}#TavdLSn`r1>SWoE8MHF&p8>HmhXVOUnqeJq zCTw*ofD$;jY=GtB!{AOA8*>g)9bc+{cFo?k{llVbp?tmm{K6)3}^Ae_X8uGME!jt(! zl_a@f4LI;2wQOm?m%`}vn~GDFsCHQNp>ft0KG4WqiN2X z!)|>|`_WIh$>sNG8Q#SaYmey5?4W7g-3NC7w~OFi4QfSQ16>8yO5|uVCN*SiWRH0LP0*_jvAAYi`u z{Pw#ZGRujm86Qx-9I?Zlr23^ zEBjf-3i}&5)QoUlr?x+6ah}e5y6^7cdj|=zJlB0&U3eWs zmDhp3!=^Sd>6>ZtJ*}7cy7v2ZhwgE`yT60ZZJ%rF7OlL->=md2M!JR(A2n$u8qC2Q z=RVpIq-*iJThb<|*S-}WJYIL_no zb0JqjYOcMNC!Dq7Yutsj&{{n$qfUrODM_hyohMG7NjE}qhgoFpx8PDFdsXGRF)GL? z64p>`GJf?z;X2HY_W-%6p%4N1TYj&ku;aB@j9J35ZG1GQ$6}gda!|7z)y?4QV_(dr zysG;msB6Is>tHOqTjY}kaMu$*r|FC>y69ZO5bM z4r?V6a}H>Z+q*A$kgmCvPHe5$v4ZiXrDuwk^8}rU|H|inCrSqhV+F7AdB&C;0A!op z^c8(1t;19MynsFWENURK00+BPJzJN}0stcMv7K1tY z=crxy??>(bU(Jifn@cN}`WZzF@Xh^A%^>}&Yo7h@D$_>sqb`~p6UgCqUJdr9rj?QQJ4aMrOh8!80p@WOQ+{XAi4FqB&fR2eV%J{Je5b)^#jCsvUF~Lig zIq`1+@eb`T;^ez;poaT5>g%M(@ytEP#=ni1kvgCQX3>qA_7Y>G`b#Bt9OCiM3^>4v z)j)0+OSUC+VqIX*wh#>+(bmo#-V<5tuYdJmPL(33O4?YUFx`c_v8iU0n^7V>HRTc= z-4T&FCev>mK7m<(Js#-}cs}}bo34H$_agB3RSMlU>v4@MX%!PGWW$1=f7*T#z0#@@ zx`nHDl8w2B{EVJyHO42StiYV|m%!g3*cUFV%jQF_twBna#)V21pg+KZpEIA?jS*sQ zB*0h8j4VGdgPeU<`&F16hMVebr5h&OV77~1W5UJ=eI}S9w>onV?DP}(DBAEq@P{>SJ9I6f?|9Om&M2vBRzKRKrVc@I}1bGiX29&5Re~V zscbP5{=QN5Uq%D}zl;Xu|J7)KQWI$dKqV6Md@R5HMpjKUv~4fF;~0&f#`+Z?i`EHd z-;>W?{Z&23y$>6sa^`W)%Dt|Szk)@Dh-fSM+IK|1xU?S_QBYglY9{3FJ2!hdqtNBM zCXefE#Uk(4&Jy3b)hp`jko;_omZbFo6S3uXXE436Hmcd9wH?0rn&8mJM+kPJSG|;^ z7(Jt#E+%@&KfQ}t-X9*vn6K0OM|z}#3qEKQY&ruWq_()Cok{a_8pf zU&JXs`J^!)Ekh(RD+KgcCSTX!#qU2Wj`SUkI$0gOWZ?0rrQyOb;F$(AS+mPv^Q$C6 zB2cLlnrU)cqHEq{91Rtc041ZwVGk+Mu784m;+ zJ1*25&oX8Q5>f-T5z-Dk2&!zr{dfia68#mj0K18ytvw|IUUI+Xjaa)+gl_z9LMf35 z@v|z@c5wRa#C1<~Mg6Fy{iFh%+Mes+*Z3U`9jPmph&vwQGzOGy$mwG|3S+L~wGx`S z#e7J!gRiQDW&PoK3fyokd3mZhQAmzlRt58BJI9f|q7Ws^gIdH<& z$^od3#<~j?S4(iWSc$%4|JZ0VI1(OB}xbB+(i$MCRfx>W%LR21|t6lVdTEHtp; z{Uikmm1eom?v2&0ZybzIh*$dkw@BOk`p~yn>86D&IM>J@0BO|!;c#uw{N-?&0uC3H zl1Q781>u%!-9a9p$@D8h^ely#yXm-$n?E2qZO{GVlYLwu5Q`Uh!q7G6wriWh&{;5q z!nw7_%f{VlHd5Ad1LI<$d@@Jc)Td4GtPT)W91?$xH*j_SDacpxE2NC9{1#ScY;?dO z<;VrJ8Pk5YVsh#%<|dl8O!W^6%=f6KX2P=dZ=tAyGb0vazD1`On$n@<_( z-O|NEZpg)Ezmw2+;&}1J!@i)gXw%)9|GWwUavF6Tup0^}3MIZLFPjLlgS=+M{Y&T53VuRIUAUGcW%OVmOi3Q&DeRx z#%0aUd*XI9vb8)*?n4}#7NJ5%DLP~?Ge;(Rvu=sG8YG6$GY)aV+HMWX-r&aB)O~9$ zYY}K=j9Yp!uN!}5#(gY%g`E#4^j+%kv5APdZM?CO-| z0b)nE|1EZ;AKE%xQBh_Ep_P0^ojN9t+gvBEn`W5Sxn5CvUN(H${)l&J@H|I$eyhr0 zU8~>!s-Wbh{&`Ixzq5mGjMm*{Ry^lW%VJePfxKpR1;FnW^<2m~m&MuEV@=NVO_l=w z+G8&|9Da$DANc0ObR@EKEpXLecI?2$ng}ypwkc*Ty=T(MIHoPMv>l_ggQof{{m$ledLV;@!IemyUk|g0u?rch9 zLM73FtER2@M;3~Cs7yd4Re<=v4v{LBQO!i~*Z)xiRZ z*sOyQ1huKdWCkHY*(>xS2t-FC?S%y66w!qsNzn>-Z8h}yRjbbKx|juq@-n||CcyIV ztJ5?`(<>frCvRMs65bdg&*;0)tjfnW)qeYq;XWSn#(86r@+7`E@%x-3ULsyO)A>RA z%+zd*AQuMhHQ!Vj--!P@tyeuvZBpZ{6SG+HkmMKa8&!UX4?_Wikffc}@$Z!KLeUjS$ z^7^M*fH4lEKCcI~8Myy+WO%_*O-=#;nxXdh2V}LbDiG@VOpaZDZCi`D^9-6^t~Z?S zyQTWBLB8|6-)!z1r?E<`+9B7$hw8?j(E|8Fa&iCe{CwJ*oE~YSnP~lt&c~Zh*`fxH zXpdmfgSygm9ZqnGosEoX@`tKIZd;sfp2@cdxn+J;&>@9=w(WB>oJ(3Pey6;dy_g-t zmK`ZSeE9lvc|eP0Z4h)dNePPd-cQPd&0JB?aiN^+=^nr$v<{yaoZ<4#I+d68tqeJ* zCg!op;nVsmOu3vJqhJh{x$5iTnP8?^2xgOECq0T?KXyXzzL*UA6F;VU6;r>AP~D?L zAlrN0#QWK7RtIHk-ebU67)Jq_ZM{-yFyZ@LcvW#UtRAyE8neR83Efd*IxVu>BKMP{ zYP&b0)Z<1$=}B$$Il>0f6^XxU>F}sM<4ZX~A77$jez%x|m&bxhWs6B=`nucVW|V*r zoUo)BvEv%)O5Al_4Aa(5?`m?l_nEEnI8ZSFa!}b_&xK*p!K9I|4oCC8njwewq@ufP zMbip|b|FJPS~uTKAa0`fxsG4Gj^4l3_sb>TtGn|`1E-Bwl|%2)nO`FP`fLpK-~&-Jnfws8FnbjlAczKT ze}!%b8lY`45N{r^;P_s>&!ahDy9a=1dHKJImZ!flC@$RnXG^bk(~p~v?(40iQ?FfH z=~R^?b%xv#Qis=8pL;kcYqM-IWT+J^VP!lZ{N&LSRgPk0a~%4G*hJrK`yoZvw z?K#TY8t$v46tpp1bJz%Zx{$t-JukbEPG{t#Teu%I({cTm{%If*d;|y4HYsJ<06n|t zB5!R7vz1omJYbdQh+{9#zC7vHCdXrDs-sZ2EkXG-A{Jk{tt%!JrjW>DJbcplU>SR9 z;>9&z@fDft_ozDo`f)xPZ;8PnAK|h3C^s9ty;%^p?srqD(T2VRS^ppgQ1FxyI@I$i znGF}Mirtm52x#4AKhu1YPmk`9vM0euIiZvOU1?CXc(QLN62d(r)hM(?=RfL^VJR!2 zELD47vsQHndXTzZ1r(A`ueN+qVV47WXtj>{)TKMYi$=v6T!`!KvM`jv){QWr-1Td- zIS`usqn3g^Ut2&ay2HeW;=ya{<<;QYG8LU~orr37+Kg(x1&W$VW8aGPgVl1>yJ;v2 zUY8RgyTz`^0ImAo>OYb5#@jE46t(~n&z=1LjyFB}C-Ei~QUnb-gv}bYP6j?X-Qwp> zA!p$EQa=yb{O#}diPtjwvsIit!8;);sB=(^DK5*_us8cDB$S|D1t7~bvcuON)G;5{ zXll79sw>{!R!@(d{V|Nf3AI8kr>a|Wye!1+Tl$3#EckXFbB0YD|su-GplU)4f7n@E=8>`CQ7xOBvPX{Z`;M7CxD} zn{q?$=j=BJ+#K%WFY@R>_(yJAcXrF_vC%mOdh7n!JmXJ$bx0TjqI7vmj#Hxv(F!*_ z{;Jc@^MjlXqV2@}j&E9Ou~n63TIjOzCT70uk4ix|OovC@`BXO65d2Zai5w8Gw%On+ z$mofWVY(K#dr_vKv2M9xjd(mX3O`|NG*B!`-fbsDD%d?EFbv_!-48(GRQz74aODcb zNr6u{!(67H=J$_#U>96Q~kWM&)ZCb3UGEy2|r=0}X2 zHv##M4g$#$mtf^L@?WwjAb+W8gi;khd+UPyc|mA9x2xE`kK;qDaGNpLA9asRptoFJ z?Eg})hHQT+&~w0*d?cx7=y-{Yws*5b*A;-HI#{4_{1xkigr);MsIj zql4Locb(Z@lY=n*oclG@vV1G_NgDSmp>98@7qjd%1^*hEw9zeoyy?v=`~L2<GKsCx_aRppqfeh1LarI zk~Hin`7FJAF#>!}q|olJ_dIgdWA+K**GcB#o=H1H?RyMGbibLfJ%c$o2?hP3k}{r& z7WrmA^j5HbeADBGce-)FCrxW_>AjxCthcdWAhc?h6kPQHy_AtE%}Dw-MqYkCWtx3_ zF=_2(%>a9T0azw@>9bG4jEsKg6d|*xI&|s9UVEN5l7H*{K;V9CV}%SthN{^rInS}x znV6I|rq)P_;M>&_0<=i5*p-1NY)HNo$1y2VVWK<78f9nlNo_`C`DLs+!6uJt{nprs z+?FW<==_3~9NNGKsMq+jvQr26hy=PUDc7uHm=dPL;vqwdx)3~T_Q_`sD#t`;Hn0oq z`T~Gu`viEQaewzYjDJ=4&q#uP7|z@rer0`RRhwxL5f&N#KS6?MzCR$r^&PKOW!e&) zy1oUh#ET2=py!^TNyeEbU^V)fj)!Q^Wtj58=H65cE`2H`SI}`)Bk}r``EVhROlIK% z%GFKbiB7c)?d)@#lW<&&PDT00w~rhw7a3oYb}rek&VJ?8^!vuXdK0YRI{gw2G5;yr zSv|FA{*y0Se?QQ7+zei~HDY?rVR=^HO;?KtmI!SH^Awa4b9u-3+OgX=tEfRV+s+pOB?9zZpgmc8tP#`fR7~~)4OY>;IHdm^! zK4>wKf7U{bv`b2|Rq`$P>;XiqqFcB#x0^8RwpF)?T3@IQj zU6 z-h8qWcz_y>D3hIQVx<+cn$&^Gr9m@Nrsx$NAj4t(9iz)w)}OvP{X@vk-6ZraO3hE= zVbqkvQNRMIUK$`Ndvbx8Kq`B}fO@ByxZmmW<^Kgr%{_Yj7kaRjzV|=7tE2|Sru-W1 z!_(fh?I&YFKCK;*E=RQ|P{sfC0=`u8HyHx4AHWM3y}z{mr~h?Gr@9Ghf8gg1n!JAX zgA)5`+Z+UaRPVYoy%@PAodJcL^(@ho-QAdyQV(W&Kl*DZxuc~+-{>`@a=wpClFKur z%S z1V5ro^!{$JUB%4HJs53zDD7aDnU5=Hyb0!9=W*TVDAs-=&=;c#ow4ic;JRSo`sKH8 z1Sq6`{SDOfV8`X-z@89I)qyt@HI)wikgkM#t$`;_>k#6)zFM4gyYvu)@ zK1V1k+A$cpFfpRG;rJ5P-(qwa$N3jP>@!n>s2hoq=%#B5;-$6>b9$Nwp)+3&r1OQc z@+y>P+6Ck-d4qF@#?!@I>t2{rb10@QCiu0cnLgk2;)|n(Dwxgz21bI_qGoC*`K_x7 z+W8A1LH?*_wUQHju;CY%)9Z$0EVgHZ0Y0+qOwVmm;-Lg6-EP176GE8;_RASR_62&P z?ZZLx21vChCRvQk2p7i13@wy}Kk4#qS~4~#+}=^yY1 zBMPl!@fQEyshmvz^>sUdJ4 z>c=nTq8`X+Th@FPFHj6_)D&i8!bPhC{I{8Sjh3`vxRJ9nzts$evwf}ii z9C|8-lvF1rt-OVXm)1v^9GchWrq%5U`n4VP@^G7=q}GoPd@scq6(kj9XQIYlH!ZZ7 zpU&%e3zD&j#=Y8~03D@LWDuYy$*WexlRk|qEE}U#VT+FJ!<_i>9p^`B-TTTFGHf}J zc2|BOtL%^o&$PUn(rvHHKY-j$ErLi1fK?k`LAxEcJiNqb*!4hX&MfM2wQ}a%JpPAX zr14HPPt=t8j~ZpzeGO*q1BR&emm*I~S~H<$AwzEI;mbn_-n`$L)wJ+eCh9~Iqg#eSSoR7hP9n?f-%^smv0a`P8Kc4>Ydi?*Q_)0f^ zi!EvXCvvmO_5iI5SZ}$zfWgEu{iAOGtf=l(#Yrc6#|GfY^{RZ}5W^9}*=A3%03zwe2IU zzk$t{X?iLZN6b6I?cAB)AM|0#E|lobd=zbD)M^l11~ob;E~5&0#x}MKXFx=Z3m!-;;bdv9X0|1Pi&1}^XYOz`W}*`8EIy{@hnx_^-Q zE-d#Z!ja{%JrPQ(F}^>VSz0Qt*nD)dt~85T(+AIW)AzGFO2%OWxAV%m@#zL4p#QzN zyi6m#KXCU`F`zvFMhHl=f!V$5s4QQWKrM$@mZGe%Huz4(~W| zYzpL&{eWp?irelk^QAgIrtMZV42CUyg9gbdkgmOY)@p2PxrWmuCnRnAN z7)dvh{cP;D)fU@5y~8$Rj|G<*3=i9IDb%Ez{_B} z^5=3e;^o(gPdY}{ZSxyLipY+^oNHWgvHg@@z!g_%$@a=Pw=?Rn7a#pch?zJx`pavs zBXug$Cu`gEj6*|R17Z9xn*`w^_E zcw^k}FFt0UI~!VF0FrDBlVv0A(OfRAITHNQ+-i4gup$S?R*5NQ(qVBGg#D0pASAmO%W%TIYe9XNHkDo~bWFS4`4mw9aLm`1CxqL~H zk~gt_7kXAcz5>vi|IP^3%@BEMsOFPLaf_;9BM^8m{7(qAippOQ>Ln5o;wysECI+=` z%0sAJd~~XQ^m0F;SshjfDi^_SSxU?Y)g1n8_uZt9LCWXJqyANn@22`LQ_SHhm6*}; z_cQFibGqs59eo$G?QW+e=wn(tDY3_zV~JF%4|FVlGyJ14~*u`c+B$(VWZquI-F zSvQG}6ify2rDJQ|r1tDUZKNTLD8(ghcZy1GSBvl-UP6}=-uVg_aBiO!SH%7S7X)HH)@0|{)kagF*&ad)2G zE5p_M59ug|dE3GvdRF7yR0an6NFYi7wdzivK1;2Sux|{C$D=JmMT+cmx}Nb0>V(64 zfU?tAMeqMD0JswV!2_I29Q;G0tC8!Ht~6X8XF=xiS$-WVG=53UV12*&WH^XtpdA$? zPHqr(8eT9OtC|O9&Dku|Y zrRrR!psSQF4hNQVs|H+1i)W?E<@wFCbHbw#GMty{fzGHUL#=Ug7L z!t+-Ms?cMNlrcNhYFgGLBca#X?RR1oeir3U2Y>@ed^3IdJwbt2cRc&~_z+TSQq$6x zTu)W(`)LKmpcHRg8?JdtFzH^l8`Ua9v@UURA(WzY{9N$pBh*bxWS;tr(Xg2B%rOD5 zm6*pWpmSlZ@U3gYw5SWoS~-9eD9mWt3A|v(>GAI?x?QT1Bg;`KX)FvSN$sc*H=?N zV3dX^6CG!RL*bZ@!JuGI0+u`i;NWV{ayh-yk3Va{qkn4r*G^L^UCHZ5V)eMD$7aPr zyOKhH*)5Va0JUHm0ci1|V?3@7v~QR4^+|6_QkYfTpe9ln;f3rjKA5X!D`-;9(PgVI*3F@a!*CZ_R+AwmeB z%_r`Td;|7H7D9!i;C0F*=S1%M9F~XYTzO9h^sIRNi;-#S-Hi2?u&NmgM{~itTIR&^ z#R$XwEA&-kn$~>J0|dn{Pq3Z_2V4RxRw~a{IJL3XpRj6k2IUihXxq;t65j9lSH<@h zDV8R`oKL7G<;XaMuXMYnX3ps{#(J(sG&p@`e-?L3UpD0=5Wou0abBGNvfDBp$!g*U zvv7XQqKhXyqr{SgHI}zN8Eoa0>T!M-6Oy?vnCDsnc~r4<7rMdacEB#7^?SluBne^@ z5(dZki6=;>x5%Dxr|*Au4YPGQ9h)10o7~Bj^jaNoLv+Nh_>`z~DmX6B!;enx`3t>V zjt-ECtn59h!dM?8%Fc4FCu?~IO5<3FJmyHJqIws7CNXKzVJ*cM{>cQ>Ah~#ei({5m`_f^>`isy)xfaGl(5^oLz7WsE1Yc5Pk|YsfPh@I=)MDps&Mx>HS&bQ4{X8+QxNnzq-XErT?NOCe`VOy%^?1XV;p% z#x(Ahs{bDl;oiu(3$ycEyG{&#$i6@9Lb|B!zaC8mv4Ou z*FrOv&f(ez$VJMOhk2PCGM1~;-|aHsgI|Q^Gk{oJuEpRri(d`ToYQ6DCcceqEyoU9 zAoa;GX(tDuiSU5;82X*BW0>a(wmNGMOCwi&ZMB*b+iy1I>%S0Uj zDb!N(sHIIbXYThOv8GOc{+k0*@ImThrS}+uwG#C>avMX1gmuqG zyjL)4$XI16mNmewJ%Zu+lj+H3R$Q%`;D{dZr%-u@1o=mh+UoSSR`arq;VX3hc3oNk z++g>cx0GqX2OaNDVHwqwp4lPa*GxkR#bIlsE{B@l`HXiv&X$w8F2LuJt)17LK5yB# z%KjvF2NQG83L}7ctS75#?)w|YSfBl#!qyQt<$Bl ztGVg+xOC0@M`iO^)C>ECP z_O2hh+_!K){RS)Y!q|e^fUtc>Er+Vy@#{R$FXvr?HF~A)^f z>fwuFN%-0A!M(8MzYUn?0RdB*5F1Dv`rXX+dlWrrR(#+y>I95s z`EVU13&)uR9}d&TKfNCqIY*f{u)&95^TbB3k4_V&iz}KPJEzRdXX@W3VPXb)^3~_h z?(Vka$u*6eokp!JmPch<>|hW(3I=(tvP5Gp(sTtJ7GPu#79R7L%J?B>V;7FFZwl#G zhG~dM+bzKhP3Gn~*U*Rv&Q0^i_V%NqowTns5+A8*Ve7HqDX&vjVcVx+hAuLOW_}_1 z8$+=bgXh+xLX0Y!U01NPrMc9st`7hgR((%H?zT_CKrMsMDt1;rW#&Ow(>JadSvhPq z<%(U?;1bsK)k@8%B(7?P0Lf$&nm%li0M8 zGG(&~)45ek*_Yh+Rzj7T?rc!=5i%p*>?zm>e7>C=*=mSVG_ zJ|-+FH%JWH)ExUv<8(t`kh^`gm*AJE20B}vN|&(|zZAX>+DM!#O3eh=V|hk1X+oebSKn!sw>65F>x$c{;XsA!yXD1qG< z02#GM_bS$@sWkb3d(6sxftiBTCu4g>V+-87|9;?2v2@2jgpDCVlfn@)JfPP_fJzJ5 zc<#!%fdqZ+{q~es0d;1%I8+hB*HUrX`Le22z(Py19QgHXiykjMSy@<1U^bAr1gtu8 zhKg4j=p$@W)GWd&C!GZ%NiD7}^t)SzT&{EGbw2&mq%tD&TnoOZIECb$KQARNJuinL zvaACB+*umq*t`lMP&?d%*{K4Cl9E&oL(G-l=Y{QSgPei?t09ntHXkqBeO5OQGUMD? zvGT4s5#|!IbZdgn><(-b*{~E=dSDH%n8nD-o_3EDzJF*6Me5F9iA|f#KAT<33SBKu zGey{tujeiEV0U9N2))GC^549F>WKw8CnP`ab-ZKGkKU)gOhbV$+c=hq`M^W{SBSFTsi{_0ryk#mr@6LCmT8w8uj*)^_ zFKV$_n(jxk=qPUha0)hN?sHfNU``PNRBvBSwR~)P(G3q+!>-uY=5d$Qx^?Wf=ia*c zttZOsyS0l{S7lN1fo9&5s8iN_z{o}Tw8%GN!q(d#Gj=#~WdshBv z)d!ihxfCFX9trZe;fNSGOuGpXvi~EafFBJmUy99UQt|1Ju=|r4WIr?e2^9i{tXOFu z47A+1JfS*I5_j$#Ogdk9$xLv%Ik}1L6zBdGF@Fc z3NP^2;+2=~1(;v6?VFWjr6D2Pw}*K?OQ1bW1YV%Z9r3i|&tx1B_QQF#c%2l5Fi%U^ zv)!*iNa%yV(4tM-F~xgE2W?cWJDOxY@OvHXYAKjKdIQrF7K^`?%59DnfF_k{}MdRr*bl`v27MrH}ME>zN6@mdVKGvbaaUo=~p{MLr- zIUahh)JX7EoOt#gHyU3BK+<9$v5N5gQfND`6E)&cj3=s;|;dOgH#yMt2 zL~Uwu$>a1?I(O&~LaKMC>;*DPqu}tOHi+LU{hkoYXC@=XfO%tWWx42vjN4hcm`r_V zlZk8bTN%K57d)=*yZOQ2kEoN(>~-<+9roTMUAFx>BwjSB>c&E8EXAt-f&Brd9cENf z2y25nH6SwEn$v!0xrUJ(iG86Y4GPeQH+FWh%$Is$auH&-z}nmwFi_XmWbJIm#Lk%k zj{GIoo8ACs7;z^7a^fK%Vmls200(zy^kI$?!s7%M;4c+aDVtbKbxCWctyT}1;zpZV zc`uywEfv@XivZ7(1!DkvTD~i)=tgZYSD83IFM}|jYg|uaHUY*#R>JlE|#1W}FXs6%i%n%9;ov18rF%7mT33IJ^tXlXc;+1@a z!PZnC#w0Wx7Hc5@Z_U)uYzRx{WeMIK;Z`guFZ%~jF- zu2&=Q2S^+A-+{FMA!K*_VT;mOkt^m9~X_KU{BX$_nXj8xCSDL46=>?#-6-CTutc`&RZHT?VdK~lYT?_rsCOV zb0$y6Xd%iDZX~;Rr8-MwxI2xP2Le#`_~^{UFOJ^7L&N%3KkFMP|8Sr`Il5M85HFI4 zdX_w6h1)tqM^d^lLpYLg3djRie#L&>pbHv zb`;0@^$F71HCAgdViobwxuJ+{vg7w7rpoP`Obl(B3#S}589I5YCn*If7Ej$I<3iaF z!U^RUU2iB8=(#T#;Z4f{d^5scf4b@6=K9v`%Yvl|-Hlo12@6}SmE(bjGZeR*pcm=W zlbEnLs*iU~S%b}w6EYk$r+fDkKF?J`f)M50Kew;OaaVAopK7)y$?vuCENhP7hGMs& zA)hs>d*d`sc6g3aV=-84+d*L9_$Qn+?aU?eiNk}hhuhN{X2w;~fnuhpm4^<=)!3pf zY*)3o zC#6bZ^yRSlIpjYWyG6i{pX&AWQB`BTd7pg2MxpSIpmmsb+xK zKJ5$>NHD9619iv&_&*&UQf#2d;DAaM(9g)yLJtwh)j@+;tpKoZ0dv_;HnxMrNLjHf z5-|Pv@K_D<8wXcNSxAVFSd#co%ZmP+e3944hY5m($`1{Vtj%JH0wrcb>q{-WAw#}W z9u^tOtAigGBvRR@MZfjpVDo@ag}Elb8S+8!Be_ROu2g3!tb8cl{*@RUP1Qx%eCO?n z_h~N)IeZU3#}+7Gs(9jST&_t)0^ zv~7oRSB%d6UjFj^(y0NyyOEb@AJ`S*ladGWa-G_S5PBwN8~34}n*pXz;F4Qzey+v^ zmi14SGXcBndCDA%{1#jdKx{lb6xM?$vezb47)_~d&h&jutuGz6uCaq8Tf;t9`6l$@ zjlot5*04{IrC&Y%*3qXbkN~DC3~y&q^oUn74)Vxbwtz!e)#R)=UkoIsU|{B%Ozk6+ zm!!D4&GRbr+~)|NnjdCIL}~cxqY|zcHcwDyQ)Bw6ncJuVEm;1&f!_Gz6_VW>a$r) zGFx*xRAls*B&Cy!Zdz$L_~qca>6=M(XgNKJ)o^rUpW?{b^*%zZI@Xe7?2HJwMYcl!I0$oAq& zX>6vA1`sZ<7oCQevqwas)V~eq0`fWJr-d`9-n95xA8iON%e8a6iPwb(l-%)a{7+#x z(a3blYz}>&bAb{OuK}xS$%tS^OA`C$&K-vEDIdDZ$KJ2m8s}25_$I!Uc^%@l5T&mL z&4hl>GMlzCi>BwT$r`zi5jIxo&uCPC>GqIUyY8>sGNtz#c;9r`FqW{f#)2nbp`I~-nAG)L>*KD(P`a<~g2cI*BAH~L?y*qU z+s3lp*z-+aDO2FHafW(2|8*Y9&9}Uu@=fR?BaElaa$Yyq_&vAG=&}~?iCgbI)2*FN zLc$_?+MrTThy;hM!RAB_ny}+$fHSKpZs|KNg84I3>xcWiid*j4vp}ZR2P_8wK&lvk zu-DuDP*N43;#m0+(LWD-OAmM&eg8eQyEM+=`AWpU$XAj7+t{f6UfLkd1t@C+?|;x& zS>QJ)qQb4C?u^yZU*=u~_?PlA=3gS(LL%JZ%D*-%ZiwC%C+DNv_ziz@q6R;viir@p zk`runY11l0*WzBtxctYGI6JwML@xa z$_p9|7$Nm~21>m}&XZ}U2Ze~m(yw{7-|?3LS-Z^T+@G(I+b6MD+j*}%C{RP50 zzb1g03a|G3=z}#`Y)cg7T7&|e?AL|@l;HINA--!?F4HNGMKKj(tJ9Yy(^T>{TPpLw zUwo}^0Ka+yrcnHr+nHzbIdX%?6zrg zkaJYUPgdwGFuj<@1}gY7B4oXVu3m)%yraX*4=wRyH}!w~DcEiO_kvv+C0o%@-L6*l zR@1EsA?{aHwcJ}jqzEgu!H&DhG~`ch6DKwv8t)P{g0D@A@Sm3RpW$YIV>#>h1D10y zZI*U*g3fWKaa!2^p687n+A$yi#^5tPqm`N!dB;uaY?VB!xlLqk-r=G{pRQ)u1P7NB zVkSb#z%?YnkhPQV5F6!q&^GG<#ImNiL-UWlQZk%V;x;qcqU>4h;k;eHHJRz{>eiT&T+8mIOhF`E|j0T}rArY^gC_6R5kJpvmnG zPgdpyKzL=nc_9KzMw#EFRW5`CClpRFX5%vFzFl(-LO}j z)!PPLE?rH|Z_mDoI>G22Jx^DU(ce_}rPYC653IiohzUd6@0y4|8D=Q;S3j6grx_vyh4+S_wvp!_sdK1MDIamye1WT04i zdZyK_Vaa~FU?P8t%RRt8_0q>2^hI$75A%qqoeu+X0IjsJc-cF#;jt-Ri?3PDTaKtB zVsY!WlOP1YBiaJ)2Fv(z~|PrsK4T_a^fRs8rbm-pUWESi`#7bz9(K?!39?;p9z zr+HwpAE-CWU~@uEHfpFQq8sgGitV~Cmq1#Aik=Xbwfg2(ll6dj{L8#7=5Xa3a+8~S zDH6*U3|z=N{9MJ4Mt=}FK6hpV&N4VSVk{c4n+qxxK{tH0b2MZQ^J>~l6cz(|oLRri z)6d8wa&1~)PT~29XO-j#iA+{1ar^>$x4`{PvVKPFoJA|sziQ1lSE8%?r^x!_o-d3R z2CtXYF6{PpyAzrpFMr;8>>{}G9T<8%zQ3b`I=uFTaCL{7rj#J{CC6K3(`tgaJ#&|- z_jwlBV^x?JNaaB79T%~)Eh`5u3Mtzk74g+f2&d?1VE{(yIsR1&$zjJfrzo`%7VX0X zI+&!u^7&}Z=xmJBlCtp(9ag#au*$5Rr=L~_z1w#KW?&=!R07Zk z*?vF&xt#Ozb$>_F>_3rnR1TwQGk-B1%BO(0bhx^&aH29}&7Twh~DNFDzRV<7s#dpo!; zzU$0t93+!Y9Kvij8bK6s2^o8Kl}V>|tln*ipT57xeLv2}d0ppqpZDJ|?|HvJuj6$b z&qMN)e*1gJVJq;CNo$I&WY9J1nt-8&MQ%EOW^uV`Cn~1DB z`Kk$j;g_T8@6=qWeR1he6@z3gHEyN*RqUcN%bYr-rea?NO0d!4m+)dZbw)fRZvC!& zv|q>1K+$MdOS(GK1fl_Ga-N3AD@t3@R^LY!Q5&2pcCI2SoHm_0%|BFSqq=V%{?t!r zJw=QRabG{{gcIWo+G;^LJ!t!&8kPqG2Lnkx7TZt>Fk`As@0KFhQaS+i!amp%6k}c? zYF)+8w9Jw!bIEtjvQhH*<73iz1C~3G4Syn9u%T-z+wOeF_n`J^pToGyX+dtY5lbRB z+qR>aWrkqs=`4aXQm(Gd^HXGf0oSnlqY?{9*}~S{<{U|dgLH!tB58iwp=R9W3~GA; zxt-FZK9!TD-khUx9pOBOd1tX+`&?#C!)0kok^aVMG5XgBi9NZ%`)zp!ruD_f%c8#* z#IwF-dDp}EM0$dl(Pgwznfb{5)Di#;akx)npkJyVySBm~%-*;cvBRQ7TKB_#eg#$y zY(Az7+{%G~BQ7l;EUiCGo5$6yd=;_V(9cv~p9)!|dBu*Ct+v3>$&ap0U(2_r;rZbw%~(HnM{PSB_;u+IYGf&h`4V^gQ%*OZsY`=1%$ zwh5kQo6)zpSs&K5n>GAjata8&W12@J?{^y&V9MP{N++L>BIgU8E?>*MSI22)-+HqXe#&Qk+A1L#{=TGh!+Rx{%+l~ z%bWN1UI(0Ot$GU9m^-uK6=X)~e`o!4@K@!uo09_`_Kci%U${gMbrQaHp&7o3*ZkFf z?h~d^b&s?z{3Sk5&~&90w!_{Un`bU8D3?s(<^=5@CiL`mxO_vPD9NKS@(ty|9@x*a zwS2ib$c;5&N}WI*IKZ~ZuXBBU)ivn`ELg@9fDt5MUoc0NI{30t8^{DBfv7Au6~Sc zI39KQF=f=;^|k#ZDHHU=ePi-s0^03e0IBAL96938z<@5A~r@42+XR+V!2M}BM11?Z<{en9BW+JR5+xba9k?~ZJ z+RRFPT*J&&das8)b2j|m?_xyx#Q4Gz?o2^!-F32jt@rxdq+bOFriWkQ=rYAcIQ_Bs zRHbPJGPO?0;4C|8>??G2@t_56TI^ql|C*5sh!s3krGVR(wI2ayrKYL_lgy_8a$0WS zrj-9lU-}2WWexoR>(m~xBb!`EU^xUmm0$*h#n0Rm>_}!k$4t2_^6axJb2`US^krZv zB(#-UpzOp?VmdEL`NOQ#zIC~;#XY08&!;5Ap^1J|Ig3?iC{rO+aCAcT1An`lgmImz9t>lxdba~JV8{lUKnQHC0|_690^whMgGv3W_`EegBoI>>3&l=#5D z0F;@#dzB!{!-F$s$H2>@qms+Ue<-16C#C`SDKgJYrd=ayyG?_vTVK_~*e}LxoekY# z$~x-WywY&fCM_Al#8*}acB}QRrE7}~S{RhNQNhnpv&HWtOQNGg+C4`VZFIcH0zRJS zP1S4gmNrNFDeB)B2{_ewo)2iSFdAAjwvWHjPCs}w=;8~kaJKBslGUbt#zL0X(c`3^ zx)2D_S7TrcDh!eo>0V8~E#VMf{SU_EWx$9Axp*ePf}uqwRWu;>6%LeP|6Ggxlz*

K-6D;ZqX17~q@GgBXZV1L{ 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 orJzaVk9|kaG9C! znpC@mgm#A*7ZtlQmLq)4MBV=|JWEHA;c0wCO2mKSSFouK?@hG->3!+q0;U>u{m7U? zmcE32Hdpz&+RFrbaMC_*vozz84sXlIobM8Pls4fAYjDxWVL0`)_Lqu`8@a!U;YJo3 zoBr+rqVe4v`qWrffew1*Ko%{Yi2j^ZCJEN11j*Sd;FfQ{D4l(ufU@C9llhgwLFUcB zg4`?OGo{<0zepBaz8jU-aKi=pM z6lC+jJL;D%#V%b%FYQ2IfUnGH7NJ>Tte96P8C7Dg>UI zmw?02R8ya4ri1vB`Q*fxL!78EIAO|p`5~}OIF|#&$f7}id=dmbBO%lrkVEicHVK ztWQzT{+X8YuccEO7@HS9x!DiqVu~LRVwXXdMg!%A+}Xw0aH&=2s^tiT-HZa`K_xjr zwF5?iCQvHXNkPU#uXhRSSW%SXdwhYzTRFpwSrq)~F$?S;^r#(>_WoN*T95T7lcEIi ztY+h4GsA^r+-6&A9`Pw2ETfZ3hx--;p9$zs?y~G*1xSMxR^f`I%C(c9#?arvVvn%C z{|d?&R3OD+#vbdWOoIuhVCLOryLta^ObJ<7FW0?j5_30*E{ zIhH)ni5F3LLWP6ybNUB2xl(zkKOdY*K#hFCi+Jxf6JO_uKr~LE7JQ&ri zG>pAHV9_+{w2ao)TBDcI;$<@R8>(iacG3}<$B+psAba@LtsZ6^oPo56|AFEM8u#b^e|kc{Mh$td|1J!^X(%tV5OF2mK%9aK1P=OX$t0>QbiN6Z!qi*U0X{2bopOy$obP8I@Z%d@KyE4-2sO#)? z?T~u$rv$=O>7@t5_qc5EhbHmaW@gc?-b{lsulDpVDU6VVL?~2B+j^v_iT9ZFO+`%g zor8NYyut_1zlyY3wm9=oPs+LpW*6vp3o&e1yzu;edTK#^6DE6}*?w^!Zc3RWfO;xg+)$)g*hsNjlDf!iqcqUWx*N^$|doCWsEj7S&t zkQ`^u9`aMrFie^c_r|Fzu`j65gA=6H7Fv0{Cd z`0#-uj>NjsJy)|%MPm{po#8A!SFbnj_8Ky(jb_ZBYi@;+o?<7V$wS!l zfl2sg{+Yd4S6AG^?+KTVqJ1}F()2bTtmSk6tm=SW7e9yM`5mEgqbzr}4wyl-gRZ|` z6;9bhY4d1{u;T*(xT<6D#12pU2%DM7{CMo5Fdr?_F4C>R*`*-+jKVdLNkYK2!Dhy2 zu?UH-jKsVtS_!$Kt(I%7&|^-!Tp5X!4VOqN+MF=W5Iib2?gPe8o>S#vM;ze41s?`| KQ1agT&;K8yd~}-t From 5971981976fedeb917abdf4aa2d1a5472ef004fc Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Thu, 6 Apr 2023 15:46:07 +0200 Subject: [PATCH 060/146] clippy --- wgpu/examples/ray-cube/main.rs | 6 ++-- wgpu/src/backend/web.rs | 63 ++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/wgpu/examples/ray-cube/main.rs b/wgpu/examples/ray-cube/main.rs index f2ed53299b..64a4da67c6 100644 --- a/wgpu/examples/ray-cube/main.rs +++ b/wgpu/examples/ray-cube/main.rs @@ -142,7 +142,7 @@ impl AccelerationStructureInstance { Self::rows_to_affine(&self.transform) } pub fn set_transform(&mut self, transform: &Affine3A) { - self.transform = Self::affine_to_rows(&transform); + self.transform = Self::affine_to_rows(transform); } pub fn custom_index(&self) -> u32 { @@ -378,7 +378,7 @@ impl framework::Example for Example { label: None, flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, update_mode: wgpu::AccelerationStructureUpdateMode::Build, - max_instances: side_count*side_count, + max_instances: side_count * side_count, }); let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { @@ -608,7 +608,7 @@ impl framework::Example for Example { let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: None, color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view: &view, + view, resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 96b1a5b76a..223e6ba39f 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -819,6 +819,11 @@ impl crate::context::Context for Context { type PopErrorScopeFuture = MakeSendFuture Option>; + type BlasData = (); + type BlasId = ObjectId; + type TlasData = (); + type TlasId = ObjectId; + fn init(_instance_desc: wgt::InstanceDescriptor) -> Self { let global: Global = js_sys::global().unchecked_into(); let gpu = if !global.window().is_undefined() { @@ -1377,6 +1382,9 @@ impl crate::context::Context for Context { crate::BindingResource::TextureViewArray(..) => { panic!("Web backend does not support BINDING_INDEXING extension") } + crate::BindingResource::AccelerationStructure(_) => { + unimplemented!("Raytracing not implemented for web") + } }; web_sys::GpuBindGroupEntry::new(binding.binding, &mapped_resource) @@ -3107,6 +3115,61 @@ impl crate::context::Context for Context { .collect::(); pass.0.execute_bundles(&mapped); } + + fn device_create_blas( + &self, + _device: &Self::DeviceId, + _device_data: &Self::DeviceData, + _desc: &crate::CreateBlasDescriptor<'_>, + _sizes: wgt::BlasGeometrySizeDescriptors, + ) -> (Self::BlasId, Option, Self::BlasData) { + unimplemented!("Raytracing not implemented for web"); + } + + fn device_create_tlas( + &self, + _device: &Self::DeviceId, + _device_data: &Self::DeviceData, + _desc: &crate::CreateTlasDescriptor<'_>, + ) -> (Self::TlasId, Self::TlasData) { + unimplemented!("Raytracing not implemented for web"); + } + + fn command_encoder_build_acceleration_structures_unsafe_tlas<'a>( + &'a self, + _encoder: &Self::CommandEncoderId, + _encoder_data: &Self::CommandEncoderData, + _blas: impl Iterator>, + _tlas: impl Iterator>, + ) { + unimplemented!("Raytracing not implemented for web"); + } + + fn command_encoder_build_acceleration_structures<'a>( + &'a self, + _encoder: &Self::CommandEncoderId, + _encoder_data: &Self::CommandEncoderData, + _blas: impl Iterator>, + _tlas: impl Iterator>, + ) { + unimplemented!("Raytracing not implemented for web"); + } + + fn blas_destroy(&self, _blas: &Self::BlasId, _blas_data: &Self::BlasData) { + unimplemented!("Raytracing not implemented for web"); + } + + fn blas_drop(&self, _blas: &Self::BlasId, _blas_data: &Self::BlasData) { + unimplemented!("Raytracing not implemented for web"); + } + + fn tlas_destroy(&self, _tlas: &Self::TlasId, _tlas_data: &Self::TlasData) { + unimplemented!("Raytracing not implemented for web"); + } + + fn tlas_drop(&self, _tlas: &Self::TlasId, _tlas_data: &Self::TlasData) { + unimplemented!("Raytracing not implemented for web"); + } } pub(crate) type SurfaceOutputDetail = (); From 386fdba441de9a3e2e1bebd4bf1491c60d1c5d7a Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Fri, 7 Apr 2023 10:53:29 +0200 Subject: [PATCH 061/146] WIP validation (alignments) --- wgpu-core/src/command/ray_tracing.rs | 50 +++++++++++++++++++--------- wgpu-core/src/ray_tracing.rs | 6 ++++ wgpu-types/src/lib.rs | 6 ++++ 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index cdb2245f00..f9c09a4f66 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -152,13 +152,6 @@ impl Global { for (i, mesh) in triangle_geometries.enumerate() { let size_desc = match &blas.sizes { &wgt::BlasGeometrySizeDescriptors::Triangles { ref desc } => desc, - // _ => { - // return Err( - // BuildAccelerationStructureError::IncompatibleBlasBuildSizes( - // entry.blas_id, - // ), - // ) - // } }; if i >= size_desc.len() { return Err( @@ -285,6 +278,13 @@ impl Global { wgt::IndexFormat::Uint16 => 2, wgt::IndexFormat::Uint32 => 4, }; + if mesh.index_buffer_offset.unwrap() % index_stride != 0 { + return Err( + BuildAccelerationStructureError::UnalignedIndexBufferOffset( + index_id, + ), + ); + } let index_buffer_size = mesh.size.index_count.unwrap() as u64 * index_stride; @@ -362,7 +362,16 @@ impl Global { { input_barriers.push(barrier); } - + if mesh.transform_buffer_offset.unwrap() + % wgt::TRANSFORM_BUFFER_ALIGNMENT + != 0 + { + return Err( + BuildAccelerationStructureError::UnalignedTransformBufferOffset( + transform_id, + ), + ); + } if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { return Err( BuildAccelerationStructureError::InsufficientBufferSize( @@ -764,13 +773,6 @@ impl Global { for (i, mesh) in triangle_geometries.enumerate() { let size_desc = match &blas.sizes { &wgt::BlasGeometrySizeDescriptors::Triangles { ref desc } => desc, - // _ => { - // return Err( - // BuildAccelerationStructureError::IncompatibleBlasBuildSizes( - // entry.blas_id, - // ), - // ) - // } }; if i >= size_desc.len() { return Err( @@ -897,6 +899,13 @@ impl Global { wgt::IndexFormat::Uint16 => 2, wgt::IndexFormat::Uint32 => 4, }; + if mesh.index_buffer_offset.unwrap() % index_stride != 0 { + return Err( + BuildAccelerationStructureError::UnalignedIndexBufferOffset( + index_id, + ), + ); + } let index_buffer_size = mesh.size.index_count.unwrap() as u64 * index_stride; @@ -974,7 +983,16 @@ impl Global { { input_barriers.push(barrier); } - + if mesh.transform_buffer_offset.unwrap() + % wgt::TRANSFORM_BUFFER_ALIGNMENT + != 0 + { + return Err( + BuildAccelerationStructureError::UnalignedTransformBufferOffset( + transform_id, + ), + ); + } if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { return Err( BuildAccelerationStructureError::InsufficientBufferSize( diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index da568b2581..56c7436f5d 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -65,6 +65,12 @@ pub enum BuildAccelerationStructureError { #[error("Buffer {0:?} associated index buffer sizes invalid (less then three indices)")] EmptyIndexBuffer(BufferId), + #[error("Buffer {0:?} associated offset doesn't align with the index type")] + UnalignedIndexBufferOffset(BufferId), + + #[error("Buffer {0:?} associated offset is unaligned")] + UnalignedTransformBufferOffset(BufferId), + #[error("Buffer {0:?} associated index count not divisible by 3 (count: {1}")] InvalidIndexCount(BufferId, u32), diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 1dfd964546..d23e01d901 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6288,3 +6288,9 @@ bitflags::bitflags!( } ); impl_bitflags!(AccelerationStructureGeometryFlags); + +/// Alignemnet requirement for transform buffers used in acceleration structure builds +pub const TRANSFORM_BUFFER_ALIGNMENT: BufferAddress = 16; + +/// Alignemnet requirement for instanc buffers used in acceleration structure builds +pub const INSTANCE_BUFFER_ALIGNMENT: BufferAddress = 16; From e4f4ec40b07985a23e7c9ffabc23a74820764337 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Fri, 7 Apr 2023 10:57:37 +0200 Subject: [PATCH 062/146] added blas input alignment requirement --- wgpu-hal/src/vulkan/device.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index bd1e2784d3..05438423d0 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -841,10 +841,10 @@ impl crate::Device for super::Device { desc.memory_flags.contains(crate::MemoryFlags::TRANSIENT), ); - let alignment_mask = if desc - .usage - .contains(crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT) - { + let alignment_mask = if desc.usage.intersects( + crate::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT + | crate::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) { 16 } else { req.alignment From 9d7d11d72303a3952628301c1bdb5d2d1483c8fe Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Fri, 7 Apr 2023 19:03:44 +0200 Subject: [PATCH 063/146] more validation --- wgpu-core/src/command/ray_tracing.rs | 25 +++++++++++++++---------- wgpu-core/src/device/ray_tracing.rs | 16 +--------------- wgpu-core/src/ray_tracing.rs | 15 +++++++++++---- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index f9c09a4f66..8677f9dbe7 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -20,7 +20,6 @@ use std::{cmp::max, iter, num::NonZeroU64, ops::Range, ptr}; use super::BakedCommands; -// TODO: a lot impl Global { pub fn command_encoder_build_acceleration_structures_unsafe_tlas<'a, A: HalApi>( &self, @@ -421,7 +420,7 @@ impl Global { } let scratch_buffer_offset = scratch_buffer_blas_size; - scratch_buffer_blas_size += blas.size_info.build_scratch_size; // TODO Alignment + scratch_buffer_blas_size += blas.size_info.build_scratch_size; blas_storage.push(( blas, @@ -483,7 +482,7 @@ impl Global { }); let scratch_buffer_offset = scratch_buffer_tlas_size; - scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; // TODO Alignment + scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; tlas_storage.push(( tlas, @@ -527,7 +526,7 @@ impl Global { } hal::BuildAccelerationStructureDescriptor { entries, - mode: hal::AccelerationStructureBuildMode::Build, // TODO + mode: hal::AccelerationStructureBuildMode::Build, flags: blas.flags, source_acceleration_structure: None, destination_acceleration_structure: blas.raw.as_ref().unwrap(), @@ -545,7 +544,7 @@ impl Global { } hal::BuildAccelerationStructureDescriptor { entries, - mode: hal::AccelerationStructureBuildMode::Build, // TODO + mode: hal::AccelerationStructureBuildMode::Build, flags: tlas.flags, source_acceleration_structure: None, destination_acceleration_structure: tlas.raw.as_ref().unwrap(), @@ -1042,7 +1041,7 @@ impl Global { } let scratch_buffer_offset = scratch_buffer_blas_size; - scratch_buffer_blas_size += blas.size_info.build_scratch_size; // TODO Alignment + scratch_buffer_blas_size += blas.size_info.build_scratch_size; blas_storage.push(( blas, @@ -1074,7 +1073,7 @@ impl Global { } let scratch_buffer_offset = scratch_buffer_tlas_size; - scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; // TODO Alignment + scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; let first_byte_index = instance_buffer_staging_source.len(); @@ -1082,7 +1081,11 @@ impl Global { let mut instance_count = 0; for instance in entry.instances.flatten() { - // TODO validation + if instance.custom_index >= (1u32 << 24u32) { + return Err(BuildAccelerationStructureError::TlasInvalidCustomIndex( + entry.tlas_id, + )); + } let blas = cmd_buf .trackers .blas_s @@ -1186,7 +1189,7 @@ impl Global { } hal::BuildAccelerationStructureDescriptor { entries, - mode: hal::AccelerationStructureBuildMode::Build, // TODO + mode: hal::AccelerationStructureBuildMode::Build, flags: blas.flags, source_acceleration_structure: None, destination_acceleration_structure: blas.raw.as_ref().unwrap(), @@ -1202,7 +1205,7 @@ impl Global { } hal::BuildAccelerationStructureDescriptor { entries, - mode: hal::AccelerationStructureBuildMode::Build, // TODO + mode: hal::AccelerationStructureBuildMode::Build, flags: tlas.flags, source_acceleration_structure: None, destination_acceleration_structure: tlas.raw.as_ref().unwrap(), @@ -1340,6 +1343,7 @@ impl BakedCommands { &mut self, blas_guard: &mut Storage, BlasId>, ) -> Result<(), ValidateBlasActionsError> { + profiling::scope!("CommandEncoder::[submission]::validate_blas_actions"); let mut built = FastHashSet::default(); for action in self.blas_actions.drain(..) { match action.kind { @@ -1371,6 +1375,7 @@ impl BakedCommands { blas_guard: &Storage, BlasId>, tlas_guard: &mut Storage, TlasId>, ) -> Result<(), ValidateTlasActionsError> { + profiling::scope!("CommandEncoder::[submission]::validate_tlas_actions"); for action in self.tlas_actions.drain(..) { match action.kind { crate::ray_tracing::TlasActionKind::Build { diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index d894f4dac5..6cd91950a7 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -11,9 +11,6 @@ use crate::{ use hal::{AccelerationStructureTriangleIndices, Device as _}; impl Device { - // TODO: - // validation - // comments/documentation fn create_blas( &self, self_id: id::DeviceId, @@ -28,9 +25,8 @@ impl Device { Vec::>::with_capacity(desc.len()); for x in desc { if x.index_count.is_some() != x.index_format.is_some() { - return Err(CreateBlasError::Unimplemented); + return Err(CreateBlasError::MissingIndexData); } - // TODO more validation let indices = x.index_count .map(|count| AccelerationStructureTriangleIndices:: { @@ -89,9 +85,6 @@ impl Device { }) } - // TODO: - // validation - // comments/documentation fn create_tlas( &self, self_id: id::DeviceId, @@ -99,7 +92,6 @@ impl Device { ) -> Result, CreateTlasError> { debug_assert_eq!(self_id.backend(), A::VARIANT); - // TODO validate max_instances let size_info = unsafe { self.raw.get_acceleration_structure_build_sizes( &hal::GetAccelerationStructureBuildSizesDescriptor { @@ -155,9 +147,6 @@ impl Device { } impl Global { - // TODO: - // tracing - // comments/documentation pub fn device_create_blas( &self, device_id: id::DeviceId, @@ -206,9 +195,6 @@ impl Global { (id, None, Some(error)) } - // TODO: - // tracing - // comments/documentation pub fn device_create_tlas( &self, device_id: id::DeviceId, diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 56c7436f5d..8ce2c39fa7 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -1,11 +1,11 @@ /// Ray tracing /// Major missing optimizations (no api surface changes needed): -/// - use custom tracker to track build state instead of mutex +/// - 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)) +/// - ([non performance] extract function in build (rust function extraction with guards is a pain)) use std::{num::NonZeroU64, slice}; use crate::{ @@ -25,8 +25,10 @@ pub enum CreateBlasError { Device(#[from] DeviceError), #[error(transparent)] CreateBufferError(#[from] CreateBufferError), - #[error("Unimplemented Blas error: this error is not yet implemented")] - Unimplemented, + #[error( + "Only one of 'index_count' and 'index_format' was provided (either provide both or none)" + )] + MissingIndexData, } #[derive(Clone, Debug, Error)] @@ -85,6 +87,11 @@ pub enum BuildAccelerationStructureError { #[error("Blas {0:?} is invalid or destroyed")] InvalidBlas(BlasId), + #[error( + "Tlas {0:?} an associated instances contains an invalid custom index (more than 24bits)" + )] + TlasInvalidCustomIndex(TlasId), + #[error("Blas {0:?} is invalid or destroyed (for instance)")] InvalidBlasForInstance(BlasId), From 2dd47a6afeb7901ebc82a7f91f04b32ae9f805fa Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sun, 9 Apr 2023 13:33:49 +0200 Subject: [PATCH 064/146] Documentation --- wgpu-types/src/lib.rs | 46 +++++++------ wgpu/src/lib.rs | 157 ++++++++++++++++++++++++++---------------- 2 files changed, 124 insertions(+), 79 deletions(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index d23e01d901..e8cf9ced2a 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6170,28 +6170,30 @@ impl Default for InstanceDescriptor { #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "trace", derive(serde::Serialize))] #[cfg_attr(feature = "replay", derive(serde::Deserialize))] -/// TODO Docu +/// Descriptor for all size definiing attributes of a single triangle geometry inside a bottom level acceleration structure. pub struct BlasTriangleGeometrySizeDescriptor { - /// TODO Docu + /// Format of a vertex position. pub vertex_format: VertexFormat, - /// TODO Docu + /// Number of vertices. pub vertex_count: u32, - /// TODO Docu + /// Format of an index. Only needed if an index buffer is used. + /// If `index_format` is provided `index_count` is required. pub index_format: Option, - /// TODO Docu + /// Number of indices. Only needed if an index buffer is used. + /// If `index_count` is provided `index_format` is required. pub index_count: Option, - /// TODO Docu + /// Flags for the geometry. pub flags: AccelerationStructureGeometryFlags, } #[derive(Clone, Debug)] #[cfg_attr(feature = "trace", derive(serde::Serialize))] #[cfg_attr(feature = "replay", derive(serde::Deserialize))] -/// TODO Docu +/// Descriptor for all size definiing attributes of all geometries inside a bottom level acceleration structure. pub enum BlasGeometrySizeDescriptors { - /// TODO Docu + /// Triangle geometry version. Triangles { - /// TODO Docu + /// Descriptor for each triangle geometry. desc: Vec, }, } @@ -6200,11 +6202,13 @@ pub enum BlasGeometrySizeDescriptors { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "trace", derive(serde::Serialize))] #[cfg_attr(feature = "replay", derive(serde::Deserialize))] -/// TODO Docu +/// Update mode for acceleration structure builds. pub enum AccelerationStructureUpdateMode { - /// TODO Docu + /// Allwasy perform a full build. Build, - /// TODO Docu + /// If possible, perform an incremental update. + /// Not advised for major topology changes. + /// (Usefull for e.g. skinning) PreferUpdate, } @@ -6212,13 +6216,13 @@ pub enum AccelerationStructureUpdateMode { #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "trace", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] -/// TODO Docu +/// Descriptor for creating a bottom level acceleration structure. pub struct CreateBlasDescriptor { - /// TODO Docu + /// Label for the bottom level acceleration structure. pub label: L, - /// TODO Docu + /// Flags for the bottom level acceleration structure. pub flags: AccelerationStructureFlags, - /// TODO Docu + /// Update mode for the bottom level acceleration structure. pub update_mode: AccelerationStructureUpdateMode, } @@ -6237,15 +6241,15 @@ impl CreateBlasDescriptor { #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "trace", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] -/// TODO Docu +/// Descriptor for creating a top level acceleration structure. pub struct CreateTlasDescriptor { - /// TODO Docu + /// Label for the top level acceleration structure. pub label: L, - /// TODO Docu + /// Number of instances that can be stored in the acceleration structure. pub max_instances: u32, - /// TODO Docu + /// Flags for the bottom level acceleration structure. pub flags: AccelerationStructureFlags, - /// TODO Docu + /// Update mode for the bottom level acceleration structure. pub update_mode: AccelerationStructureUpdateMode, } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 47703f6eac..3de13b0e3e 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -2245,7 +2245,9 @@ impl Device { DynContext::device_stop_capture(&*self.context, &self.id, self.data.as_ref()) } - /// Creates a [`Blas`]. + /// Create a bottom level acceleration structure, used inside a top level acceleration structure for ray tracing. + /// - desc: The descriptor of the acceleration structure. + /// - sizes: Size descriptor limiting what can be built into the acceleration structure. pub fn create_blas( &self, desc: &CreateBlasDescriptor, @@ -2267,7 +2269,8 @@ impl Device { } } - /// Creates a [`Tlas`]. + /// Create a top level acceleration structure, used for ray tracing. + /// - desc: The descriptor of the acceleration structure. pub fn create_tlas(&self, desc: &CreateTlasDescriptor) -> Tlas { let (id, data) = DynContext::device_create_tlas(&*self.context, &self.id, self.data.as_ref(), desc); @@ -2973,9 +2976,16 @@ impl CommandEncoder { DynContext::command_encoder_pop_debug_group(&*self.context, id, self.data.as_ref()); } - /// Build bottom and top level acceleration structures + /// Build bottom and top level acceleration structures. + /// See [`build_acceleration_structures`] for the safe version and more details. + /// /// # Safety - /// TODO + /// + /// - The contents of the raw instance buffer must be valid for the underling api. + /// - All bottom level acceleration structures, referenced in the raw instance buffer must be valid and built, + /// when the corresponding top level acceleration structure is built. (builds may happen in the same invocation of this function). + /// - At the time when the top level acceleration structure is used in a bind group, all associated bottom level acceleration structures must be valid, + /// and built (no later than the time when the top level acceleration structure was built). pub unsafe fn build_acceleration_structures_unsafe_tlas<'a>( &mut self, blas: impl IntoIterator>, @@ -3029,7 +3039,24 @@ impl CommandEncoder { ); } - /// Build bottom and top level acceleration structures + /// Build bottom and top level acceleration structures. + /// - blas: Iterator of bottom level acceleration structure entries to build + /// For each entry, the provided size descriptor must be strictly smaller or equal to the descriptor given at bottom level acceleration structure creation: + /// - Less or equal number of geometries + /// - Same kind of geometry (with index buffer or without) (same vertex/index format) + /// - Same flags + /// - Less or equal number of vertices + /// - Less or equal number of indices (if applicable) + /// - tlas: iterator of top level acceleration structure packages to build + /// + /// A bottom level acceleration structure may be build and used as a reference in a top level acceleration structure in the same invocation of this function. + /// + /// # Bind group usage + /// + /// When a top level acceleration structure is used in a bind group, some validation takes place: + /// - The top level acceleration structure is valid and has been built. + /// - All the bottom level acceleration structures referenced by the top level acceleration structure are valid and have been built prior, + /// or at same time as the containing top level acceleration structure. pub fn build_acceleration_structures<'a>( &mut self, blas: impl IntoIterator>, @@ -4648,75 +4675,78 @@ impl Display for Error { } } -/// TODO Docu +/// Descriptor for the size defining attributes of a triangle geometry, for a bottom level acceleration structure. pub type BlasTriangleGeometrySizeDescriptor = wgt::BlasTriangleGeometrySizeDescriptor; static_assertions::assert_impl_all!(BlasTriangleGeometrySizeDescriptor: Send, Sync); -/// TODO Docu +/// Descriptor for the size defining attributes, for a bottom level acceleration structure. pub type BlasGeometrySizeDescriptors = wgt::BlasGeometrySizeDescriptors; static_assertions::assert_impl_all!(BlasGeometrySizeDescriptors: Send, Sync); -/// TODO Docu +/// Flags for an acceleration structure. pub type AccelerationStructureFlags = wgt::AccelerationStructureFlags; static_assertions::assert_impl_all!(AccelerationStructureFlags: Send, Sync); -/// TODO Docu +/// Flags for a geometry inside a bottom level acceleration structure. pub type AccelerationStructureGeometryFlags = wgt::AccelerationStructureGeometryFlags; static_assertions::assert_impl_all!(AccelerationStructureGeometryFlags: Send, Sync); -/// TODO Docu +/// Update mode for acceleration structure builds. pub type AccelerationStructureUpdateMode = wgt::AccelerationStructureUpdateMode; static_assertions::assert_impl_all!(AccelerationStructureUpdateMode: Send, Sync); -/// TODO Docu +/// Descriptor to create bottom level acceleration structures. pub type CreateBlasDescriptor<'a> = wgt::CreateBlasDescriptor>; static_assertions::assert_impl_all!(CreateBlasDescriptor: Send, Sync); -/// TODO Docu +/// Descriptor to create top level acceleration structures. pub type CreateTlasDescriptor<'a> = wgt::CreateTlasDescriptor>; static_assertions::assert_impl_all!(CreateTlasDescriptor: Send, Sync); #[derive(Debug)] -/// TODO Docu +/// Definition for a triangle geometry. +/// The size must match the rest of the structures fields, otherwise the build will fail. +/// (e.g. if a index count is present in the size, the index buffer must be present as well.) pub struct BlasTriangleGeometry<'a> { - /// TODO Docu + /// Sub descriptor for the size defining attributes of a triangle geometry. pub size: &'a BlasTriangleGeometrySizeDescriptor, - /// TODO Docu + /// Vertex buffer. pub vertex_buffer: &'a Buffer, - /// TODO Docu + /// Offset into the vertex buffer as a factor of the vertex stride. pub first_vertex: u32, - /// TODO Docu + /// Vertex stride. pub vertex_stride: wgt::BufferAddress, - /// TODO Docu + /// Index buffer (optional). pub index_buffer: Option<&'a Buffer>, - /// TODO Docu + /// Index buffer offset in bytes (optional, required if index buffer is present). pub index_buffer_offset: Option, - /// TODO Docu + /// Transform buffer containing 3x4 (rows x columns, row mayor) affine transform matrices `[f32; 12]` (optional). pub transform_buffer: Option<&'a Buffer>, - /// TODO Docu + /// Transform buffer offset in bytes (optional, required if transform buffer is present). pub transform_buffer_offset: Option, } static_assertions::assert_impl_all!(BlasTriangleGeometry: Send, Sync); #[derive(Debug)] -/// TODO Docu +/// Geometries for a bottom level acceleration structure. pub enum BlasGeometries<'a> { - /// TODO Docu + /// Triangle geometry variant. TriangleGeometries(&'a [BlasTriangleGeometry<'a>]), } static_assertions::assert_impl_all!(BlasGeometries: Send, Sync); -/// TODO Docu +/// Entry for a bottom level acceleration structure build. pub struct BlasBuildEntry<'a> { - /// TODO Docu + /// Reference to the acceleration structure. pub blas: &'a Blas, - /// TODO Docu + /// Reference to the geometries. pub geometry: &'a BlasGeometries<'a>, } static_assertions::assert_impl_all!(BlasBuildEntry: Send, Sync); #[derive(Debug)] -/// TODO Docu +/// Bottom level acceleration structure. +/// Used to represent a collection of geometries for ray tracing inside a top level acceleration structure. pub struct Blas { context: Arc, id: ObjectId, @@ -4724,12 +4754,13 @@ pub struct Blas { handle: Option, } static_assertions::assert_impl_all!(Blas: Send, Sync); + impl Blas { - /// TODO Docu + /// Raw handle to the acceleration structure, used inside raw instance buffers. pub fn handle(&self) -> Option { self.handle } - /// TODO Docu + /// Destroy the associated native resources as soon as possible. pub fn destroy(&self) { DynContext::blas_destroy(&*self.context, &self.id, self.data.as_ref()); } @@ -4744,7 +4775,8 @@ impl Drop for Blas { } #[derive(Debug)] -/// TODO Docu +/// Top level acceleration structure. +/// Used to represent a collection of bottom level acceleration structure instances for ray tracing. pub struct Tlas { context: Arc, id: ObjectId, @@ -4753,7 +4785,7 @@ pub struct Tlas { static_assertions::assert_impl_all!(Tlas: Send, Sync); impl Tlas { - /// TODO Docu + /// Destroy the associated native resources as soon as possible. pub fn destroy(&self) { DynContext::tlas_destroy(&*self.context, &self.id, self.data.as_ref()); } @@ -4767,32 +4799,36 @@ impl Drop for Tlas { } } -/// TODO Docu +/// Entry for a top level acceleration structure build. +/// Used with raw instance buffers for a unvalidated builds. pub struct TlasBuildEntry<'a> { - /// TODO Docu + /// Reference to the acceleration structure. pub tlas: &'a Tlas, - /// TODO Docu + /// Reference to the raw instance buffer. pub instance_buffer: &'a Buffer, - /// TODO Docu + /// Number of instances in the instance buffer. pub instance_count: u32, } static_assertions::assert_impl_all!(TlasBuildEntry: Send, Sync); -/// TODO Docu -/// Very unstable +/// Safe instance for a top level acceleration structure. #[derive(Debug, Clone)] pub struct TlasInstance { blas: ObjectId, - /// TODO Docu + /// Affine transform matrix 3x4 (rows x columns, row mayor order). pub transform: [f32; 12], - /// TODO Docu + /// Custom index for the instance used inside the shader (max 24 bits). pub custom_index: u32, - /// TODO Docu + /// Mask for the instance used inside the shader to filter instances. pub mask: u8, } impl TlasInstance { - /// TODO Docu + /// Construct TlasInstance. + /// - blas: Reference to the bottom level acceleration structure + /// - transform: Transform buffer offset in bytes (optional, required if transform buffer is present) + /// - custom_index: Custom index for the instance used inside the shader (max 24 bits) + /// - mask: Mask for the instance used inside the shader to filter instances pub fn new(blas: &Blas, transform: [f32; 12], custom_index: u32, mask: u8) -> Self { Self { blas: blas.id, @@ -4802,7 +4838,7 @@ impl TlasInstance { } } - /// TODO Docu + /// Set the bottom level acceleration structure. pub fn set_blas(&mut self, blas: &Blas) { self.blas = blas.id; } @@ -4815,7 +4851,7 @@ pub(crate) struct DynContextTlasInstance<'a> { mask: u8, } -/// TODO Docu +/// [Context version] see `TlasInstance`. pub struct ContextTlasInstance<'a, T: Context> { blas_id: T::BlasId, transform: &'a [f32; 12], @@ -4823,7 +4859,7 @@ pub struct ContextTlasInstance<'a, T: Context> { mask: u8, } -/// TODO Docu +/// The safe version of TlasEntry, containing TlasInstances instead of a raw buffer. pub struct TlasPackage { tlas: Tlas, instances: Vec>, @@ -4832,12 +4868,14 @@ pub struct TlasPackage { static_assertions::assert_impl_all!(TlasPackage: Send, Sync); impl TlasPackage { - /// TODO Docu + /// Construct TlasPackage consuming the Tlas (prevents modification of the Tlas without using this package). + /// (max_instances needs to fit into tlas) pub fn new(tlas: Tlas, max_instances: u32) -> Self { Self::new_with_instances(tlas, vec![None; max_instances as usize]) } - /// TODO Docu + /// Construct TlasPackage consuming the Tlas (prevents modification of the Tlas without using this package). + /// This contructor moves the instances into the package (the number of instances needs to fit into tlas). pub fn new_with_instances(tlas: Tlas, instances: Vec>) -> Self { Self { tlas, @@ -4846,12 +4884,15 @@ impl TlasPackage { } } - /// TODO Docu + /// Get a reference to all instances. pub fn get(&self) -> &[Option] { &self.instances } - /// TODO Docu + /// Get a mutable slice to a range of instances. + /// Returns None if the range is out of bounds. + /// All elements from the lowest accessed index up are marked as modified. + /// For better performance it is recommended to reduce access to low elements. pub fn get_mut_slice(&mut self, range: Range) -> Option<&mut [Option]> { if range.end > self.instances.len() { return None; @@ -4862,7 +4903,10 @@ impl TlasPackage { Some(&mut self.instances[range]) } - /// TODO Docu + /// Get a single mutable reference to an instance. + /// Returns None if the range is out of bounds. + /// All elements from the lowest accessed index up are marked as modified. + /// For better performance it is recommended to reduce access to low elements. pub fn get_mut_single(&mut self, index: usize) -> Option<&mut Option> { if index >= self.instances.len() { return None; @@ -4906,7 +4950,7 @@ pub(crate) struct DynContextTlasPackage<'a> { lowest_unmodified: u32, } -/// TODO Docu +/// [Context version] see `BlasTriangleGeometry`. pub struct ContextBlasTriangleGeometry<'a, T: Context> { size: &'a BlasTriangleGeometrySizeDescriptor, vertex_buffer: T::BufferId, @@ -4918,29 +4962,26 @@ pub struct ContextBlasTriangleGeometry<'a, T: Context> { transform_buffer_offset: Option, } -/// TODO Docu +/// [Context version] see `BlasGeometries`. pub enum ContextBlasGeometries<'a, T: Context> { - /// TODO Docu + /// Triangle geometries. TriangleGeometries(Box> + 'a>), } -/// TODO Docu +/// [Context version] see `BlasBuildEntry`. pub struct ContextBlasBuildEntry<'a, T: Context> { blas_id: T::BlasId, - // blas_data: &'a T::BlasData, geometries: ContextBlasGeometries<'a, T>, } -/// TODO Docu +/// [Context version] see `TlasBuildEntry`. pub struct ContextTlasBuildEntry { tlas_id: T::TlasId, - // tlas_data: &'a T::TlasData, instance_buffer_id: T::BufferId, - // instance_buffer_data: &'a T::BufferData, instance_count: u32, } -/// TODO Docu +/// [Context version] see `TlasPackage`. pub struct ContextTlasPackage<'a, T: Context> { tlas_id: T::TlasId, instances: Box>> + 'a>, From 03181700e238e75804446f1ec9134cf7b633b09f Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sun, 9 Apr 2023 13:35:02 +0200 Subject: [PATCH 065/146] validation fix --- wgpu-core/src/command/ray_tracing.rs | 32 +++++++++++++++++++++------- wgpu-core/src/ray_tracing.rs | 3 +++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 8677f9dbe7..98ebd7c915 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -179,6 +179,12 @@ impl Global { ); } + if size_desc.index_count.is_some() && mesh.index_buffer.is_none() { + return Err(BuildAccelerationStructureError::MissingIndexBuffer( + entry.blas_id, + )); + } + let vertex_buffer = { let (vertex_buffer, vertex_pending) = cmd_buf .trackers @@ -800,6 +806,12 @@ impl Global { ); } + if size_desc.index_count.is_some() && mesh.index_buffer.is_none() { + return Err(BuildAccelerationStructureError::MissingIndexBuffer( + entry.blas_id, + )); + } + let vertex_buffer = { let (vertex_buffer, vertex_pending) = cmd_buf .trackers @@ -1283,10 +1295,12 @@ impl Global { if tlas_present { unsafe { - cmd_buf_raw.transition_buffers(iter::once(hal::BufferBarrier:: { - buffer: staging_buffer.as_ref().unwrap(), - usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, - })); + if let Some(staging_buffer) = &staging_buffer { + cmd_buf_raw.transition_buffers(iter::once(hal::BufferBarrier:: { + buffer: staging_buffer, + usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, + })); + } } for &(tlas, ref _entries, ref _scratch_buffer_offset, ref range) in &tlas_storage { @@ -1322,10 +1336,12 @@ impl Global { ); } - device - .pending_writes - .temp_resources - .push(TempResource::Buffer(staging_buffer.unwrap())); + if let Some(staging_buffer) = staging_buffer { + device + .pending_writes + .temp_resources + .push(TempResource::Buffer(staging_buffer)); + } } device diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 8ce2c39fa7..92da9bf3c8 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -84,6 +84,9 @@ pub enum BuildAccelerationStructureError { )] IncompatibleBlasBuildSizes(BlasId), + #[error("Blas {0:?} build sizes require index buffer but none was provided")] + MissingIndexBuffer(BlasId), + #[error("Blas {0:?} is invalid or destroyed")] InvalidBlas(BlasId), From b447ced6800c2141f95254b0305146938a1b5df1 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sun, 9 Apr 2023 13:39:00 +0200 Subject: [PATCH 066/146] new example + example changes --- wgpu/Cargo.toml | 6 +- wgpu/examples/ray-cube-compute/README.md | 14 + .../{ray-cube => ray-cube-compute}/blit.wgsl | 0 .../{ray-cube => ray-cube-compute}/main.rs | 8 +- wgpu/examples/ray-cube-compute/screenshot.png | Bin 0 -> 490444 bytes .../shader.wgsl | 4 +- .../{ray-cube => ray-cube-fragment}/README.md | 2 +- wgpu/examples/ray-cube-fragment/main.rs | 428 ++++++++++++++++++ .../examples/ray-cube-fragment/screenshot.png | Bin 0 -> 598032 bytes wgpu/examples/ray-cube-fragment/shader.wgsl | 74 +++ wgpu/examples/ray-cube/screenshot.png | Bin 487485 -> 0 bytes 11 files changed, 528 insertions(+), 8 deletions(-) create mode 100644 wgpu/examples/ray-cube-compute/README.md rename wgpu/examples/{ray-cube => ray-cube-compute}/blit.wgsl (100%) rename wgpu/examples/{ray-cube => ray-cube-compute}/main.rs (99%) create mode 100644 wgpu/examples/ray-cube-compute/screenshot.png rename wgpu/examples/{ray-cube => ray-cube-compute}/shader.wgsl (95%) rename wgpu/examples/{ray-cube => ray-cube-fragment}/README.md (79%) create mode 100644 wgpu/examples/ray-cube-fragment/main.rs create mode 100644 wgpu/examples/ray-cube-fragment/screenshot.png create mode 100644 wgpu/examples/ray-cube-fragment/shader.wgsl delete mode 100644 wgpu/examples/ray-cube/screenshot.png diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index a20b0d7dd8..bccf1b27d2 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -86,7 +86,11 @@ name = "stencil-triangles" test = true [[example]] -name = "ray-cube" +name = "ray-cube-compute" +test = true + +[[example]] +name = "ray-cube-fragment" test = true [features] diff --git a/wgpu/examples/ray-cube-compute/README.md b/wgpu/examples/ray-cube-compute/README.md new file mode 100644 index 0000000000..7020f6a37c --- /dev/null +++ b/wgpu/examples/ray-cube-compute/README.md @@ -0,0 +1,14 @@ +# ray-cube + +This example renders a ray traced cube with hardware acceleration. +A separate compute shader is used to perform the ray queries. + +## To Run + +``` +cargo run --example ray-cube-compute +``` + +## Screenshots + +![Cube example](./screenshot.png) diff --git a/wgpu/examples/ray-cube/blit.wgsl b/wgpu/examples/ray-cube-compute/blit.wgsl similarity index 100% rename from wgpu/examples/ray-cube/blit.wgsl rename to wgpu/examples/ray-cube-compute/blit.wgsl diff --git a/wgpu/examples/ray-cube/main.rs b/wgpu/examples/ray-cube-compute/main.rs similarity index 99% rename from wgpu/examples/ray-cube/main.rs rename to wgpu/examples/ray-cube-compute/main.rs index 64a4da67c6..10b3a6ce96 100644 --- a/wgpu/examples/ray-cube/main.rs +++ b/wgpu/examples/ray-cube-compute/main.rs @@ -324,7 +324,7 @@ impl framework::Example for Example { let view = Mat4::look_at_rh(Vec3::new(0.0, 0.0, 2.5), Vec3::ZERO, Vec3::Y); let proj = Mat4::perspective_rh( 59.0_f32.to_radians(), - config.height as f32 / config.width as f32, + config.width as f32 / config.height as f32, 0.001, 1000.0, ); @@ -470,7 +470,7 @@ impl framework::Example for Example { &blas, AccelerationStructureInstance::affine_to_rows( &Affine3A::from_rotation_translation( - Quat::from_rotation_x(45.9_f32.to_radians()), + Quat::from_rotation_y(45.9_f32.to_radians()), Vec3 { x: x as f32 * dist, y: y as f32 * dist, @@ -637,9 +637,9 @@ fn main() { } #[test] -fn ray_cube() { +fn ray_cube_compute() { framework::test::(framework::FrameworkRefTest { - image_path: "/examples/ray-cube/screenshot.png", + image_path: "/examples/ray-cube-compute/screenshot.png", width: 1024, height: 768, optional_features: wgpu::Features::default(), diff --git a/wgpu/examples/ray-cube-compute/screenshot.png b/wgpu/examples/ray-cube-compute/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..6b737f1e2a82a45865265c9112e1c7d5942a0951 GIT binary patch literal 490444 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

; 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%0DmoVY1wCn(%0YxS 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

Ikx7!)lBM$T!)~1kAsV`l7t;*Pa>` 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≶-N|QY^(kKg%wkV6sKxm35~zfQ^H}T8RjU-l-ld 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 literal 0 HcmV?d00001 diff --git a/wgpu/examples/ray-cube/shader.wgsl b/wgpu/examples/ray-cube-compute/shader.wgsl similarity index 95% rename from wgpu/examples/ray-cube/shader.wgsl rename to wgpu/examples/ray-cube-compute/shader.wgsl index 0afa96a038..45d6be11cb 100644 --- a/wgpu/examples/ray-cube/shader.wgsl +++ b/wgpu/examples/ray-cube-compute/shader.wgsl @@ -60,8 +60,8 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { var color = vec4(vec2(global_id.xy) / vec2(target_size), 0.0, 1.0); - let pixel_center = vec2(global_id.yx) + vec2(0.5); - let in_uv = pixel_center/vec2(target_size.yx); + let pixel_center = vec2(global_id.xy) + vec2(0.5); + let in_uv = pixel_center/vec2(target_size.xy); let d = in_uv * 2.0 - 1.0; let origin = (uniforms.view_inv * vec4(0.0,0.0,0.0,1.0)).xyz; diff --git a/wgpu/examples/ray-cube/README.md b/wgpu/examples/ray-cube-fragment/README.md similarity index 79% rename from wgpu/examples/ray-cube/README.md rename to wgpu/examples/ray-cube-fragment/README.md index f9966e6810..f101fb5eaa 100644 --- a/wgpu/examples/ray-cube/README.md +++ b/wgpu/examples/ray-cube-fragment/README.md @@ -5,7 +5,7 @@ This example renders a ray traced cube with hardware acceleration. ## To Run ``` -cargo run --example ray-cube +cargo run --example ray-cube-fragment ``` ## Screenshots diff --git a/wgpu/examples/ray-cube-fragment/main.rs b/wgpu/examples/ray-cube-fragment/main.rs new file mode 100644 index 0000000000..617fec7faf --- /dev/null +++ b/wgpu/examples/ray-cube-fragment/main.rs @@ -0,0 +1,428 @@ +use std::{borrow::Cow, future::Future, iter, mem, pin::Pin, task, time::Instant}; + +use bytemuck::{Pod, Zeroable}; +use glam::{Affine3A, Mat4, Quat, Vec3}; +use wgpu::util::DeviceExt; + +#[path = "../framework.rs"] +mod framework; + +// from cube +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +struct Vertex { + _pos: [f32; 4], + _tex_coord: [f32; 2], +} + +fn vertex(pos: [i8; 3], tc: [i8; 2]) -> Vertex { + Vertex { + _pos: [pos[0] as f32, pos[1] as f32, pos[2] as f32, 1.0], + _tex_coord: [tc[0] as f32, tc[1] as f32], + } +} + +fn create_vertices() -> (Vec, Vec) { + let vertex_data = [ + // top (0, 0, 1) + vertex([-1, -1, 1], [0, 0]), + vertex([1, -1, 1], [1, 0]), + vertex([1, 1, 1], [1, 1]), + vertex([-1, 1, 1], [0, 1]), + // bottom (0, 0, -1) + vertex([-1, 1, -1], [1, 0]), + vertex([1, 1, -1], [0, 0]), + vertex([1, -1, -1], [0, 1]), + vertex([-1, -1, -1], [1, 1]), + // right (1, 0, 0) + vertex([1, -1, -1], [0, 0]), + vertex([1, 1, -1], [1, 0]), + vertex([1, 1, 1], [1, 1]), + vertex([1, -1, 1], [0, 1]), + // left (-1, 0, 0) + vertex([-1, -1, 1], [1, 0]), + vertex([-1, 1, 1], [0, 0]), + vertex([-1, 1, -1], [0, 1]), + vertex([-1, -1, -1], [1, 1]), + // front (0, 1, 0) + vertex([1, 1, -1], [1, 0]), + vertex([-1, 1, -1], [0, 0]), + vertex([-1, 1, 1], [0, 1]), + vertex([1, 1, 1], [1, 1]), + // back (0, -1, 0) + vertex([1, -1, 1], [0, 0]), + vertex([-1, -1, 1], [1, 0]), + vertex([-1, -1, -1], [1, 1]), + vertex([1, -1, -1], [0, 1]), + ]; + + let index_data: &[u16] = &[ + 0, 1, 2, 2, 3, 0, // top + 4, 5, 6, 6, 7, 4, // bottom + 8, 9, 10, 10, 11, 8, // right + 12, 13, 14, 14, 15, 12, // left + 16, 17, 18, 18, 19, 16, // front + 20, 21, 22, 22, 23, 20, // back + ]; + + (vertex_data.to_vec(), index_data.to_vec()) +} + +#[inline] +fn affine_to_rows(mat: &Affine3A) -> [f32; 12] { + let row_0 = mat.matrix3.row(0); + let row_1 = mat.matrix3.row(1); + let row_2 = mat.matrix3.row(2); + let translation = mat.translation; + [ + row_0.x, + row_0.y, + row_0.z, + translation.x, + row_1.x, + row_1.y, + row_1.z, + translation.y, + row_2.x, + row_2.y, + row_2.z, + translation.z, + ] +} + +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +struct Uniforms { + view_inverse: [[f32; 4]; 4], + proj_inverse: [[f32; 4]; 4], +} + +/// A wrapper for `pop_error_scope` futures that panics if an error occurs. +/// +/// Given a future `inner` of an `Option` for some error type `E`, +/// wait for the future to be ready, and panic if its value is `Some`. +/// +/// This can be done simpler with `FutureExt`, but we don't want to add +/// a dependency just for this small case. +struct ErrorFuture { + inner: F, +} +impl>> Future for ErrorFuture { + type Output = (); + fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<()> { + let inner = unsafe { self.map_unchecked_mut(|me| &mut me.inner) }; + inner.poll(cx).map(|error| { + if let Some(e) = error { + panic!("Rendering {e}"); + } + }) + } +} + +#[allow(dead_code)] +struct Example { + uniforms: Uniforms, + uniform_buf: wgpu::Buffer, + vertex_buf: wgpu::Buffer, + index_buf: wgpu::Buffer, + blas: wgpu::Blas, + tlas_package: wgpu::TlasPackage, + pipeline: wgpu::RenderPipeline, + bind_group: wgpu::BindGroup, + start_inst: Instant, +} + +impl framework::Example for Example { + fn required_features() -> wgpu::Features { + wgpu::Features::TEXTURE_BINDING_ARRAY + | wgpu::Features::STORAGE_RESOURCE_BINDING_ARRAY + | wgpu::Features::VERTEX_WRITABLE_STORAGE + | wgpu::Features::RAY_QUERY + | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE + } + + fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities { + wgpu::DownlevelCapabilities::default() + } + fn required_limits() -> wgpu::Limits { + wgpu::Limits::default() + } + + fn init( + config: &wgpu::SurfaceConfiguration, + _adapter: &wgpu::Adapter, + device: &wgpu::Device, + queue: &wgpu::Queue, + ) -> Self { + let side_count = 8; + + let uniforms = { + let view = Mat4::look_at_rh(Vec3::new(0.0, 0.0, 2.5), Vec3::ZERO, Vec3::Y); + let proj = Mat4::perspective_rh( + 59.0_f32.to_radians(), + config.width as f32 / config.height as f32, + 0.001, + 1000.0, + ); + + Uniforms { + view_inverse: view.inverse().to_cols_array_2d(), + proj_inverse: proj.inverse().to_cols_array_2d(), + } + }; + + let uniform_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Uniform Buffer"), + contents: bytemuck::cast_slice(&[uniforms]), + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + }); + + let (vertex_data, index_data) = create_vertices(); + + let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(&vertex_data), + usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::BLAS_INPUT, + }); + + let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(&index_data), + usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::BLAS_INPUT, + }); + + let blas_geo_size_desc = wgpu::BlasTriangleGeometrySizeDescriptor { + vertex_format: wgpu::VertexFormat::Float32x4, + vertex_count: vertex_data.len() as u32, + index_format: Some(wgpu::IndexFormat::Uint16), + index_count: Some(index_data.len() as u32), + flags: wgpu::AccelerationStructureGeometryFlags::OPAQUE, + }; + + let blas = device.create_blas( + &wgpu::CreateBlasDescriptor { + label: None, + flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: wgpu::AccelerationStructureUpdateMode::Build, + }, + wgpu::BlasGeometrySizeDescriptors::Triangles { + desc: vec![blas_geo_size_desc.clone()], + }, + ); + + let tlas = device.create_tlas(&wgpu::CreateTlasDescriptor { + label: None, + flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: wgpu::AccelerationStructureUpdateMode::Build, + max_instances: side_count * side_count, + }); + + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), + }); + + let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: None, + layout: None, + vertex: wgpu::VertexState { + module: &shader, + entry_point: "vs_main", + buffers: &[], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "fs_main", + targets: &[Some(config.format.into())], + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + ..Default::default() + }, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + multiview: None, + }); + + let bind_group_layout = pipeline.get_bind_group_layout(0); + + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: uniform_buf.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::AccelerationStructure(&tlas), + }, + ], + }); + + let tlas_package = wgpu::TlasPackage::new(tlas, side_count * side_count); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + encoder.build_acceleration_structures( + iter::once(&wgpu::BlasBuildEntry { + blas: &blas, + geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ + wgpu::BlasTriangleGeometry { + size: &blas_geo_size_desc, + vertex_buffer: &vertex_buf, + first_vertex: 0, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&index_buf), + index_buffer_offset: Some(0), + transform_buffer: None, + transform_buffer_offset: None, + }, + ]), + }), + // iter::empty(), + iter::once(&tlas_package), + ); + + queue.submit(Some(encoder.finish())); + + let start_inst = Instant::now(); + + Example { + uniforms, + uniform_buf, + vertex_buf, + index_buf, + blas, + tlas_package, + pipeline, + bind_group, + start_inst, + } + } + + fn update(&mut self, _event: winit::event::WindowEvent) {} + + fn resize( + &mut self, + config: &wgpu::SurfaceConfiguration, + _device: &wgpu::Device, + queue: &wgpu::Queue, + ) { + let proj = Mat4::perspective_rh( + 59.0_f32.to_radians(), + config.width as f32 / config.height as f32, + 0.001, + 1000.0, + ); + + self.uniforms.proj_inverse = proj.inverse().to_cols_array_2d(); + + queue.write_buffer(&self.uniform_buf, 0, bytemuck::cast_slice(&[self.uniforms])); + } + + fn render( + &mut self, + view: &wgpu::TextureView, + device: &wgpu::Device, + queue: &wgpu::Queue, + spawner: &framework::Spawner, + ) { + device.push_error_scope(wgpu::ErrorFilter::Validation); + + // scene update + { + let dist = 12.0; + + let side_count = 8; + + let anim_time = self.start_inst.elapsed().as_secs_f64() as f32; + + for x in 0..side_count { + for y in 0..side_count { + let instance = self + .tlas_package + .get_mut_single((x + y * side_count) as usize) + .unwrap(); + + let x = x as f32 / (side_count - 1) as f32; + let y = y as f32 / (side_count - 1) as f32; + let x = x * 2.0 - 1.0; + let y = y * 2.0 - 1.0; + + let transform = affine_to_rows(&Affine3A::from_rotation_translation( + Quat::from_euler( + glam::EulerRot::XYZ, + anim_time * 0.5 * 0.342, + anim_time * 0.5 * 0.254, + anim_time * 0.5 * 0.832, + ), + Vec3 { + x: x * dist, + y: y * dist, + z: -24.0, + }, + )); + + *instance = Some(wgpu::TlasInstance::new(&self.blas, transform, 0, 0xff)); + } + } + } + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + encoder.build_acceleration_structures(iter::empty(), iter::once(&self.tlas_package)); + + { + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), + store: true, + }, + })], + depth_stencil_attachment: None, + }); + + rpass.set_pipeline(&self.pipeline); + rpass.set_bind_group(0, &self.bind_group, &[]); + rpass.draw(0..3, 0..1); + } + + queue.submit(Some(encoder.finish())); + + // If an error occurs, report it and panic. + spawner.spawn_local(ErrorFuture { + inner: device.pop_error_scope(), + }); + } +} + +fn main() { + framework::run::("ray-cube"); +} + +#[test] +fn ray_cube_fragment() { + framework::test::(framework::FrameworkRefTest { + image_path: "/examples/ray-cube-fragment/screenshot.png", + width: 1024, + height: 768, + optional_features: wgpu::Features::default(), + base_test_parameters: framework::test_common::TestParameters { + required_features: ::required_features(), + required_downlevel_properties: + ::required_downlevel_capabilities(), + required_limits: ::required_limits(), + failures: Vec::new(), + }, + tolerance: 1, + max_outliers: 1225, // Bounded by swiftshader + }); +} diff --git a/wgpu/examples/ray-cube-fragment/screenshot.png b/wgpu/examples/ray-cube-fragment/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..5e95786759ed9038756515c67ba5e16178a01900 GIT binary patch literal 598032 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�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%0A0=pq8u3Px~ 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%0A}6N%C`Ym>;*=_asW-M0MRtA5 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 VF#Qh;slY!, + @location(0) tex_coords: vec2, +}; + +// meant to be called with 3 vertex indices: 0, 1, 2 +// draws one large triangle over the clip space like this: +// (the asterisks represent the clip space bounds) +//-1,1 1,1 +// --------------------------------- +// | * . +// | * . +// | * . +// | * . +// | * . +// | * . +// |*************** +// | . 1,-1 +// | . +// | . +// | . +// | . +// |. +@vertex +fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput { + var result: VertexOutput; + let x = i32(vertex_index) / 2; + let y = i32(vertex_index) & 1; + let tc = vec2( + f32(x) * 2.0, + f32(y) * 2.0 + ); + result.position = vec4( + tc.x * 2.0 - 1.0, + 1.0 - tc.y * 2.0, + 0.0, 1.0 + ); + result.tex_coords = tc; + return result; +} + +struct Uniforms { + view_inv: mat4x4, + proj_inv: mat4x4, +}; + +@group(0) @binding(0) +var uniforms: Uniforms; + +@group(0) @binding(1) +var acc_struct: acceleration_structure; + +@fragment +fn fs_main(vertex: VertexOutput) -> @location(0) vec4 { + + var color = vec4(vertex.tex_coords, 0.0, 1.0); + + let d = vertex.tex_coords * 2.0 - 1.0; + + let origin = (uniforms.view_inv * vec4(0.0,0.0,0.0,1.0)).xyz; + let temp = uniforms.proj_inv * vec4(d.x, d.y, 1.0, 1.0); + let direction = (uniforms.view_inv * vec4(normalize(temp.xyz), 0.0)).xyz; + + var rq: ray_query; + rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 0.1, 200.0, origin, direction)); + rayQueryProceed(&rq); + + let intersection = rayQueryGetCommittedIntersection(&rq); + if (intersection.kind != RAY_QUERY_INTERSECTION_NONE) { + color = vec4(intersection.barycentrics, 1.0 - intersection.barycentrics.x - intersection.barycentrics.y, 1.0); + } + + return color; // vec4(vertex.tex_coords, 1.0, 1.0); +} diff --git a/wgpu/examples/ray-cube/screenshot.png b/wgpu/examples/ray-cube/screenshot.png deleted file mode 100644 index 3d5142d1fd05673e7c7c8ec6d8d7c7951a19e2d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 487485 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 *HI9_`*%qh?aQEdslXA(;V)J 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

Nosh^y6mu?#G#qV5gT7JyYk<8r$!VXBTQjVuw- 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%0DZ0^E`1bKHCTN*`K&KXP2USihSz8340 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

5Uv+0`uP_N|qw=sbl!d=p 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

pT)kIRc}tOg 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%0D#hxgBlln{$1h)f_l99KTGq+L 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 z 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 From 2dc8bf48284b808de6b35b2455bc95ae245f5434 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sun, 9 Apr 2023 14:59:55 +0200 Subject: [PATCH 067/146] extracted into ray_tracing module in wgpu --- wgpu/examples/ray-cube-compute/main.rs | 73 ++-- wgpu/examples/ray-cube-fragment/main.rs | 53 +-- wgpu/src/backend/direct.rs | 65 +-- wgpu/src/backend/web.rs | 12 +- wgpu/src/context.rs | 164 ++++---- wgpu/src/lib.rs | 508 +--------------------- wgpu/src/ray_tracing.rs | 533 ++++++++++++++++++++++++ 7 files changed, 726 insertions(+), 682 deletions(-) create mode 100644 wgpu/src/ray_tracing.rs diff --git a/wgpu/examples/ray-cube-compute/main.rs b/wgpu/examples/ray-cube-compute/main.rs index 10b3a6ce96..5918c7796e 100644 --- a/wgpu/examples/ray-cube-compute/main.rs +++ b/wgpu/examples/ray-cube-compute/main.rs @@ -4,6 +4,9 @@ use bytemuck::{Pod, Zeroable}; use glam::{Affine3A, Mat4, Quat, Vec3}; use wgpu::util::DeviceExt; +use rt::traits::*; +use wgpu::ray_tracing as rt; + #[path = "../framework.rs"] mod framework; @@ -250,8 +253,8 @@ struct Example { uniform_buf: wgpu::Buffer, vertex_buf: wgpu::Buffer, index_buf: wgpu::Buffer, - blas: wgpu::Blas, - tlas_package: wgpu::TlasPackage, + blas: rt::Blas, + tlas_package: rt::TlasPackage, compute_pipeline: wgpu::ComputePipeline, compute_bind_group: wgpu::BindGroup, blit_pipeline: wgpu::RenderPipeline, @@ -355,29 +358,29 @@ impl framework::Example for Example { usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::BLAS_INPUT, }); - let blas_geo_size_desc = wgpu::BlasTriangleGeometrySizeDescriptor { + let blas_geo_size_desc = rt::BlasTriangleGeometrySizeDescriptor { vertex_format: wgpu::VertexFormat::Float32x4, vertex_count: vertex_data.len() as u32, index_format: Some(wgpu::IndexFormat::Uint16), index_count: Some(index_data.len() as u32), - flags: wgpu::AccelerationStructureGeometryFlags::OPAQUE, + flags: rt::AccelerationStructureGeometryFlags::OPAQUE, }; let blas = device.create_blas( - &wgpu::CreateBlasDescriptor { + &rt::CreateBlasDescriptor { label: None, - flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, - update_mode: wgpu::AccelerationStructureUpdateMode::Build, + flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: rt::AccelerationStructureUpdateMode::Build, }, - wgpu::BlasGeometrySizeDescriptors::Triangles { + rt::BlasGeometrySizeDescriptors::Triangles { desc: vec![blas_geo_size_desc.clone()], }, ); - let tlas = device.create_tlas(&wgpu::CreateTlasDescriptor { + let tlas = device.create_tlas(&rt::CreateTlasDescriptor { label: None, - flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, - update_mode: wgpu::AccelerationStructureUpdateMode::Build, + flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: rt::AccelerationStructureUpdateMode::Build, max_instances: side_count * side_count, }); @@ -458,7 +461,7 @@ impl framework::Example for Example { ], }); - let mut tlas_package = wgpu::TlasPackage::new(tlas, side_count * side_count); + let mut tlas_package = rt::TlasPackage::new(tlas, side_count * side_count); let dist = 3.0; @@ -466,7 +469,7 @@ impl framework::Example for Example { for y in 0..side_count { *tlas_package .get_mut_single((x + y * side_count) as usize) - .unwrap() = Some(wgpu::TlasInstance::new( + .unwrap() = Some(rt::TlasInstance::new( &blas, AccelerationStructureInstance::affine_to_rows( &Affine3A::from_rotation_translation( @@ -488,45 +491,23 @@ impl framework::Example for Example { device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); encoder.build_acceleration_structures( - iter::once(&wgpu::BlasBuildEntry { + iter::once(&rt::BlasBuildEntry { blas: &blas, - geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ - wgpu::BlasTriangleGeometry { - size: &blas_geo_size_desc, - vertex_buffer: &vertex_buf, - first_vertex: 0, - vertex_stride: mem::size_of::() as u64, - index_buffer: Some(&index_buf), - index_buffer_offset: Some(0), - transform_buffer: None, - transform_buffer_offset: None, - }, - ]), + geometry: &rt::BlasGeometries::TriangleGeometries(&[rt::BlasTriangleGeometry { + size: &blas_geo_size_desc, + vertex_buffer: &vertex_buf, + first_vertex: 0, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&index_buf), + index_buffer_offset: Some(0), + transform_buffer: None, + transform_buffer_offset: None, + }]), }), // iter::empty(), iter::once(&tlas_package), ); - // encoder.build_acceleration_structures( - // iter::once(&wgpu::BlasBuildEntry { - // blas: &blas, - // geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ - // wgpu::BlasTriangleGeometry { - // size: &blas_geo_size_desc, - // vertex_buffer: &vertex_buf, - // first_vertex: 0, - // vertex_stride: mem::size_of::() as u64, - // index_buffer: Some(&index_buf), - // index_buffer_offset: Some(0), - // transform_buffer: None, - // transform_buffer_offset: None, - // }, - // ]), - // }), - // iter::empty(), - // // iter::once(&tlas_package), - // ); - queue.submit(Some(encoder.finish())); let start_inst = Instant::now(); diff --git a/wgpu/examples/ray-cube-fragment/main.rs b/wgpu/examples/ray-cube-fragment/main.rs index 617fec7faf..a454d30990 100644 --- a/wgpu/examples/ray-cube-fragment/main.rs +++ b/wgpu/examples/ray-cube-fragment/main.rs @@ -4,6 +4,9 @@ use bytemuck::{Pod, Zeroable}; use glam::{Affine3A, Mat4, Quat, Vec3}; use wgpu::util::DeviceExt; +use rt::traits::*; +use wgpu::ray_tracing as rt; + #[path = "../framework.rs"] mod framework; @@ -125,8 +128,8 @@ struct Example { uniform_buf: wgpu::Buffer, vertex_buf: wgpu::Buffer, index_buf: wgpu::Buffer, - blas: wgpu::Blas, - tlas_package: wgpu::TlasPackage, + blas: rt::Blas, + tlas_package: rt::TlasPackage, pipeline: wgpu::RenderPipeline, bind_group: wgpu::BindGroup, start_inst: Instant, @@ -191,29 +194,29 @@ impl framework::Example for Example { usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::BLAS_INPUT, }); - let blas_geo_size_desc = wgpu::BlasTriangleGeometrySizeDescriptor { + let blas_geo_size_desc = rt::BlasTriangleGeometrySizeDescriptor { vertex_format: wgpu::VertexFormat::Float32x4, vertex_count: vertex_data.len() as u32, index_format: Some(wgpu::IndexFormat::Uint16), index_count: Some(index_data.len() as u32), - flags: wgpu::AccelerationStructureGeometryFlags::OPAQUE, + flags: rt::AccelerationStructureGeometryFlags::OPAQUE, }; let blas = device.create_blas( - &wgpu::CreateBlasDescriptor { + &rt::CreateBlasDescriptor { label: None, - flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, - update_mode: wgpu::AccelerationStructureUpdateMode::Build, + flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: rt::AccelerationStructureUpdateMode::Build, }, - wgpu::BlasGeometrySizeDescriptors::Triangles { + rt::BlasGeometrySizeDescriptors::Triangles { desc: vec![blas_geo_size_desc.clone()], }, ); - let tlas = device.create_tlas(&wgpu::CreateTlasDescriptor { + let tlas = device.create_tlas(&rt::CreateTlasDescriptor { label: None, - flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE, - update_mode: wgpu::AccelerationStructureUpdateMode::Build, + flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: rt::AccelerationStructureUpdateMode::Build, max_instances: side_count * side_count, }); @@ -261,26 +264,24 @@ impl framework::Example for Example { ], }); - let tlas_package = wgpu::TlasPackage::new(tlas, side_count * side_count); + let tlas_package = rt::TlasPackage::new(tlas, side_count * side_count); let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); encoder.build_acceleration_structures( - iter::once(&wgpu::BlasBuildEntry { + iter::once(&rt::BlasBuildEntry { blas: &blas, - geometry: &wgpu::BlasGeometries::TriangleGeometries(&[ - wgpu::BlasTriangleGeometry { - size: &blas_geo_size_desc, - vertex_buffer: &vertex_buf, - first_vertex: 0, - vertex_stride: mem::size_of::() as u64, - index_buffer: Some(&index_buf), - index_buffer_offset: Some(0), - transform_buffer: None, - transform_buffer_offset: None, - }, - ]), + geometry: &rt::BlasGeometries::TriangleGeometries(&[rt::BlasTriangleGeometry { + size: &blas_geo_size_desc, + vertex_buffer: &vertex_buf, + first_vertex: 0, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&index_buf), + index_buffer_offset: Some(0), + transform_buffer: None, + transform_buffer_offset: None, + }]), }), // iter::empty(), iter::once(&tlas_package), @@ -366,7 +367,7 @@ impl framework::Example for Example { }, )); - *instance = Some(wgpu::TlasInstance::new(&self.blas, transform, 0, 0xff)); + *instance = Some(rt::TlasInstance::new(&self.blas, transform, 0, 0xff)); } } } diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 167fb67075..c1c2b4305c 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -2,8 +2,8 @@ use crate::{ context::{ObjectId, Unused}, AdapterInfo, BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BufferBinding, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, - ContextTlasInstance, DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, - Operations, PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, + DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, Operations, + PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, ShaderSource, SurfaceStatus, TextureDescriptor, TextureViewDescriptor, UncapturedErrorHandler, }; @@ -2959,7 +2959,7 @@ impl crate::Context for Context { &self, device: &Self::DeviceId, device_data: &Self::DeviceData, - desc: &crate::CreateBlasDescriptor<'_>, + desc: &crate::ray_tracing::CreateBlasDescriptor<'_>, sizes: wgt::BlasGeometrySizeDescriptors, ) -> (Self::BlasId, Option, Self::BlasData) { let global = &self.0; @@ -2991,7 +2991,7 @@ impl crate::Context for Context { &self, device: &Self::DeviceId, device_data: &Self::DeviceData, - desc: &crate::CreateTlasDescriptor<'_>, + desc: &crate::ray_tracing::CreateTlasDescriptor<'_>, ) -> (Self::TlasId, Self::TlasData) { let global = &self.0; let (id, error) = wgc::gfx_select!(device => global.device_create_tlas( @@ -3020,14 +3020,16 @@ impl crate::Context for Context { &'a self, encoder: &Self::CommandEncoderId, encoder_data: &Self::CommandEncoderData, - blas: impl Iterator>, - tlas: impl Iterator>, + blas: impl Iterator>, + tlas: impl Iterator>, ) { let global = &self.0; - let blas = blas.map(|e: crate::ContextBlasBuildEntry| { + let blas = blas.map(|e: crate::ray_tracing::ContextBlasBuildEntry| { let geometries = match e.geometries { - crate::ContextBlasGeometries::TriangleGeometries(triangle_geometries) => { + crate::ray_tracing::ContextBlasGeometries::TriangleGeometries( + triangle_geometries, + ) => { let iter = triangle_geometries.into_iter().map(|tg| { wgc::ray_tracing::BlasTriangleGeometry { vertex_buffer: tg.vertex_buffer, @@ -3051,13 +3053,13 @@ impl crate::Context for Context { let tlas = tlas .into_iter() - .map( - |e: crate::ContextTlasBuildEntry| wgc::ray_tracing::TlasBuildEntry { + .map(|e: crate::ray_tracing::ContextTlasBuildEntry| { + wgc::ray_tracing::TlasBuildEntry { tlas_id: e.tlas_id, instance_buffer_id: e.instance_buffer_id, instance_count: e.instance_count, - }, - ); + } + }); if let Err(cause) = wgc::gfx_select!(encoder => global.command_encoder_build_acceleration_structures_unsafe_tlas( *encoder, @@ -3076,14 +3078,16 @@ impl crate::Context for Context { &'a self, encoder: &Self::CommandEncoderId, encoder_data: &Self::CommandEncoderData, - blas: impl Iterator>, - tlas: impl Iterator>, + blas: impl Iterator>, + tlas: impl Iterator>, ) { let global = &self.0; - let blas = blas.map(|e: crate::ContextBlasBuildEntry| { + let blas = blas.map(|e: crate::ray_tracing::ContextBlasBuildEntry| { let geometries = match e.geometries { - crate::ContextBlasGeometries::TriangleGeometries(triangle_geometries) => { + crate::ray_tracing::ContextBlasGeometries::TriangleGeometries( + triangle_geometries, + ) => { let iter = triangle_geometries.into_iter().map(|tg| { wgc::ray_tracing::BlasTriangleGeometry { vertex_buffer: tg.vertex_buffer, @@ -3106,21 +3110,20 @@ impl crate::Context for Context { }); let tlas = tlas.into_iter().map(|e| { - let instances = - e.instances - .into_iter() - .map(|instance: Option>| { - if let Some(instance) = instance { - Some(wgc::ray_tracing::TlasInstance { - blas_id: instance.blas_id, - transform: instance.transform, - custom_index: instance.custom_index, - mask: instance.mask, - }) - } else { - None - } - }); + let instances = e.instances.into_iter().map( + |instance: Option>| { + if let Some(instance) = instance { + Some(wgc::ray_tracing::TlasInstance { + blas_id: instance.blas_id, + transform: instance.transform, + custom_index: instance.custom_index, + mask: instance.mask, + }) + } else { + None + } + }, + ); wgc::ray_tracing::TlasPackage { tlas_id: e.tlas_id, instances: Box::new(instances), diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 223e6ba39f..bd8e0b7b22 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -3120,7 +3120,7 @@ impl crate::context::Context for Context { &self, _device: &Self::DeviceId, _device_data: &Self::DeviceData, - _desc: &crate::CreateBlasDescriptor<'_>, + _desc: &crate::ray_tracing::CreateBlasDescriptor<'_>, _sizes: wgt::BlasGeometrySizeDescriptors, ) -> (Self::BlasId, Option, Self::BlasData) { unimplemented!("Raytracing not implemented for web"); @@ -3130,7 +3130,7 @@ impl crate::context::Context for Context { &self, _device: &Self::DeviceId, _device_data: &Self::DeviceData, - _desc: &crate::CreateTlasDescriptor<'_>, + _desc: &crate::ray_tracing::CreateTlasDescriptor<'_>, ) -> (Self::TlasId, Self::TlasData) { unimplemented!("Raytracing not implemented for web"); } @@ -3139,8 +3139,8 @@ impl crate::context::Context for Context { &'a self, _encoder: &Self::CommandEncoderId, _encoder_data: &Self::CommandEncoderData, - _blas: impl Iterator>, - _tlas: impl Iterator>, + _blas: impl Iterator>, + _tlas: impl Iterator>, ) { unimplemented!("Raytracing not implemented for web"); } @@ -3149,8 +3149,8 @@ impl crate::context::Context for Context { &'a self, _encoder: &Self::CommandEncoderId, _encoder_data: &Self::CommandEncoderData, - _blas: impl Iterator>, - _tlas: impl Iterator>, + _blas: impl Iterator>, + _tlas: impl Iterator>, ) { unimplemented!("Raytracing not implemented for web"); } diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 41b2160257..692c9e46df 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -9,14 +9,13 @@ use wgt::{ use crate::{ BindGroupDescriptor, BindGroupLayoutDescriptor, Buffer, BufferAsyncError, BufferDescriptor, - CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, - ContextBlasTriangleGeometry, ContextTlasInstance, ContextTlasPackage, CreateBlasDescriptor, - CreateTlasDescriptor, DeviceDescriptor, DynContextTlasInstance, DynContextTlasPackage, Error, - ErrorFilter, ImageCopyBuffer, ImageCopyTexture, Maintain, MapMode, PipelineLayoutDescriptor, - QuerySetDescriptor, RenderBundleDescriptor, RenderBundleEncoderDescriptor, - RenderPassDescriptor, RenderPipelineDescriptor, RequestAdapterOptions, RequestDeviceError, - SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, Texture, - TextureDescriptor, TextureViewDescriptor, UncapturedErrorHandler, + CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, DeviceDescriptor, + Error, ErrorFilter, ImageCopyBuffer, ImageCopyTexture, Maintain, MapMode, + PipelineLayoutDescriptor, QuerySetDescriptor, RenderBundleDescriptor, + RenderBundleEncoderDescriptor, RenderPassDescriptor, RenderPipelineDescriptor, + RequestAdapterOptions, RequestDeviceError, SamplerDescriptor, ShaderModuleDescriptor, + ShaderModuleDescriptorSpirV, Texture, TextureDescriptor, TextureViewDescriptor, + UncapturedErrorHandler, }; /// Meta trait for an id tracked by a context. @@ -1000,28 +999,28 @@ pub trait Context: Debug + Send + Sized + Sync { &self, device: &Self::DeviceId, device_data: &Self::DeviceData, - desc: &CreateBlasDescriptor, + desc: &crate::ray_tracing::CreateBlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, ) -> (Self::BlasId, Option, Self::BlasData); fn device_create_tlas( &self, device: &Self::DeviceId, device_data: &Self::DeviceData, - desc: &CreateTlasDescriptor, + desc: &crate::ray_tracing::CreateTlasDescriptor, ) -> (Self::TlasId, Self::TlasData); fn command_encoder_build_acceleration_structures_unsafe_tlas<'a>( &'a self, encoder: &Self::CommandEncoderId, encoder_data: &Self::CommandEncoderData, - blas: impl Iterator>, - tlas: impl Iterator>, + blas: impl Iterator>, + tlas: impl Iterator>, ); fn command_encoder_build_acceleration_structures<'a>( &'a self, encoder: &Self::CommandEncoderId, encoder_data: &Self::CommandEncoderData, - blas: impl Iterator>, - tlas: impl Iterator>, + blas: impl Iterator>, + tlas: impl Iterator>, ); fn blas_destroy(&self, blas: &Self::BlasId, blas_data: &Self::BlasData); fn blas_drop(&self, blas: &Self::BlasId, blas_data: &Self::BlasData); @@ -1946,28 +1945,28 @@ pub(crate) trait DynContext: Debug + Send + Sync { &self, device: &ObjectId, device_data: &crate::Data, - desc: &crate::CreateBlasDescriptor, + desc: &crate::ray_tracing::CreateBlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, ) -> (ObjectId, Option, Box); fn device_create_tlas( &self, device: &ObjectId, device_data: &crate::Data, - desc: &crate::CreateTlasDescriptor, + desc: &crate::ray_tracing::CreateTlasDescriptor, ) -> (ObjectId, Box); fn command_encoder_build_acceleration_structures_unsafe_tlas<'a>( &self, encoder: &ObjectId, encoder_data: &crate::Data, - blas: &mut dyn Iterator>, - tlas: &mut dyn Iterator, + blas: &mut dyn Iterator>, + tlas: &mut dyn Iterator, ); fn command_encoder_build_acceleration_structures<'a>( &self, encoder: &ObjectId, encoder_data: &crate::Data, - blas: &mut dyn Iterator>, - tlas: &mut dyn Iterator, + blas: &mut dyn Iterator>, + tlas: &mut dyn Iterator, ); fn blas_destroy(&self, blas: &ObjectId, blas_data: &crate::Data); fn blas_drop(&self, blas: &ObjectId, blas_data: &crate::Data); @@ -3928,7 +3927,7 @@ where &self, device: &ObjectId, device_data: &crate::Data, - desc: &crate::CreateBlasDescriptor, + desc: &crate::ray_tracing::CreateBlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, ) -> (ObjectId, Option, Box) { let device = ::from(*device); @@ -3942,7 +3941,7 @@ where &self, device: &ObjectId, device_data: &crate::Data, - desc: &crate::CreateTlasDescriptor, + desc: &crate::ray_tracing::CreateTlasDescriptor, ) -> (ObjectId, Box) { let device = ::from(*device); let device_data = downcast_ref(device_data); @@ -3954,47 +3953,50 @@ where &self, encoder: &ObjectId, encoder_data: &crate::Data, - blas: &mut dyn Iterator>, - tlas: &mut dyn Iterator, + blas: &mut dyn Iterator>, + tlas: &mut dyn Iterator, ) { let encoder = ::from(*encoder); let encoder_data = downcast_ref(encoder_data); let blas = blas.into_iter().map(|e| { let geometries = match e.geometries { - crate::DynContextBlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = - triangle_geometries - .into_iter() - .map(|tg| ContextBlasTriangleGeometry { - vertex_buffer: ::from(tg.vertex_buffer), - index_buffer: tg.index_buffer.map(::from), - transform_buffer: tg.transform_buffer.map(::from), - size: tg.size, - transform_buffer_offset: tg.transform_buffer_offset, - first_vertex: tg.first_vertex, - vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, - }); - crate::ContextBlasGeometries::TriangleGeometries(Box::new(iter)) + crate::ray_tracing::DynContextBlasGeometries::TriangleGeometries( + triangle_geometries, + ) => { + let iter = triangle_geometries.into_iter().map(|tg| { + crate::ray_tracing::ContextBlasTriangleGeometry { + vertex_buffer: ::from(tg.vertex_buffer), + index_buffer: tg.index_buffer.map(::from), + transform_buffer: tg.transform_buffer.map(::from), + size: tg.size, + transform_buffer_offset: tg.transform_buffer_offset, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + } + }); + crate::ray_tracing::ContextBlasGeometries::TriangleGeometries(Box::new(iter)) } }; - crate::ContextBlasBuildEntry { + crate::ray_tracing::ContextBlasBuildEntry { blas_id: ::from(e.blas_id), // blas_data: downcast_ref(e.blas_data), geometries, } }); - let tlas = tlas.into_iter().map(|e: crate::DynContextTlasBuildEntry| { - crate::ContextTlasBuildEntry { - tlas_id: ::from(e.tlas_id), - // tlas_data: downcast_ref(e.tlas_data), - instance_buffer_id: ::from(e.instance_buffer_id), - // instance_buffer_data: downcast_ref(e.instance_buffer_data), - instance_count: e.instance_count, - } - }); + let tlas = tlas + .into_iter() + .map(|e: crate::ray_tracing::DynContextTlasBuildEntry| { + crate::ray_tracing::ContextTlasBuildEntry { + tlas_id: ::from(e.tlas_id), + // tlas_data: downcast_ref(e.tlas_data), + instance_buffer_id: ::from(e.instance_buffer_id), + // instance_buffer_data: downcast_ref(e.instance_buffer_data), + instance_count: e.instance_count, + } + }); Context::command_encoder_build_acceleration_structures_unsafe_tlas( self, @@ -4009,56 +4011,58 @@ where &self, encoder: &ObjectId, encoder_data: &crate::Data, - blas: &mut dyn Iterator>, - tlas: &mut dyn Iterator, + blas: &mut dyn Iterator>, + tlas: &mut dyn Iterator, ) { let encoder = ::from(*encoder); let encoder_data = downcast_ref(encoder_data); let blas = blas.into_iter().map(|e| { let geometries = match e.geometries { - crate::DynContextBlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = - triangle_geometries - .into_iter() - .map(|tg| ContextBlasTriangleGeometry { - vertex_buffer: ::from(tg.vertex_buffer), - index_buffer: tg.index_buffer.map(::from), - transform_buffer: tg.transform_buffer.map(::from), - size: tg.size, - transform_buffer_offset: tg.transform_buffer_offset, - first_vertex: tg.first_vertex, - vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, - }); - crate::ContextBlasGeometries::TriangleGeometries(Box::new(iter)) + crate::ray_tracing::DynContextBlasGeometries::TriangleGeometries( + triangle_geometries, + ) => { + let iter = triangle_geometries.into_iter().map(|tg| { + crate::ray_tracing::ContextBlasTriangleGeometry { + vertex_buffer: ::from(tg.vertex_buffer), + index_buffer: tg.index_buffer.map(::from), + transform_buffer: tg.transform_buffer.map(::from), + size: tg.size, + transform_buffer_offset: tg.transform_buffer_offset, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + } + }); + crate::ray_tracing::ContextBlasGeometries::TriangleGeometries(Box::new(iter)) } }; - crate::ContextBlasBuildEntry { + crate::ray_tracing::ContextBlasBuildEntry { blas_id: ::from(e.blas_id), // blas_data: downcast_ref(e.blas_data), geometries, } }); - let tlas = tlas.into_iter().map(|e: DynContextTlasPackage| { - let instances = - e.instances - .into_iter() - .map(|instance: Option| { - instance.map(|instance| ContextTlasInstance { + let tlas = tlas + .into_iter() + .map(|e: crate::ray_tracing::DynContextTlasPackage| { + let instances = e.instances.into_iter().map( + |instance: Option| { + instance.map(|instance| crate::ray_tracing::ContextTlasInstance { blas_id: ::from(instance.blas), transform: instance.transform, custom_index: instance.custom_index, mask: instance.mask, }) - }); - ContextTlasPackage { - tlas_id: ::from(e.tlas_id), - instances: Box::new(instances), - lowest_unmodified: e.lowest_unmodified, - } - }); + }, + ); + crate::ray_tracing::ContextTlasPackage { + tlas_id: ::from(e.tlas_id), + instances: Box::new(instances), + lowest_unmodified: e.lowest_unmodified, + } + }); Context::command_encoder_build_acceleration_structures( self, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 3de13b0e3e..df07d71817 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -12,6 +12,20 @@ pub mod util; #[macro_use] mod macros; +/// Module to add ray tracing support to wgpu. +/// It adds support for acceleration structures and ray queries. +/// The features [`wgpu::Features::RAY_QUERY`] and [`wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE`] where added and are required to use this module. +/// This is an experimental feature and is not available on all backends. +/// It is not part of the WebGPU standard and is only natively supported with the Vulkan backend so far. +/// DirectX 12 and Metal support are planned, the API is subject to change. +/// (It should be somewhat stable, unless adding ray tracing to the WebGPU standard requires deep changes.) +/// +/// Functions to create and build acceleration structures are provided, In traits on the [`Device`] and [`CommandEncoder`]. +/// To use ray queries, add a top level acceleration structure to a bind group, and use the ray query extension in a shader. +/// Naga (our shader compiler) has support for the ray query extension for "wgsl" shaders. +/// For more details see the examples (starting with ray-). +pub mod ray_tracing; + use std::{ any::Any, borrow::Cow, @@ -761,7 +775,7 @@ pub enum BindingResource<'a> { /// [`BindGroupLayoutEntry::count`] set to Some. TextureViewArray(&'a [&'a TextureView]), /// Todo - AccelerationStructure(&'a Tlas), + AccelerationStructure(&'a crate::ray_tracing::Tlas), } static_assertions::assert_impl_all!(BindingResource: Send, Sync); @@ -2245,43 +2259,6 @@ impl Device { DynContext::device_stop_capture(&*self.context, &self.id, self.data.as_ref()) } - /// Create a bottom level acceleration structure, used inside a top level acceleration structure for ray tracing. - /// - desc: The descriptor of the acceleration structure. - /// - sizes: Size descriptor limiting what can be built into the acceleration structure. - pub fn create_blas( - &self, - desc: &CreateBlasDescriptor, - sizes: wgt::BlasGeometrySizeDescriptors, - ) -> Blas { - let (id, handle, data) = DynContext::device_create_blas( - &*self.context, - &self.id, - self.data.as_ref(), - desc, - sizes, - ); - - Blas { - context: Arc::clone(&self.context), - id, - data, - handle, - } - } - - /// Create a top level acceleration structure, used for ray tracing. - /// - desc: The descriptor of the acceleration structure. - pub fn create_tlas(&self, desc: &CreateTlasDescriptor) -> Tlas { - let (id, data) = - DynContext::device_create_tlas(&*self.context, &self.id, self.data.as_ref(), desc); - - Tlas { - context: Arc::clone(&self.context), - id, - data, - } - } - /// Apply a callback to this `Device`'s underlying backend device. /// /// If this `Device` is implemented by the backend API given by `A` (Vulkan, @@ -2975,148 +2952,6 @@ impl CommandEncoder { let id = self.id.as_ref().unwrap(); DynContext::command_encoder_pop_debug_group(&*self.context, id, self.data.as_ref()); } - - /// Build bottom and top level acceleration structures. - /// See [`build_acceleration_structures`] for the safe version and more details. - /// - /// # Safety - /// - /// - The contents of the raw instance buffer must be valid for the underling api. - /// - All bottom level acceleration structures, referenced in the raw instance buffer must be valid and built, - /// when the corresponding top level acceleration structure is built. (builds may happen in the same invocation of this function). - /// - At the time when the top level acceleration structure is used in a bind group, all associated bottom level acceleration structures must be valid, - /// and built (no later than the time when the top level acceleration structure was built). - pub unsafe fn build_acceleration_structures_unsafe_tlas<'a>( - &mut self, - blas: impl IntoIterator>, - tlas: impl IntoIterator>, - ) { - let id = self.id.as_ref().unwrap(); - - let mut blas = blas.into_iter().map(|e: &BlasBuildEntry| { - let geometries = match e.geometry { - BlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry| { - DynContextBlasTriangleGeometry { - size: tg.size, - vertex_buffer: tg.vertex_buffer.id, - - index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.id), - - transform_buffer: tg - .transform_buffer - .map(|transform_buffer| transform_buffer.id), - - first_vertex: tg.first_vertex, - vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, - transform_buffer_offset: tg.transform_buffer_offset, - } - }); - DynContextBlasGeometries::TriangleGeometries(Box::new(iter)) - } - }; - DynContextBlasBuildEntry { - blas_id: e.blas.id, - geometries, - } - }); - - let mut tlas = tlas - .into_iter() - .map(|e: &TlasBuildEntry| DynContextTlasBuildEntry { - tlas_id: e.tlas.id, - instance_buffer_id: e.instance_buffer.id, - instance_count: e.instance_count, - }); - - DynContext::command_encoder_build_acceleration_structures_unsafe_tlas( - &*self.context, - id, - self.data.as_ref(), - &mut blas, - &mut tlas, - ); - } - - /// Build bottom and top level acceleration structures. - /// - blas: Iterator of bottom level acceleration structure entries to build - /// For each entry, the provided size descriptor must be strictly smaller or equal to the descriptor given at bottom level acceleration structure creation: - /// - Less or equal number of geometries - /// - Same kind of geometry (with index buffer or without) (same vertex/index format) - /// - Same flags - /// - Less or equal number of vertices - /// - Less or equal number of indices (if applicable) - /// - tlas: iterator of top level acceleration structure packages to build - /// - /// A bottom level acceleration structure may be build and used as a reference in a top level acceleration structure in the same invocation of this function. - /// - /// # Bind group usage - /// - /// When a top level acceleration structure is used in a bind group, some validation takes place: - /// - The top level acceleration structure is valid and has been built. - /// - All the bottom level acceleration structures referenced by the top level acceleration structure are valid and have been built prior, - /// or at same time as the containing top level acceleration structure. - pub fn build_acceleration_structures<'a>( - &mut self, - blas: impl IntoIterator>, - tlas: impl IntoIterator, - ) { - let id = self.id.as_ref().unwrap(); - - let mut blas = blas.into_iter().map(|e: &BlasBuildEntry| { - let geometries = match e.geometry { - BlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry| { - DynContextBlasTriangleGeometry { - size: tg.size, - vertex_buffer: tg.vertex_buffer.id, - - index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.id), - - transform_buffer: tg - .transform_buffer - .map(|transform_buffer| transform_buffer.id), - - first_vertex: tg.first_vertex, - vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, - transform_buffer_offset: tg.transform_buffer_offset, - } - }); - DynContextBlasGeometries::TriangleGeometries(Box::new(iter)) - } - }; - DynContextBlasBuildEntry { - blas_id: e.blas.id, - geometries, - } - }); - - let mut tlas = tlas.into_iter().map(|e: &TlasPackage| { - let instances = e.instances.iter().map(|instance: &Option| { - instance.as_ref().map(|instance| DynContextTlasInstance { - blas: instance.blas, - transform: &instance.transform, - custom_index: instance.custom_index, - mask: instance.mask, - }) - }); - DynContextTlasPackage { - tlas_id: e.tlas.id, - instances: Box::new(instances), - lowest_unmodified: e.lowest_unmodified, - } - }); - - DynContext::command_encoder_build_acceleration_structures( - &*self.context, - id, - self.data.as_ref(), - &mut blas, - &mut tlas, - ); - } } /// [`Features::TIMESTAMP_QUERY`] must be enabled on the device in order to call these functions. @@ -4674,316 +4509,3 @@ impl Display for Error { } } } - -/// Descriptor for the size defining attributes of a triangle geometry, for a bottom level acceleration structure. -pub type BlasTriangleGeometrySizeDescriptor = wgt::BlasTriangleGeometrySizeDescriptor; -static_assertions::assert_impl_all!(BlasTriangleGeometrySizeDescriptor: Send, Sync); - -/// Descriptor for the size defining attributes, for a bottom level acceleration structure. -pub type BlasGeometrySizeDescriptors = wgt::BlasGeometrySizeDescriptors; -static_assertions::assert_impl_all!(BlasGeometrySizeDescriptors: Send, Sync); - -/// Flags for an acceleration structure. -pub type AccelerationStructureFlags = wgt::AccelerationStructureFlags; -static_assertions::assert_impl_all!(AccelerationStructureFlags: Send, Sync); - -/// Flags for a geometry inside a bottom level acceleration structure. -pub type AccelerationStructureGeometryFlags = wgt::AccelerationStructureGeometryFlags; -static_assertions::assert_impl_all!(AccelerationStructureGeometryFlags: Send, Sync); - -/// Update mode for acceleration structure builds. -pub type AccelerationStructureUpdateMode = wgt::AccelerationStructureUpdateMode; -static_assertions::assert_impl_all!(AccelerationStructureUpdateMode: Send, Sync); - -/// Descriptor to create bottom level acceleration structures. -pub type CreateBlasDescriptor<'a> = wgt::CreateBlasDescriptor>; -static_assertions::assert_impl_all!(CreateBlasDescriptor: Send, Sync); - -/// Descriptor to create top level acceleration structures. -pub type CreateTlasDescriptor<'a> = wgt::CreateTlasDescriptor>; -static_assertions::assert_impl_all!(CreateTlasDescriptor: Send, Sync); - -#[derive(Debug)] -/// Definition for a triangle geometry. -/// The size must match the rest of the structures fields, otherwise the build will fail. -/// (e.g. if a index count is present in the size, the index buffer must be present as well.) -pub struct BlasTriangleGeometry<'a> { - /// Sub descriptor for the size defining attributes of a triangle geometry. - pub size: &'a BlasTriangleGeometrySizeDescriptor, - /// Vertex buffer. - pub vertex_buffer: &'a Buffer, - /// Offset into the vertex buffer as a factor of the vertex stride. - pub first_vertex: u32, - /// Vertex stride. - pub vertex_stride: wgt::BufferAddress, - /// Index buffer (optional). - pub index_buffer: Option<&'a Buffer>, - /// Index buffer offset in bytes (optional, required if index buffer is present). - pub index_buffer_offset: Option, - /// Transform buffer containing 3x4 (rows x columns, row mayor) affine transform matrices `[f32; 12]` (optional). - pub transform_buffer: Option<&'a Buffer>, - /// Transform buffer offset in bytes (optional, required if transform buffer is present). - pub transform_buffer_offset: Option, -} -static_assertions::assert_impl_all!(BlasTriangleGeometry: Send, Sync); - -#[derive(Debug)] -/// Geometries for a bottom level acceleration structure. -pub enum BlasGeometries<'a> { - /// Triangle geometry variant. - TriangleGeometries(&'a [BlasTriangleGeometry<'a>]), -} -static_assertions::assert_impl_all!(BlasGeometries: Send, Sync); - -/// Entry for a bottom level acceleration structure build. -pub struct BlasBuildEntry<'a> { - /// Reference to the acceleration structure. - pub blas: &'a Blas, - /// Reference to the geometries. - pub geometry: &'a BlasGeometries<'a>, -} -static_assertions::assert_impl_all!(BlasBuildEntry: Send, Sync); - -#[derive(Debug)] -/// Bottom level acceleration structure. -/// Used to represent a collection of geometries for ray tracing inside a top level acceleration structure. -pub struct Blas { - context: Arc, - id: ObjectId, - data: Box, - handle: Option, -} -static_assertions::assert_impl_all!(Blas: Send, Sync); - -impl Blas { - /// Raw handle to the acceleration structure, used inside raw instance buffers. - pub fn handle(&self) -> Option { - self.handle - } - /// Destroy the associated native resources as soon as possible. - pub fn destroy(&self) { - DynContext::blas_destroy(&*self.context, &self.id, self.data.as_ref()); - } -} - -impl Drop for Blas { - fn drop(&mut self) { - if !thread::panicking() { - self.context.blas_drop(&self.id, self.data.as_ref()); - } - } -} - -#[derive(Debug)] -/// Top level acceleration structure. -/// Used to represent a collection of bottom level acceleration structure instances for ray tracing. -pub struct Tlas { - context: Arc, - id: ObjectId, - data: Box, -} -static_assertions::assert_impl_all!(Tlas: Send, Sync); - -impl Tlas { - /// Destroy the associated native resources as soon as possible. - pub fn destroy(&self) { - DynContext::tlas_destroy(&*self.context, &self.id, self.data.as_ref()); - } -} - -impl Drop for Tlas { - fn drop(&mut self) { - if !thread::panicking() { - self.context.tlas_drop(&self.id, self.data.as_ref()); - } - } -} - -/// Entry for a top level acceleration structure build. -/// Used with raw instance buffers for a unvalidated builds. -pub struct TlasBuildEntry<'a> { - /// Reference to the acceleration structure. - pub tlas: &'a Tlas, - /// Reference to the raw instance buffer. - pub instance_buffer: &'a Buffer, - /// Number of instances in the instance buffer. - pub instance_count: u32, -} -static_assertions::assert_impl_all!(TlasBuildEntry: Send, Sync); - -/// Safe instance for a top level acceleration structure. -#[derive(Debug, Clone)] -pub struct TlasInstance { - blas: ObjectId, - /// Affine transform matrix 3x4 (rows x columns, row mayor order). - pub transform: [f32; 12], - /// Custom index for the instance used inside the shader (max 24 bits). - pub custom_index: u32, - /// Mask for the instance used inside the shader to filter instances. - pub mask: u8, -} - -impl TlasInstance { - /// Construct TlasInstance. - /// - blas: Reference to the bottom level acceleration structure - /// - transform: Transform buffer offset in bytes (optional, required if transform buffer is present) - /// - custom_index: Custom index for the instance used inside the shader (max 24 bits) - /// - mask: Mask for the instance used inside the shader to filter instances - pub fn new(blas: &Blas, transform: [f32; 12], custom_index: u32, mask: u8) -> Self { - Self { - blas: blas.id, - transform, - custom_index, - mask, - } - } - - /// Set the bottom level acceleration structure. - pub fn set_blas(&mut self, blas: &Blas) { - self.blas = blas.id; - } -} - -pub(crate) struct DynContextTlasInstance<'a> { - blas: ObjectId, - transform: &'a [f32; 12], - custom_index: u32, - mask: u8, -} - -/// [Context version] see `TlasInstance`. -pub struct ContextTlasInstance<'a, T: Context> { - blas_id: T::BlasId, - transform: &'a [f32; 12], - custom_index: u32, - mask: u8, -} - -/// The safe version of TlasEntry, containing TlasInstances instead of a raw buffer. -pub struct TlasPackage { - tlas: Tlas, - instances: Vec>, - lowest_unmodified: u32, -} -static_assertions::assert_impl_all!(TlasPackage: Send, Sync); - -impl TlasPackage { - /// Construct TlasPackage consuming the Tlas (prevents modification of the Tlas without using this package). - /// (max_instances needs to fit into tlas) - pub fn new(tlas: Tlas, max_instances: u32) -> Self { - Self::new_with_instances(tlas, vec![None; max_instances as usize]) - } - - /// Construct TlasPackage consuming the Tlas (prevents modification of the Tlas without using this package). - /// This contructor moves the instances into the package (the number of instances needs to fit into tlas). - pub fn new_with_instances(tlas: Tlas, instances: Vec>) -> Self { - Self { - tlas, - lowest_unmodified: instances.len() as u32, - instances, - } - } - - /// Get a reference to all instances. - pub fn get(&self) -> &[Option] { - &self.instances - } - - /// Get a mutable slice to a range of instances. - /// Returns None if the range is out of bounds. - /// All elements from the lowest accessed index up are marked as modified. - /// For better performance it is recommended to reduce access to low elements. - pub fn get_mut_slice(&mut self, range: Range) -> Option<&mut [Option]> { - if range.end > self.instances.len() { - return None; - } - if range.end as u32 > self.lowest_unmodified { - self.lowest_unmodified = range.end as u32; - } - Some(&mut self.instances[range]) - } - - /// Get a single mutable reference to an instance. - /// Returns None if the range is out of bounds. - /// All elements from the lowest accessed index up are marked as modified. - /// For better performance it is recommended to reduce access to low elements. - pub fn get_mut_single(&mut self, index: usize) -> Option<&mut Option> { - if index >= self.instances.len() { - return None; - } - if index as u32 + 1 > self.lowest_unmodified { - self.lowest_unmodified = index as u32 + 1; - } - Some(&mut self.instances[index]) - } -} - -pub(crate) struct DynContextBlasTriangleGeometry<'a> { - size: &'a BlasTriangleGeometrySizeDescriptor, - vertex_buffer: ObjectId, - index_buffer: Option, - transform_buffer: Option, - first_vertex: u32, - vertex_stride: wgt::BufferAddress, - index_buffer_offset: Option, - transform_buffer_offset: Option, -} - -pub(crate) enum DynContextBlasGeometries<'a> { - TriangleGeometries(Box> + 'a>), -} - -pub(crate) struct DynContextBlasBuildEntry<'a> { - blas_id: ObjectId, - geometries: DynContextBlasGeometries<'a>, -} - -pub(crate) struct DynContextTlasBuildEntry { - tlas_id: ObjectId, - instance_buffer_id: ObjectId, - instance_count: u32, -} - -pub(crate) struct DynContextTlasPackage<'a> { - tlas_id: ObjectId, - instances: Box>> + 'a>, - lowest_unmodified: u32, -} - -/// [Context version] see `BlasTriangleGeometry`. -pub struct ContextBlasTriangleGeometry<'a, T: Context> { - size: &'a BlasTriangleGeometrySizeDescriptor, - vertex_buffer: T::BufferId, - index_buffer: Option, - transform_buffer: Option, - first_vertex: u32, - vertex_stride: wgt::BufferAddress, - index_buffer_offset: Option, - transform_buffer_offset: Option, -} - -/// [Context version] see `BlasGeometries`. -pub enum ContextBlasGeometries<'a, T: Context> { - /// Triangle geometries. - TriangleGeometries(Box> + 'a>), -} - -/// [Context version] see `BlasBuildEntry`. -pub struct ContextBlasBuildEntry<'a, T: Context> { - blas_id: T::BlasId, - geometries: ContextBlasGeometries<'a, T>, -} - -/// [Context version] see `TlasBuildEntry`. -pub struct ContextTlasBuildEntry { - tlas_id: T::TlasId, - instance_buffer_id: T::BufferId, - instance_count: u32, -} - -/// [Context version] see `TlasPackage`. -pub struct ContextTlasPackage<'a, T: Context> { - tlas_id: T::TlasId, - instances: Box>> + 'a>, - lowest_unmodified: u32, -} diff --git a/wgpu/src/ray_tracing.rs b/wgpu/src/ray_tracing.rs new file mode 100644 index 0000000000..8d1dd6434a --- /dev/null +++ b/wgpu/src/ray_tracing.rs @@ -0,0 +1,533 @@ +use std::{fmt::Debug, ops::Range, sync::Arc, thread}; + +use crate::{ + context::{Context, DynContext, ObjectId}, + Buffer, CommandEncoder, Data, Device, Label, C, +}; + +/// Descriptor for the size defining attributes of a triangle geometry, for a bottom level acceleration structure. +pub type BlasTriangleGeometrySizeDescriptor = wgt::BlasTriangleGeometrySizeDescriptor; +static_assertions::assert_impl_all!(BlasTriangleGeometrySizeDescriptor: Send, Sync); + +/// Descriptor for the size defining attributes, for a bottom level acceleration structure. +pub type BlasGeometrySizeDescriptors = wgt::BlasGeometrySizeDescriptors; +static_assertions::assert_impl_all!(BlasGeometrySizeDescriptors: Send, Sync); + +/// Flags for an acceleration structure. +pub type AccelerationStructureFlags = wgt::AccelerationStructureFlags; +static_assertions::assert_impl_all!(AccelerationStructureFlags: Send, Sync); + +/// Flags for a geometry inside a bottom level acceleration structure. +pub type AccelerationStructureGeometryFlags = wgt::AccelerationStructureGeometryFlags; +static_assertions::assert_impl_all!(AccelerationStructureGeometryFlags: Send, Sync); + +/// Update mode for acceleration structure builds. +pub type AccelerationStructureUpdateMode = wgt::AccelerationStructureUpdateMode; +static_assertions::assert_impl_all!(AccelerationStructureUpdateMode: Send, Sync); + +/// Descriptor to create bottom level acceleration structures. +pub type CreateBlasDescriptor<'a> = wgt::CreateBlasDescriptor>; +static_assertions::assert_impl_all!(CreateBlasDescriptor: Send, Sync); + +/// Descriptor to create top level acceleration structures. +pub type CreateTlasDescriptor<'a> = wgt::CreateTlasDescriptor>; +static_assertions::assert_impl_all!(CreateTlasDescriptor: Send, Sync); + +#[derive(Debug)] +/// Definition for a triangle geometry. +/// The size must match the rest of the structures fields, otherwise the build will fail. +/// (e.g. if a index count is present in the size, the index buffer must be present as well.) +pub struct BlasTriangleGeometry<'a> { + /// Sub descriptor for the size defining attributes of a triangle geometry. + pub size: &'a BlasTriangleGeometrySizeDescriptor, + /// Vertex buffer. + pub vertex_buffer: &'a Buffer, + /// Offset into the vertex buffer as a factor of the vertex stride. + pub first_vertex: u32, + /// Vertex stride. + pub vertex_stride: wgt::BufferAddress, + /// Index buffer (optional). + pub index_buffer: Option<&'a Buffer>, + /// Index buffer offset in bytes (optional, required if index buffer is present). + pub index_buffer_offset: Option, + /// Transform buffer containing 3x4 (rows x columns, row mayor) affine transform matrices `[f32; 12]` (optional). + pub transform_buffer: Option<&'a Buffer>, + /// Transform buffer offset in bytes (optional, required if transform buffer is present). + pub transform_buffer_offset: Option, +} +static_assertions::assert_impl_all!(BlasTriangleGeometry: Send, Sync); + +#[derive(Debug)] +/// Geometries for a bottom level acceleration structure. +pub enum BlasGeometries<'a> { + /// Triangle geometry variant. + TriangleGeometries(&'a [BlasTriangleGeometry<'a>]), +} +static_assertions::assert_impl_all!(BlasGeometries: Send, Sync); + +/// Entry for a bottom level acceleration structure build. +pub struct BlasBuildEntry<'a> { + /// Reference to the acceleration structure. + pub blas: &'a Blas, + /// Reference to the geometries. + pub geometry: &'a BlasGeometries<'a>, +} +static_assertions::assert_impl_all!(BlasBuildEntry: Send, Sync); + +#[derive(Debug)] +/// Bottom level acceleration structure. +/// Used to represent a collection of geometries for ray tracing inside a top level acceleration structure. +pub struct Blas { + pub(crate) context: Arc, + pub(crate) id: ObjectId, + pub(crate) data: Box, + pub(crate) handle: Option, +} +static_assertions::assert_impl_all!(Blas: Send, Sync); + +impl Blas { + /// Raw handle to the acceleration structure, used inside raw instance buffers. + pub fn handle(&self) -> Option { + self.handle + } + /// Destroy the associated native resources as soon as possible. + pub fn destroy(&self) { + DynContext::blas_destroy(&*self.context, &self.id, self.data.as_ref()); + } +} + +impl Drop for Blas { + fn drop(&mut self) { + if !thread::panicking() { + self.context.blas_drop(&self.id, self.data.as_ref()); + } + } +} + +#[derive(Debug)] +/// Top level acceleration structure. +/// Used to represent a collection of bottom level acceleration structure instances for ray tracing. +pub struct Tlas { + pub(crate) context: Arc, + pub(crate) id: ObjectId, + pub(crate) data: Box, +} +static_assertions::assert_impl_all!(Tlas: Send, Sync); + +impl Tlas { + /// Destroy the associated native resources as soon as possible. + pub fn destroy(&self) { + DynContext::tlas_destroy(&*self.context, &self.id, self.data.as_ref()); + } +} + +impl Drop for Tlas { + fn drop(&mut self) { + if !thread::panicking() { + self.context.tlas_drop(&self.id, self.data.as_ref()); + } + } +} + +/// Entry for a top level acceleration structure build. +/// Used with raw instance buffers for a unvalidated builds. +pub struct TlasBuildEntry<'a> { + /// Reference to the acceleration structure. + pub tlas: &'a Tlas, + /// Reference to the raw instance buffer. + pub instance_buffer: &'a Buffer, + /// Number of instances in the instance buffer. + pub instance_count: u32, +} +static_assertions::assert_impl_all!(TlasBuildEntry: Send, Sync); + +/// Safe instance for a top level acceleration structure. +#[derive(Debug, Clone)] +pub struct TlasInstance { + pub(crate) blas: ObjectId, + /// Affine transform matrix 3x4 (rows x columns, row mayor order). + pub transform: [f32; 12], + /// Custom index for the instance used inside the shader (max 24 bits). + pub custom_index: u32, + /// Mask for the instance used inside the shader to filter instances. + pub mask: u8, +} + +impl TlasInstance { + /// Construct TlasInstance. + /// - blas: Reference to the bottom level acceleration structure + /// - transform: Transform buffer offset in bytes (optional, required if transform buffer is present) + /// - custom_index: Custom index for the instance used inside the shader (max 24 bits) + /// - mask: Mask for the instance used inside the shader to filter instances + pub fn new(blas: &Blas, transform: [f32; 12], custom_index: u32, mask: u8) -> Self { + Self { + blas: blas.id, + transform, + custom_index, + mask, + } + } + + /// Set the bottom level acceleration structure. + pub fn set_blas(&mut self, blas: &Blas) { + self.blas = blas.id; + } +} + +pub(crate) struct DynContextTlasInstance<'a> { + pub(crate) blas: ObjectId, + pub(crate) transform: &'a [f32; 12], + pub(crate) custom_index: u32, + pub(crate) mask: u8, +} + +/// [Context version] see `TlasInstance`. +pub struct ContextTlasInstance<'a, T: Context> { + pub(crate) blas_id: T::BlasId, + pub(crate) transform: &'a [f32; 12], + pub(crate) custom_index: u32, + pub(crate) mask: u8, +} + +/// The safe version of TlasEntry, containing TlasInstances instead of a raw buffer. +pub struct TlasPackage { + pub(crate) tlas: Tlas, + pub(crate) instances: Vec>, + pub(crate) lowest_unmodified: u32, +} +static_assertions::assert_impl_all!(TlasPackage: Send, Sync); + +impl TlasPackage { + /// Construct TlasPackage consuming the Tlas (prevents modification of the Tlas without using this package). + /// (max_instances needs to fit into tlas) + pub fn new(tlas: Tlas, max_instances: u32) -> Self { + Self::new_with_instances(tlas, vec![None; max_instances as usize]) + } + + /// Construct TlasPackage consuming the Tlas (prevents modification of the Tlas without using this package). + /// This contructor moves the instances into the package (the number of instances needs to fit into tlas). + pub fn new_with_instances(tlas: Tlas, instances: Vec>) -> Self { + Self { + tlas, + lowest_unmodified: instances.len() as u32, + instances, + } + } + + /// Get a reference to all instances. + pub fn get(&self) -> &[Option] { + &self.instances + } + + /// Get a mutable slice to a range of instances. + /// Returns None if the range is out of bounds. + /// All elements from the lowest accessed index up are marked as modified. + /// For better performance it is recommended to reduce access to low elements. + pub fn get_mut_slice(&mut self, range: Range) -> Option<&mut [Option]> { + if range.end > self.instances.len() { + return None; + } + if range.end as u32 > self.lowest_unmodified { + self.lowest_unmodified = range.end as u32; + } + Some(&mut self.instances[range]) + } + + /// Get a single mutable reference to an instance. + /// Returns None if the range is out of bounds. + /// All elements from the lowest accessed index up are marked as modified. + /// For better performance it is recommended to reduce access to low elements. + pub fn get_mut_single(&mut self, index: usize) -> Option<&mut Option> { + if index >= self.instances.len() { + return None; + } + if index as u32 + 1 > self.lowest_unmodified { + self.lowest_unmodified = index as u32 + 1; + } + Some(&mut self.instances[index]) + } +} + +pub(crate) struct DynContextBlasTriangleGeometry<'a> { + pub(crate) size: &'a BlasTriangleGeometrySizeDescriptor, + pub(crate) vertex_buffer: ObjectId, + pub(crate) index_buffer: Option, + pub(crate) transform_buffer: Option, + pub(crate) first_vertex: u32, + pub(crate) vertex_stride: wgt::BufferAddress, + pub(crate) index_buffer_offset: Option, + pub(crate) transform_buffer_offset: Option, +} + +pub(crate) enum DynContextBlasGeometries<'a> { + TriangleGeometries(Box> + 'a>), +} + +pub(crate) struct DynContextBlasBuildEntry<'a> { + pub(crate) blas_id: ObjectId, + pub(crate) geometries: DynContextBlasGeometries<'a>, +} + +pub(crate) struct DynContextTlasBuildEntry { + pub(crate) tlas_id: ObjectId, + pub(crate) instance_buffer_id: ObjectId, + pub(crate) instance_count: u32, +} + +pub(crate) struct DynContextTlasPackage<'a> { + pub(crate) tlas_id: ObjectId, + pub(crate) instances: Box>> + 'a>, + pub(crate) lowest_unmodified: u32, +} + +/// [Context version] see `BlasTriangleGeometry`. +pub struct ContextBlasTriangleGeometry<'a, T: Context> { + pub(crate) size: &'a BlasTriangleGeometrySizeDescriptor, + pub(crate) vertex_buffer: T::BufferId, + pub(crate) index_buffer: Option, + pub(crate) transform_buffer: Option, + pub(crate) first_vertex: u32, + pub(crate) vertex_stride: wgt::BufferAddress, + pub(crate) index_buffer_offset: Option, + pub(crate) transform_buffer_offset: Option, +} + +/// [Context version] see `BlasGeometries`. +pub enum ContextBlasGeometries<'a, T: Context> { + /// Triangle geometries. + TriangleGeometries(Box> + 'a>), +} + +/// [Context version] see `BlasBuildEntry`. +pub struct ContextBlasBuildEntry<'a, T: Context> { + pub(crate) blas_id: T::BlasId, + pub(crate) geometries: ContextBlasGeometries<'a, T>, +} + +/// [Context version] see `TlasBuildEntry`. +pub struct ContextTlasBuildEntry { + pub(crate) tlas_id: T::TlasId, + pub(crate) instance_buffer_id: T::BufferId, + pub(crate) instance_count: u32, +} + +/// [Context version] see `TlasPackage`. +pub struct ContextTlasPackage<'a, T: Context> { + pub(crate) tlas_id: T::TlasId, + pub(crate) instances: Box>> + 'a>, + pub(crate) lowest_unmodified: u32, +} + +/// Utility module to add traits for the device and command encoder. +pub mod traits { + pub use super::{CommandEncoderRayTracing as _, DeviceRayTracing as _}; +} + +/// Trait to add ray tracing functions to a [`Device`]. +pub trait DeviceRayTracing { + /// Create a bottom level acceleration structure, used inside a top level acceleration structure for ray tracing. + /// - desc: The descriptor of the acceleration structure. + /// - sizes: Size descriptor limiting what can be built into the acceleration structure. + fn create_blas( + &self, + desc: &CreateBlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, + ) -> Blas; + + /// Create a top level acceleration structure, used for ray tracing. + /// - desc: The descriptor of the acceleration structure. + fn create_tlas(&self, desc: &CreateTlasDescriptor) -> Tlas; +} + +impl DeviceRayTracing for Device { + fn create_blas( + &self, + desc: &CreateBlasDescriptor, + sizes: wgt::BlasGeometrySizeDescriptors, + ) -> Blas { + let (id, handle, data) = DynContext::device_create_blas( + &*self.context, + &self.id, + self.data.as_ref(), + desc, + sizes, + ); + + Blas { + context: Arc::clone(&self.context), + id, + data, + handle, + } + } + + fn create_tlas(&self, desc: &CreateTlasDescriptor) -> Tlas { + let (id, data) = + DynContext::device_create_tlas(&*self.context, &self.id, self.data.as_ref(), desc); + + Tlas { + context: Arc::clone(&self.context), + id, + data, + } + } +} + +/// Trait to add ray tracing functions to a [`CommandEncoder`]. +pub trait CommandEncoderRayTracing { + /// Build bottom and top level acceleration structures. + /// - blas: Iterator of bottom level acceleration structure entries to build + /// For each entry, the provided size descriptor must be strictly smaller or equal to the descriptor given at bottom level acceleration structure creation: + /// - Less or equal number of geometries + /// - Same kind of geometry (with index buffer or without) (same vertex/index format) + /// - Same flags + /// - Less or equal number of vertices + /// - Less or equal number of indices (if applicable) + /// - tlas: iterator of top level acceleration structure packages to build + /// + /// A bottom level acceleration structure may be build and used as a reference in a top level acceleration structure in the same invocation of this function. + /// + /// # Bind group usage + /// + /// When a top level acceleration structure is used in a bind group, some validation takes place: + /// - The top level acceleration structure is valid and has been built. + /// - All the bottom level acceleration structures referenced by the top level acceleration structure are valid and have been built prior, + /// or at same time as the containing top level acceleration structure. + fn build_acceleration_structures<'a>( + &mut self, + blas: impl IntoIterator>, + tlas: impl IntoIterator, + ); + + /// Build bottom and top level acceleration structures. + /// See [`build_acceleration_structures`] for the safe version and more details. + /// + /// # Safety + /// + /// - The contents of the raw instance buffer must be valid for the underling api. + /// - All bottom level acceleration structures, referenced in the raw instance buffer must be valid and built, + /// when the corresponding top level acceleration structure is built. (builds may happen in the same invocation of this function). + /// - At the time when the top level acceleration structure is used in a bind group, all associated bottom level acceleration structures must be valid, + /// and built (no later than the time when the top level acceleration structure was built). + unsafe fn build_acceleration_structures_unsafe_tlas<'a>( + &mut self, + blas: impl IntoIterator>, + tlas: impl IntoIterator>, + ); +} + +impl CommandEncoderRayTracing for CommandEncoder { + fn build_acceleration_structures<'a>( + &mut self, + blas: impl IntoIterator>, + tlas: impl IntoIterator, + ) { + let id = self.id.as_ref().unwrap(); + + let mut blas = blas.into_iter().map(|e: &BlasBuildEntry| { + let geometries = match e.geometry { + BlasGeometries::TriangleGeometries(triangle_geometries) => { + let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry| { + DynContextBlasTriangleGeometry { + size: tg.size, + vertex_buffer: tg.vertex_buffer.id, + + index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.id), + + transform_buffer: tg + .transform_buffer + .map(|transform_buffer| transform_buffer.id), + + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + } + }); + DynContextBlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + DynContextBlasBuildEntry { + blas_id: e.blas.id, + geometries, + } + }); + + let mut tlas = tlas.into_iter().map(|e: &TlasPackage| { + let instances = e.instances.iter().map(|instance: &Option| { + instance.as_ref().map(|instance| DynContextTlasInstance { + blas: instance.blas, + transform: &instance.transform, + custom_index: instance.custom_index, + mask: instance.mask, + }) + }); + DynContextTlasPackage { + tlas_id: e.tlas.id, + instances: Box::new(instances), + lowest_unmodified: e.lowest_unmodified, + } + }); + + DynContext::command_encoder_build_acceleration_structures( + &*self.context, + id, + self.data.as_ref(), + &mut blas, + &mut tlas, + ); + } + + unsafe fn build_acceleration_structures_unsafe_tlas<'a>( + &mut self, + blas: impl IntoIterator>, + tlas: impl IntoIterator>, + ) { + let id = self.id.as_ref().unwrap(); + + let mut blas = blas.into_iter().map(|e: &BlasBuildEntry| { + let geometries = match e.geometry { + BlasGeometries::TriangleGeometries(triangle_geometries) => { + let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry| { + DynContextBlasTriangleGeometry { + size: tg.size, + vertex_buffer: tg.vertex_buffer.id, + + index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.id), + + transform_buffer: tg + .transform_buffer + .map(|transform_buffer| transform_buffer.id), + + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + } + }); + DynContextBlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + DynContextBlasBuildEntry { + blas_id: e.blas.id, + geometries, + } + }); + + let mut tlas = tlas + .into_iter() + .map(|e: &TlasBuildEntry| DynContextTlasBuildEntry { + tlas_id: e.tlas.id, + instance_buffer_id: e.instance_buffer.id, + instance_count: e.instance_count, + }); + + DynContext::command_encoder_build_acceleration_structures_unsafe_tlas( + &*self.context, + id, + self.data.as_ref(), + &mut blas, + &mut tlas, + ); + } +} From 90a52403ca2feaf6730a3e6c663846eaee55db28 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sun, 9 Apr 2023 16:54:46 +0200 Subject: [PATCH 068/146] simplified example --- wgpu/examples/ray-cube-fragment/main.rs | 37 +++++-------------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/wgpu/examples/ray-cube-fragment/main.rs b/wgpu/examples/ray-cube-fragment/main.rs index a454d30990..210c5054bf 100644 --- a/wgpu/examples/ray-cube-fragment/main.rs +++ b/wgpu/examples/ray-cube-fragment/main.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, future::Future, iter, mem, pin::Pin, task, time::Instant}; use bytemuck::{Pod, Zeroable}; -use glam::{Affine3A, Mat4, Quat, Vec3}; +use glam::{Mat4, Quat, Vec3}; use wgpu::util::DeviceExt; use rt::traits::*; @@ -71,28 +71,6 @@ fn create_vertices() -> (Vec, Vec) { (vertex_data.to_vec(), index_data.to_vec()) } -#[inline] -fn affine_to_rows(mat: &Affine3A) -> [f32; 12] { - let row_0 = mat.matrix3.row(0); - let row_1 = mat.matrix3.row(1); - let row_2 = mat.matrix3.row(2); - let translation = mat.translation; - [ - row_0.x, - row_0.y, - row_0.z, - translation.x, - row_1.x, - row_1.y, - row_1.z, - translation.y, - row_2.x, - row_2.y, - row_2.z, - translation.z, - ] -} - #[repr(C)] #[derive(Clone, Copy, Pod, Zeroable)] struct Uniforms { @@ -137,11 +115,7 @@ struct Example { impl framework::Example for Example { fn required_features() -> wgpu::Features { - wgpu::Features::TEXTURE_BINDING_ARRAY - | wgpu::Features::STORAGE_RESOURCE_BINDING_ARRAY - | wgpu::Features::VERTEX_WRITABLE_STORAGE - | wgpu::Features::RAY_QUERY - | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE + wgpu::Features::RAY_QUERY | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE } fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities { @@ -353,7 +327,7 @@ impl framework::Example for Example { let x = x * 2.0 - 1.0; let y = y * 2.0 - 1.0; - let transform = affine_to_rows(&Affine3A::from_rotation_translation( + let transform = Mat4::from_rotation_translation( Quat::from_euler( glam::EulerRot::XYZ, anim_time * 0.5 * 0.342, @@ -365,7 +339,10 @@ impl framework::Example for Example { y: y * dist, z: -24.0, }, - )); + ); + let transform = transform.transpose().to_cols_array()[..12] + .try_into() + .unwrap(); *instance = Some(rt::TlasInstance::new(&self.blas, transform, 0, 0xff)); } From 21193918b24bfeea77cda2b3a021e41373bb70f6 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 10 Apr 2023 10:05:06 +0200 Subject: [PATCH 069/146] removed incorrect validation --- wgpu-core/src/command/ray_tracing.rs | 16 ---------------- wgpu-core/src/ray_tracing.rs | 3 --- 2 files changed, 19 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 98ebd7c915..b39e948911 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -293,14 +293,6 @@ impl Global { let index_buffer_size = mesh.size.index_count.unwrap() as u64 * index_stride; - if mesh.size.index_count.unwrap() as u64 - - mesh.index_buffer_offset.unwrap() / index_stride - < 3 - { - return Err(BuildAccelerationStructureError::EmptyIndexBuffer( - index_id, - )); - } if mesh.size.index_count.unwrap() % 3 != 0 { return Err(BuildAccelerationStructureError::InvalidIndexCount( index_id, @@ -920,14 +912,6 @@ impl Global { let index_buffer_size = mesh.size.index_count.unwrap() as u64 * index_stride; - if mesh.size.index_count.unwrap() as u64 - - mesh.index_buffer_offset.unwrap() / index_stride - < 3 - { - return Err(BuildAccelerationStructureError::EmptyIndexBuffer( - index_id, - )); - } if mesh.size.index_count.unwrap() % 3 != 0 { return Err(BuildAccelerationStructureError::InvalidIndexCount( index_id, diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 92da9bf3c8..c8361ded3b 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -64,9 +64,6 @@ pub enum BuildAccelerationStructureError { #[error("Buffer {0:?} associated vertex buffer sizes invalid (no vertices)")] EmptyVertexBuffer(BufferId), - #[error("Buffer {0:?} associated index buffer sizes invalid (less then three indices)")] - EmptyIndexBuffer(BufferId), - #[error("Buffer {0:?} associated offset doesn't align with the index type")] UnalignedIndexBufferOffset(BufferId), From d9a4ebd2154ef55e3bf7dd3745a997f59ee4c02f Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 10 Apr 2023 10:07:01 +0200 Subject: [PATCH 070/146] WIP build api changes --- wgpu-core/src/command/ray_tracing.rs | 2 +- wgpu/examples/ray-cube-compute/main.rs | 2 +- wgpu/examples/ray-cube-fragment/main.rs | 2 +- wgpu/src/ray_tracing.rs | 16 ++++------------ 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index b39e948911..efd5de588e 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1279,7 +1279,7 @@ impl Global { if tlas_present { unsafe { - if let Some(staging_buffer) = &staging_buffer { + if let Some(ref staging_buffer) = staging_buffer { cmd_buf_raw.transition_buffers(iter::once(hal::BufferBarrier:: { buffer: staging_buffer, usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, diff --git a/wgpu/examples/ray-cube-compute/main.rs b/wgpu/examples/ray-cube-compute/main.rs index 5918c7796e..20d5b6d170 100644 --- a/wgpu/examples/ray-cube-compute/main.rs +++ b/wgpu/examples/ray-cube-compute/main.rs @@ -493,7 +493,7 @@ impl framework::Example for Example { encoder.build_acceleration_structures( iter::once(&rt::BlasBuildEntry { blas: &blas, - geometry: &rt::BlasGeometries::TriangleGeometries(&[rt::BlasTriangleGeometry { + geometry: rt::BlasGeometries::TriangleGeometries(&[rt::BlasTriangleGeometry { size: &blas_geo_size_desc, vertex_buffer: &vertex_buf, first_vertex: 0, diff --git a/wgpu/examples/ray-cube-fragment/main.rs b/wgpu/examples/ray-cube-fragment/main.rs index 210c5054bf..9520b1a101 100644 --- a/wgpu/examples/ray-cube-fragment/main.rs +++ b/wgpu/examples/ray-cube-fragment/main.rs @@ -246,7 +246,7 @@ impl framework::Example for Example { encoder.build_acceleration_structures( iter::once(&rt::BlasBuildEntry { blas: &blas, - geometry: &rt::BlasGeometries::TriangleGeometries(&[rt::BlasTriangleGeometry { + geometry: rt::BlasGeometries::TriangleGeometries(&[rt::BlasTriangleGeometry { size: &blas_geo_size_desc, vertex_buffer: &vertex_buf, first_vertex: 0, diff --git a/wgpu/src/ray_tracing.rs b/wgpu/src/ray_tracing.rs index 8d1dd6434a..51bf2838ed 100644 --- a/wgpu/src/ray_tracing.rs +++ b/wgpu/src/ray_tracing.rs @@ -69,8 +69,8 @@ static_assertions::assert_impl_all!(BlasGeometries: Send, Sync); pub struct BlasBuildEntry<'a> { /// Reference to the acceleration structure. pub blas: &'a Blas, - /// Reference to the geometries. - pub geometry: &'a BlasGeometries<'a>, + /// Geometries. + pub geometry: BlasGeometries<'a>, } static_assertions::assert_impl_all!(BlasBuildEntry: Send, Sync); @@ -328,11 +328,7 @@ pub trait DeviceRayTracing { /// Create a bottom level acceleration structure, used inside a top level acceleration structure for ray tracing. /// - desc: The descriptor of the acceleration structure. /// - sizes: Size descriptor limiting what can be built into the acceleration structure. - fn create_blas( - &self, - desc: &CreateBlasDescriptor, - sizes: wgt::BlasGeometrySizeDescriptors, - ) -> Blas; + fn create_blas(&self, desc: &CreateBlasDescriptor, sizes: BlasGeometrySizeDescriptors) -> Blas; /// Create a top level acceleration structure, used for ray tracing. /// - desc: The descriptor of the acceleration structure. @@ -340,11 +336,7 @@ pub trait DeviceRayTracing { } impl DeviceRayTracing for Device { - fn create_blas( - &self, - desc: &CreateBlasDescriptor, - sizes: wgt::BlasGeometrySizeDescriptors, - ) -> Blas { + fn create_blas(&self, desc: &CreateBlasDescriptor, sizes: BlasGeometrySizeDescriptors) -> Blas { let (id, handle, data) = DynContext::device_create_blas( &*self.context, &self.id, From f981b4568a41d246bd2476ac45a7e30a9d9acc0b Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 10 Apr 2023 10:08:34 +0200 Subject: [PATCH 071/146] WIP new example --- wgpu/Cargo.toml | 4 + wgpu/examples/ray-scene/main.rs | 495 ++++++++++++++++++++++++++++ wgpu/examples/ray-scene/shader.wgsl | 74 +++++ 3 files changed, 573 insertions(+) create mode 100644 wgpu/examples/ray-scene/main.rs create mode 100644 wgpu/examples/ray-scene/shader.wgsl diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index bccf1b27d2..5c84fbada2 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -93,6 +93,10 @@ test = true name = "ray-cube-fragment" test = true +[[example]] +name = "ray-scene" +test = false + [features] default = ["wgsl"] # Apply run-time checks, even in release builds. These are in addition diff --git a/wgpu/examples/ray-scene/main.rs b/wgpu/examples/ray-scene/main.rs new file mode 100644 index 0000000000..6c76753d6e --- /dev/null +++ b/wgpu/examples/ray-scene/main.rs @@ -0,0 +1,495 @@ +use std::{borrow::Cow, future::Future, iter, mem, ops::Range, pin::Pin, task, time::Instant}; + +use bytemuck::{Pod, Zeroable}; +use glam::{Mat4, Quat, Vec3}; +use wgpu::util::DeviceExt; + +use rt::traits::*; +use wgpu::ray_tracing as rt; + +#[path = "../framework.rs"] +mod framework; + +// from cube +#[repr(C)] +#[derive(Debug, Clone, Copy, Pod, Zeroable)] +struct Vertex { + _pos: [f32; 3], + _tex_coord: [f32; 2], +} + +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +struct Uniforms { + view_inverse: [[f32; 4]; 4], + proj_inverse: [[f32; 4]; 4], +} + +/// A wrapper for `pop_error_scope` futures that panics if an error occurs. +/// +/// Given a future `inner` of an `Option` for some error type `E`, +/// wait for the future to be ready, and panic if its value is `Some`. +/// +/// This can be done simpler with `FutureExt`, but we don't want to add +/// a dependency just for this small case. +struct ErrorFuture { + inner: F, +} +impl>> Future for ErrorFuture { + type Output = (); + fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<()> { + let inner = unsafe { self.map_unchecked_mut(|me| &mut me.inner) }; + inner.poll(cx).map(|error| { + if let Some(e) = error { + panic!("Rendering {e}"); + } + }) + } +} + +#[derive(Debug, Clone, Default)] +struct RawSceneComponents { + vertices: Vec, + indices: Vec, + geometries: Vec>, + instances: Vec<(Range, Range)>, //vertex range, geometry range +} + +#[allow(dead_code)] +struct SceneComponents { + vertices: wgpu::Buffer, + indices: wgpu::Buffer, + geometries: wgpu::Buffer, + instances: wgpu::Buffer, + bottom_level_acceleration_structures: Vec, +} + +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +struct InstanceEntry { + first_vertex: u32, + first_geometry: u32, +} + +fn load_model(scene: &mut RawSceneComponents, source: &[u8]) { + let data = obj::ObjData::load_buf(&source[..]).unwrap(); + + let start_vertex_index = scene.vertices.len(); + let start_geometry_index = scene.geometries.len(); + + scene.vertices.extend( + data.position + .iter() + // .zip(data.normal.iter()) + .map(|pos| Vertex { + _pos: *pos, + _tex_coord: [0.0, 0.0], + }), + ); + + for object in data.objects { + for group in object.groups { + let start_index_index = scene.indices.len(); + for poly in group.polys { + for end_index in 2..poly.0.len() { + for &index in &[0, end_index - 1, end_index] { + let obj::IndexTuple(position_id, _texture_id, _normal_id) = poly.0[index]; + scene.indices.push(position_id as u16); + } + } + } + scene + .geometries + .push(start_index_index..scene.indices.len()); + } + } + scene.instances.push(( + start_vertex_index..scene.vertices.len(), + start_geometry_index..scene.geometries.len(), + )); +} + +fn upload_scene_components( + device: &wgpu::Device, + queue: &wgpu::Queue, + scene: &RawSceneComponents, +) -> SceneComponents { + let geometry_buffer_content = scene + .geometries + .iter() + .map(|geometry| geometry.start as u32) + .collect::>(); + + let instance_buffer_content = scene + .instances + .iter() + .map(|geometry| InstanceEntry { + first_vertex: geometry.0.start as u32, + first_geometry: geometry.1.start as u32, + }) + .collect::>(); + + let vertices = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertices"), + contents: bytemuck::cast_slice(&scene.vertices), + usage: wgpu::BufferUsages::VERTEX + | wgpu::BufferUsages::STORAGE + | wgpu::BufferUsages::BLAS_INPUT, + }); + let indices = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Indices"), + contents: bytemuck::cast_slice(&scene.indices), + usage: wgpu::BufferUsages::INDEX + | wgpu::BufferUsages::STORAGE + | wgpu::BufferUsages::BLAS_INPUT, + }); + let geometries = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Geometries"), + contents: bytemuck::cast_slice(&geometry_buffer_content), + usage: wgpu::BufferUsages::STORAGE, + }); + let instances = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Instances"), + contents: bytemuck::cast_slice(&instance_buffer_content), + usage: wgpu::BufferUsages::STORAGE, + }); + + let mut temp_storage = Vec::new(); + let mut bottom_level_acceleration_structures = Vec::new(); + + for (vertex_range, geometry_range) in scene.instances.iter() { + let size_desc: Vec = (*geometry_range) + .clone() + .into_iter() + .map(|i| rt::BlasTriangleGeometrySizeDescriptor { + vertex_format: wgpu::VertexFormat::Float32x3, + vertex_count: vertex_range.end as u32 - vertex_range.start as u32, + index_format: Some(wgpu::IndexFormat::Uint16), + index_count: Some( + scene.geometries[i].end as u32 - scene.geometries[i].start as u32, + ), + flags: rt::AccelerationStructureGeometryFlags::OPAQUE, + }) + .collect(); + let blas = device.create_blas( + &rt::CreateBlasDescriptor { + label: None, + flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: rt::AccelerationStructureUpdateMode::Build, + }, + rt::BlasGeometrySizeDescriptors::Triangles { + desc: size_desc.clone(), + }, + ); + + temp_storage.push((size_desc, vertex_range.start as u32, geometry_range)); + bottom_level_acceleration_structures.push(blas); + } + + let mut triangle_geometries_storage = Vec::new(); + + for (size_desc, vertex_offset, geometries) in temp_storage.iter() { + let triangle_geometries: Vec<_> = size_desc + .iter() + .zip((**geometries).clone().into_iter()) + .map(|(size, i)| rt::BlasTriangleGeometry { + size: &size, + vertex_buffer: &vertices, + first_vertex: *vertex_offset, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&indices), + index_buffer_offset: Some(scene.geometries[i].start as u64 * 2), + transform_buffer: None, + transform_buffer_offset: None, + }) + .collect(); + + triangle_geometries_storage.push(triangle_geometries); + } + + let build_entries: Vec<_> = triangle_geometries_storage + .iter() + .zip(bottom_level_acceleration_structures.iter()) + .map(|(triangle_geometries, blas)| rt::BlasBuildEntry { + blas, + geometry: rt::BlasGeometries::TriangleGeometries(&triangle_geometries), + }) + .collect(); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + encoder.build_acceleration_structures(build_entries.iter(), iter::empty()); + + queue.submit(Some(encoder.finish())); + + SceneComponents { + vertices, + indices, + geometries, + instances, + bottom_level_acceleration_structures, + } +} + +fn load_scene(device: &wgpu::Device, queue: &wgpu::Queue) -> SceneComponents { + let mut scene = RawSceneComponents::default(); + load_model( + &mut scene, + include_bytes!("../skybox/models/teslacyberv3.0.obj"), + ); + + upload_scene_components(device, queue, &scene) +} + +#[allow(dead_code)] +struct Example { + uniforms: Uniforms, + uniform_buf: wgpu::Buffer, + tlas_package: rt::TlasPackage, + pipeline: wgpu::RenderPipeline, + bind_group: wgpu::BindGroup, + start_inst: Instant, + scene_components: SceneComponents, +} + +impl framework::Example for Example { + fn required_features() -> wgpu::Features { + wgpu::Features::RAY_QUERY | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE + } + + fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities { + wgpu::DownlevelCapabilities::default() + } + fn required_limits() -> wgpu::Limits { + wgpu::Limits::default() + } + + fn init( + config: &wgpu::SurfaceConfiguration, + _adapter: &wgpu::Adapter, + device: &wgpu::Device, + queue: &wgpu::Queue, + ) -> Self { + let side_count = 8; + + let uniforms = { + let view = Mat4::look_at_rh(Vec3::new(0.0, 0.0, 2.5), Vec3::ZERO, Vec3::Y); + let proj = Mat4::perspective_rh( + 59.0_f32.to_radians(), + config.width as f32 / config.height as f32, + 0.001, + 1000.0, + ); + + Uniforms { + view_inverse: view.inverse().to_cols_array_2d(), + proj_inverse: proj.inverse().to_cols_array_2d(), + } + }; + + let uniform_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Uniform Buffer"), + contents: bytemuck::cast_slice(&[uniforms]), + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + }); + + let tlas = device.create_tlas(&rt::CreateTlasDescriptor { + label: None, + flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: rt::AccelerationStructureUpdateMode::Build, + max_instances: side_count * side_count, + }); + + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), + }); + + let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: None, + layout: None, + vertex: wgpu::VertexState { + module: &shader, + entry_point: "vs_main", + buffers: &[], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "fs_main", + targets: &[Some(config.format.into())], + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + ..Default::default() + }, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + multiview: None, + }); + + let bind_group_layout = pipeline.get_bind_group_layout(0); + + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: uniform_buf.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::AccelerationStructure(&tlas), + }, + ], + }); + + let tlas_package = rt::TlasPackage::new(tlas, side_count * side_count); + + let scene_components = load_scene(device, queue); + + let start_inst = Instant::now(); + + Example { + uniforms, + uniform_buf, + tlas_package, + pipeline, + bind_group, + start_inst, + scene_components, + } + } + + fn update(&mut self, _event: winit::event::WindowEvent) {} + + fn resize( + &mut self, + config: &wgpu::SurfaceConfiguration, + _device: &wgpu::Device, + queue: &wgpu::Queue, + ) { + let proj = Mat4::perspective_rh( + 59.0_f32.to_radians(), + config.width as f32 / config.height as f32, + 0.001, + 1000.0, + ); + + self.uniforms.proj_inverse = proj.inverse().to_cols_array_2d(); + + queue.write_buffer(&self.uniform_buf, 0, bytemuck::cast_slice(&[self.uniforms])); + } + + fn render( + &mut self, + view: &wgpu::TextureView, + device: &wgpu::Device, + queue: &wgpu::Queue, + spawner: &framework::Spawner, + ) { + device.push_error_scope(wgpu::ErrorFilter::Validation); + + // scene update + { + let dist = 1.0; + + let side_count = 1; + + let anim_time = self.start_inst.elapsed().as_secs_f64() as f32; + + for x in 0..side_count { + for y in 0..side_count { + let instance = self + .tlas_package + .get_mut_single((x + y * side_count) as usize) + .unwrap(); + + let x = x as f32 / side_count as f32; + let y = y as f32 / side_count as f32; + let x = x * 2.0 - 1.0; + let y = y * 2.0 - 1.0; + + let transform = Mat4::from_rotation_translation( + Quat::from_euler( + glam::EulerRot::XYZ, + anim_time * 0.5 * 0.342, + anim_time * 0.5 * 0.254, + anim_time * 0.5 * 0.832, + ), + Vec3 { + x: x * dist, + y: y * dist, + z: -5.0, + }, + ); + let transform = transform.transpose().to_cols_array()[..12] + .try_into() + .unwrap(); + + *instance = Some(rt::TlasInstance::new( + &self.scene_components.bottom_level_acceleration_structures[0], + transform, + 0, + 0xff, + )); + } + } + } + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + encoder.build_acceleration_structures(iter::empty(), iter::once(&self.tlas_package)); + + { + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), + store: true, + }, + })], + depth_stencil_attachment: None, + }); + + rpass.set_pipeline(&self.pipeline); + rpass.set_bind_group(0, &self.bind_group, &[]); + rpass.draw(0..3, 0..1); + } + + queue.submit(Some(encoder.finish())); + + // If an error occurs, report it and panic. + spawner.spawn_local(ErrorFuture { + inner: device.pop_error_scope(), + }); + } +} + +fn main() { + framework::run::("ray-cube"); +} + +#[test] +fn ray_cube_fragment() { + framework::test::(framework::FrameworkRefTest { + image_path: "/examples/ray-cube-fragment/screenshot.png", + width: 1024, + height: 768, + optional_features: wgpu::Features::default(), + base_test_parameters: framework::test_common::TestParameters { + required_features: ::required_features(), + required_downlevel_properties: + ::required_downlevel_capabilities(), + required_limits: ::required_limits(), + failures: Vec::new(), + }, + tolerance: 1, + max_outliers: 1225, // Bounded by swiftshader + }); +} diff --git a/wgpu/examples/ray-scene/shader.wgsl b/wgpu/examples/ray-scene/shader.wgsl new file mode 100644 index 0000000000..de331770ae --- /dev/null +++ b/wgpu/examples/ray-scene/shader.wgsl @@ -0,0 +1,74 @@ +struct VertexOutput { + @builtin(position) position: vec4, + @location(0) tex_coords: vec2, +}; + +// meant to be called with 3 vertex indices: 0, 1, 2 +// draws one large triangle over the clip space like this: +// (the asterisks represent the clip space bounds) +//-1,1 1,1 +// --------------------------------- +// | * . +// | * . +// | * . +// | * . +// | * . +// | * . +// |*************** +// | . 1,-1 +// | . +// | . +// | . +// | . +// |. +@vertex +fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput { + var result: VertexOutput; + let x = i32(vertex_index) / 2; + let y = i32(vertex_index) & 1; + let tc = vec2( + f32(x) * 2.0, + f32(y) * 2.0 + ); + result.position = vec4( + tc.x * 2.0 - 1.0, + 1.0 - tc.y * 2.0, + 0.0, 1.0 + ); + result.tex_coords = tc; + return result; +} + +struct Uniforms { + view_inv: mat4x4, + proj_inv: mat4x4, +}; + +@group(0) @binding(0) +var uniforms: Uniforms; + +@group(0) @binding(1) +var acc_struct: acceleration_structure; + +@fragment +fn fs_main(vertex: VertexOutput) -> @location(0) vec4 { + + var color = vec4(vertex.tex_coords, 0.0, 1.0); + + let d = vertex.tex_coords * 2.0 - 1.0; + + let origin = (uniforms.view_inv * vec4(0.0,0.0,0.0,1.0)).xyz; + let temp = uniforms.proj_inv * vec4(d.x, d.y, 1.0, 1.0); + let direction = (uniforms.view_inv * vec4(normalize(temp.xyz), 0.0)).xyz; + + var rq: ray_query; + rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 0.1, 200.0, origin, direction)); + rayQueryProceed(&rq); + + let intersection = rayQueryGetCommittedIntersection(&rq); + if (intersection.kind != RAY_QUERY_INTERSECTION_NONE) { + color = vec4(intersection.barycentrics, 1.0 - intersection.barycentrics.x - intersection.barycentrics.y, 1.0); + } + + return color; // vec4(vertex.tex_coords, 1.0, 1.0); +} From 63fabe4d577fe13e9014b2d795f14d0c41bd6719 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 10 Apr 2023 10:24:22 +0200 Subject: [PATCH 072/146] removed incorrect vertex validation --- wgpu-core/src/command/ray_tracing.rs | 10 ---------- wgpu-core/src/ray_tracing.rs | 3 --- 2 files changed, 13 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index efd5de588e..de77031cc8 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -212,11 +212,6 @@ impl Global { { input_barriers.push(barrier); } - if mesh.size.vertex_count as i64 - mesh.first_vertex as i64 <= 0 { - return Err(BuildAccelerationStructureError::EmptyVertexBuffer( - mesh.vertex_buffer, - )); - } if vertex_buffer.size < (mesh.size.vertex_count + mesh.first_vertex) as u64 * mesh.vertex_stride @@ -831,11 +826,6 @@ impl Global { { input_barriers.push(barrier); } - if mesh.size.vertex_count as i64 - mesh.first_vertex as i64 <= 0 { - return Err(BuildAccelerationStructureError::EmptyVertexBuffer( - mesh.vertex_buffer, - )); - } if vertex_buffer.size < (mesh.size.vertex_count + mesh.first_vertex) as u64 * mesh.vertex_stride diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index c8361ded3b..8ba0c3c158 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -61,9 +61,6 @@ pub enum BuildAccelerationStructureError { )] InsufficientBufferSize(BufferId, u64, u64), - #[error("Buffer {0:?} associated vertex buffer sizes invalid (no vertices)")] - EmptyVertexBuffer(BufferId), - #[error("Buffer {0:?} associated offset doesn't align with the index type")] UnalignedIndexBufferOffset(BufferId), From 0963c15d41f8c9ed3945c6559ff3cf0c6e49d6ad Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 10 Apr 2023 10:25:27 +0200 Subject: [PATCH 073/146] WIP example multiple blas in single build --- wgpu/examples/ray-scene/cube.mtl | 12 ++++++++++ wgpu/examples/ray-scene/cube.obj | 40 ++++++++++++++++++++++++++++++++ wgpu/examples/ray-scene/main.rs | 21 ++++++++++++----- 3 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 wgpu/examples/ray-scene/cube.mtl create mode 100644 wgpu/examples/ray-scene/cube.obj diff --git a/wgpu/examples/ray-scene/cube.mtl b/wgpu/examples/ray-scene/cube.mtl new file mode 100644 index 0000000000..630f8abac0 --- /dev/null +++ b/wgpu/examples/ray-scene/cube.mtl @@ -0,0 +1,12 @@ +# Blender 3.3.1 MTL File: 'None' +# www.blender.org + +newmtl Material +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 diff --git a/wgpu/examples/ray-scene/cube.obj b/wgpu/examples/ray-scene/cube.obj new file mode 100644 index 0000000000..2aef89d5a0 --- /dev/null +++ b/wgpu/examples/ray-scene/cube.obj @@ -0,0 +1,40 @@ +# Blender 3.3.1 +# www.blender.org +mtllib cube.mtl +o Cube +v 1.000000 1.000000 -1.000000 +v 1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 1.000000 +v 1.000000 -1.000000 1.000000 +v -1.000000 1.000000 -1.000000 +v -1.000000 -1.000000 -1.000000 +v -1.000000 1.000000 1.000000 +v -1.000000 -1.000000 1.000000 +vn -0.0000 1.0000 -0.0000 +vn -0.0000 -0.0000 1.0000 +vn -1.0000 -0.0000 -0.0000 +vn -0.0000 -1.0000 -0.0000 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 -1.0000 +vt 0.625000 0.500000 +vt 0.375000 0.500000 +vt 0.625000 0.750000 +vt 0.375000 0.750000 +vt 0.875000 0.500000 +vt 0.625000 0.250000 +vt 0.125000 0.500000 +vt 0.375000 0.250000 +vt 0.875000 0.750000 +vt 0.625000 1.000000 +vt 0.625000 0.000000 +vt 0.375000 1.000000 +vt 0.375000 0.000000 +vt 0.125000 0.750000 +s 0 +usemtl Material +f 1/1/1 5/5/1 7/9/1 3/3/1 +f 4/4/2 3/3/2 7/10/2 8/12/2 +f 8/13/3 7/11/3 5/6/3 6/8/3 +f 6/7/4 2/2/4 4/4/4 8/14/4 +f 2/2/5 1/1/5 3/3/5 4/4/5 +f 6/8/6 5/6/6 1/1/6 2/2/6 diff --git a/wgpu/examples/ray-scene/main.rs b/wgpu/examples/ray-scene/main.rs index 6c76753d6e..aae363522c 100644 --- a/wgpu/examples/ray-scene/main.rs +++ b/wgpu/examples/ray-scene/main.rs @@ -107,6 +107,11 @@ fn load_model(scene: &mut RawSceneComponents, source: &[u8]) { start_vertex_index..scene.vertices.len(), start_geometry_index..scene.geometries.len(), )); + + // dbg!(scene.vertices.len()); + // dbg!(scene.indices.len()); + // dbg!(&scene.geometries); + // dbg!(&scene.instances); } fn upload_scene_components( @@ -239,6 +244,8 @@ fn load_scene(device: &wgpu::Device, queue: &wgpu::Queue) -> SceneComponents { include_bytes!("../skybox/models/teslacyberv3.0.obj"), ); + load_model(&mut scene, include_bytes!("cube.obj")); + upload_scene_components(device, queue, &scene) } @@ -393,9 +400,9 @@ impl framework::Example for Example { // scene update { - let dist = 1.0; + let dist = 3.0; - let side_count = 1; + let side_count = 2; let anim_time = self.start_inst.elapsed().as_secs_f64() as f32; @@ -406,8 +413,10 @@ impl framework::Example for Example { .get_mut_single((x + y * side_count) as usize) .unwrap(); - let x = x as f32 / side_count as f32; - let y = y as f32 / side_count as f32; + let blas_index = (x + y) % 2; + + let x = x as f32 / (side_count - 1) as f32; + let y = y as f32 / (side_count - 1) as f32; let x = x * 2.0 - 1.0; let y = y * 2.0 - 1.0; @@ -421,7 +430,7 @@ impl framework::Example for Example { Vec3 { x: x * dist, y: y * dist, - z: -5.0, + z: -10.0, }, ); let transform = transform.transpose().to_cols_array()[..12] @@ -429,7 +438,7 @@ impl framework::Example for Example { .unwrap(); *instance = Some(rt::TlasInstance::new( - &self.scene_components.bottom_level_acceleration_structures[0], + &self.scene_components.bottom_level_acceleration_structures[blas_index], transform, 0, 0xff, From 8e6e327e5a1513dbe50bd9d2ea8401b62005359c Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 10 Apr 2023 11:13:28 +0200 Subject: [PATCH 074/146] API change made TriangleGeometries owning --- wgpu-hal/examples/ray-traced-triangle/main.rs | 2 +- wgpu/examples/ray-cube-compute/main.rs | 2 +- wgpu/examples/ray-cube-fragment/main.rs | 2 +- wgpu/examples/ray-scene/main.rs | 112 +++++++++--------- wgpu/src/ray_tracing.rs | 7 +- 5 files changed, 61 insertions(+), 64 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 67630a05f4..45e7f23ad6 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -86,7 +86,7 @@ impl AccelerationStructureInstance { Self::rows_to_affine(&self.transform) } pub fn set_transform(&mut self, transform: &Affine3A) { - self.transform = Self::affine_to_rows(&transform); + self.transform = Self::affine_to_rows(transform); } pub fn custom_index(&self) -> u32 { diff --git a/wgpu/examples/ray-cube-compute/main.rs b/wgpu/examples/ray-cube-compute/main.rs index 20d5b6d170..9c564a5e88 100644 --- a/wgpu/examples/ray-cube-compute/main.rs +++ b/wgpu/examples/ray-cube-compute/main.rs @@ -493,7 +493,7 @@ impl framework::Example for Example { encoder.build_acceleration_structures( iter::once(&rt::BlasBuildEntry { blas: &blas, - geometry: rt::BlasGeometries::TriangleGeometries(&[rt::BlasTriangleGeometry { + geometry: rt::BlasGeometries::TriangleGeometries(vec![rt::BlasTriangleGeometry { size: &blas_geo_size_desc, vertex_buffer: &vertex_buf, first_vertex: 0, diff --git a/wgpu/examples/ray-cube-fragment/main.rs b/wgpu/examples/ray-cube-fragment/main.rs index 9520b1a101..488b827143 100644 --- a/wgpu/examples/ray-cube-fragment/main.rs +++ b/wgpu/examples/ray-cube-fragment/main.rs @@ -246,7 +246,7 @@ impl framework::Example for Example { encoder.build_acceleration_structures( iter::once(&rt::BlasBuildEntry { blas: &blas, - geometry: rt::BlasGeometries::TriangleGeometries(&[rt::BlasTriangleGeometry { + geometry: rt::BlasGeometries::TriangleGeometries(vec![rt::BlasTriangleGeometry { size: &blas_geo_size_desc, vertex_buffer: &vertex_buf, first_vertex: 0, diff --git a/wgpu/examples/ray-scene/main.rs b/wgpu/examples/ray-scene/main.rs index aae363522c..ff82b448af 100644 --- a/wgpu/examples/ray-scene/main.rs +++ b/wgpu/examples/ray-scene/main.rs @@ -72,7 +72,7 @@ struct InstanceEntry { } fn load_model(scene: &mut RawSceneComponents, source: &[u8]) { - let data = obj::ObjData::load_buf(&source[..]).unwrap(); + let data = obj::ObjData::load_buf(source).unwrap(); let start_vertex_index = scene.vertices.len(); let start_geometry_index = scene.geometries.len(); @@ -159,65 +159,63 @@ fn upload_scene_components( usage: wgpu::BufferUsages::STORAGE, }); - let mut temp_storage = Vec::new(); - let mut bottom_level_acceleration_structures = Vec::new(); - - for (vertex_range, geometry_range) in scene.instances.iter() { - let size_desc: Vec = (*geometry_range) - .clone() - .into_iter() - .map(|i| rt::BlasTriangleGeometrySizeDescriptor { - vertex_format: wgpu::VertexFormat::Float32x3, - vertex_count: vertex_range.end as u32 - vertex_range.start as u32, - index_format: Some(wgpu::IndexFormat::Uint16), - index_count: Some( - scene.geometries[i].end as u32 - scene.geometries[i].start as u32, - ), - flags: rt::AccelerationStructureGeometryFlags::OPAQUE, - }) - .collect(); - let blas = device.create_blas( - &rt::CreateBlasDescriptor { - label: None, - flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, - update_mode: rt::AccelerationStructureUpdateMode::Build, - }, - rt::BlasGeometrySizeDescriptors::Triangles { - desc: size_desc.clone(), - }, - ); - - temp_storage.push((size_desc, vertex_range.start as u32, geometry_range)); - bottom_level_acceleration_structures.push(blas); - } - - let mut triangle_geometries_storage = Vec::new(); - - for (size_desc, vertex_offset, geometries) in temp_storage.iter() { - let triangle_geometries: Vec<_> = size_desc - .iter() - .zip((**geometries).clone().into_iter()) - .map(|(size, i)| rt::BlasTriangleGeometry { - size: &size, - vertex_buffer: &vertices, - first_vertex: *vertex_offset, - vertex_stride: mem::size_of::() as u64, - index_buffer: Some(&indices), - index_buffer_offset: Some(scene.geometries[i].start as u64 * 2), - transform_buffer: None, - transform_buffer_offset: None, - }) - .collect(); - - triangle_geometries_storage.push(triangle_geometries); - } + let (size_descriptors, bottom_level_acceleration_structures): (Vec<_>, Vec<_>) = scene + .instances + .iter() + .map(|(vertex_range, geometry_range)| { + let size_desc: Vec = (*geometry_range) + .clone() + .into_iter() + .map(|i| rt::BlasTriangleGeometrySizeDescriptor { + vertex_format: wgpu::VertexFormat::Float32x3, + vertex_count: vertex_range.end as u32 - vertex_range.start as u32, + index_format: Some(wgpu::IndexFormat::Uint16), + index_count: Some( + scene.geometries[i].end as u32 - scene.geometries[i].start as u32, + ), + flags: rt::AccelerationStructureGeometryFlags::OPAQUE, + }) + .collect(); + + let blas = device.create_blas( + &rt::CreateBlasDescriptor { + label: None, + flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: rt::AccelerationStructureUpdateMode::Build, + }, + rt::BlasGeometrySizeDescriptors::Triangles { + desc: size_desc.clone(), + }, + ); + (size_desc, blas) + }) + .unzip(); - let build_entries: Vec<_> = triangle_geometries_storage + let build_entries: Vec<_> = scene + .instances .iter() + .zip(size_descriptors.iter()) .zip(bottom_level_acceleration_structures.iter()) - .map(|(triangle_geometries, blas)| rt::BlasBuildEntry { - blas, - geometry: rt::BlasGeometries::TriangleGeometries(&triangle_geometries), + .map(|(((vertex_range, geometry_range), size_desc), blas)| { + let triangle_geometries: Vec<_> = size_desc + .iter() + .zip(geometry_range.clone().into_iter()) + .map(|(size, i)| rt::BlasTriangleGeometry { + size, + vertex_buffer: &vertices, + first_vertex: vertex_range.start as u32, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&indices), + index_buffer_offset: Some(scene.geometries[i].start as u64 * 2), + transform_buffer: None, + transform_buffer_offset: None, + }) + .collect(); + + rt::BlasBuildEntry { + blas, + geometry: rt::BlasGeometries::TriangleGeometries(triangle_geometries), + } }) .collect(); diff --git a/wgpu/src/ray_tracing.rs b/wgpu/src/ray_tracing.rs index 51bf2838ed..4d28ea8cf8 100644 --- a/wgpu/src/ray_tracing.rs +++ b/wgpu/src/ray_tracing.rs @@ -57,11 +57,10 @@ pub struct BlasTriangleGeometry<'a> { } static_assertions::assert_impl_all!(BlasTriangleGeometry: Send, Sync); -#[derive(Debug)] /// Geometries for a bottom level acceleration structure. pub enum BlasGeometries<'a> { /// Triangle geometry variant. - TriangleGeometries(&'a [BlasTriangleGeometry<'a>]), + TriangleGeometries(Vec>), } static_assertions::assert_impl_all!(BlasGeometries: Send, Sync); @@ -417,7 +416,7 @@ impl CommandEncoderRayTracing for CommandEncoder { let id = self.id.as_ref().unwrap(); let mut blas = blas.into_iter().map(|e: &BlasBuildEntry| { - let geometries = match e.geometry { + let geometries = match &e.geometry { BlasGeometries::TriangleGeometries(triangle_geometries) => { let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry| { DynContextBlasTriangleGeometry { @@ -478,7 +477,7 @@ impl CommandEncoderRayTracing for CommandEncoder { let id = self.id.as_ref().unwrap(); let mut blas = blas.into_iter().map(|e: &BlasBuildEntry| { - let geometries = match e.geometry { + let geometries = match &e.geometry { BlasGeometries::TriangleGeometries(triangle_geometries) => { let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry| { DynContextBlasTriangleGeometry { From 4906c3ebc7c11a99bced349de84f6fb45cf65582 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 10 Apr 2023 13:56:39 +0200 Subject: [PATCH 075/146] WIP scene --- wgpu/examples/ray-scene/cube.mtl | 14 +- wgpu/examples/ray-scene/cube.obj | 2593 ++++++++++++++++++++++++++- wgpu/examples/ray-scene/main.rs | 133 +- wgpu/examples/ray-scene/shader.wgsl | 125 +- 4 files changed, 2784 insertions(+), 81 deletions(-) diff --git a/wgpu/examples/ray-scene/cube.mtl b/wgpu/examples/ray-scene/cube.mtl index 630f8abac0..59994638a4 100644 --- a/wgpu/examples/ray-scene/cube.mtl +++ b/wgpu/examples/ray-scene/cube.mtl @@ -1,12 +1,20 @@ -# Blender 3.3.1 MTL File: 'None' -# www.blender.org +# Blender MTL File: 'None' +# Material Count: 2 newmtl Material Ns 250.000000 Ka 1.000000 1.000000 1.000000 -Kd 0.800000 0.800000 0.800000 +Kd 0.000000 0.009087 0.800000 Ks 0.500000 0.500000 0.500000 Ke 0.000000 0.000000 0.000000 Ni 1.450000 d 1.000000 illum 2 + +newmtl None +Ns 500 +Ka 0.8 0.8 0.8 +Kd 0.8 0.8 0.8 +Ks 0.8 0.8 0.8 +d 1 +illum 2 diff --git a/wgpu/examples/ray-scene/cube.obj b/wgpu/examples/ray-scene/cube.obj index 2aef89d5a0..855a249d94 100644 --- a/wgpu/examples/ray-scene/cube.obj +++ b/wgpu/examples/ray-scene/cube.obj @@ -1,4 +1,4 @@ -# Blender 3.3.1 +# Blender v3.3.1 OBJ File: '' # www.blender.org mtllib cube.mtl o Cube @@ -10,31 +10,2578 @@ v -1.000000 1.000000 -1.000000 v -1.000000 -1.000000 -1.000000 v -1.000000 1.000000 1.000000 v -1.000000 -1.000000 1.000000 -vn -0.0000 1.0000 -0.0000 -vn -0.0000 -0.0000 1.0000 -vn -1.0000 -0.0000 -0.0000 -vn -0.0000 -1.0000 -0.0000 -vn 1.0000 -0.0000 -0.0000 -vn -0.0000 -0.0000 -1.0000 -vt 0.625000 0.500000 -vt 0.375000 0.500000 +vt 0.875000 0.500000 vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.375000 1.000000 vt 0.375000 0.750000 -vt 0.875000 0.500000 -vt 0.625000 0.250000 -vt 0.125000 0.500000 -vt 0.375000 0.250000 -vt 0.875000 0.750000 -vt 0.625000 1.000000 vt 0.625000 0.000000 -vt 0.375000 1.000000 +vt 0.375000 0.250000 vt 0.375000 0.000000 +vt 0.375000 0.500000 vt 0.125000 0.750000 -s 0 +vt 0.125000 0.500000 +vt 0.625000 0.250000 +vt 0.875000 0.750000 +vt 0.625000 1.000000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 usemtl Material -f 1/1/1 5/5/1 7/9/1 3/3/1 -f 4/4/2 3/3/2 7/10/2 8/12/2 -f 8/13/3 7/11/3 5/6/3 6/8/3 -f 6/7/4 2/2/4 4/4/4 8/14/4 -f 2/2/5 1/1/5 3/3/5 4/4/5 -f 6/8/6 5/6/6 1/1/6 2/2/6 +s off +f 5/1/1 3/2/1 1/3/1 +f 3/2/2 8/4/2 4/5/2 +f 7/6/3 6/7/3 8/8/3 +f 2/9/4 8/10/4 6/11/4 +f 1/3/5 4/5/5 2/9/5 +f 5/12/6 2/9/6 6/7/6 +f 5/1/1 7/13/1 3/2/1 +f 3/2/2 7/14/2 8/4/2 +f 7/6/3 5/12/3 6/7/3 +f 2/9/4 4/5/4 8/10/4 +f 1/3/5 3/2/5 4/5/5 +f 5/12/6 1/3/6 2/9/6 +o Suzanne +v 0.437500 2.679682 0.765625 +v -0.437500 2.679682 0.765625 +v 0.500000 2.609370 0.687500 +v -0.500000 2.609370 0.687500 +v 0.546875 2.570307 0.578125 +v -0.546875 2.570307 0.578125 +v 0.351562 2.492182 0.617188 +v -0.351562 2.492182 0.617188 +v 0.351562 2.546870 0.718750 +v -0.351562 2.546870 0.718750 +v 0.351562 2.648432 0.781250 +v -0.351562 2.648432 0.781250 +v 0.273438 2.679682 0.796875 +v -0.273438 2.679682 0.796875 +v 0.203125 2.609370 0.742188 +v -0.203125 2.609370 0.742188 +v 0.156250 2.570307 0.648438 +v -0.156250 2.570307 0.648438 +v 0.078125 2.757807 0.656250 +v -0.078125 2.757807 0.656250 +v 0.140625 2.757807 0.742188 +v -0.140625 2.757807 0.742188 +v 0.242188 2.757807 0.796875 +v -0.242188 2.757807 0.796875 +v 0.273438 2.843745 0.796875 +v -0.273438 2.843745 0.796875 +v 0.203125 2.906245 0.742188 +v -0.203125 2.906245 0.742188 +v 0.156250 2.953120 0.648438 +v -0.156250 2.953120 0.648438 +v 0.351562 3.031245 0.617188 +v -0.351562 3.031245 0.617188 +v 0.351562 2.968745 0.718750 +v -0.351562 2.968745 0.718750 +v 0.351562 2.874995 0.781250 +v -0.351562 2.874995 0.781250 +v 0.437500 2.843745 0.765625 +v -0.437500 2.843745 0.765625 +v 0.500000 2.906245 0.687500 +v -0.500000 2.906245 0.687500 +v 0.546875 2.953120 0.578125 +v -0.546875 2.953120 0.578125 +v 0.625000 2.757807 0.562500 +v -0.625000 2.757807 0.562500 +v 0.562500 2.757807 0.671875 +v -0.562500 2.757807 0.671875 +v 0.468750 2.757807 0.757812 +v -0.468750 2.757807 0.757812 +v 0.476562 2.757807 0.773438 +v -0.476562 2.757807 0.773438 +v 0.445312 2.851557 0.781250 +v -0.445312 2.851557 0.781250 +v 0.351562 2.890620 0.804688 +v -0.351562 2.890620 0.804688 +v 0.265625 2.851557 0.820312 +v -0.265625 2.851557 0.820312 +v 0.226562 2.757807 0.820312 +v -0.226562 2.757807 0.820312 +v 0.265625 2.671870 0.820312 +v -0.265625 2.671870 0.820312 +v 0.351562 2.757807 0.828125 +v -0.351562 2.757807 0.828125 +v 0.351562 2.632807 0.804688 +v -0.351562 2.632807 0.804688 +v 0.445312 2.671870 0.781250 +v -0.445312 2.671870 0.781250 +v 0.000000 2.945307 0.742188 +v 0.000000 2.867182 0.820312 +v 0.000000 1.835932 0.734375 +v 0.000000 2.195307 0.781250 +v 0.000000 2.328120 0.796875 +v 0.000000 1.742182 0.718750 +v 0.000000 2.921870 0.601562 +v 0.000000 3.085932 0.570312 +v 0.000000 3.414057 -0.546875 +v 0.000000 3.078120 -0.851562 +v 0.000000 2.585932 -0.828125 +v 0.000000 2.132807 -0.351562 +v 0.203125 2.328120 0.562500 +v -0.203125 2.328120 0.562500 +v 0.312500 2.078120 0.570312 +v -0.312500 2.078120 0.570312 +v 0.351562 1.820307 0.570312 +v -0.351562 1.820307 0.570312 +v 0.367188 1.624995 0.531250 +v -0.367188 1.624995 0.531250 +v 0.328125 1.570307 0.523438 +v -0.328125 1.570307 0.523438 +v 0.179688 1.546870 0.554688 +v -0.179688 1.546870 0.554688 +v 0.000000 1.531245 0.578125 +v 0.437500 2.374995 0.531250 +v -0.437500 2.374995 0.531250 +v 0.632812 2.476557 0.539062 +v -0.632812 2.476557 0.539062 +v 0.828125 2.664057 0.445312 +v -0.828125 2.664057 0.445312 +v 0.859375 2.945307 0.593750 +v -0.859375 2.945307 0.593750 +v 0.710938 2.999995 0.625000 +v -0.710938 2.999995 0.625000 +v 0.492188 3.117182 0.687500 +v -0.492188 3.117182 0.687500 +v 0.320312 3.273432 0.734375 +v -0.320312 3.273432 0.734375 +v 0.156250 3.234370 0.757812 +v -0.156250 3.234370 0.757812 +v 0.062500 3.007807 0.750000 +v -0.062500 3.007807 0.750000 +v 0.164062 2.929682 0.773438 +v -0.164062 2.929682 0.773438 +v 0.125000 2.820307 0.765625 +v -0.125000 2.820307 0.765625 +v 0.203125 2.609370 0.742188 +v -0.203125 2.609370 0.742188 +v 0.375000 2.531245 0.703125 +v -0.375000 2.531245 0.703125 +v 0.492188 2.578120 0.671875 +v -0.492188 2.578120 0.671875 +v 0.625000 2.703120 0.648438 +v -0.625000 2.703120 0.648438 +v 0.640625 2.812495 0.648438 +v -0.640625 2.812495 0.648438 +v 0.601562 2.890620 0.664062 +v -0.601562 2.890620 0.664062 +v 0.429688 2.953120 0.718750 +v -0.429688 2.953120 0.718750 +v 0.250000 2.984370 0.757812 +v -0.250000 2.984370 0.757812 +v 0.000000 1.749995 0.734375 +v 0.109375 1.796870 0.734375 +v -0.109375 1.796870 0.734375 +v 0.117188 1.679682 0.710938 +v -0.117188 1.679682 0.710938 +v 0.062500 1.632807 0.695312 +v -0.062500 1.632807 0.695312 +v 0.000000 1.624995 0.687500 +v 0.000000 2.320307 0.750000 +v 0.000000 2.374995 0.742188 +v 0.101562 2.367182 0.742188 +v -0.101562 2.367182 0.742188 +v 0.125000 2.289057 0.750000 +v -0.125000 2.289057 0.750000 +v 0.085938 2.226557 0.742188 +v -0.085938 2.226557 0.742188 +v 0.398438 2.468745 0.671875 +v -0.398438 2.468745 0.671875 +v 0.617188 2.570307 0.625000 +v -0.617188 2.570307 0.625000 +v 0.726562 2.718745 0.601562 +v -0.726562 2.718745 0.601562 +v 0.742188 2.890620 0.656250 +v -0.742188 2.890620 0.656250 +v 0.687500 2.929682 0.726562 +v -0.687500 2.929682 0.726562 +v 0.437500 3.062495 0.796875 +v -0.437500 3.062495 0.796875 +v 0.312500 3.156245 0.835938 +v -0.312500 3.156245 0.835938 +v 0.203125 3.132807 0.851562 +v -0.203125 3.132807 0.851562 +v 0.101562 2.945307 0.843750 +v -0.101562 2.945307 0.843750 +v 0.125000 2.414057 0.812500 +v -0.125000 2.414057 0.812500 +v 0.210938 2.070307 0.710938 +v -0.210938 2.070307 0.710938 +v 0.250000 1.812495 0.687500 +v -0.250000 1.812495 0.687500 +v 0.265625 1.695307 0.664062 +v -0.265625 1.695307 0.664062 +v 0.234375 1.601557 0.632812 +v -0.234375 1.601557 0.632812 +v 0.164062 1.585932 0.632812 +v -0.164062 1.585932 0.632812 +v 0.000000 1.570307 0.640625 +v 0.000000 2.562495 0.726562 +v 0.000000 2.726557 0.765625 +v 0.328125 2.992182 0.742188 +v -0.328125 2.992182 0.742188 +v 0.164062 2.656245 0.750000 +v -0.164062 2.656245 0.750000 +v 0.132812 2.726557 0.757812 +v -0.132812 2.726557 0.757812 +v 0.117188 1.828120 0.734375 +v -0.117188 1.828120 0.734375 +v 0.078125 2.070307 0.750000 +v -0.078125 2.070307 0.750000 +v 0.000000 2.070307 0.750000 +v 0.000000 2.187495 0.742188 +v 0.093750 2.242182 0.781250 +v -0.093750 2.242182 0.781250 +v 0.132812 2.289057 0.796875 +v -0.132812 2.289057 0.796875 +v 0.109375 2.382807 0.781250 +v -0.109375 2.382807 0.781250 +v 0.039062 2.390620 0.781250 +v -0.039062 2.390620 0.781250 +v 0.000000 2.312495 0.828125 +v 0.046875 2.367182 0.812500 +v -0.046875 2.367182 0.812500 +v 0.093750 2.359370 0.812500 +v -0.093750 2.359370 0.812500 +v 0.109375 2.289057 0.828125 +v -0.109375 2.289057 0.828125 +v 0.078125 2.265620 0.804688 +v -0.078125 2.265620 0.804688 +v 0.000000 2.226557 0.804688 +v 0.257812 2.203120 0.554688 +v -0.257812 2.203120 0.554688 +v 0.164062 2.273432 0.710938 +v -0.164062 2.273432 0.710938 +v 0.179688 2.203120 0.710938 +v -0.179688 2.203120 0.710938 +v 0.234375 2.265620 0.554688 +v -0.234375 2.265620 0.554688 +v 0.000000 1.640620 0.687500 +v 0.046875 1.648432 0.687500 +v -0.046875 1.648432 0.687500 +v 0.093750 1.695307 0.710938 +v -0.093750 1.695307 0.710938 +v 0.093750 1.773432 0.726562 +v -0.093750 1.773432 0.726562 +v 0.000000 1.734370 0.656250 +v 0.093750 1.765620 0.664062 +v -0.093750 1.765620 0.664062 +v 0.093750 1.703120 0.640625 +v -0.093750 1.703120 0.640625 +v 0.046875 1.664057 0.632812 +v -0.046875 1.664057 0.632812 +v 0.000000 1.656245 0.632812 +v 0.171875 2.734370 0.781250 +v -0.171875 2.734370 0.781250 +v 0.187500 2.671870 0.773438 +v -0.187500 2.671870 0.773438 +v 0.335938 2.945307 0.757812 +v -0.335938 2.945307 0.757812 +v 0.273438 2.937495 0.773438 +v -0.273438 2.937495 0.773438 +v 0.421875 2.914057 0.773438 +v -0.421875 2.914057 0.773438 +v 0.562500 2.867182 0.695312 +v -0.562500 2.867182 0.695312 +v 0.585938 2.804682 0.687500 +v -0.585938 2.804682 0.687500 +v 0.578125 2.710932 0.679688 +v -0.578125 2.710932 0.679688 +v 0.476562 2.617182 0.718750 +v -0.476562 2.617182 0.718750 +v 0.375000 2.578120 0.742188 +v -0.375000 2.578120 0.742188 +v 0.226562 2.624995 0.781250 +v -0.226562 2.624995 0.781250 +v 0.179688 2.812495 0.781250 +v -0.179688 2.812495 0.781250 +v 0.210938 2.890620 0.781250 +v -0.210938 2.890620 0.781250 +v 0.234375 2.874995 0.757812 +v -0.234375 2.874995 0.757812 +v 0.195312 2.812495 0.757812 +v -0.195312 2.812495 0.757812 +v 0.242188 2.640620 0.757812 +v -0.242188 2.640620 0.757812 +v 0.375000 2.601557 0.726562 +v -0.375000 2.601557 0.726562 +v 0.460938 2.632807 0.703125 +v -0.460938 2.632807 0.703125 +v 0.546875 2.726557 0.671875 +v -0.546875 2.726557 0.671875 +v 0.554688 2.796870 0.671875 +v -0.554688 2.796870 0.671875 +v 0.531250 2.851557 0.679688 +v -0.531250 2.851557 0.679688 +v 0.414062 2.906245 0.750000 +v -0.414062 2.906245 0.750000 +v 0.281250 2.914057 0.765625 +v -0.281250 2.914057 0.765625 +v 0.335938 2.921870 0.750000 +v -0.335938 2.921870 0.750000 +v 0.203125 2.687495 0.750000 +v -0.203125 2.687495 0.750000 +v 0.195312 2.742182 0.750000 +v -0.195312 2.742182 0.750000 +v 0.109375 2.976557 0.609375 +v -0.109375 2.976557 0.609375 +v 0.195312 3.179682 0.617188 +v -0.195312 3.179682 0.617188 +v 0.335938 3.203120 0.593750 +v -0.335938 3.203120 0.593750 +v 0.484375 3.070307 0.554688 +v -0.484375 3.070307 0.554688 +v 0.679688 2.968745 0.492188 +v -0.679688 2.968745 0.492188 +v 0.796875 2.921870 0.460938 +v -0.796875 2.921870 0.460938 +v 0.773438 2.679682 0.375000 +v -0.773438 2.679682 0.375000 +v 0.601562 2.515620 0.414062 +v -0.601562 2.515620 0.414062 +v 0.437500 2.421870 0.468750 +v -0.437500 2.421870 0.468750 +v 0.000000 3.414057 0.289062 +v 0.000000 3.499995 -0.078125 +v 0.000000 2.320307 -0.671875 +v 0.000000 2.054682 0.187500 +v 0.000000 1.539057 0.460938 +v 0.000000 1.710932 0.343750 +v 0.000000 1.945307 0.320312 +v 0.000000 2.031245 0.281250 +v 0.851562 2.749995 0.054688 +v -0.851562 2.749995 0.054688 +v 0.859375 2.835932 -0.046875 +v -0.859375 2.835932 -0.046875 +v 0.773438 2.781245 -0.437500 +v -0.773438 2.781245 -0.437500 +v 0.460938 2.953120 -0.703125 +v -0.460938 2.953120 -0.703125 +v 0.734375 2.468745 0.070312 +v -0.734375 2.468745 0.070312 +v 0.593750 2.390620 -0.164062 +v -0.593750 2.390620 -0.164062 +v 0.640625 2.507807 -0.429688 +v -0.640625 2.507807 -0.429688 +v 0.335938 2.570307 -0.664062 +v -0.335938 2.570307 -0.664062 +v 0.234375 2.164057 0.406250 +v -0.234375 2.164057 0.406250 +v 0.179688 2.101557 0.257812 +v -0.179688 2.101557 0.257812 +v 0.289062 1.804682 0.382812 +v -0.289062 1.804682 0.382812 +v 0.250000 2.015620 0.390625 +v -0.250000 2.015620 0.390625 +v 0.328125 1.601557 0.398438 +v -0.328125 1.601557 0.398438 +v 0.140625 1.757807 0.367188 +v -0.140625 1.757807 0.367188 +v 0.125000 1.976557 0.359375 +v -0.125000 1.976557 0.359375 +v 0.164062 1.570307 0.437500 +v -0.164062 1.570307 0.437500 +v 0.218750 2.234370 0.429688 +v -0.218750 2.234370 0.429688 +v 0.210938 2.289057 0.468750 +v -0.210938 2.289057 0.468750 +v 0.203125 2.343745 0.500000 +v -0.203125 2.343745 0.500000 +v 0.210938 2.124995 0.164062 +v -0.210938 2.124995 0.164062 +v 0.296875 2.203120 -0.265625 +v -0.296875 2.203120 -0.265625 +v 0.343750 2.367182 -0.539062 +v -0.343750 2.367182 -0.539062 +v 0.453125 3.382807 -0.382812 +v -0.453125 3.382807 -0.382812 +v 0.453125 3.445307 -0.070312 +v -0.453125 3.445307 -0.070312 +v 0.453125 3.367182 0.234375 +v -0.453125 3.367182 0.234375 +v 0.460938 3.039057 0.429688 +v -0.460938 3.039057 0.429688 +v 0.726562 2.921870 0.335938 +v -0.726562 2.921870 0.335938 +v 0.632812 2.968745 0.281250 +v -0.632812 2.968745 0.281250 +v 0.640625 3.218745 0.054688 +v -0.640625 3.218745 0.054688 +v 0.796875 3.078120 0.125000 +v -0.796875 3.078120 0.125000 +v 0.796875 3.132807 -0.117188 +v -0.796875 3.132807 -0.117188 +v 0.640625 3.265620 -0.195312 +v -0.640625 3.265620 -0.195312 +v 0.640625 3.195307 -0.445312 +v -0.640625 3.195307 -0.445312 +v 0.796875 3.054682 -0.359375 +v -0.796875 3.054682 -0.359375 +v 0.617188 2.843745 -0.585938 +v -0.617188 2.843745 -0.585938 +v 0.484375 2.539057 -0.546875 +v -0.484375 2.539057 -0.546875 +v 0.820312 2.843745 -0.203125 +v -0.820312 2.843745 -0.203125 +v 0.406250 2.343745 0.148438 +v -0.406250 2.343745 0.148438 +v 0.429688 2.320307 -0.210938 +v -0.429688 2.320307 -0.210938 +v 0.890625 2.921870 -0.234375 +v -0.890625 2.921870 -0.234375 +v 0.773438 2.374995 -0.125000 +v -0.773438 2.374995 -0.125000 +v 1.039062 2.414057 -0.328125 +v -1.039062 2.414057 -0.328125 +v 1.281250 2.570307 -0.429688 +v -1.281250 2.570307 -0.429688 +v 1.351562 2.835932 -0.421875 +v -1.351562 2.835932 -0.421875 +v 1.234375 3.023432 -0.421875 +v -1.234375 3.023432 -0.421875 +v 1.023438 2.992182 -0.312500 +v -1.023438 2.992182 -0.312500 +v 1.015625 2.929682 -0.289062 +v -1.015625 2.929682 -0.289062 +v 1.187500 2.953120 -0.390625 +v -1.187500 2.953120 -0.390625 +v 1.265625 2.804682 -0.406250 +v -1.265625 2.804682 -0.406250 +v 1.210938 2.593745 -0.406250 +v -1.210938 2.593745 -0.406250 +v 1.031250 2.476557 -0.304688 +v -1.031250 2.476557 -0.304688 +v 0.828125 2.445307 -0.132812 +v -0.828125 2.445307 -0.132812 +v 0.921875 2.874995 -0.218750 +v -0.921875 2.874995 -0.218750 +v 0.945312 2.820307 -0.289062 +v -0.945312 2.820307 -0.289062 +v 0.882812 2.492182 -0.210938 +v -0.882812 2.492182 -0.210938 +v 1.039062 2.515620 -0.367188 +v -1.039062 2.515620 -0.367188 +v 1.187500 2.609370 -0.445312 +v -1.187500 2.609370 -0.445312 +v 1.234375 2.765620 -0.445312 +v -1.234375 2.765620 -0.445312 +v 1.171875 2.874995 -0.437500 +v -1.171875 2.874995 -0.437500 +v 1.023438 2.859370 -0.359375 +v -1.023438 2.859370 -0.359375 +v 0.843750 2.804682 -0.210938 +v -0.843750 2.804682 -0.210938 +v 0.835938 2.687495 -0.273438 +v -0.835938 2.687495 -0.273438 +v 0.757812 2.609370 -0.273438 +v -0.757812 2.609370 -0.273438 +v 0.820312 2.601557 -0.273438 +v -0.820312 2.601557 -0.273438 +v 0.843750 2.531245 -0.273438 +v -0.843750 2.531245 -0.273438 +v 0.812500 2.499995 -0.273438 +v -0.812500 2.499995 -0.273438 +v 0.726562 2.515620 -0.070312 +v -0.726562 2.515620 -0.070312 +v 0.718750 2.492182 -0.171875 +v -0.718750 2.492182 -0.171875 +v 0.718750 2.554682 -0.187500 +v -0.718750 2.554682 -0.187500 +v 0.796875 2.718745 -0.210938 +v -0.796875 2.718745 -0.210938 +v 0.890625 2.757807 -0.265625 +v -0.890625 2.757807 -0.265625 +v 0.890625 2.749995 -0.320312 +v -0.890625 2.749995 -0.320312 +v 0.812500 2.499995 -0.320312 +v -0.812500 2.499995 -0.320312 +v 0.851562 2.531245 -0.320312 +v -0.851562 2.531245 -0.320312 +v 0.828125 2.593745 -0.320312 +v -0.828125 2.593745 -0.320312 +v 0.765625 2.609370 -0.320312 +v -0.765625 2.609370 -0.320312 +v 0.843750 2.687495 -0.320312 +v -0.843750 2.687495 -0.320312 +v 1.039062 2.843745 -0.414062 +v -1.039062 2.843745 -0.414062 +v 1.187500 2.859370 -0.484375 +v -1.187500 2.859370 -0.484375 +v 1.257812 2.757807 -0.492188 +v -1.257812 2.757807 -0.492188 +v 1.210938 2.601557 -0.484375 +v -1.210938 2.601557 -0.484375 +v 1.046875 2.515620 -0.421875 +v -1.046875 2.515620 -0.421875 +v 0.882812 2.499995 -0.265625 +v -0.882812 2.499995 -0.265625 +v 0.953125 2.804682 -0.343750 +v -0.953125 2.804682 -0.343750 +v 0.890625 2.624995 -0.328125 +v -0.890625 2.624995 -0.328125 +v 0.937500 2.578120 -0.335938 +v -0.937500 2.578120 -0.335938 +v 1.000000 2.640620 -0.367188 +v -1.000000 2.640620 -0.367188 +v 0.960938 2.687495 -0.351562 +v -0.960938 2.687495 -0.351562 +v 1.015625 2.749995 -0.375000 +v -1.015625 2.749995 -0.375000 +v 1.054688 2.703120 -0.382812 +v -1.054688 2.703120 -0.382812 +v 1.109375 2.726557 -0.390625 +v -1.109375 2.726557 -0.390625 +v 1.085938 2.789057 -0.390625 +v -1.085938 2.789057 -0.390625 +v 1.023438 2.953120 -0.484375 +v -1.023438 2.953120 -0.484375 +v 1.250000 2.984370 -0.546875 +v -1.250000 2.984370 -0.546875 +v 1.367188 2.812495 -0.500000 +v -1.367188 2.812495 -0.500000 +v 1.312500 2.570307 -0.531250 +v -1.312500 2.570307 -0.531250 +v 1.039062 2.429682 -0.492188 +v -1.039062 2.429682 -0.492188 +v 0.789062 2.390620 -0.328125 +v -0.789062 2.390620 -0.328125 +v 0.859375 2.898432 -0.382812 +v -0.859375 2.898432 -0.382812 +vt 0.890955 0.590063 +vt 0.860081 0.560115 +vt 0.904571 0.559404 +vt 0.856226 0.850547 +vt 0.888398 0.821999 +vt 0.900640 0.853232 +vt 0.853018 0.521562 +vt 0.920166 0.524546 +vt 0.847458 0.888748 +vt 0.914672 0.888748 +vt 0.798481 0.569535 +vt 0.795104 0.838402 +vt 0.870622 0.589649 +vt 0.828900 0.590771 +vt 0.826436 0.818537 +vt 0.868067 0.821510 +vt 0.854402 0.604754 +vt 0.828171 0.633354 +vt 0.827598 0.775964 +vt 0.852534 0.805700 +vt 0.791018 0.645443 +vt 0.791018 0.762238 +vt 0.855181 0.668527 +vt 0.856142 0.742025 +vt 0.844839 0.707525 +vt 0.854107 0.625459 +vt 0.853157 0.785002 +vt 0.867508 0.642291 +vt 0.900375 0.666964 +vt 0.901223 0.745592 +vt 0.867293 0.768782 +vt 0.842358 0.702491 +vt 0.921180 0.713713 +vt 0.931889 0.636832 +vt 0.918898 0.699697 +vt 0.931368 0.777093 +vt 0.968213 0.770220 +vt 0.905882 0.627902 +vt 0.890474 0.641909 +vt 0.904990 0.784860 +vt 0.906232 0.605742 +vt 0.904357 0.807013 +vt 0.931250 0.820926 +vt 0.933717 0.593037 +vt 0.968392 0.645333 +vt 0.965038 0.841671 +vt 0.968392 0.573812 +vt 0.889591 0.593275 +vt 0.887178 0.818729 +vt 0.900583 0.804677 +vt 0.902359 0.607909 +vt 0.898822 0.786233 +vt 0.899781 0.626257 +vt 0.890219 0.770183 +vt 0.887351 0.775442 +vt 0.887842 0.636527 +vt 0.870376 0.775972 +vt 0.859881 0.623942 +vt 0.870908 0.635245 +vt 0.858859 0.786774 +vt 0.859664 0.608186 +vt 0.857942 0.802505 +vt 0.871664 0.593961 +vt 0.869299 0.817249 +vt 0.879400 0.616512 +vt 0.878029 0.795063 +vt 0.536419 0.062072 +vt 0.518916 0.050294 +vt 0.540260 0.053805 +vt 0.501452 0.062043 +vt 0.518925 0.059681 +vt 0.542788 0.064089 +vt 0.551930 0.058338 +vt 0.495083 0.064047 +vt 0.497626 0.053770 +vt 0.555073 0.061900 +vt 0.482805 0.061829 +vt 0.485955 0.058273 +vt 0.563812 0.076586 +vt 0.546290 0.072669 +vt 0.491565 0.072625 +vt 0.474014 0.076511 +vt 0.583135 0.108495 +vt 0.548333 0.084893 +vt 0.489507 0.084858 +vt 0.454527 0.108481 +vt 0.605512 0.165134 +vt 0.621513 0.227818 +vt 0.553118 0.209599 +vt 0.416514 0.229490 +vt 0.432024 0.165644 +vt 0.485339 0.210053 +vt 0.676379 0.233241 +vt 0.647395 0.200502 +vt 0.360308 0.235899 +vt 0.372747 0.256357 +vt 0.683908 0.279995 +vt 0.664761 0.253225 +vt 0.353696 0.284606 +vt 0.707254 0.310054 +vt 0.715342 0.265392 +vt 0.330721 0.316853 +vt 0.351187 0.317440 +vt 0.697446 0.332673 +vt 0.687515 0.311539 +vt 0.341964 0.339667 +vt 0.362723 0.329722 +vt 0.662817 0.372521 +vt 0.676824 0.323937 +vt 0.379297 0.378686 +vt 0.402772 0.362131 +vt 0.618316 0.375151 +vt 0.639050 0.357330 +vt 0.424583 0.379267 +vt 0.604826 0.397804 +vt 0.626842 0.395792 +vt 0.439252 0.401540 +vt 0.442396 0.381222 +vt 0.553095 0.390512 +vt 0.600808 0.377857 +vt 0.490934 0.391862 +vt 0.482938 0.358497 +vt 0.521923 0.386009 +vt 0.559674 0.357011 +vt 0.521086 0.343868 +vt 0.599845 0.344815 +vt 0.577279 0.340156 +vt 0.441977 0.347815 +vt 0.615546 0.342005 +vt 0.634472 0.332311 +vt 0.425972 0.345582 +vt 0.662406 0.312804 +vt 0.406362 0.336480 +vt 0.668440 0.297958 +vt 0.377061 0.317685 +vt 0.664101 0.277872 +vt 0.370304 0.302644 +vt 0.639236 0.253047 +vt 0.374100 0.281778 +vt 0.613992 0.242662 +vt 0.398938 0.255633 +vt 0.572941 0.258564 +vt 0.424464 0.244473 +vt 0.519760 0.248864 +vt 0.466409 0.259709 +vt 0.558527 0.316594 +vt 0.482619 0.317843 +vt 0.520277 0.294764 +vt 0.556923 0.291214 +vt 0.483433 0.292249 +vt 0.563905 0.272007 +vt 0.475886 0.273078 +vt 0.525483 0.068967 +vt 0.512375 0.068956 +vt 0.531231 0.073829 +vt 0.506626 0.073811 +vt 0.531019 0.087431 +vt 0.555621 0.121749 +vt 0.532669 0.090920 +vt 0.505177 0.090908 +vt 0.482177 0.121781 +vt 0.506827 0.087416 +vt 0.518981 0.151749 +vt 0.532042 0.127713 +vt 0.538112 0.158382 +vt 0.505828 0.127728 +vt 0.518941 0.128358 +vt 0.518925 0.093952 +vt 0.518927 0.085180 +vt 0.548362 0.173560 +vt 0.535214 0.166808 +vt 0.502799 0.166857 +vt 0.489683 0.173693 +vt 0.499851 0.158434 +vt 0.544281 0.193366 +vt 0.537959 0.175966 +vt 0.500100 0.176033 +vt 0.493996 0.193428 +vt 0.528757 0.191785 +vt 0.519841 0.200843 +vt 0.509219 0.191626 +vt 0.500890 0.187571 +vt 0.519132 0.185382 +vt 0.517577 0.190607 +vt 0.518998 0.159028 +vt 0.519016 0.165599 +vt 0.506910 0.171667 +vt 0.528222 0.186316 +vt 0.509787 0.186260 +vt 0.533528 0.184215 +vt 0.537248 0.187577 +vt 0.504547 0.184206 +vt 0.504604 0.176791 +vt 0.531131 0.171631 +vt 0.533449 0.176739 +vt 0.519099 0.179457 +vt 0.561572 0.167779 +vt 0.476363 0.167996 +vt 0.478371 0.149447 +vt 0.559475 0.149319 +vt 0.596138 0.133426 +vt 0.441395 0.133592 +vt 0.601169 0.147885 +vt 0.436337 0.148194 +vt 0.528933 0.084957 +vt 0.508915 0.084945 +vt 0.518925 0.083865 +vt 0.529036 0.075429 +vt 0.508820 0.075415 +vt 0.523751 0.070508 +vt 0.514106 0.070501 +vt 0.518928 0.067899 +vt 0.518929 0.069468 +vt 0.518928 0.074259 +vt 0.516297 0.074966 +vt 0.524236 0.076691 +vt 0.521560 0.074970 +vt 0.513619 0.076684 +vt 0.524601 0.079886 +vt 0.513252 0.079879 +vt 0.518926 0.079331 +vt 0.571787 0.277295 +vt 0.568351 0.292904 +vt 0.468070 0.278617 +vt 0.471978 0.294282 +vt 0.573085 0.311386 +vt 0.467790 0.313081 +vt 0.584855 0.327708 +vt 0.456477 0.329961 +vt 0.458737 0.268049 +vt 0.611720 0.255725 +vt 0.580734 0.266620 +vt 0.427062 0.257728 +vt 0.632494 0.262853 +vt 0.406068 0.265508 +vt 0.653658 0.279971 +vt 0.384904 0.283634 +vt 0.656064 0.297636 +vt 0.383015 0.301864 +vt 0.386858 0.314615 +vt 0.652752 0.310186 +vt 0.411556 0.327673 +vt 0.614408 0.331972 +vt 0.629040 0.323864 +vt 0.426727 0.335361 +vt 0.601033 0.333624 +vt 0.440344 0.336537 +vt 0.601799 0.328453 +vt 0.439372 0.331331 +vt 0.450408 0.323919 +vt 0.613335 0.327083 +vt 0.427623 0.330358 +vt 0.626851 0.320513 +vt 0.413648 0.324175 +vt 0.646248 0.306421 +vt 0.393381 0.310510 +vt 0.649541 0.296225 +vt 0.389662 0.300183 +vt 0.647785 0.283486 +vt 0.391040 0.287071 +vt 0.629829 0.267263 +vt 0.408893 0.269959 +vt 0.612641 0.261560 +vt 0.426254 0.263693 +vt 0.585166 0.270991 +vt 0.454369 0.272583 +vt 0.578124 0.281900 +vt 0.461798 0.283441 +vt 0.579548 0.309340 +vt 0.590644 0.321516 +vt 0.461204 0.311233 +vt 0.577524 0.293776 +vt 0.462754 0.295432 +vt 0.553209 0.433063 +vt 0.523031 0.433628 +vt 0.492809 0.434538 +vt 0.609819 0.431516 +vt 0.435860 0.435740 +vt 0.416915 0.400552 +vt 0.396518 0.425416 +vt 0.648174 0.419316 +vt 0.350292 0.396229 +vt 0.692106 0.388274 +vt 0.312756 0.350588 +vt 0.735879 0.312112 +vt 0.726332 0.341754 +vt 0.301067 0.320593 +vt 0.320452 0.270303 +vt 0.304876 0.261087 +vt 0.698172 0.216906 +vt 0.729900 0.256393 +vt 0.337414 0.219179 +vt 0.663103 0.190671 +vt 0.373474 0.191872 +vt 0.649444 0.022378 +vt 0.621440 0.048089 +vt 0.626908 0.015608 +vt 0.388827 0.021586 +vt 0.416419 0.047631 +vt 0.376796 0.075296 +vt 0.577206 0.032801 +vt 0.567460 0.000144 +vt 0.411318 0.015131 +vt 0.460782 0.032656 +vt 0.547413 0.041724 +vt 0.518922 0.024886 +vt 0.470636 0.000144 +vt 0.490511 0.041669 +vt 0.558059 0.053871 +vt 0.479842 0.053785 +vt 0.576951 0.057998 +vt 0.460920 0.057845 +vt 0.611687 0.078268 +vt 0.425932 0.077985 +vt 0.660451 0.076084 +vt 0.626663 0.111357 +vt 0.410618 0.111244 +vt 0.629482 0.130456 +vt 0.407648 0.130594 +vt 0.413741 0.147158 +vt 0.619303 0.159841 +vt 0.418035 0.160361 +vt 0.389677 0.201890 +vt 0.886245 0.121777 +vt 0.891780 0.036916 +vt 0.945900 0.079569 +vt 0.141314 0.112482 +vt 0.142277 0.021467 +vt 0.183115 0.092127 +vt 0.849114 0.099732 +vt 0.805584 0.010786 +vt 0.232648 0.003484 +vt 0.246353 0.076510 +vt 0.687018 0.077204 +vt 0.672384 0.022201 +vt 0.349875 0.075955 +vt 0.365979 0.020991 +vt 0.760215 0.193244 +vt 0.789046 0.233323 +vt 0.271553 0.193871 +vt 0.241255 0.236977 +vt 0.909112 0.183261 +vt 0.994525 0.167705 +vt 0.107928 0.179083 +vt 0.078961 0.060719 +vt 0.862868 0.338556 +vt 0.962901 0.344752 +vt 0.911671 0.402429 +vt 0.160557 0.356821 +vt 0.043968 0.367038 +vt 0.123776 0.315519 +vt 0.915360 0.259804 +vt 0.999856 0.254640 +vt 0.098965 0.266968 +vt 0.000144 0.259113 +vt 0.011829 0.155367 +vt 0.749542 0.334683 +vt 0.766337 0.300809 +vt 0.789162 0.313727 +vt 0.267408 0.310142 +vt 0.288183 0.346496 +vt 0.242992 0.325552 +vt 0.815314 0.276388 +vt 0.846174 0.293397 +vt 0.213065 0.285164 +vt 0.178537 0.304983 +vt 0.845007 0.256352 +vt 0.873517 0.265922 +vt 0.179662 0.263312 +vt 0.147089 0.274284 +vt 0.859075 0.228168 +vt 0.886999 0.233769 +vt 0.162803 0.231720 +vt 0.131514 0.237587 +vt 0.875030 0.184705 +vt 0.842355 0.195160 +vt 0.145224 0.182749 +vt 0.894128 0.301884 +vt 0.794286 0.364062 +vt 0.770185 0.379538 +vt 0.239776 0.382592 +vt 0.845499 0.449967 +vt 0.106400 0.432652 +vt 0.815858 0.445381 +vt 0.755700 0.418603 +vt 0.287033 0.442912 +vt 0.219260 0.477186 +vt 0.268122 0.398737 +vt 0.185281 0.484099 +vt 0.819845 0.468071 +vt 0.215894 0.503605 +vt 0.809631 0.233887 +vt 0.219168 0.237388 +vt 0.829287 0.219562 +vt 0.199067 0.222464 +vt 0.788458 0.080826 +vt 0.715482 0.139727 +vt 0.319538 0.139409 +vt 0.246666 0.114850 +vt 0.785486 0.152330 +vt 0.245969 0.151002 +vt 0.623495 0.146796 +vt 0.837382 0.156361 +vt 0.196622 0.155241 +vt 0.171653 0.132294 +vt 0.786480 0.117591 +vt 0.858171 0.137775 +vt 0.432388 0.894943 +vt 0.491058 0.881714 +vt 0.506166 0.904851 +vt 0.321637 0.893225 +vt 0.263032 0.878321 +vt 0.315867 0.868209 +vt 0.572792 0.860484 +vt 0.604825 0.879946 +vt 0.181486 0.854693 +vt 0.247207 0.901159 +vt 0.148729 0.873349 +vt 0.619962 0.791615 +vt 0.136063 0.784093 +vt 0.169745 0.787474 +vt 0.586396 0.793977 +vt 0.563786 0.739211 +vt 0.194086 0.733241 +vt 0.208656 0.740879 +vt 0.549027 0.746412 +vt 0.508270 0.697693 +vt 0.250811 0.693249 +vt 0.258399 0.707497 +vt 0.438641 0.680683 +vt 0.434803 0.658882 +vt 0.320962 0.677959 +vt 0.325318 0.656224 +vt 0.500314 0.711729 +vt 0.452955 0.700023 +vt 0.306136 0.696976 +vt 0.505666 0.730944 +vt 0.252524 0.726592 +vt 0.568148 0.787367 +vt 0.188269 0.781375 +vt 0.214575 0.750414 +vt 0.555495 0.826352 +vt 0.199850 0.820889 +vt 0.501231 0.844356 +vt 0.253846 0.840502 +vt 0.457832 0.840040 +vt 0.297562 0.837358 +vt 0.783193 0.187449 +vt 0.246955 0.187075 +vt 0.233625 0.175620 +vt 0.394766 0.686125 +vt 0.391039 0.611891 +vt 0.364838 0.684445 +vt 0.391747 0.862097 +vt 0.438797 0.870229 +vt 0.363377 0.861308 +vt 0.435018 0.718280 +vt 0.323658 0.715731 +vt 0.384658 0.710299 +vt 0.433669 0.729661 +vt 0.374400 0.708969 +vt 0.410995 0.747662 +vt 0.427812 0.742828 +vt 0.324726 0.727177 +vt 0.347028 0.745816 +vt 0.330270 0.740536 +vt 0.384657 0.795423 +vt 0.418086 0.784946 +vt 0.372270 0.794472 +vt 0.431333 0.817535 +vt 0.401605 0.841460 +vt 0.324790 0.815460 +vt 0.338952 0.783073 +vt 0.354026 0.840297 +vt 0.825107 0.209762 +vt 0.199767 0.214827 +vt 0.816266 0.203086 +vt 0.209828 0.206161 +vt 0.226485 0.183086 +vt 0.796021 0.176969 +vt 0.802192 0.184609 +vt 0.448505 0.804621 +vt 0.473386 0.824700 +vt 0.307886 0.802031 +vt 0.282357 0.821525 +vt 0.321237 0.777208 +vt 0.423718 0.754191 +vt 0.435868 0.779569 +vt 0.334089 0.752045 +vt 0.319919 0.747250 +vt 0.437950 0.749777 +vt 0.312907 0.729222 +vt 0.440995 0.724383 +vt 0.445392 0.731997 +vt 0.317510 0.721697 +vt 0.455277 0.713731 +vt 0.303460 0.710657 +vt 0.512485 0.828811 +vt 0.242975 0.824574 +vt 0.550942 0.811814 +vt 0.204839 0.806417 +vt 0.552139 0.787682 +vt 0.204331 0.782156 +vt 0.539407 0.764539 +vt 0.542850 0.755753 +vt 0.217774 0.759319 +vt 0.508439 0.743135 +vt 0.249419 0.738732 +vt 0.454776 0.761665 +vt 0.302729 0.758742 +vt 0.286960 0.745020 +vt 0.470841 0.748408 +vt 0.475403 0.783904 +vt 0.281439 0.780511 +vt 0.268291 0.766661 +vt 0.503673 0.787562 +vt 0.494476 0.802470 +vt 0.252972 0.783410 +vt 0.261790 0.798626 +vt 0.516802 0.807339 +vt 0.239243 0.802891 +vt 0.237920 0.787045 +vt 0.518562 0.791602 +vt 0.484068 0.628776 +vt 0.543385 0.683538 +vt 0.276936 0.625067 +vt 0.216123 0.678120 +vt 0.581052 0.726933 +vt 0.177176 0.720426 +vt 0.616701 0.759965 +vt 0.140379 0.752377 +vt 0.660647 0.741167 +vt 0.707492 0.759884 +vt 0.097038 0.732052 +vt 0.677256 0.670436 +vt 0.745511 0.652100 +vt 0.049526 0.748824 +vt 0.083564 0.662038 +vt 0.671403 0.592656 +vt 0.740843 0.572428 +vt 0.019409 0.639749 +vt 0.092820 0.589862 +vt 0.834705 0.206959 +vt 0.051216 0.522659 +vt 0.033664 0.564403 +vt 0.620420 0.565675 +vt 0.498072 0.552315 +vt 0.145041 0.562595 +vt 0.264218 0.550140 +vt 0.369913 0.610196 +vt 0.464579 0.342230 +vt 0.176788 0.196179 +vt 0.770572 0.444261 +vt 0.271364 0.473316 +vt 0.488870 0.770464 +vt 0.834578 0.206879 +vn 0.9693 -0.0118 0.2456 +vn 0.6076 -0.5104 0.6085 +vn 0.8001 -0.0028 0.5999 +vn -0.6076 -0.5104 0.6085 +vn -0.9693 -0.0118 0.2456 +vn -0.8001 -0.0028 0.5999 +vn 0.6802 -0.5463 0.4888 +vn 0.8682 -0.0048 0.4961 +vn -0.6802 -0.5463 0.4888 +vn -0.8682 -0.0048 0.4961 +vn 0.1193 -0.8712 0.4763 +vn -0.1193 -0.8712 0.4763 +vn 0.7290 -0.6566 0.1934 +vn 0.0995 -0.7515 0.6522 +vn -0.0995 -0.7515 0.6522 +vn -0.7290 -0.6566 0.1934 +vn 0.0314 -0.9670 0.2529 +vn -0.4563 -0.5362 0.7101 +vn 0.4563 -0.5362 0.7101 +vn -0.0314 -0.9670 0.2529 +vn -0.5539 -0.6332 0.5406 +vn 0.5539 -0.6332 0.5406 +vn -0.6899 -0.0041 0.7239 +vn 0.6899 -0.0041 0.7239 +vn 0.8097 -0.0070 0.5868 +vn -0.6506 -0.6883 0.3210 +vn 0.6506 -0.6883 0.3210 +vn -0.9521 -0.0102 0.3057 +vn -0.4560 0.5222 0.7207 +vn 0.4560 0.5222 0.7207 +vn 0.9521 -0.0102 0.3057 +vn -0.8097 -0.0070 0.5868 +vn 0.5306 0.6258 0.5717 +vn 0.1031 0.7402 0.6644 +vn -0.5306 0.6258 0.5717 +vn -0.1031 0.7402 0.6644 +vn -0.1257 0.8416 0.5253 +vn 0.0258 0.9726 0.2312 +vn -0.6644 0.6821 0.3056 +vn -0.0258 0.9726 0.2312 +vn 0.7364 0.6521 0.1803 +vn -0.7364 0.6521 0.1803 +vn -0.6102 0.4956 0.6181 +vn 0.6102 0.4956 0.6181 +vn 0.1257 0.8416 0.5253 +vn -0.6682 0.5371 0.5148 +vn 0.6682 0.5371 0.5148 +vn 0.9645 -0.0127 0.2639 +vn -0.9645 -0.0127 0.2639 +vn -0.7216 0.6556 0.2224 +vn 0.7216 0.6556 0.2224 +vn -0.0432 0.9389 0.3415 +vn 0.0432 0.9389 0.3415 +vn 0.6644 0.6821 0.3056 +vn 0.6237 0.6285 0.4647 +vn -0.6237 0.6285 0.4647 +vn 0.9270 -0.0130 0.3749 +vn -0.6159 -0.6366 0.4641 +vn -0.9270 -0.0130 0.3749 +vn 0.6159 -0.6366 0.4641 +vn 0.0426 -0.9404 0.3375 +vn -0.0426 -0.9404 0.3375 +vn 0.7152 -0.6625 0.2227 +vn -0.7152 -0.6625 0.2227 +vn 0.1836 -0.0053 0.9830 +vn -0.1836 -0.0053 0.9830 +vn 0.1554 -0.7590 0.6323 +vn 0.0000 -0.9677 0.2523 +vn 0.1596 -0.9753 0.1529 +vn -0.1554 -0.7590 0.6323 +vn 0.0000 -0.7753 0.6316 +vn 0.3502 -0.6392 0.6847 +vn 0.5267 -0.8347 0.1611 +vn -0.3502 -0.6392 0.6847 +vn -0.1596 -0.9753 0.1529 +vn 0.9457 -0.2579 0.1977 +vn -0.9457 -0.2579 0.1977 +vn -0.5267 -0.8347 0.1611 +vn 0.9728 0.1003 0.2087 +vn 0.5557 -0.2264 0.8000 +vn -0.5557 -0.2264 0.8000 +vn -0.9728 0.1003 0.2087 +vn 0.9557 0.2492 0.1565 +vn 0.5652 -0.0297 0.8244 +vn -0.5652 -0.0297 0.8244 +vn -0.9557 0.2492 0.1565 +vn 0.8916 -0.3307 0.3095 +vn 0.3842 -0.5671 0.7286 +vn 0.0402 -0.2722 0.9614 +vn -0.3842 -0.5671 0.7286 +vn -0.8916 -0.3307 0.3095 +vn -0.0402 -0.2722 0.9614 +vn 0.5875 -0.7849 0.1970 +vn 0.3489 -0.9371 -0.0082 +vn -0.5875 -0.7849 0.1970 +vn -0.4991 -0.3761 0.7807 +vn 0.5666 -0.3188 0.7598 +vn 0.4991 -0.3761 0.7807 +vn -0.5666 -0.3188 0.7598 +vn 0.8451 0.4434 0.2985 +vn 0.9070 -0.4009 -0.1290 +vn -0.8451 0.4434 0.2985 +vn -0.4607 -0.1448 0.8757 +vn 0.5171 0.8291 0.2125 +vn 0.4607 -0.1448 0.8757 +vn -0.5171 0.8291 0.2125 +vn -0.4801 -0.1833 0.8578 +vn 0.5976 0.7847 0.1646 +vn 0.4801 -0.1833 0.8578 +vn -0.5976 0.7847 0.1646 +vn -0.3085 0.0039 0.9512 +vn 0.2666 0.2166 0.9392 +vn 0.3085 0.0039 0.9512 +vn -0.2666 0.2166 0.9392 +vn -0.6051 0.7680 0.2098 +vn 0.2313 0.9570 0.1751 +vn 0.6051 0.7680 0.2098 +vn 0.1574 0.1660 0.9735 +vn -0.8242 0.5468 0.1473 +vn -0.1574 0.1660 0.9735 +vn 0.8242 0.5468 0.1473 +vn 0.0611 -0.0253 0.9978 +vn 0.0000 0.9636 0.2673 +vn -0.0611 -0.0253 0.9978 +vn 0.0000 -0.0827 0.9966 +vn 0.2582 -0.1265 0.9578 +vn 0.3679 -0.2836 0.8856 +vn -0.2582 -0.1265 0.9578 +vn 0.1490 -0.1542 0.9767 +vn 0.2190 0.0372 0.9750 +vn -0.1490 -0.1542 0.9767 +vn 0.2254 -0.3608 0.9050 +vn -0.2190 0.0372 0.9750 +vn 0.3588 -0.1192 0.9258 +vn -0.2254 -0.3608 0.9050 +vn 0.4602 -0.1651 0.8723 +vn -0.3588 -0.1192 0.9258 +vn 0.4279 -0.3895 0.8156 +vn -0.4602 -0.1651 0.8723 +vn 0.3322 -0.3667 0.8690 +vn -0.4279 -0.3895 0.8156 +vn -0.1522 -0.2549 0.9549 +vn -0.3322 -0.3667 0.8690 +vn -0.0000 0.0643 0.9979 +vn 0.1522 -0.2549 0.9549 +vn 0.0316 -0.1782 0.9835 +vn -0.0316 -0.1782 0.9835 +vn -0.0000 -0.2220 0.9750 +vn -0.2006 -0.1350 0.9703 +vn 0.2006 -0.1350 0.9703 +vn -0.2393 -0.3012 0.9230 +vn 0.2393 -0.3012 0.9230 +vn -0.0589 -0.3784 0.9238 +vn 0.0589 -0.3784 0.9238 +vn 0.1307 -0.3187 0.9388 +vn -0.1307 -0.3187 0.9388 +vn 0.1460 -0.1202 0.9820 +vn 0.5937 0.1082 0.7974 +vn 0.1815 -0.0452 0.9823 +vn -0.1815 -0.0452 0.9823 +vn -0.5937 0.1082 0.7974 +vn -0.1460 -0.1202 0.9820 +vn 0.0000 -0.4760 0.8795 +vn 0.1341 0.0063 0.9909 +vn 0.5003 -0.4293 0.7520 +vn -0.1341 0.0063 0.9909 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -0.0341 0.9994 +vn -0.0000 -0.5870 0.8096 +vn 0.9304 -0.1242 0.3448 +vn 0.5836 -0.6929 0.4235 +vn -0.5836 -0.6929 0.4235 +vn -0.9304 -0.1242 0.3448 +vn -0.5003 -0.4293 0.7520 +vn 0.4931 -0.3412 0.8002 +vn 0.9306 -0.2353 0.2804 +vn -0.9306 -0.2353 0.2804 +vn -0.4931 -0.3412 0.8002 +vn -0.2405 0.9491 0.2036 +vn 0.0000 0.5166 0.8562 +vn 0.2405 0.9491 0.2036 +vn -0.6286 0.7688 0.1177 +vn 0.0000 0.8287 0.5597 +vn 0.0000 0.9515 0.3076 +vn 0.0000 -0.8654 0.5011 +vn 0.0000 -0.4815 0.8764 +vn -0.1833 -0.5864 0.7890 +vn -0.1858 0.5956 0.7815 +vn 0.1858 0.5956 0.7815 +vn 0.3611 0.4713 0.8047 +vn 0.6286 0.7688 0.1177 +vn -0.3611 0.4713 0.8047 +vn -0.4488 -0.3147 0.8364 +vn 0.1833 -0.5864 0.7890 +vn 0.4488 -0.3147 0.8364 +vn 0.0000 0.1578 0.9875 +vn 0.7752 0.0387 0.6306 +vn -0.7752 0.0387 0.6306 +vn -0.6507 0.1488 0.7447 +vn 0.6507 0.1488 0.7447 +vn 0.9278 0.3530 0.1209 +vn -0.9278 0.3530 0.1209 +vn 0.9306 0.3435 0.1263 +vn -0.9306 0.3435 0.1263 +vn -0.1369 -0.5273 0.8386 +vn 0.1369 -0.5273 0.8386 +vn 0.0000 -0.9619 0.2732 +vn -0.6351 0.0428 0.7712 +vn 0.6351 0.0428 0.7712 +vn -0.4141 0.5798 0.7016 +vn 0.4141 0.5798 0.7016 +vn 0.0000 -0.3465 0.9380 +vn 0.0000 0.5588 0.8293 +vn 0.0000 0.5334 0.8459 +vn 0.2959 0.4750 0.8288 +vn -0.6738 0.1155 0.7299 +vn -0.2959 0.4750 0.8288 +vn 0.6738 0.1155 0.7299 +vn -0.5177 -0.7041 0.4860 +vn 0.5177 -0.7041 0.4860 +vn 0.0000 -0.6989 0.7152 +vn -0.0101 -0.0700 0.9975 +vn 0.1581 -0.0843 0.9838 +vn 0.0101 -0.0700 0.9975 +vn -0.1581 -0.0843 0.9838 +vn 0.2934 -0.0602 0.9541 +vn -0.2934 -0.0602 0.9541 +vn 0.1588 -0.1065 0.9816 +vn -0.1588 -0.1065 0.9816 +vn 0.0317 -0.2198 0.9750 +vn 0.1845 -0.1863 0.9650 +vn -0.0317 -0.2198 0.9750 +vn -0.1845 -0.1863 0.9650 +vn 0.2990 -0.0356 0.9536 +vn -0.2990 -0.0356 0.9536 +vn 0.2943 -0.1021 0.9502 +vn -0.2943 -0.1020 0.9502 +vn 0.1776 -0.0608 0.9822 +vn -0.1776 -0.0608 0.9822 +vn -0.2944 0.0046 0.9557 +vn 0.2944 0.0046 0.9557 +vn -0.0887 -0.1272 0.9879 +vn 0.2036 0.1032 0.9736 +vn 0.0887 -0.1272 0.9879 +vn -0.2036 0.1032 0.9736 +vn 0.1435 0.0966 0.9849 +vn -0.1435 0.0966 0.9849 +vn 0.2886 -0.2786 0.9160 +vn -0.2886 -0.2786 0.9160 +vn -0.4508 -0.4658 0.7614 +vn 0.1133 -0.3142 0.9426 +vn -0.1133 -0.3142 0.9426 +vn -0.2741 -0.8556 0.4391 +vn 0.2741 -0.8556 0.4391 +vn -0.1423 -0.5826 0.8002 +vn 0.1423 -0.5826 0.8002 +vn -0.4229 -0.1078 0.8997 +vn 0.4229 -0.1078 0.8997 +vn -0.1921 0.1914 0.9625 +vn 0.1921 0.1914 0.9625 +vn -0.1653 0.6098 0.7751 +vn 0.1653 0.6098 0.7751 +vn 0.1431 0.5587 0.8169 +vn -0.1431 0.5587 0.8169 +vn 0.4323 0.5833 0.6877 +vn -0.4323 0.5833 0.6877 +vn 0.6881 0.2985 0.6614 +vn -0.6881 0.2985 0.6614 +vn 0.7894 -0.2032 0.5793 +vn 0.4508 -0.4658 0.7614 +vn -0.7894 -0.2032 0.5793 +vn 0.8016 0.0110 0.5977 +vn -0.8016 0.0110 0.5977 +vn -0.4603 0.8619 0.2127 +vn 0.0000 0.8592 0.5116 +vn 0.4603 0.8619 0.2127 +vn -0.4792 0.5120 -0.7129 +vn 0.4792 0.5120 -0.7129 +vn -0.2313 0.9570 0.1751 +vn -0.1217 0.6503 -0.7499 +vn 0.1217 0.6503 -0.7499 +vn -0.2275 0.8745 -0.4283 +vn 0.2275 0.8745 -0.4283 +vn -0.3456 0.9125 -0.2192 +vn 0.6957 0.5814 -0.4218 +vn 0.3456 0.9125 -0.2192 +vn -0.6957 0.5814 -0.4218 +vn -0.9070 -0.4009 -0.1290 +vn -0.9302 -0.3062 -0.2024 +vn 0.5444 -0.8372 -0.0533 +vn 0.9302 -0.3062 -0.2024 +vn -0.5444 -0.8372 -0.0533 +vn 0.4720 -0.8637 -0.1768 +vn -0.4720 -0.8637 -0.1768 +vn 0.0000 -0.7711 -0.6367 +vn 0.2771 -0.3147 -0.9078 +vn -0.0000 -0.2133 -0.9770 +vn -0.2771 -0.3147 -0.9078 +vn -0.6894 -0.6687 -0.2786 +vn 0.1514 -0.1510 -0.9769 +vn 0.0000 -0.2974 -0.9548 +vn -0.1514 -0.1510 -0.9769 +vn 0.0675 -0.7832 -0.6181 +vn 0.0000 -0.8818 -0.4716 +vn -0.0675 -0.7832 -0.6181 +vn 0.5551 -0.4762 -0.6820 +vn -0.5551 -0.4762 -0.6820 +vn 0.6204 0.0835 -0.7798 +vn -0.6204 0.0835 -0.7798 +vn 0.7799 -0.0105 -0.6259 +vn -0.7799 -0.0105 -0.6259 +vn 0.6894 -0.6687 -0.2786 +vn 0.8957 0.2578 -0.3624 +vn -0.8957 0.2578 -0.3624 +vn 0.9787 -0.1959 0.0615 +vn -0.9787 -0.1959 0.0615 +vn -0.8872 -0.1577 0.4336 +vn 0.7857 -0.5715 0.2368 +vn -0.7857 -0.5715 0.2368 +vn -0.3489 -0.9371 -0.0082 +vn 0.4455 -0.3584 -0.8204 +vn 0.0000 -0.6913 -0.7226 +vn -0.0000 -0.3049 -0.9524 +vn -0.4455 -0.3584 -0.8204 +vn -0.5223 -0.6536 -0.5477 +vn 0.5223 -0.6536 -0.5477 +vn 0.0000 -0.9417 -0.3365 +vn -0.5071 -0.8376 -0.2033 +vn 0.5727 -0.8197 0.0120 +vn 0.0000 -0.9831 -0.1833 +vn -0.5727 -0.8197 0.0120 +vn 0.7211 -0.6898 0.0651 +vn 0.9850 -0.1605 0.0631 +vn -0.7211 -0.6898 0.0651 +vn -0.9850 -0.1605 0.0631 +vn 0.4730 0.1763 -0.8632 +vn 0.0000 0.3650 -0.9310 +vn -0.4730 0.1763 -0.8632 +vn 0.4442 0.7244 0.5271 +vn 0.0000 0.9997 0.0226 +vn 0.0000 0.8306 0.5568 +vn -0.4442 0.7244 0.5271 +vn -0.4135 0.9096 0.0395 +vn 0.3913 0.8153 -0.4268 +vn 0.0000 0.8343 -0.5514 +vn -0.3913 0.8153 -0.4268 +vn 0.7717 0.6311 0.0785 +vn 0.4444 0.7886 0.4250 +vn -0.7717 0.6311 0.0785 +vn -0.4444 0.7886 0.4250 +vn 0.7418 0.5164 0.4279 +vn 0.6682 0.6719 0.3195 +vn -0.7418 0.5164 0.4279 +vn -0.6682 0.6719 0.3195 +vn 0.8486 0.5288 -0.0140 +vn 0.6784 0.7314 -0.0695 +vn -0.8486 0.5288 -0.0140 +vn -0.6784 0.7314 -0.0695 +vn 0.8722 0.3146 -0.3747 +vn 0.6075 0.5696 -0.5536 +vn -0.8722 0.3146 -0.3747 +vn -0.6075 0.5696 -0.5536 +vn 0.6197 -0.0605 -0.7825 +vn 0.6708 -0.0453 -0.7403 +vn -0.6197 -0.0605 -0.7825 +vn 0.4135 0.9096 0.0395 +vn 0.3406 0.8832 0.3223 +vn -0.3406 0.8832 0.3223 +vn 0.0000 0.5293 0.8485 +vn 0.9983 -0.0283 -0.0502 +vn -0.9983 -0.0283 -0.0502 +vn 0.8403 0.4934 0.2246 +vn -0.8403 0.4934 0.2246 +vn 0.5071 -0.8376 -0.2033 +vn 0.5790 -0.8027 0.1427 +vn -0.5790 -0.8027 0.1427 +vn -0.5633 -0.8173 -0.1213 +vn 0.3123 -0.9500 0.0012 +vn -0.3123 -0.9500 0.0012 +vn 0.8872 -0.1577 0.4336 +vn 0.3255 -0.6029 -0.7284 +vn -0.3255 -0.6029 -0.7284 +vn -0.5292 -0.5051 -0.6817 +vn 0.5633 -0.8173 -0.1213 +vn 0.5292 -0.5051 -0.6817 +vn -0.2793 0.7683 0.5759 +vn 0.5512 -0.0788 0.8307 +vn 0.0188 0.8723 0.4887 +vn 0.2793 0.7683 0.5759 +vn -0.5512 -0.0788 0.8307 +vn -0.4493 -0.0383 0.8926 +vn 0.3215 -0.0923 0.9424 +vn 0.3836 0.8630 0.3288 +vn -0.3215 -0.0923 0.9424 +vn -0.0188 0.8723 0.4887 +vn -0.3836 0.8630 0.3288 +vn 0.7788 0.1678 0.6044 +vn -0.7788 0.1678 0.6044 +vn 0.1545 -0.1239 0.9802 +vn -0.1545 -0.1239 0.9802 +vn 0.6526 -0.4768 0.5888 +vn -0.6526 -0.4768 0.5888 +vn 0.0411 0.3108 0.9496 +vn -0.0411 0.3108 0.9496 +vn 0.5029 -0.7810 0.3703 +vn -0.5029 -0.7810 0.3703 +vn -0.5384 0.2953 0.7893 +vn 0.3300 0.3157 0.8896 +vn 0.0295 -0.6350 0.7719 +vn -0.3300 0.3157 0.8896 +vn -0.0295 -0.6350 0.7719 +vn 0.5384 0.2953 0.7893 +vn 0.1629 0.8581 0.4870 +vn -0.1629 0.8581 0.4870 +vn -0.1868 0.9538 0.2351 +vn 0.1868 0.9538 0.2351 +vn -0.9848 -0.0996 0.1426 +vn 0.9848 -0.0996 0.1426 +vn 0.7622 0.6471 -0.0193 +vn -0.1496 -0.7455 0.6495 +vn 0.1496 -0.7455 0.6495 +vn 0.5605 -0.6609 0.4991 +vn -0.5605 -0.6609 0.4991 +vn 0.6842 -0.5558 0.4722 +vn -0.6842 -0.5558 0.4722 +vn 0.8572 -0.4931 -0.1483 +vn -0.8572 -0.4931 -0.1483 +vn -0.7312 0.1144 0.6725 +vn 0.7312 0.1144 0.6725 +vn 0.4493 -0.0383 0.8926 +vn 0.5998 0.5131 0.6139 +vn -0.5998 0.5131 0.6139 +vn 0.9610 -0.1188 0.2499 +vn 0.8420 -0.1763 0.5098 +vn -0.9610 -0.1188 0.2499 +vn 0.8515 0.0414 0.5228 +vn 0.4814 0.6344 0.6048 +vn -0.8420 -0.1763 0.5098 +vn -0.8515 0.0414 0.5228 +vn -0.4814 0.6344 0.6048 +vn 0.8303 -0.4790 0.2850 +vn 0.6864 -0.6234 0.3746 +vn -0.8303 -0.4790 0.2850 +vn 0.7261 -0.4989 0.4732 +vn 0.7949 -0.2332 0.5601 +vn -0.7261 -0.4989 0.4732 +vn -0.6864 -0.6234 0.3746 +vn -0.7949 -0.2332 0.5601 +vn 0.6593 -0.4685 0.5881 +vn 0.6482 -0.4206 0.6347 +vn -0.6593 -0.4685 0.5881 +vn -0.6482 -0.4206 0.6347 +vn -0.5725 -0.4189 0.7048 +vn 0.7584 0.2665 0.5948 +vn 0.5725 -0.4189 0.7048 +vn -0.7584 0.2665 0.5948 +vn -0.4492 0.3799 0.8086 +vn 0.4492 0.3799 0.8086 +vn -0.2929 0.3709 0.8813 +vn 0.6450 0.3102 0.6984 +vn 0.2929 0.3709 0.8813 +vn -0.6450 0.3102 0.6984 +vn -0.0331 0.9449 0.3256 +vn 0.0331 0.9449 0.3256 +vn 0.4618 -0.3291 0.8237 +vn -0.4618 -0.3291 0.8237 +vn -0.2624 -0.5331 0.8043 +vn 0.2624 -0.5331 0.8043 +vn -0.7529 -0.0338 0.6573 +vn 0.7529 -0.0338 0.6573 +vn -0.5831 0.4999 0.6403 +vn -0.7622 0.6471 -0.0193 +vn 0.5831 0.4999 0.6403 +vn 0.0650 0.7039 0.7074 +vn -0.0650 0.7039 0.7074 +vn 0.1951 0.0390 0.9800 +vn -0.1951 0.0390 0.9800 +vn -0.4085 0.1273 0.9039 +vn 0.4085 0.1273 0.9039 +vn 0.3347 -0.0046 0.9423 +vn -0.3347 -0.0046 0.9423 +vn -0.4448 -0.0937 0.8907 +vn 0.3144 -0.1038 0.9436 +vn 0.3343 0.1068 0.9364 +vn -0.3144 -0.1038 0.9436 +vn -0.3343 0.1068 0.9364 +vn 0.2897 0.3158 0.9035 +vn -0.2897 0.3158 0.9035 +vn -0.3831 -0.0685 0.9211 +vn 0.3831 -0.0685 0.9211 +vn -0.0989 -0.8408 -0.5322 +vn -0.0253 -0.6796 -0.7331 +vn 0.0989 -0.8408 -0.5322 +vn 0.0253 -0.6796 -0.7331 +vn 0.6366 -0.5043 -0.5834 +vn -0.6366 -0.5043 -0.5834 +vn 0.9253 0.0918 -0.3680 +vn -0.9253 0.0918 -0.3680 +vn 0.2870 0.5978 -0.7485 +vn -0.2870 0.5978 -0.7485 +vn -0.4142 0.5509 -0.7245 +vn 0.4142 0.5509 -0.7245 +vn -0.6501 0.5847 -0.4854 +vn 0.6501 0.5847 -0.4854 +vn -0.6708 -0.0453 -0.7403 +vn -0.3679 -0.2836 0.8856 +vn 0.4448 -0.0937 0.8907 +usemtl None +s 1 +f 55/15/7 11/16/8 53/17/9 +f 12/18/10 56/19/11 54/20/12 +f 53/17/9 13/21/13 51/22/14 +f 14/23/15 54/20/12 52/24/16 +f 11/16/8 15/25/17 13/21/13 +f 16/26/18 12/18/10 14/23/15 +f 9/27/19 17/28/20 11/16/8 +f 18/29/21 10/30/22 12/18/10 +f 19/31/23 23/32/24 17/28/20 +f 24/33/25 20/34/26 18/29/21 +f 17/28/20 25/35/27 15/25/17 +f 26/36/28 18/29/21 16/26/18 +f 29/37/29 25/35/27 23/32/24 +f 30/38/30 26/36/28 28/39/31 +f 21/40/32 29/37/29 23/32/24 +f 30/38/30 22/41/33 24/33/25 +f 31/42/34 35/43/35 29/37/29 +f 36/44/36 32/45/37 30/38/30 +f 35/43/35 27/46/38 29/37/29 +f 36/44/36 28/39/31 38/47/39 +f 41/48/40 37/49/41 35/43/35 +f 42/50/42 38/47/39 40/51/43 +f 43/52/44 35/43/35 33/53/45 +f 44/54/46 36/44/36 42/50/42 +f 45/55/47 41/48/40 43/52/44 +f 46/56/48 42/50/42 48/57/49 +f 47/58/50 39/59/51 41/48/40 +f 48/57/49 40/51/43 50/60/52 +f 53/17/9 49/61/53 47/58/50 +f 54/20/12 50/60/52 52/24/16 +f 55/15/7 47/58/50 45/55/47 +f 56/19/11 48/57/49 54/20/12 +f 45/55/47 57/62/54 55/15/7 +f 46/56/48 58/63/55 60/64/56 +f 43/52/44 59/65/57 45/55/47 +f 44/54/46 60/64/56 62/66/58 +f 33/53/45 61/67/59 43/52/44 +f 34/68/60 62/66/58 64/69/61 +f 31/42/34 63/70/62 33/53/45 +f 32/45/37 64/69/61 66/71/63 +f 31/42/34 67/72/64 65/73/65 +f 68/74/66 32/45/37 66/71/63 +f 21/40/32 71/75/67 67/72/64 +f 72/76/68 22/41/33 68/74/66 +f 19/31/23 73/77/69 71/75/67 +f 74/78/70 20/34/26 72/76/68 +f 9/27/19 57/62/54 73/77/69 +f 58/63/55 10/30/22 74/78/70 +f 69/79/71 73/77/69 57/62/54 +f 58/63/55 74/78/70 70/80/72 +f 71/75/67 73/77/69 69/79/71 +f 70/80/72 74/78/70 72/76/68 +f 69/79/71 67/72/64 71/75/67 +f 72/76/68 68/74/66 70/80/72 +f 69/79/71 65/73/65 67/72/64 +f 68/74/66 66/71/63 70/80/72 +f 69/79/71 63/70/62 65/73/65 +f 66/71/63 64/69/61 70/80/72 +f 69/79/71 61/67/59 63/70/62 +f 64/69/61 62/66/58 70/80/72 +f 69/79/71 59/65/57 61/67/59 +f 62/66/58 60/64/56 70/80/72 +f 69/79/71 57/62/54 59/65/57 +f 60/64/56 58/63/55 70/80/72 +f 182/81/73 99/82/74 97/83/75 +f 183/84/76 99/82/74 184/85/77 +f 180/86/78 97/83/75 95/87/79 +f 181/88/80 98/89/81 183/84/76 +f 93/90/82 180/86/78 95/87/79 +f 181/88/80 94/91/83 96/92/84 +f 91/93/85 178/94/86 93/90/82 +f 179/95/87 92/96/88 94/91/83 +f 89/97/89 176/98/90 91/93/85 +f 177/99/91 90/100/92 92/96/88 +f 87/101/93 154/102/94 172/103/95 +f 155/104/96 88/105/97 173/106/98 +f 102/107/99 154/102/94 100/108/100 +f 103/109/101 155/104/96 157/110/102 +f 102/107/99 158/111/103 156/112/104 +f 159/113/105 103/109/101 157/110/102 +f 106/114/106 158/111/103 104/115/107 +f 107/116/108 159/113/105 161/117/109 +f 108/118/110 160/119/111 106/114/106 +f 109/120/112 161/117/109 163/121/113 +f 110/122/114 162/123/115 108/118/110 +f 111/124/116 163/121/113 165/125/117 +f 110/122/114 166/126/118 164/127/119 +f 167/128/120 111/124/116 165/125/117 +f 114/129/121 166/126/118 112/130/122 +f 115/131/123 167/128/120 169/132/124 +f 116/133/125 168/134/126 114/129/121 +f 117/135/127 169/132/124 171/136/128 +f 75/137/129 170/138/130 116/133/125 +f 75/137/129 171/136/128 76/139/131 +f 136/140/132 170/138/130 118/141/133 +f 137/142/134 171/136/128 169/132/124 +f 136/140/132 166/126/118 168/134/126 +f 167/128/120 137/142/134 169/132/124 +f 164/127/119 187/143/135 134/144/136 +f 165/125/117 188/145/137 167/128/120 +f 162/123/115 134/144/136 132/146/138 +f 163/121/113 135/147/139 165/125/117 +f 160/119/111 132/146/138 130/148/140 +f 161/117/109 133/149/141 163/121/113 +f 158/111/103 130/148/140 128/150/142 +f 159/113/105 131/151/143 161/117/109 +f 156/112/104 128/150/142 126/152/144 +f 157/110/102 129/153/145 159/113/105 +f 154/102/94 126/152/144 124/154/146 +f 155/104/96 127/155/147 157/110/102 +f 172/103/95 124/154/146 122/156/148 +f 173/106/98 125/157/149 155/104/96 +f 122/156/148 185/158/150 172/103/95 +f 185/158/150 123/159/151 173/106/98 +f 170/138/130 120/160/152 118/141/133 +f 171/136/128 121/161/153 76/139/131 +f 120/160/152 186/162/154 191/163/155 +f 186/162/154 121/161/153 192/164/156 +f 189/165/157 186/162/154 185/158/150 +f 190/166/158 186/162/154 192/164/156 +f 143/167/159 184/85/77 182/81/73 +f 184/85/77 144/168/160 183/84/76 +f 141/169/161 182/81/73 180/86/78 +f 183/84/76 142/170/162 181/88/80 +f 141/169/161 178/94/86 139/171/163 +f 142/170/162 179/95/87 181/88/80 +f 174/172/164 193/173/165 176/98/90 +f 194/174/166 175/175/167 177/99/91 +f 139/171/163 176/98/90 193/173/165 +f 177/99/91 140/176/168 194/174/166 +f 198/177/169 195/178/170 152/179/171 +f 198/177/169 196/180/172 197/181/173 +f 195/178/170 77/182/174 193/173/165 +f 196/180/172 77/182/174 197/181/173 +f 139/171/163 77/182/174 138/183/175 +f 140/176/168 77/182/174 194/174/166 +f 150/184/176 199/185/177 152/179/171 +f 200/186/178 151/187/179 153/188/180 +f 148/189/181 201/190/182 150/184/176 +f 202/191/183 149/192/184 151/187/179 +f 205/193/185 148/189/181 147/194/186 +f 206/195/187 149/192/184 204/196/188 +f 79/197/189 147/194/186 146/198/190 +f 79/197/189 147/194/186 206/195/187 +f 152/179/171 78/199/191 198/177/169 +f 153/188/180 78/199/191 200/186/178 +f 199/185/177 216/200/192 78/199/191 +f 200/186/178 216/200/192 215/201/193 +f 79/197/189 208/202/194 205/193/185 +f 209/203/195 79/197/189 206/195/187 +f 205/193/185 210/204/196 203/205/197 +f 211/206/198 206/195/187 204/196/188 +f 210/204/196 201/190/182 203/205/197 +f 211/206/198 202/191/183 213/207/199 +f 201/190/182 214/208/200 199/185/177 +f 215/201/193 202/191/183 200/186/178 +f 212/209/201 208/202/194 207/210/202 +f 213/207/199 209/203/195 211/206/198 +f 207/210/202 214/208/200 212/209/201 +f 215/201/193 207/210/202 213/207/199 +f 147/194/186 172/103/95 185/158/150 +f 173/106/98 147/194/186 185/158/150 +f 148/189/181 219/211/203 172/103/95 +f 220/212/204 149/192/184 173/106/98 +f 152/179/171 219/211/203 150/184/176 +f 153/188/180 220/212/204 222/213/205 +f 195/178/170 221/214/206 152/179/171 +f 196/180/172 222/213/205 175/175/167 +f 217/215/207 174/172/164 89/97/89 +f 218/216/208 175/175/167 222/213/205 +f 223/217/209 221/214/206 217/215/207 +f 224/218/210 222/213/205 220/212/204 +f 87/101/93 219/211/203 223/217/209 +f 220/212/204 88/105/97 224/218/210 +f 138/183/175 230/219/211 139/171/163 +f 138/183/175 231/220/212 80/221/213 +f 141/169/161 230/219/211 228/222/214 +f 231/220/212 142/170/162 229/223/215 +f 143/167/159 228/222/214 226/224/216 +f 229/223/215 144/168/160 227/225/217 +f 145/226/218 226/224/216 225/227/219 +f 227/225/217 145/226/218 225/227/219 +f 226/224/216 239/228/220 225/227/219 +f 227/225/217 239/228/220 238/229/221 +f 226/224/216 235/230/222 237/231/223 +f 236/232/224 227/225/217 238/229/221 +f 228/222/214 233/233/225 235/230/222 +f 234/234/226 229/223/215 236/232/224 +f 80/221/213 233/233/225 230/219/211 +f 80/221/213 234/234/226 232/235/227 +f 232/235/227 237/231/223 233/233/225 +f 238/229/221 232/235/227 234/234/226 +f 233/233/225 237/231/223 235/230/222 +f 236/232/224 238/229/221 234/234/226 +f 191/163/155 242/236/228 240/237/229 +f 243/238/230 192/164/156 241/239/231 +f 120/160/152 240/237/229 262/240/232 +f 241/239/231 121/161/153 263/241/233 +f 120/160/152 264/242/234 118/141/133 +f 121/161/153 265/243/235 263/241/233 +f 122/156/148 242/236/228 189/165/157 +f 123/159/151 243/238/230 261/244/236 +f 122/156/148 258/245/237 260/246/238 +f 259/247/239 123/159/151 261/244/236 +f 124/154/146 256/248/240 258/245/237 +f 257/249/241 125/157/149 259/247/239 +f 126/152/144 254/250/242 256/248/240 +f 255/251/243 127/155/147 257/249/241 +f 128/150/142 252/252/244 254/250/242 +f 253/253/245 129/153/145 255/251/243 +f 132/146/138 252/252/244 130/148/140 +f 133/149/141 253/253/245 251/254/246 +f 134/144/136 250/255/247 132/146/138 +f 135/147/139 251/254/246 249/256/248 +f 134/144/136 244/257/249 248/258/250 +f 245/259/251 135/147/139 249/256/248 +f 187/143/135 246/260/252 244/257/249 +f 247/261/253 188/145/137 245/259/251 +f 136/140/132 264/242/234 246/260/252 +f 265/243/235 137/142/134 247/261/253 +f 264/242/234 284/262/254 246/260/252 +f 265/243/235 285/263/255 267/264/256 +f 244/257/249 284/262/254 286/265/257 +f 285/263/255 245/259/251 287/266/258 +f 244/257/249 282/267/259 248/258/250 +f 245/259/251 283/268/260 287/266/258 +f 248/258/250 280/269/261 250/255/247 +f 249/256/248 281/270/262 283/268/260 +f 252/252/244 280/269/261 278/271/263 +f 281/270/262 253/253/245 279/272/264 +f 252/252/244 276/273/265 254/250/242 +f 253/253/245 277/274/266 279/272/264 +f 256/248/240 276/273/265 274/275/267 +f 277/274/266 257/249/241 275/276/268 +f 256/248/240 272/277/269 258/245/237 +f 257/249/241 273/278/270 275/276/268 +f 258/245/237 270/279/271 260/246/238 +f 259/247/239 271/280/272 273/278/270 +f 242/236/228 270/279/271 288/281/273 +f 271/280/272 243/238/230 289/282/274 +f 264/242/234 268/283/275 266/284/276 +f 269/285/277 265/243/235 267/264/256 +f 262/240/232 290/286/278 268/283/275 +f 291/287/279 263/241/233 269/285/277 +f 240/237/229 288/281/273 290/286/278 +f 289/282/274 241/239/231 291/287/279 +f 75/137/129 292/288/280 81/289/281 +f 293/290/282 75/137/129 81/289/281 +f 116/133/125 294/291/283 292/288/280 +f 295/292/284 117/135/127 293/290/282 +f 112/130/122 294/291/283 114/129/121 +f 113/293/285 295/292/284 297/294/286 +f 110/122/114 296/295/287 112/130/122 +f 111/124/116 297/294/286 299/296/288 +f 108/118/110 298/297/289 110/122/114 +f 109/120/112 299/296/288 301/298/290 +f 108/118/110 302/299/291 300/300/292 +f 303/301/293 109/120/112 301/298/290 +f 104/115/107 302/299/291 106/114/106 +f 105/302/294 303/301/293 305/303/295 +f 104/115/107 306/304/296 304/305/297 +f 307/306/298 105/302/294 305/303/295 +f 102/107/99 308/307/299 306/304/296 +f 309/308/300 103/109/101 307/306/298 +f 317/309/301 346/310/302 316/311/303 +f 317/312/301 347/313/304 337/314/305 +f 316/311/303 344/315/306 315/316/307 +f 316/317/303 345/318/308 347/313/304 +f 315/316/307 348/319/309 314/320/310 +f 315/321/307 349/322/311 345/318/308 +f 97/83/75 314/320/310 348/319/309 +f 314/320/310 98/89/81 349/322/311 +f 95/87/79 348/319/309 342/323/312 +f 349/322/311 96/92/84 343/324/313 +f 93/90/82 342/323/312 338/325/314 +f 343/324/313 94/91/83 339/326/315 +f 91/93/85 338/325/314 340/327/316 +f 339/326/315 92/96/88 341/328/317 +f 338/325/314 346/310/302 340/327/316 +f 347/313/304 339/326/315 341/328/317 +f 342/323/312 344/315/306 338/325/314 +f 343/324/313 345/318/308 349/322/311 +f 340/327/316 336/329/318 334/330/319 +f 341/328/317 337/314/305 347/313/304 +f 89/97/89 340/327/316 334/330/319 +f 341/328/317 90/100/92 335/331/320 +f 350/332/321 223/217/209 217/215/207 +f 351/333/322 224/218/210 353/334/323 +f 334/330/319 217/215/207 89/97/89 +f 335/331/320 218/216/208 351/333/322 +f 223/217/209 354/335/324 87/101/93 +f 224/218/210 355/336/325 353/334/323 +f 354/335/324 100/108/100 87/101/93 +f 355/336/325 101/337/326 309/308/300 +f 332/338/327 312/339/328 85/340/329 +f 333/341/330 312/342/328 361/343/331 +f 360/344/332 86/345/333 312/339/328 +f 361/343/331 86/346/333 359/347/334 +f 86/345/333 356/348/335 313/349/336 +f 357/350/337 86/346/333 313/351/336 +f 313/349/336 336/329/318 317/309/301 +f 337/314/305 313/351/336 317/312/301 +f 336/329/318 350/332/321 334/330/319 +f 337/314/305 351/333/322 357/350/337 +f 304/305/297 326/352/338 318/353/339 +f 327/354/340 305/303/295 319/355/341 +f 324/356/342 85/340/329 84/357/343 +f 325/358/344 85/359/329 333/341/330 +f 366/360/345 311/361/346 310/362/347 +f 367/363/348 311/364/346 365/365/349 +f 311/361/346 362/366/350 83/367/351 +f 363/368/352 311/364/346 83/369/351 +f 83/367/351 324/356/342 84/357/343 +f 325/358/344 83/369/351 84/370/343 +f 300/371/292 370/372/353 372/373/354 +f 371/374/355 301/375/290 373/376/356 +f 372/373/354 376/377/357 374/378/358 +f 377/379/359 373/376/356 375/380/360 +f 374/378/358 378/381/361 380/382/362 +f 379/383/363 375/380/360 381/384/364 +f 380/382/362 384/385/365 382/386/366 +f 385/387/367 381/384/364 383/388/368 +f 386/389/369 384/385/365 322/390/370 +f 387/391/371 385/387/367 383/388/368 +f 324/356/342 382/386/366 386/389/369 +f 383/388/368 325/358/344 387/391/371 +f 362/366/350 380/382/362 382/386/366 +f 381/384/364 363/368/352 383/388/368 +f 364/392/372 374/378/358 380/382/362 +f 375/380/360 365/365/349 381/384/364 +f 366/360/345 372/373/354 374/378/358 +f 373/376/356 367/363/348 375/380/360 +f 300/371/292 368/393/373 298/394/289 +f 301/375/290 369/395/374 373/376/356 +f 368/393/373 310/362/347 82/396/375 +f 369/395/374 310/397/347 367/363/348 +f 292/398/280 296/399/287 298/394/289 +f 297/400/286 293/401/282 299/402/288 +f 292/398/280 368/393/373 82/396/375 +f 369/395/374 293/401/282 82/403/375 +f 81/404/281 292/398/280 82/396/375 +f 82/403/375 293/401/282 81/405/281 +f 304/305/297 370/372/353 302/299/291 +f 305/303/295 371/374/355 319/355/341 +f 318/353/339 376/377/357 370/372/353 +f 377/379/359 319/355/341 371/374/355 +f 320/406/376 378/381/361 376/377/357 +f 379/383/363 321/407/377 377/379/359 +f 384/385/365 390/408/378 322/390/370 +f 385/387/367 391/409/379 379/383/363 +f 358/410/380 392/411/381 356/348/335 +f 359/347/334 393/412/382 395/413/383 +f 392/411/381 328/414/384 326/352/338 +f 393/412/382 329/415/385 395/413/383 +f 306/304/296 392/411/381 326/352/338 +f 393/412/382 307/306/298 327/354/340 +f 308/307/299 350/332/321 392/411/381 +f 351/333/322 309/308/300 393/412/382 +f 350/332/321 356/348/335 392/411/381 +f 393/412/382 357/350/337 351/333/322 +f 308/307/299 354/335/324 352/416/386 +f 353/334/323 355/336/325 309/308/300 +f 330/417/387 386/389/369 322/390/370 +f 331/418/388 387/391/371 389/419/389 +f 386/389/369 332/338/327 324/356/342 +f 387/391/371 333/341/330 389/419/389 +f 394/420/390 330/417/387 328/414/384 +f 395/413/383 331/418/388 389/419/389 +f 360/344/332 394/420/390 358/410/380 +f 361/343/331 395/413/383 389/419/389 +f 332/338/327 388/421/391 360/344/332 +f 361/343/331 389/419/389 333/341/330 +f 396/422/392 410/423/393 408/424/394 +f 397/425/395 411/426/396 423/427/397 +f 408/424/394 412/428/398 406/429/399 +f 413/430/400 409/431/401 407/432/402 +f 412/428/398 404/433/403 406/429/399 +f 413/430/400 405/434/404 415/435/405 +f 414/436/406 402/437/407 404/433/403 +f 415/435/405 403/438/408 417/439/409 +f 416/440/410 400/441/411 402/437/407 +f 417/439/409 401/442/412 419/443/413 +f 400/441/411 420/444/414 398/445/415 +f 421/446/416 401/442/412 399/447/417 +f 418/448/418 426/449/419 420/444/414 +f 427/450/420 419/443/413 421/446/416 +f 416/440/410 428/451/421 418/448/418 +f 429/452/422 417/439/409 419/443/413 +f 432/453/423 416/440/410 414/436/406 +f 433/454/424 417/439/409 431/455/425 +f 434/456/426 414/436/406 412/428/398 +f 435/457/427 415/435/405 433/454/424 +f 436/458/428 412/428/398 410/423/393 +f 437/459/429 413/430/400 435/457/427 +f 410/423/393 424/460/430 436/458/428 +f 425/461/431 411/426/396 437/459/429 +f 328/414/384 450/462/432 326/352/338 +f 329/415/385 451/463/433 453/464/434 +f 398/445/415 452/465/435 328/466/384 +f 399/447/417 453/467/434 421/446/416 +f 318/353/339 450/462/432 320/406/376 +f 451/463/433 319/355/341 321/407/377 +f 390/468/378 422/469/436 396/422/392 +f 423/427/397 391/470/379 397/425/395 +f 420/444/414 448/471/437 452/465/435 +f 449/472/438 421/446/416 453/467/434 +f 454/473/439 448/471/437 446/474/440 +f 455/475/441 449/472/438 453/467/434 +f 442/476/442 446/474/440 444/477/443 +f 447/478/444 443/479/445 445/480/446 +f 456/481/447 442/476/442 440/482/448 +f 457/483/449 443/479/445 455/475/441 +f 456/481/447 458/484/450 438/485/451 +f 457/483/449 459/486/452 441/487/453 +f 438/485/451 424/460/430 422/469/436 +f 439/488/454 425/461/431 459/486/452 +f 320/406/376 438/489/451 390/408/378 +f 439/490/454 321/407/377 391/409/379 +f 450/462/432 456/491/447 320/406/376 +f 451/463/433 457/492/449 455/493/441 +f 450/462/432 452/494/435 454/495/439 +f 455/493/441 453/464/434 451/463/433 +f 424/460/430 460/496/455 484/497/456 +f 461/498/457 425/461/431 485/499/458 +f 440/482/448 460/496/455 458/484/450 +f 441/487/453 461/498/457 471/500/459 +f 440/482/448 468/501/460 470/502/461 +f 469/503/462 441/487/453 471/500/459 +f 444/477/443 468/501/460 442/476/442 +f 445/480/446 469/503/462 467/504/463 +f 446/474/440 466/505/464 444/477/443 +f 447/478/444 467/504/463 465/506/465 +f 446/474/440 462/507/466 464/508/467 +f 463/509/468 447/478/444 465/506/465 +f 448/471/437 482/510/469 462/507/466 +f 483/511/470 449/472/438 463/509/468 +f 436/458/428 484/497/456 472/512/471 +f 485/499/458 437/459/429 473/513/472 +f 434/456/426 472/512/471 474/514/473 +f 473/513/472 435/457/427 475/515/474 +f 432/453/423 474/514/473 476/516/475 +f 475/515/474 433/454/424 477/517/476 +f 432/453/423 478/518/477 430/519/478 +f 433/454/424 479/520/479 477/517/476 +f 430/519/478 480/521/480 428/451/421 +f 431/455/425 481/522/481 479/520/479 +f 428/451/421 482/510/469 426/449/419 +f 429/452/422 483/511/470 481/522/481 +f 464/508/467 486/523/482 466/505/464 +f 465/506/465 487/524/483 489/525/484 +f 488/526/485 492/527/486 486/523/482 +f 489/525/484 493/528/487 491/529/488 +f 492/527/486 496/530/489 494/531/490 +f 497/532/491 493/528/487 495/533/492 +f 496/530/489 500/534/493 494/531/490 +f 497/532/491 501/535/494 499/536/495 +f 472/512/471 494/531/490 500/534/493 +f 495/533/492 473/513/472 501/535/494 +f 492/527/486 484/497/456 460/496/455 +f 493/528/487 485/499/458 495/533/492 +f 470/502/461 492/527/486 460/496/455 +f 471/500/459 493/528/487 487/524/483 +f 466/505/464 470/502/461 468/501/460 +f 471/500/459 467/504/463 469/503/462 +f 482/510/469 464/508/467 462/507/466 +f 483/511/470 465/506/465 489/525/484 +f 480/521/480 488/526/485 482/510/469 +f 489/525/484 481/522/481 483/511/470 +f 496/530/489 480/521/480 478/518/477 +f 497/532/491 481/522/481 491/529/488 +f 498/537/496 478/518/477 476/516/475 +f 499/536/495 479/520/479 497/532/491 +f 474/514/473 498/537/496 476/516/475 +f 499/536/495 475/515/474 477/517/476 +f 472/512/471 500/534/493 474/514/473 +f 475/515/474 501/535/494 473/513/472 +f 400/441/411 512/538/497 510/539/498 +f 513/540/499 401/442/412 511/541/500 +f 402/437/407 510/539/498 508/542/501 +f 511/541/500 403/438/408 509/543/502 +f 402/437/407 506/544/503 404/433/403 +f 403/438/408 507/545/504 509/543/502 +f 404/433/403 504/546/505 406/547/399 +f 405/434/404 505/548/506 507/545/504 +f 406/547/399 502/549/507 408/550/394 +f 407/551/402 503/552/508 505/548/506 +f 408/550/394 514/553/509 396/554/392 +f 409/555/401 515/556/510 503/552/508 +f 510/539/498 514/553/509 502/549/507 +f 511/541/500 515/556/510 513/540/499 +f 502/549/507 508/542/501 510/539/498 +f 509/543/502 503/552/508 511/541/500 +f 504/546/505 506/544/503 508/542/501 +f 509/543/502 507/545/504 505/548/506 +f 390/408/378 514/557/509 322/390/370 +f 391/558/379 515/556/510 397/559/395 +f 322/560/370 512/538/497 330/561/387 +f 513/540/499 323/562/511 331/563/388 +f 328/466/384 512/538/497 398/445/415 +f 513/540/499 329/564/385 399/447/417 +f 55/15/7 9/27/19 11/16/8 +f 12/18/10 10/30/22 56/19/11 +f 53/17/9 11/16/8 13/21/13 +f 14/23/15 12/18/10 54/20/12 +f 11/16/8 17/28/20 15/25/17 +f 16/26/18 18/29/21 12/18/10 +f 9/27/19 19/31/23 17/28/20 +f 18/29/21 20/34/26 10/30/22 +f 19/31/23 21/40/32 23/32/24 +f 24/33/25 22/41/33 20/34/26 +f 17/28/20 23/32/24 25/35/27 +f 26/36/28 24/33/25 18/29/21 +f 29/37/29 27/46/38 25/35/27 +f 30/38/30 24/33/25 26/36/28 +f 21/40/32 31/42/34 29/37/29 +f 30/38/30 32/45/37 22/41/33 +f 31/42/34 33/53/45 35/43/35 +f 36/44/36 34/68/60 32/45/37 +f 35/43/35 37/49/41 27/46/38 +f 36/44/36 30/38/30 28/39/31 +f 41/48/40 39/59/51 37/49/41 +f 42/50/42 36/44/36 38/47/39 +f 43/52/44 41/48/40 35/43/35 +f 44/54/46 34/68/60 36/44/36 +f 45/55/47 47/58/50 41/48/40 +f 46/56/48 44/54/46 42/50/42 +f 47/58/50 49/61/53 39/59/51 +f 48/57/49 42/50/42 40/51/43 +f 53/17/9 51/22/14 49/61/53 +f 54/20/12 48/57/49 50/60/52 +f 55/15/7 53/17/9 47/58/50 +f 56/19/11 46/56/48 48/57/49 +f 45/55/47 59/65/57 57/62/54 +f 46/56/48 56/19/11 58/63/55 +f 43/52/44 61/67/59 59/65/57 +f 44/54/46 46/56/48 60/64/56 +f 33/53/45 63/70/62 61/67/59 +f 34/68/60 44/54/46 62/66/58 +f 31/42/34 65/73/65 63/70/62 +f 32/45/37 34/68/60 64/69/61 +f 31/42/34 21/40/32 67/72/64 +f 68/74/66 22/41/33 32/45/37 +f 21/40/32 19/31/23 71/75/67 +f 72/76/68 20/34/26 22/41/33 +f 19/31/23 9/27/19 73/77/69 +f 74/78/70 10/30/22 20/34/26 +f 9/27/19 55/15/7 57/62/54 +f 58/63/55 56/19/11 10/30/22 +f 182/81/73 184/85/77 99/82/74 +f 183/84/76 98/89/81 99/82/74 +f 180/86/78 182/81/73 97/83/75 +f 181/88/80 96/92/84 98/89/81 +f 93/90/82 178/94/86 180/86/78 +f 181/88/80 179/95/87 94/91/83 +f 91/93/85 176/98/90 178/94/86 +f 179/95/87 177/99/91 92/96/88 +f 89/97/89 174/172/164 176/98/90 +f 177/99/91 175/175/167 90/100/92 +f 87/101/93 100/108/100 154/102/94 +f 155/104/96 101/337/326 88/105/97 +f 102/107/99 156/112/104 154/102/94 +f 103/109/101 101/337/326 155/104/96 +f 102/107/99 104/115/107 158/111/103 +f 159/113/105 105/302/294 103/109/101 +f 106/114/106 160/119/111 158/111/103 +f 107/116/108 105/302/294 159/113/105 +f 108/118/110 162/123/115 160/119/111 +f 109/120/112 107/116/108 161/117/109 +f 110/122/114 164/127/119 162/123/115 +f 111/124/116 109/120/112 163/121/113 +f 110/122/114 112/130/122 166/126/118 +f 167/128/120 113/293/285 111/124/116 +f 114/129/121 168/134/126 166/126/118 +f 115/131/123 113/293/285 167/128/120 +f 116/133/125 170/138/130 168/134/126 +f 117/135/127 115/131/123 169/132/124 +f 75/137/129 76/139/131 170/138/130 +f 75/137/129 117/135/127 171/136/128 +f 136/140/132 168/134/126 170/138/130 +f 137/142/134 119/565/512 171/136/128 +f 136/140/132 187/143/135 166/126/118 +f 167/128/120 188/145/137 137/142/134 +f 164/127/119 166/126/118 187/143/135 +f 165/125/117 135/147/139 188/145/137 +f 162/123/115 164/127/119 134/144/136 +f 163/121/113 133/149/141 135/147/139 +f 160/119/111 162/123/115 132/146/138 +f 161/117/109 131/151/143 133/149/141 +f 158/111/103 160/119/111 130/148/140 +f 159/113/105 129/153/145 131/151/143 +f 156/112/104 158/111/103 128/150/142 +f 157/110/102 127/155/147 129/153/145 +f 154/102/94 156/112/104 126/152/144 +f 155/104/96 125/157/149 127/155/147 +f 172/103/95 154/102/94 124/154/146 +f 173/106/98 123/159/151 125/157/149 +f 122/156/148 189/165/157 185/158/150 +f 185/158/150 190/166/158 123/159/151 +f 170/138/130 76/139/131 120/160/152 +f 171/136/128 119/565/512 121/161/153 +f 120/160/152 76/139/131 186/162/154 +f 186/162/154 76/139/131 121/161/153 +f 189/165/157 191/163/155 186/162/154 +f 190/166/158 185/158/150 186/162/154 +f 143/167/159 145/226/218 184/85/77 +f 184/85/77 145/226/218 144/168/160 +f 141/169/161 143/167/159 182/81/73 +f 183/84/76 144/168/160 142/170/162 +f 141/169/161 180/86/78 178/94/86 +f 142/170/162 140/176/168 179/95/87 +f 174/172/164 195/178/170 193/173/165 +f 194/174/166 196/180/172 175/175/167 +f 139/171/163 178/94/86 176/98/90 +f 177/99/91 179/95/87 140/176/168 +f 198/177/169 197/181/173 195/178/170 +f 198/177/169 153/188/180 196/180/172 +f 195/178/170 197/181/173 77/182/174 +f 196/180/172 194/174/166 77/182/174 +f 139/171/163 193/173/165 77/182/174 +f 140/176/168 138/183/175 77/182/174 +f 150/184/176 201/190/182 199/185/177 +f 200/186/178 202/191/183 151/187/179 +f 148/189/181 203/205/197 201/190/182 +f 202/191/183 204/196/188 149/192/184 +f 205/193/185 203/205/197 148/189/181 +f 206/195/187 147/194/186 149/192/184 +f 79/197/189 205/193/185 147/194/186 +f 79/197/189 146/198/190 147/194/186 +f 152/179/171 199/185/177 78/199/191 +f 153/188/180 198/177/169 78/199/191 +f 199/185/177 214/208/200 216/200/192 +f 200/186/178 78/199/191 216/200/192 +f 79/197/189 207/210/202 208/202/194 +f 209/203/195 207/210/202 79/197/189 +f 205/193/185 208/202/194 210/204/196 +f 211/206/198 209/203/195 206/195/187 +f 210/204/196 212/209/201 201/190/182 +f 211/206/198 204/196/188 202/191/183 +f 201/190/182 212/209/201 214/208/200 +f 215/201/193 213/207/199 202/191/183 +f 212/209/201 210/204/196 208/202/194 +f 213/207/199 207/210/202 209/203/195 +f 207/210/202 216/200/192 214/208/200 +f 215/201/193 216/200/192 207/210/202 +f 147/194/186 148/189/181 172/103/95 +f 173/106/98 149/192/184 147/194/186 +f 148/189/181 150/184/176 219/211/203 +f 220/212/204 151/187/179 149/192/184 +f 152/179/171 221/214/206 219/211/203 +f 153/188/180 151/187/179 220/212/204 +f 195/178/170 174/172/164 221/214/206 +f 196/180/172 153/188/180 222/213/205 +f 217/215/207 221/214/206 174/172/164 +f 218/216/208 90/100/92 175/175/167 +f 223/217/209 219/211/203 221/214/206 +f 224/218/210 218/216/208 222/213/205 +f 87/101/93 172/103/95 219/211/203 +f 220/212/204 173/106/98 88/105/97 +f 138/183/175 80/221/213 230/219/211 +f 138/183/175 140/176/168 231/220/212 +f 141/169/161 139/171/163 230/219/211 +f 231/220/212 140/176/168 142/170/162 +f 143/167/159 141/169/161 228/222/214 +f 229/223/215 142/170/162 144/168/160 +f 145/226/218 143/167/159 226/224/216 +f 227/225/217 144/168/160 145/226/218 +f 226/224/216 237/231/223 239/228/220 +f 227/225/217 225/227/219 239/228/220 +f 226/224/216 228/222/214 235/230/222 +f 236/232/224 229/223/215 227/225/217 +f 228/222/214 230/219/211 233/233/225 +f 234/234/226 231/220/212 229/223/215 +f 80/221/213 232/235/227 233/233/225 +f 80/221/213 231/220/212 234/234/226 +f 232/235/227 239/228/220 237/231/223 +f 238/229/221 239/228/220 232/235/227 +f 191/163/155 189/165/157 242/236/228 +f 243/238/230 190/166/158 192/164/156 +f 120/160/152 191/163/155 240/237/229 +f 241/239/231 192/164/156 121/161/153 +f 120/160/152 262/240/232 264/242/234 +f 121/161/153 119/565/512 265/243/235 +f 122/156/148 260/246/238 242/236/228 +f 123/159/151 190/166/158 243/238/230 +f 122/156/148 124/154/146 258/245/237 +f 259/247/239 125/157/149 123/159/151 +f 124/154/146 126/152/144 256/248/240 +f 257/249/241 127/155/147 125/157/149 +f 126/152/144 128/150/142 254/250/242 +f 255/251/243 129/153/145 127/155/147 +f 128/150/142 130/148/140 252/252/244 +f 253/253/245 131/151/143 129/153/145 +f 132/146/138 250/255/247 252/252/244 +f 133/149/141 131/151/143 253/253/245 +f 134/144/136 248/258/250 250/255/247 +f 135/147/139 133/149/141 251/254/246 +f 134/144/136 187/143/135 244/257/249 +f 245/259/251 188/145/137 135/147/139 +f 187/143/135 136/140/132 246/260/252 +f 247/261/253 137/142/134 188/145/137 +f 136/140/132 118/141/133 264/242/234 +f 265/243/235 119/565/512 137/142/134 +f 264/242/234 266/284/276 284/262/254 +f 265/243/235 247/261/253 285/263/255 +f 244/257/249 246/260/252 284/262/254 +f 285/263/255 247/261/253 245/259/251 +f 244/257/249 286/265/257 282/267/259 +f 245/259/251 249/256/248 283/268/260 +f 248/258/250 282/267/259 280/269/261 +f 249/256/248 251/254/246 281/270/262 +f 252/252/244 250/255/247 280/269/261 +f 281/270/262 251/254/246 253/253/245 +f 252/252/244 278/271/263 276/273/265 +f 253/253/245 255/251/243 277/274/266 +f 256/248/240 254/250/242 276/273/265 +f 277/274/266 255/251/243 257/249/241 +f 256/248/240 274/275/267 272/277/269 +f 257/249/241 259/247/239 273/278/270 +f 258/245/237 272/277/269 270/279/271 +f 259/247/239 261/244/236 271/280/272 +f 242/236/228 260/246/238 270/279/271 +f 271/280/272 261/244/236 243/238/230 +f 264/242/234 262/240/232 268/283/275 +f 269/285/277 263/241/233 265/243/235 +f 262/240/232 240/237/229 290/286/278 +f 291/287/279 241/239/231 263/241/233 +f 240/237/229 242/236/228 288/281/273 +f 289/282/274 243/238/230 241/239/231 +f 75/137/129 116/133/125 292/288/280 +f 293/290/282 117/135/127 75/137/129 +f 116/133/125 114/129/121 294/291/283 +f 295/292/284 115/131/123 117/135/127 +f 112/130/122 296/295/287 294/291/283 +f 113/293/285 115/131/123 295/292/284 +f 110/122/114 298/297/289 296/295/287 +f 111/124/116 113/293/285 297/294/286 +f 108/118/110 300/300/292 298/297/289 +f 109/120/112 111/124/116 299/296/288 +f 108/118/110 106/114/106 302/299/291 +f 303/301/293 107/116/108 109/120/112 +f 104/115/107 304/305/297 302/299/291 +f 105/302/294 107/116/108 303/301/293 +f 104/115/107 102/107/99 306/304/296 +f 307/306/298 103/109/101 105/302/294 +f 102/107/99 100/108/100 308/307/299 +f 309/308/300 101/337/326 103/109/101 +f 317/309/301 336/329/318 346/310/302 +f 317/312/301 316/317/303 347/313/304 +f 316/311/303 346/310/302 344/315/306 +f 316/317/303 315/321/307 345/318/308 +f 315/316/307 344/315/306 348/319/309 +f 315/321/307 314/320/310 349/322/311 +f 97/83/75 99/82/74 314/320/310 +f 314/320/310 99/82/74 98/89/81 +f 95/87/79 97/83/75 348/319/309 +f 349/322/311 98/89/81 96/92/84 +f 93/90/82 95/87/79 342/323/312 +f 343/324/313 96/92/84 94/91/83 +f 91/93/85 93/90/82 338/325/314 +f 339/326/315 94/91/83 92/96/88 +f 338/325/314 344/315/306 346/310/302 +f 347/313/304 345/318/308 339/326/315 +f 342/323/312 348/319/309 344/315/306 +f 343/324/313 339/326/315 345/318/308 +f 340/327/316 346/310/302 336/329/318 +f 341/328/317 335/331/320 337/314/305 +f 89/97/89 91/93/85 340/327/316 +f 341/328/317 92/96/88 90/100/92 +f 350/332/321 352/416/386 223/217/209 +f 351/333/322 218/216/208 224/218/210 +f 334/330/319 350/332/321 217/215/207 +f 335/331/320 90/100/92 218/216/208 +f 223/217/209 352/416/386 354/335/324 +f 224/218/210 88/105/97 355/336/325 +f 354/335/324 308/307/299 100/108/100 +f 355/336/325 88/105/97 101/337/326 +f 332/338/327 360/344/332 312/339/328 +f 333/341/330 85/359/329 312/342/328 +f 360/344/332 358/410/380 86/345/333 +f 361/343/331 312/342/328 86/346/333 +f 86/345/333 358/410/380 356/348/335 +f 357/350/337 359/347/334 86/346/333 +f 313/349/336 356/348/335 336/329/318 +f 337/314/305 357/350/337 313/351/336 +f 336/329/318 356/348/335 350/332/321 +f 337/314/305 335/331/320 351/333/322 +f 304/305/297 306/304/296 326/352/338 +f 327/354/340 307/306/298 305/303/295 +f 324/356/342 332/338/327 85/340/329 +f 325/358/344 84/370/343 85/359/329 +f 366/360/345 364/392/372 311/361/346 +f 367/363/348 310/397/347 311/364/346 +f 311/361/346 364/392/372 362/366/350 +f 363/368/352 365/365/349 311/364/346 +f 83/367/351 362/366/350 324/356/342 +f 325/358/344 363/368/352 83/369/351 +f 300/371/292 302/299/291 370/372/353 +f 371/374/355 303/301/293 301/375/290 +f 372/373/354 370/372/353 376/377/357 +f 377/379/359 371/374/355 373/376/356 +f 374/378/358 376/377/357 378/381/361 +f 379/383/363 377/379/359 375/380/360 +f 380/382/362 378/381/361 384/385/365 +f 385/387/367 379/383/363 381/384/364 +f 386/389/369 382/386/366 384/385/365 +f 387/391/371 323/566/511 385/387/367 +f 324/356/342 362/366/350 382/386/366 +f 383/388/368 363/368/352 325/358/344 +f 362/366/350 364/392/372 380/382/362 +f 381/384/364 365/365/349 363/368/352 +f 364/392/372 366/360/345 374/378/358 +f 375/380/360 367/363/348 365/365/349 +f 366/360/345 368/393/373 372/373/354 +f 373/376/356 369/395/374 367/363/348 +f 300/371/292 372/373/354 368/393/373 +f 301/375/290 299/402/288 369/395/374 +f 368/393/373 366/360/345 310/362/347 +f 369/395/374 82/403/375 310/397/347 +f 292/398/280 294/567/283 296/399/287 +f 297/400/286 295/568/284 293/401/282 +f 292/398/280 298/394/289 368/393/373 +f 369/395/374 299/402/288 293/401/282 +f 304/305/297 318/353/339 370/372/353 +f 305/303/295 303/301/293 371/374/355 +f 318/353/339 320/406/376 376/377/357 +f 377/379/359 321/407/377 319/355/341 +f 320/406/376 390/408/378 378/381/361 +f 379/383/363 391/409/379 321/407/377 +f 384/385/365 378/381/361 390/408/378 +f 385/387/367 323/566/511 391/409/379 +f 358/410/380 394/420/390 392/411/381 +f 359/347/334 357/350/337 393/412/382 +f 392/411/381 394/420/390 328/414/384 +f 393/412/382 327/354/340 329/415/385 +f 306/304/296 308/307/299 392/411/381 +f 393/412/382 309/308/300 307/306/298 +f 308/307/299 352/416/386 350/332/321 +f 351/333/322 353/334/323 309/308/300 +f 330/417/387 388/421/391 386/389/369 +f 331/418/388 323/566/511 387/391/371 +f 386/389/369 388/421/391 332/338/327 +f 387/391/371 325/358/344 333/341/330 +f 394/420/390 388/421/391 330/417/387 +f 395/413/383 329/415/385 331/418/388 +f 360/344/332 388/421/391 394/420/390 +f 361/343/331 359/347/334 395/413/383 +f 396/422/392 422/469/436 410/423/393 +f 397/425/395 409/431/401 411/426/396 +f 408/424/394 410/423/393 412/428/398 +f 413/430/400 411/426/396 409/431/401 +f 412/428/398 414/436/406 404/433/403 +f 413/430/400 407/432/402 405/434/404 +f 414/436/406 416/440/410 402/437/407 +f 415/435/405 405/434/404 403/438/408 +f 416/440/410 418/448/418 400/441/411 +f 417/439/409 403/438/408 401/442/412 +f 400/441/411 418/448/418 420/444/414 +f 421/446/416 419/443/413 401/442/412 +f 418/448/418 428/451/421 426/449/419 +f 427/450/420 429/452/422 419/443/413 +f 416/440/410 430/519/478 428/451/421 +f 429/452/422 431/455/425 417/439/409 +f 432/453/423 430/519/478 416/440/410 +f 433/454/424 415/435/405 417/439/409 +f 434/456/426 432/453/423 414/436/406 +f 435/457/427 413/430/400 415/435/405 +f 436/458/428 434/456/426 412/428/398 +f 437/459/429 411/426/396 413/430/400 +f 410/423/393 422/469/436 424/460/430 +f 425/461/431 423/427/397 411/426/396 +f 328/414/384 452/494/435 450/462/432 +f 329/415/385 327/354/340 451/463/433 +f 398/445/415 420/444/414 452/465/435 +f 399/447/417 329/564/385 453/467/434 +f 318/353/339 326/352/338 450/462/432 +f 451/463/433 327/354/340 319/355/341 +f 390/468/378 438/485/451 422/469/436 +f 423/427/397 439/488/454 391/470/379 +f 420/444/414 426/449/419 448/471/437 +f 449/472/438 427/450/420 421/446/416 +f 454/473/439 452/465/435 448/471/437 +f 455/475/441 447/478/444 449/472/438 +f 442/476/442 454/473/439 446/474/440 +f 447/478/444 455/475/441 443/479/445 +f 456/481/447 454/473/439 442/476/442 +f 457/483/449 441/487/453 443/479/445 +f 456/481/447 440/482/448 458/484/450 +f 457/483/449 439/488/454 459/486/452 +f 438/485/451 458/484/450 424/460/430 +f 439/488/454 423/427/397 425/461/431 +f 320/406/376 456/491/447 438/489/451 +f 439/490/454 457/492/449 321/407/377 +f 450/462/432 454/495/439 456/491/447 +f 451/463/433 321/407/377 457/492/449 +f 424/460/430 458/484/450 460/496/455 +f 461/498/457 459/486/452 425/461/431 +f 440/482/448 470/502/461 460/496/455 +f 441/487/453 459/486/452 461/498/457 +f 440/482/448 442/476/442 468/501/460 +f 469/503/462 443/479/445 441/487/453 +f 444/477/443 466/505/464 468/501/460 +f 445/480/446 443/479/445 469/503/462 +f 446/474/440 464/508/467 466/505/464 +f 447/478/444 445/480/446 467/504/463 +f 446/474/440 448/471/437 462/507/466 +f 463/509/468 449/472/438 447/478/444 +f 448/471/437 426/449/419 482/510/469 +f 483/511/470 427/450/420 449/472/438 +f 436/458/428 424/460/430 484/497/456 +f 485/499/458 425/461/431 437/459/429 +f 434/456/426 436/458/428 472/512/471 +f 473/513/472 437/459/429 435/457/427 +f 432/453/423 434/456/426 474/514/473 +f 475/515/474 435/457/427 433/454/424 +f 432/453/423 476/516/475 478/518/477 +f 433/454/424 431/455/425 479/520/479 +f 430/519/478 478/518/477 480/521/480 +f 431/455/425 429/452/422 481/522/481 +f 428/451/421 480/521/480 482/510/469 +f 429/452/422 427/450/420 483/511/470 +f 464/508/467 488/526/485 486/523/482 +f 465/506/465 467/504/463 487/524/483 +f 488/526/485 490/569/513 492/527/486 +f 489/525/484 487/524/483 493/528/487 +f 492/527/486 490/569/513 496/530/489 +f 497/532/491 491/529/488 493/528/487 +f 496/530/489 498/537/496 500/534/493 +f 497/532/491 495/533/492 501/535/494 +f 472/512/471 484/497/456 494/531/490 +f 495/533/492 485/499/458 473/513/472 +f 492/527/486 494/531/490 484/497/456 +f 493/528/487 461/498/457 485/499/458 +f 470/502/461 486/523/482 492/527/486 +f 471/500/459 461/498/457 493/528/487 +f 466/505/464 486/523/482 470/502/461 +f 471/500/459 487/524/483 467/504/463 +f 482/510/469 488/526/485 464/508/467 +f 483/511/470 463/509/468 465/506/465 +f 480/521/480 490/569/513 488/526/485 +f 489/525/484 491/529/488 481/522/481 +f 496/530/489 490/569/513 480/521/480 +f 497/532/491 479/520/479 481/522/481 +f 498/537/496 496/530/489 478/518/477 +f 499/536/495 477/517/476 479/520/479 +f 474/514/473 500/534/493 498/537/496 +f 499/536/495 501/535/494 475/515/474 +f 400/441/411 398/445/415 512/538/497 +f 513/540/499 399/447/417 401/442/412 +f 402/437/407 400/441/411 510/539/498 +f 511/541/500 401/442/412 403/438/408 +f 402/437/407 508/542/501 506/544/503 +f 403/438/408 405/434/404 507/545/504 +f 404/433/403 506/544/503 504/546/505 +f 405/434/404 407/551/402 505/548/506 +f 406/547/399 504/546/505 502/549/507 +f 407/551/402 409/555/401 503/552/508 +f 408/550/394 502/549/507 514/553/509 +f 409/555/401 397/559/395 515/556/510 +f 510/539/498 512/538/497 514/553/509 +f 511/541/500 503/552/508 515/556/510 +f 502/549/507 504/546/505 508/542/501 +f 509/543/502 505/548/506 503/552/508 +f 390/408/378 396/570/392 514/557/509 +f 391/558/379 323/562/511 515/556/510 +f 322/560/370 514/553/509 512/538/497 +f 513/540/499 515/556/510 323/562/511 +f 328/466/384 330/561/387 512/538/497 +f 513/540/499 331/563/388 329/564/385 diff --git a/wgpu/examples/ray-scene/main.rs b/wgpu/examples/ray-scene/main.rs index ff82b448af..2611eac280 100644 --- a/wgpu/examples/ray-scene/main.rs +++ b/wgpu/examples/ray-scene/main.rs @@ -14,8 +14,9 @@ mod framework; #[repr(C)] #[derive(Debug, Clone, Copy, Pod, Zeroable)] struct Vertex { - _pos: [f32; 3], - _tex_coord: [f32; 2], + _pos: [f32; 4], + _normal: [f32; 4], + _tex_coord: [f32; 4], } #[repr(C)] @@ -50,9 +51,9 @@ impl>> Future for ErrorFuture { #[derive(Debug, Clone, Default)] struct RawSceneComponents { vertices: Vec, - indices: Vec, - geometries: Vec>, - instances: Vec<(Range, Range)>, //vertex range, geometry range + indices: Vec, + geometries: Vec<(Range, [f32; 3])>, // index range, color + instances: Vec<(Range, Range)>, // vertex range, geometry range } #[allow(dead_code)] @@ -69,23 +70,32 @@ struct SceneComponents { struct InstanceEntry { first_vertex: u32, first_geometry: u32, + last_geometry: u32, + _pad: u32, } -fn load_model(scene: &mut RawSceneComponents, source: &[u8]) { - let data = obj::ObjData::load_buf(source).unwrap(); +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +struct GeometryEntry { + first_index: u32, + r: f32, + g: f32, + b: f32, +} + +fn load_model(scene: &mut RawSceneComponents, path: &str) { + let path = env!("CARGO_MANIFEST_DIR").to_string() + "/" + path; + let mut object = obj::Obj::load(path).unwrap(); + object.load_mtls().unwrap(); + + let data = object.data; let start_vertex_index = scene.vertices.len(); let start_geometry_index = scene.geometries.len(); - scene.vertices.extend( - data.position - .iter() - // .zip(data.normal.iter()) - .map(|pos| Vertex { - _pos: *pos, - _tex_coord: [0.0, 0.0], - }), - ); + let mut mapping = std::collections::HashMap::<(usize, usize, usize), usize>::new(); + + let mut next_index = 0; for object in data.objects { for group in object.groups { @@ -93,14 +103,45 @@ fn load_model(scene: &mut RawSceneComponents, source: &[u8]) { for poly in group.polys { for end_index in 2..poly.0.len() { for &index in &[0, end_index - 1, end_index] { - let obj::IndexTuple(position_id, _texture_id, _normal_id) = poly.0[index]; - scene.indices.push(position_id as u16); + let obj::IndexTuple(position_id, texture_id, normal_id) = poly.0[index]; + let texture_id = texture_id.expect("uvs required"); + let normal_id = normal_id.expect("normals required"); + + let index = *mapping + .entry((position_id, texture_id, normal_id)) + .or_insert(next_index); + if index == next_index { + next_index += 1; + + let pos = data.position[position_id]; + let uv = data.texture[texture_id]; + let normal = data.normal[normal_id]; + + scene.vertices.push(Vertex { + _pos: [pos[0], pos[1], pos[2], 1.0], + _tex_coord: [uv[0], uv[1], 0.0, 0.0], + _normal: [normal[0], normal[1], normal[2], 0.0], + }) + } + + scene.indices.push(index as u32); } } } + + let mut col = [1.0, 0.0, 1.0]; + + if let Some(mat) = group.material { + if let obj::ObjMaterial::Mtl(mat) = mat { + if let Some(kd) = mat.kd { + col = kd; + } + } + } + scene .geometries - .push(start_index_index..scene.indices.len()); + .push((start_index_index..scene.indices.len(), col)); } } scene.instances.push(( @@ -122,8 +163,13 @@ fn upload_scene_components( let geometry_buffer_content = scene .geometries .iter() - .map(|geometry| geometry.start as u32) - .collect::>(); + .map(|(index_range, color)| GeometryEntry { + first_index: index_range.start as u32, + r: color[0], + g: color[1], + b: color[2], + }) + .collect::>(); let instance_buffer_content = scene .instances @@ -131,6 +177,8 @@ fn upload_scene_components( .map(|geometry| InstanceEntry { first_vertex: geometry.0.start as u32, first_geometry: geometry.1.start as u32, + last_geometry: geometry.1.end as u32, + _pad: 1, }) .collect::>(); @@ -169,9 +217,9 @@ fn upload_scene_components( .map(|i| rt::BlasTriangleGeometrySizeDescriptor { vertex_format: wgpu::VertexFormat::Float32x3, vertex_count: vertex_range.end as u32 - vertex_range.start as u32, - index_format: Some(wgpu::IndexFormat::Uint16), + index_format: Some(wgpu::IndexFormat::Uint32), index_count: Some( - scene.geometries[i].end as u32 - scene.geometries[i].start as u32, + scene.geometries[i].0.end as u32 - scene.geometries[i].0.start as u32, ), flags: rt::AccelerationStructureGeometryFlags::OPAQUE, }) @@ -206,7 +254,7 @@ fn upload_scene_components( first_vertex: vertex_range.start as u32, vertex_stride: mem::size_of::() as u64, index_buffer: Some(&indices), - index_buffer_offset: Some(scene.geometries[i].start as u64 * 2), + index_buffer_offset: Some(scene.geometries[i].0.start as u64 * 4), transform_buffer: None, transform_buffer_offset: None, }) @@ -237,12 +285,9 @@ fn upload_scene_components( fn load_scene(device: &wgpu::Device, queue: &wgpu::Queue) -> SceneComponents { let mut scene = RawSceneComponents::default(); - load_model( - &mut scene, - include_bytes!("../skybox/models/teslacyberv3.0.obj"), - ); + load_model(&mut scene, "/examples/skybox/models/teslacyberv3.0.obj"); - load_model(&mut scene, include_bytes!("cube.obj")); + load_model(&mut scene, "/examples/ray-scene/cube.obj"); upload_scene_components(device, queue, &scene) } @@ -278,6 +323,8 @@ impl framework::Example for Example { ) -> Self { let side_count = 8; + let scene_components = load_scene(device, queue); + let uniforms = { let view = Mat4::look_at_rh(Vec3::new(0.0, 0.0, 2.5), Vec3::ZERO, Vec3::Y); let proj = Mat4::perspective_rh( @@ -344,16 +391,30 @@ impl framework::Example for Example { resource: uniform_buf.as_entire_binding(), }, wgpu::BindGroupEntry { - binding: 1, + binding: 5, resource: wgpu::BindingResource::AccelerationStructure(&tlas), }, + wgpu::BindGroupEntry { + binding: 1, + resource: scene_components.vertices.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: scene_components.indices.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 3, + resource: scene_components.geometries.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 4, + resource: scene_components.instances.as_entire_binding(), + }, ], }); let tlas_package = rt::TlasPackage::new(tlas, side_count * side_count); - let scene_components = load_scene(device, queue); - let start_inst = Instant::now(); Example { @@ -398,7 +459,7 @@ impl framework::Example for Example { // scene update { - let dist = 3.0; + let dist = 3.5; let side_count = 2; @@ -428,7 +489,7 @@ impl framework::Example for Example { Vec3 { x: x * dist, y: y * dist, - z: -10.0, + z: -14.0, }, ); let transform = transform.transpose().to_cols_array()[..12] @@ -438,7 +499,7 @@ impl framework::Example for Example { *instance = Some(rt::TlasInstance::new( &self.scene_components.bottom_level_acceleration_structures[blas_index], transform, - 0, + blas_index as u32, 0xff, )); } @@ -479,7 +540,7 @@ impl framework::Example for Example { } fn main() { - framework::run::("ray-cube"); + framework::run::("ray-scene"); } #[test] diff --git a/wgpu/examples/ray-scene/shader.wgsl b/wgpu/examples/ray-scene/shader.wgsl index de331770ae..c4c3b6d1f0 100644 --- a/wgpu/examples/ray-scene/shader.wgsl +++ b/wgpu/examples/ray-scene/shader.wgsl @@ -3,24 +3,6 @@ struct VertexOutput { @location(0) tex_coords: vec2, }; -// meant to be called with 3 vertex indices: 0, 1, 2 -// draws one large triangle over the clip space like this: -// (the asterisks represent the clip space bounds) -//-1,1 1,1 -// --------------------------------- -// | * . -// | * . -// | * . -// | * . -// | * . -// | * . -// |*************** -// | . 1,-1 -// | . -// | . -// | . -// | . -// |. @vertex fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput { var result: VertexOutput; @@ -39,15 +21,91 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput { return result; } +/* +let RAY_FLAG_NONE = 0x00u; +let RAY_FLAG_OPAQUE = 0x01u; +let RAY_FLAG_NO_OPAQUE = 0x02u; +let RAY_FLAG_TERMINATE_ON_FIRST_HIT = 0x04u; +let RAY_FLAG_SKIP_CLOSEST_HIT_SHADER = 0x08u; +let RAY_FLAG_CULL_BACK_FACING = 0x10u; +let RAY_FLAG_CULL_FRONT_FACING = 0x20u; +let RAY_FLAG_CULL_OPAQUE = 0x40u; +let RAY_FLAG_CULL_NO_OPAQUE = 0x80u; +let RAY_FLAG_SKIP_TRIANGLES = 0x100u; +let RAY_FLAG_SKIP_AABBS = 0x200u; + +let RAY_QUERY_INTERSECTION_NONE = 0u; +let RAY_QUERY_INTERSECTION_TRIANGLE = 1u; +let RAY_QUERY_INTERSECTION_GENERATED = 2u; +let RAY_QUERY_INTERSECTION_AABB = 4u; + +struct RayDesc { + flags: u32, + cull_mask: u32, + t_min: f32, + t_max: f32, + origin: vec3, + dir: vec3, +} + +struct RayIntersection { + kind: u32, + t: f32, + instance_custom_index: u32, + instance_id: u32, + sbt_record_offset: u32, + geometry_index: u32, + primitive_index: u32, + barycentrics: vec2, + front_face: bool, + object_to_world: mat4x3, + world_to_object: mat4x3, +} +*/ + struct Uniforms { view_inv: mat4x4, proj_inv: mat4x4, }; +struct Vertex { + pos: vec4, + normal: vec4, + uv: vec4, +}; + + +struct Instance { + first_vertex: u32, + first_geometry: u32, + last_geometry: u32, + _pad: u32 +}; + +struct Geometry { + first_index: u32, + r: f32, + g: f32, + b: f32, +}; + + @group(0) @binding(0) var uniforms: Uniforms; @group(0) @binding(1) +var vertices: array; + +@group(0) @binding(2) +var indices: array; + +@group(0) @binding(3) +var geometries: array; + +@group(0) @binding(4) +var instances: array; + +@group(0) @binding(5) var acc_struct: acceleration_structure; @fragment @@ -67,8 +125,37 @@ fn fs_main(vertex: VertexOutput) -> @location(0) vec4 { let intersection = rayQueryGetCommittedIntersection(&rq); if (intersection.kind != RAY_QUERY_INTERSECTION_NONE) { - color = vec4(intersection.barycentrics, 1.0 - intersection.barycentrics.x - intersection.barycentrics.y, 1.0); + let instance = instances[intersection.instance_custom_index]; + let geometry = geometries[intersection.geometry_index + instance.first_geometry]; + + let index_offset = geometry.first_index; + let vertex_offset = instance.first_vertex; + + let first_index_index = intersection.primitive_index * 3u + index_offset; + + let v_0 = vertices[vertex_offset+indices[first_index_index+0u]]; + let v_1 = vertices[vertex_offset+indices[first_index_index+1u]]; + let v_2 = vertices[vertex_offset+indices[first_index_index+2u]]; + + let bary = vec3(1.0 - intersection.barycentrics.x - intersection.barycentrics.y, intersection.barycentrics); + + let pos = (v_0.pos * bary.x + v_1.pos * bary.y + v_2.pos * bary.z).xyz; + let normal_raw = (v_0.normal * bary.x + v_1.normal * bary.y + v_2.normal * bary.z).xyz; + let uv = (v_0.uv * bary.x + v_1.uv * bary.y + v_2.uv * bary.z).xy; + + let normal = normalize(normal_raw); + + color = vec4(geometry.r, geometry.g, geometry.b, 1.0); + + if(intersection.instance_custom_index == 1u){ + color = vec4(normal, 1.0); + } } + let vertex = vertices[0]; + let index = indices[0]; + let geometry = geometries[0]; + let instance = instances[0]; + return color; // vec4(vertex.tex_coords, 1.0, 1.0); } From 4119a4d2b4057e8a25a7084e17bb8cb30bd2b36f Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 11 Apr 2023 10:16:04 +0200 Subject: [PATCH 076/146] package tlas access + WIP scene materials --- wgpu/examples/ray-scene/main.rs | 70 ++++++++++++++++++----------- wgpu/examples/ray-scene/shader.wgsl | 27 ++++++----- wgpu/src/ray_tracing.rs | 12 ++++- 3 files changed, 72 insertions(+), 37 deletions(-) diff --git a/wgpu/examples/ray-scene/main.rs b/wgpu/examples/ray-scene/main.rs index 2611eac280..610a6d3b71 100644 --- a/wgpu/examples/ray-scene/main.rs +++ b/wgpu/examples/ray-scene/main.rs @@ -12,11 +12,14 @@ mod framework; // from cube #[repr(C)] -#[derive(Debug, Clone, Copy, Pod, Zeroable)] +#[derive(Debug, Clone, Copy, Pod, Zeroable, Default)] struct Vertex { - _pos: [f32; 4], - _normal: [f32; 4], - _tex_coord: [f32; 4], + pos: [f32; 3], + _p0: [u32; 1], + normal: [f32; 3], + _p1: [u32; 1], + uv: [f32; 2], + _p2: [u32; 2], } #[repr(C)] @@ -52,7 +55,7 @@ impl>> Future for ErrorFuture { struct RawSceneComponents { vertices: Vec, indices: Vec, - geometries: Vec<(Range, [f32; 3])>, // index range, color + geometries: Vec<(Range, Material)>, // index range, material instances: Vec<(Range, Range)>, // vertex range, geometry range } @@ -75,12 +78,22 @@ struct InstanceEntry { } #[repr(C)] -#[derive(Clone, Copy, Pod, Zeroable)] +#[derive(Clone, Copy, Pod, Zeroable, Default)] struct GeometryEntry { first_index: u32, - r: f32, - g: f32, - b: f32, + _p0: [u32; 3], + material: Material, +} + +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable, Default, Debug)] +struct Material { + roughness_exponent: f32, + metalness: f32, + specularity: f32, + _p0: [u32; 1], + albedo: [f32; 3], + _p1: [u32; 1], } fn load_model(scene: &mut RawSceneComponents, path: &str) { @@ -113,14 +126,11 @@ fn load_model(scene: &mut RawSceneComponents, path: &str) { if index == next_index { next_index += 1; - let pos = data.position[position_id]; - let uv = data.texture[texture_id]; - let normal = data.normal[normal_id]; - scene.vertices.push(Vertex { - _pos: [pos[0], pos[1], pos[2], 1.0], - _tex_coord: [uv[0], uv[1], 0.0, 0.0], - _normal: [normal[0], normal[1], normal[2], 0.0], + pos: data.position[position_id], + uv: data.texture[texture_id], + normal: data.normal[normal_id], + ..Default::default() }) } @@ -129,19 +139,28 @@ fn load_model(scene: &mut RawSceneComponents, path: &str) { } } - let mut col = [1.0, 0.0, 1.0]; + let mut material: Material = Default::default(); if let Some(mat) = group.material { if let obj::ObjMaterial::Mtl(mat) = mat { if let Some(kd) = mat.kd { - col = kd; + material.albedo = kd; + } + if let Some(ns) = mat.ns { + material.roughness_exponent = ns; + } + if let Some(ka) = mat.ka { + material.metalness = ka[0]; + } + if let Some(ks) = mat.ks { + material.specularity = ks[0]; } } } scene .geometries - .push((start_index_index..scene.indices.len(), col)); + .push((start_index_index..scene.indices.len(), material)); } } scene.instances.push(( @@ -163,11 +182,10 @@ fn upload_scene_components( let geometry_buffer_content = scene .geometries .iter() - .map(|(index_range, color)| GeometryEntry { + .map(|(index_range, material)| GeometryEntry { first_index: index_range.start as u32, - r: color[0], - g: color[1], - b: color[2], + material: *material, + ..Default::default() }) .collect::>(); @@ -353,6 +371,8 @@ impl framework::Example for Example { max_instances: side_count * side_count, }); + let tlas_package = rt::TlasPackage::new(tlas, side_count * side_count); + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: None, source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), @@ -392,7 +412,7 @@ impl framework::Example for Example { }, wgpu::BindGroupEntry { binding: 5, - resource: wgpu::BindingResource::AccelerationStructure(&tlas), + resource: tlas_package.as_binding(), }, wgpu::BindGroupEntry { binding: 1, @@ -413,8 +433,6 @@ impl framework::Example for Example { ], }); - let tlas_package = rt::TlasPackage::new(tlas, side_count * side_count); - let start_inst = Instant::now(); Example { diff --git a/wgpu/examples/ray-scene/shader.wgsl b/wgpu/examples/ray-scene/shader.wgsl index c4c3b6d1f0..ab8fc6e0b0 100644 --- a/wgpu/examples/ray-scene/shader.wgsl +++ b/wgpu/examples/ray-scene/shader.wgsl @@ -69,9 +69,9 @@ struct Uniforms { }; struct Vertex { - pos: vec4, - normal: vec4, - uv: vec4, + pos: vec3, + normal: vec3, + uv: vec2, }; @@ -82,11 +82,16 @@ struct Instance { _pad: u32 }; +struct Material{ + r: f32, + m: f32, + s: f32, + albedo: vec3 +} + struct Geometry { first_index: u32, - r: f32, - g: f32, - b: f32, + material: Material, }; @@ -139,13 +144,15 @@ fn fs_main(vertex: VertexOutput) -> @location(0) vec4 { let bary = vec3(1.0 - intersection.barycentrics.x - intersection.barycentrics.y, intersection.barycentrics); - let pos = (v_0.pos * bary.x + v_1.pos * bary.y + v_2.pos * bary.z).xyz; - let normal_raw = (v_0.normal * bary.x + v_1.normal * bary.y + v_2.normal * bary.z).xyz; - let uv = (v_0.uv * bary.x + v_1.uv * bary.y + v_2.uv * bary.z).xy; + let pos = v_0.pos * bary.x + v_1.pos * bary.y + v_2.pos * bary.z; + let normal_raw = v_0.normal * bary.x + v_1.normal * bary.y + v_2.normal * bary.z; + let uv = v_0.uv * bary.x + v_1.uv * bary.y + v_2.uv * bary.z; let normal = normalize(normal_raw); - color = vec4(geometry.r, geometry.g, geometry.b, 1.0); + let material = geometry.material; + + color = vec4(material.albedo, 1.0); if(intersection.instance_custom_index == 1u){ color = vec4(normal, 1.0); diff --git a/wgpu/src/ray_tracing.rs b/wgpu/src/ray_tracing.rs index 4d28ea8cf8..f6e5872140 100644 --- a/wgpu/src/ray_tracing.rs +++ b/wgpu/src/ray_tracing.rs @@ -2,7 +2,7 @@ use std::{fmt::Debug, ops::Range, sync::Arc, thread}; use crate::{ context::{Context, DynContext, ObjectId}, - Buffer, CommandEncoder, Data, Device, Label, C, + BindingResource, Buffer, CommandEncoder, Data, Device, Label, C, }; /// Descriptor for the size defining attributes of a triangle geometry, for a bottom level acceleration structure. @@ -245,6 +245,16 @@ impl TlasPackage { } Some(&mut self.instances[index]) } + + /// Get the binding resource for the underling acceleration structure, to be used in a + pub fn as_binding<'a>(&'a self) -> BindingResource<'a> { + BindingResource::AccelerationStructure(&self.tlas) + } + + /// Get a reference to the underling top level acceleration structure. + pub fn tlas(&self) -> &Tlas { + &self.tlas + } } pub(crate) struct DynContextBlasTriangleGeometry<'a> { From 0cf0d957d936195d1a77704fb20f16a5f83e187d Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 11 Apr 2023 10:33:36 +0200 Subject: [PATCH 077/146] fixed panic when creating tlas with size 0 --- wgpu-core/src/device/ray_tracing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 6cd91950a7..507a85f4e1 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -117,7 +117,7 @@ impl Device { } .map_err(DeviceError::from)?; - let instance_buffer_size = get_raw_tlas_instance_size::() * desc.max_instances as usize; + let instance_buffer_size = get_raw_tlas_instance_size::() * std::cmp::max(desc.max_instances,1) as usize; let instance_buffer = unsafe { self.raw.create_buffer(&hal::BufferDescriptor { label: Some("(wgpu-core) instances_buffer"), From a2cd5715d644690da32a8cbaf5916a6748e29f77 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 11 Apr 2023 10:35:47 +0200 Subject: [PATCH 078/146] fmt --- wgpu-core/src/device/ray_tracing.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 507a85f4e1..cf5d78c460 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -117,7 +117,8 @@ impl Device { } .map_err(DeviceError::from)?; - let instance_buffer_size = get_raw_tlas_instance_size::() * std::cmp::max(desc.max_instances,1) as usize; + let instance_buffer_size = + get_raw_tlas_instance_size::() * std::cmp::max(desc.max_instances, 1) as usize; let instance_buffer = unsafe { self.raw.create_buffer(&hal::BufferDescriptor { label: Some("(wgpu-core) instances_buffer"), From f37175f7d47f416ef33e1178a48ba36427599e14 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 11 Apr 2023 10:47:49 +0200 Subject: [PATCH 079/146] added instance count validation --- wgpu-core/src/command/ray_tracing.rs | 8 ++++++++ wgpu-core/src/device/ray_tracing.rs | 1 + wgpu-core/src/ray_tracing.rs | 5 +++++ wgpu-core/src/resource.rs | 1 + 4 files changed, 15 insertions(+) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index de77031cc8..d6ef39588f 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1101,6 +1101,14 @@ impl Global { }, }); + if instance_count > tlas.max_instance_count { + return Err(BuildAccelerationStructureError::TlasInstanceCountExceeded( + entry.tlas_id, + instance_count, + tlas.max_instance_count, + )); + } + tlas_storage.push(( tlas, hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index cf5d78c460..ff075b2ba1 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -143,6 +143,7 @@ impl Device { built_index: None, dependencies: Vec::new(), instance_buffer: Some(instance_buffer), + max_instance_count: desc.max_instances, }) } } diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 8ba0c3c158..8d19d0576c 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -89,6 +89,11 @@ pub enum BuildAccelerationStructureError { )] TlasInvalidCustomIndex(TlasId), + #[error( + "Tlas {0:?} has {1} active instances but only {2} are allowed as specified by the descriptor at creation" + )] + TlasInstanceCountExceeded(TlasId, u32, u32), + #[error("Blas {0:?} is invalid or destroyed (for instance)")] InvalidBlasForInstance(BlasId), diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 5864e387dd..8e3a33c931 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -824,6 +824,7 @@ pub struct Tlas { pub(crate) device_id: Stored, pub(crate) life_guard: LifeGuard, pub(crate) size_info: hal::AccelerationStructureBuildSizes, + pub(crate) max_instance_count: u32, pub(crate) flags: wgt::AccelerationStructureFlags, pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, pub(crate) built_index: Option, From fc545006e81834a6810a5be64c657c94f2cfd1a5 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 12 Apr 2023 22:22:26 +0200 Subject: [PATCH 080/146] fixed shader binding layout validation --- wgpu-core/src/validation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index 54d03ee7b7..546b53fc5e 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -538,7 +538,7 @@ impl Resource { } usage } - ResourceType::AccelerationStructure => GlobalUse::QUERY, + ResourceType::AccelerationStructure => GlobalUse::READ | GlobalUse::QUERY, }; if allowed_usage.contains(shader_usage) { From 4366ba71b5d7205722153b023de2ee0d97fcf749 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 17 Apr 2023 19:02:13 +0200 Subject: [PATCH 081/146] temporary scratch buffer alignment --- wgpu-core/src/command/ray_tracing.rs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index d6ef39588f..6234e929d6 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -13,13 +13,16 @@ use crate::{ FastHashSet, }; -use hal::{CommandEncoder, Device}; +use hal::{auxil::align_to, CommandEncoder, Device}; use wgt::BufferUsages; use std::{cmp::max, iter, num::NonZeroU64, ops::Range, ptr}; use super::BakedCommands; +// This should be queried from the device, maybe the the hal api should pre aline it, since I am unsure how else we can idiomatically get this value. +const SCRATCH_BUFFER_ALIGNMENT: u32 = 256; + impl Global { pub fn command_encoder_build_acceleration_structures_unsafe_tlas<'a, A: HalApi>( &self, @@ -413,7 +416,10 @@ impl Global { } let scratch_buffer_offset = scratch_buffer_blas_size; - scratch_buffer_blas_size += blas.size_info.build_scratch_size; + scratch_buffer_blas_size += align_to( + blas.size_info.build_scratch_size as u32, + SCRATCH_BUFFER_ALIGNMENT, + ) as u64; blas_storage.push(( blas, @@ -475,7 +481,10 @@ impl Global { }); let scratch_buffer_offset = scratch_buffer_tlas_size; - scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; + scratch_buffer_tlas_size += align_to( + tlas.size_info.build_scratch_size as u32, + SCRATCH_BUFFER_ALIGNMENT, + ) as u64; tlas_storage.push(( tlas, @@ -1027,7 +1036,10 @@ impl Global { } let scratch_buffer_offset = scratch_buffer_blas_size; - scratch_buffer_blas_size += blas.size_info.build_scratch_size; + scratch_buffer_blas_size += align_to( + blas.size_info.build_scratch_size as u32, + SCRATCH_BUFFER_ALIGNMENT, + ) as u64; blas_storage.push(( blas, @@ -1059,7 +1071,10 @@ impl Global { } let scratch_buffer_offset = scratch_buffer_tlas_size; - scratch_buffer_tlas_size += tlas.size_info.build_scratch_size; + scratch_buffer_tlas_size += align_to( + tlas.size_info.build_scratch_size as u32, + SCRATCH_BUFFER_ALIGNMENT, + ) as u64; let first_byte_index = instance_buffer_staging_source.len(); From a6f0ba3f07896f7201ca6e2250422b5e63977a12 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 17 Apr 2023 19:05:56 +0200 Subject: [PATCH 082/146] Fixed tlas tracking in bind groups and device cleanup --- wgpu-core/src/command/compute.rs | 6 ++++-- wgpu-core/src/command/render.rs | 6 ++++-- wgpu-core/src/hub.rs | 22 ++++++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index c67afefc92..2480132345 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -362,7 +362,8 @@ impl Global { let (pipeline_guard, mut token) = hub.compute_pipelines.read(&mut token); let (query_set_guard, mut token) = hub.query_sets.read(&mut token); let (buffer_guard, mut token) = hub.buffers.read(&mut token); - let (texture_guard, _) = hub.textures.read(&mut token); + let (texture_guard, mut token) = hub.textures.read(&mut token); + let (tlas_guard, _) = hub.tlas_s.read(&mut token); let mut state = State { binder: Binder::new(), @@ -386,7 +387,7 @@ impl Global { None, Some(&*query_set_guard), None, - None, + Some(&*tlas_guard), ); let hal_desc = hal::ComputePassDescriptor { label: base.label }; @@ -452,6 +453,7 @@ impl Global { cmd_buf.tlas_actions.extend( bind_group.used.acceleration_structures.used().map(|id| { + cmd_buf.trackers.tlas_s.add_single(&tlas_guard, id.0); crate::ray_tracing::TlasAction { id: id.0, kind: crate::ray_tracing::TlasActionKind::Use, diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 96eeaf9c55..935de5c11d 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1246,7 +1246,8 @@ impl Global { let (query_set_guard, mut token) = hub.query_sets.read(&mut token); let (buffer_guard, mut token) = hub.buffers.read(&mut token); let (texture_guard, mut token) = hub.textures.read(&mut token); - let (view_guard, _) = hub.texture_views.read(&mut token); + let (view_guard, mut token) = hub.texture_views.read(&mut token); + let (tlas_guard, _) = hub.tlas_s.read(&mut token); log::trace!( "Encoding render pass begin in command buffer {:?}", @@ -1276,7 +1277,7 @@ impl Global { Some(&*bundle_guard), Some(&*query_set_guard), None, - None, + Some(&*tlas_guard), ); let raw = &mut cmd_buf.encoder.raw; @@ -1358,6 +1359,7 @@ impl Global { cmd_buf.tlas_actions.extend( bind_group.used.acceleration_structures.used().map(|id| { + cmd_buf.trackers.tlas_s.add_single(&tlas_guard, id.0); crate::ray_tracing::TlasAction { id: id.0, kind: crate::ray_tracing::TlasActionKind::Use, diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index e6feaac9ef..27b81fcd1f 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -1020,6 +1020,28 @@ impl Hub { } } + for element in self.blas_s.data.write().map.drain(..) { + if let Element::Occupied(blas, _) = element { + let device = &devices[blas.device_id.value]; + if let Some(raw) = blas.raw { + unsafe { + device.raw.destroy_acceleration_structure(raw); + } + } + } + } + + for element in self.tlas_s.data.write().map.drain(..) { + if let Element::Occupied(tlas, _) = element { + let device = &devices[tlas.device_id.value]; + if let Some(raw) = tlas.raw { + unsafe { + device.raw.destroy_acceleration_structure(raw); + } + } + } + } + for element in surface_guard.map.iter_mut() { if let Element::Occupied(ref mut surface, _epoch) = *element { if surface From 926e1ee11a9944a0038848d16f412481e84dc550 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 17 Apr 2023 20:32:56 +0200 Subject: [PATCH 083/146] keep ref_count at drop --- wgpu-core/src/device/ray_tracing.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index ff075b2ba1..0e6ef8402a 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -285,13 +285,12 @@ impl Global { let hub = A::hub(self); let mut token = Token::root(); - let (ref_count, last_submit_index, device_id) = { + let (last_submit_index, device_id) = { let (mut blas_guard, _) = hub.blas_s.write(&mut token); match blas_guard.get_mut(blas_id) { Ok(blas) => { - let ref_count = blas.life_guard.ref_count.take().unwrap(); let last_submit_index = blas.life_guard.life_count(); - (ref_count, last_submit_index, blas.device_id.value) + (last_submit_index, blas.device_id.value) } Err(crate::hub::InvalidId) => { hub.blas_s.unregister_locked(blas_id, &mut *blas_guard); @@ -304,7 +303,6 @@ impl Global { let device = &device_guard[device_id]; { let mut life_lock = device.lock_life(&mut token); - drop(ref_count); life_lock .suspected_resources .blas_s @@ -370,13 +368,12 @@ impl Global { let hub = A::hub(self); let mut token = Token::root(); - let (ref_count, last_submit_index, device_id) = { + let (last_submit_index, device_id) = { let (mut tlas_guard, _) = hub.tlas_s.write(&mut token); match tlas_guard.get_mut(tlas_id) { Ok(tlas) => { - let ref_count = tlas.life_guard.ref_count.take().unwrap(); let last_submit_index = tlas.life_guard.life_count(); - (ref_count, last_submit_index, tlas.device_id.value) + (last_submit_index, tlas.device_id.value) } Err(crate::hub::InvalidId) => { hub.tlas_s.unregister_locked(tlas_id, &mut *tlas_guard); @@ -389,7 +386,6 @@ impl Global { let device = &device_guard[device_id]; { let mut life_lock = device.lock_life(&mut token); - drop(ref_count); life_lock .suspected_resources .tlas_s From d02c99d13af80f9a9404e9fe667a4d173b334540 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Tue, 27 Jun 2023 23:56:16 +0200 Subject: [PATCH 084/146] wip acceleration structure drop memory leak fix --- wgpu-core/src/device/ray_tracing.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 0e6ef8402a..50d963548d 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -285,12 +285,13 @@ impl Global { let hub = A::hub(self); let mut token = Token::root(); - let (last_submit_index, device_id) = { + let (last_submit_index, device_id, ref_count) = { let (mut blas_guard, _) = hub.blas_s.write(&mut token); match blas_guard.get_mut(blas_id) { Ok(blas) => { + let ref_count = blas.life_guard.ref_count.take().unwrap(); let last_submit_index = blas.life_guard.life_count(); - (last_submit_index, blas.device_id.value) + (last_submit_index, blas.device_id.value, ref_count) } Err(crate::hub::InvalidId) => { hub.blas_s.unregister_locked(blas_id, &mut *blas_guard); @@ -302,6 +303,7 @@ impl Global { let (device_guard, mut token) = hub.devices.read(&mut token); let device = &device_guard[device_id]; { + drop(ref_count); let mut life_lock = device.lock_life(&mut token); life_lock .suspected_resources @@ -368,12 +370,13 @@ impl Global { let hub = A::hub(self); let mut token = Token::root(); - let (last_submit_index, device_id) = { + let (last_submit_index, device_id, ref_count) = { let (mut tlas_guard, _) = hub.tlas_s.write(&mut token); match tlas_guard.get_mut(tlas_id) { Ok(tlas) => { + let ref_count = tlas.life_guard.ref_count.take().unwrap(); let last_submit_index = tlas.life_guard.life_count(); - (last_submit_index, tlas.device_id.value) + (last_submit_index, tlas.device_id.value, ref_count) } Err(crate::hub::InvalidId) => { hub.tlas_s.unregister_locked(tlas_id, &mut *tlas_guard); @@ -385,6 +388,7 @@ impl Global { let (device_guard, mut token) = hub.devices.read(&mut token); let device = &device_guard[device_id]; { + drop(ref_count); let mut life_lock = device.lock_life(&mut token); life_lock .suspected_resources From cadea32fc93ba5ba47cbc42f2fc54768ae635403 Mon Sep 17 00:00:00 2001 From: Ashley Ruglys Date: Mon, 24 Jul 2023 13:30:20 +1200 Subject: [PATCH 085/146] Small post-merge fixes --- wgpu-core/src/device/resource.rs | 4 ++-- wgpu-hal/src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index bb0fc80d66..0d8927e8c6 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -1535,7 +1535,7 @@ impl Device { } }, ) - }, + } Bt::AccelerationStructure => todo!(), }; @@ -2023,7 +2023,7 @@ impl Device { buffers: &hal_buffers, samplers: &hal_samplers, textures: &hal_textures, - acceleration_structures: &[] + acceleration_structures: &[], }; let raw = unsafe { self.raw diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index bf4a2840e5..e971c49af8 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -179,7 +179,7 @@ pub trait Api: Clone + Sized { type RenderPipeline: WasmNotSend + WasmNotSync; type ComputePipeline: WasmNotSend + WasmNotSync; - type AccelerationStructure: fmt::Debug + WasmNotSend + Sync + 'static; + type AccelerationStructure: fmt::Debug + WasmNotSend + WasmNotSync + 'static; } pub trait Instance: Sized + WasmNotSend + WasmNotSync { From 308cac8bed320ed6b565d79eacfb484dc44bcc0b Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 25 Aug 2023 16:56:50 -0700 Subject: [PATCH 086/146] Fix example --- wgpu-hal/examples/ray-traced-triangle/main.rs | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 67630a05f4..cb29a53f44 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -225,6 +225,7 @@ impl Example { hal::InstanceFlags::empty() }, dx12_shader_compiler: wgt::Dx12Compiler::Fxc, + gles_minor_version: wgt::Gles3MinorVersion::default(), }; let instance = unsafe { A::Instance::init(&instance_desc)? }; let mut surface = unsafe { @@ -905,8 +906,10 @@ impl Example { .unwrap() }; unsafe { - ctx.encoder - .begin_compute_pass(&hal::ComputePassDescriptor { label: None }); + ctx.encoder.begin_compute_pass(&hal::ComputePassDescriptor { + label: None, + timestamp_writes: None, + }); ctx.encoder.set_compute_pipeline(&self.pipeline); ctx.encoder .set_bind_group(&self.pipeline_layout, 0, &self.bind_group, &[]); @@ -1041,26 +1044,28 @@ impl Example { } } -#[cfg(all(feature = "metal"))] -type Api = hal::api::Metal; -#[cfg(all(feature = "vulkan", not(feature = "metal")))] -type Api = hal::api::Vulkan; -#[cfg(all(feature = "gles", not(feature = "metal"), not(feature = "vulkan")))] -type Api = hal::api::Gles; -#[cfg(all( - feature = "dx12", - not(feature = "metal"), - not(feature = "vulkan"), - not(feature = "gles") -))] -type Api = hal::api::Dx12; -#[cfg(not(any( - feature = "metal", - feature = "vulkan", - feature = "gles", - feature = "dx12" -)))] -type Api = hal::api::Empty; +cfg_if::cfg_if! { + // Apple + Metal + if #[cfg(all(any(target_os = "macos", target_os = "ios"), feature = "metal"))] { + type Api = hal::api::Metal; + } + // Wasm + Vulkan + else if #[cfg(all(not(target_arch = "wasm32"), feature = "vulkan"))] { + type Api = hal::api::Vulkan; + } + // Windows + DX12 + else if #[cfg(all(windows, feature = "dx12"))] { + type Api = hal::api::Dx12; + } + // Anything + GLES + else if #[cfg(feature = "gles")] { + type Api = hal::api::Gles; + } + // Fallback + else { + type Api = hal::api::Empty; + } +} fn main() { env_logger::init(); From 24ec2fe4b95209b502644342f81976c9fb3298ac Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 25 Aug 2023 17:12:37 -0700 Subject: [PATCH 087/146] Update lockfile --- Cargo.lock | 191 +++++++++++++++++++++++++++-------------------------- 1 file changed, 96 insertions(+), 95 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b705e3a42..a492279cf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -46,18 +46,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" dependencies = [ "memchr", ] [[package]] name = "android-activity" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40bc1575e653f158cbdc6ebcd917b9564e66321c5325c232c3591269c257be69" +checksum = "64529721f27c2314ced0890ce45e469574a73e5e6fdd6e9da1860eb29285f5e0" dependencies = [ "android-properties", "bitflags 1.3.2", @@ -138,9 +138,9 @@ dependencies = [ [[package]] name = "async-lock" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" dependencies = [ "event-listener", ] @@ -153,13 +153,13 @@ checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" [[package]] name = "async-trait" -version = "0.1.71" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -170,9 +170,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -277,7 +277,7 @@ checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -308,11 +308,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", + "libc", ] [[package]] @@ -770,9 +771,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encoding_rs" @@ -813,9 +814,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -915,7 +916,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -1053,7 +1054,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -1110,9 +1111,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "gl_generator" @@ -1498,9 +1499,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "lock_api" @@ -1740,9 +1741,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -1838,7 +1839,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -1912,9 +1913,9 @@ dependencies = [ [[package]] name = "object" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" dependencies = [ "memchr", ] @@ -1927,9 +1928,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "orbclient" -version = "0.3.45" +version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "221d488cd70617f1bd599ed8ceb659df2147d9393717954d82a0f5e8032a6ab1" +checksum = "8378ac0dfbd4e7895f2d2c1f1345cab3836910baf3a300b000d04250f0c8428f" dependencies = [ "redox_syscall", ] @@ -1984,7 +1985,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -2001,12 +2002,12 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "petgraph" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 1.9.3", + "indexmap 2.0.0", ] [[package]] @@ -2017,29 +2018,29 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] name = "pin-project-lite" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -2139,9 +2140,9 @@ checksum = "46b2164ebdb1dfeec5e337be164292351e11daf63a05174c6776b2f47460f0c9" [[package]] name = "quote" -version = "1.0.31" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -2243,9 +2244,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" dependencies = [ "aho-corasick", "memchr", @@ -2255,9 +2256,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" dependencies = [ "aho-corasick", "memchr", @@ -2320,9 +2321,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.4" +version = "0.38.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "9bfe0f2582b4931a45d1fa608f8a8722e8b3c7ac54dd6d5f3b3212791fedef49" dependencies = [ "bitflags 2.4.0", "errno", @@ -2406,9 +2407,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.186" +version = "1.0.187" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1" +checksum = "30a7fe14252655bd1e578af19f5fa00fe02fd0013b100ca6b49fde31c41bae4c" dependencies = [ "serde_derive", ] @@ -2424,13 +2425,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.186" +version = "1.0.187" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670" +checksum = "e46b2a6ca578b3f1d4501b12f78ed4692006d79d82a1a7c561c12dbc3d625eb8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -2514,15 +2515,15 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -2573,9 +2574,9 @@ dependencies = [ [[package]] name = "sourcemap" -version = "6.3.0" +version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8df03d85f2767c45e61b4453eb6144153c80399e4fdd6407a6d16cb87cc0347" +checksum = "e4cbf65ca7dc576cf50e21f8d0712d96d4fcfd797389744b7b222a85cdf5bd90" dependencies = [ "data-encoding", "debugid", @@ -2628,9 +2629,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", @@ -2663,7 +2664,7 @@ checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -2758,7 +2759,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", ] [[package]] @@ -2968,7 +2969,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", "wasm-bindgen-shared", ] @@ -3002,7 +3003,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.29", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3620,7 +3621,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -3640,17 +3641,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -3661,9 +3662,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" @@ -3679,9 +3680,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" @@ -3697,9 +3698,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" @@ -3715,9 +3716,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" @@ -3733,9 +3734,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" @@ -3745,9 +3746,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" @@ -3763,9 +3764,9 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winit" @@ -3837,9 +3838,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.5.0" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] From bcb646e8333fad8a71a7628b1840f81e646de823 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 25 Aug 2023 17:12:46 -0700 Subject: [PATCH 088/146] Misc fix --- examples/timestamp-queries/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/timestamp-queries/src/main.rs b/examples/timestamp-queries/src/main.rs index 3479122c79..d4f0e53361 100644 --- a/examples/timestamp-queries/src/main.rs +++ b/examples/timestamp-queries/src/main.rs @@ -140,7 +140,7 @@ impl Queries { encoder.resolve_query_set( &self.set, // TODO(https://github.com/gfx-rs/wgpu/issues/3993): Musn't be larger than the number valid queries in the set. - 0..self.next_unused_query as u32, + 0..self.next_unused_query, &self.resolve_buffer, 0, ); From 1bcbfaa6f2a71d619ffc30250cfeaac0a631831f Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 25 Aug 2023 17:18:51 -0700 Subject: [PATCH 089/146] Fix metal backend --- wgpu-hal/src/metal/command.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 26e7809b47..153373b238 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -1054,10 +1054,14 @@ impl crate::CommandEncoder for super::CommandEncoder { encoder.dispatch_thread_groups_indirect(&buffer.raw, offset, self.state.raw_wg_size); } - unsafe fn build_acceleration_structure( + unsafe fn build_acceleration_structures<'a, T>( &mut self, - _desc: &crate::BuildAccelerationStructureDescriptor, - ) { + _descriptor_count: u32, + _descriptors: T, + ) where + super::Api: 'a, + T: IntoIterator>, + { unimplemented!() } From 384767af40e2e312babaa871f22f71dfb182cecc Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 25 Aug 2023 17:33:08 -0700 Subject: [PATCH 090/146] Misc docs --- wgpu-types/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 1fd93f4e31..f389a17267 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -5861,6 +5861,12 @@ pub enum BindingType { /// A ray-tracing acceleration structure binding. /// + /// Example WGSL syntax: + /// ```rust,ignore + /// @group(0) @binding(0) + /// var as: acceleration_structure; + /// ``` + /// /// Example GLSL syntax: /// ```cpp,ignore /// layout(binding = 0) From bc8f9ca91c7843cbcccb1d33dbf5179b7d9b3106 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 25 Aug 2023 18:30:39 -0700 Subject: [PATCH 091/146] Remove misc --- examples/common/src/framework.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/common/src/framework.rs b/examples/common/src/framework.rs index b3791a7ce0..06db6092f7 100644 --- a/examples/common/src/framework.rs +++ b/examples/common/src/framework.rs @@ -220,7 +220,6 @@ async fn setup(title: &str) -> Setup { let needed_limits = E::required_limits().using_resolution(adapter.limits()); let trace_dir = std::env::var("WGPU_TRACE"); - dbg!(&trace_dir); let (device, queue) = adapter .request_device( &wgpu::DeviceDescriptor { From dd30270c07dd1571b45d87981a11b9600ef0506b Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 25 Aug 2023 19:06:07 -0700 Subject: [PATCH 092/146] Misc --- wgpu/src/context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index f8ef762508..b950e1618a 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -74,9 +74,9 @@ pub trait Context: Debug + WasmNotSend + WasmNotSync + Sized { type SurfaceId: ContextId + WasmNotSend + WasmNotSync; type SurfaceData: ContextData; - type BlasId: ContextId + Send + Sync; + type BlasId: ContextId + WasmNotSend + WasmNotSync; type BlasData: ContextData; - type TlasId: ContextId + Send + Sync; + type TlasId: ContextId + WasmNotSend + WasmNotSync; type TlasData: ContextData; type SurfaceOutputDetail: WasmNotSend + WasmNotSync + 'static; From 936da8e6fabab7efd53e561add05b89e4252ae45 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 25 Aug 2023 20:01:32 -0700 Subject: [PATCH 093/146] Fixes --- Cargo.lock | 48 ++++++++++++++++-- examples/ray-cube-compute/Cargo.toml | 22 ++++++++ .../ray-cube-compute/README.md | 0 .../ray-cube-compute/screenshot.png | Bin .../ray-cube-compute/src}/blit.wgsl | 0 .../ray-cube-compute/src}/main.rs | 30 +++++------ .../ray-cube-compute/src}/shader.wgsl | 0 examples/ray-cube-fragment/Cargo.toml | 22 ++++++++ .../ray-cube-fragment/README.md | 0 .../ray-cube-fragment/screenshot.png | Bin .../ray-cube-fragment/src}/main.rs | 24 ++++----- .../ray-cube-fragment/src}/shader.wgsl | 0 examples/ray-scene/Cargo.toml | 23 +++++++++ .../examples => examples}/ray-scene/cube.mtl | 0 .../examples => examples}/ray-scene/cube.obj | 0 .../ray-scene/src}/main.rs | 24 ++++----- .../ray-scene/src}/shader.wgsl | 0 wgpu-core/src/device/mod.rs | 1 + wgpu-core/src/device/ray_tracing.rs | 13 +++-- wgpu-core/src/device/resource.rs | 22 ++++++-- 20 files changed, 177 insertions(+), 52 deletions(-) create mode 100644 examples/ray-cube-compute/Cargo.toml rename {wgpu/examples => examples}/ray-cube-compute/README.md (100%) rename {wgpu/examples => examples}/ray-cube-compute/screenshot.png (100%) rename {wgpu/examples/ray-cube-compute => examples/ray-cube-compute/src}/blit.wgsl (100%) rename {wgpu/examples/ray-cube-compute => examples/ray-cube-compute/src}/main.rs (95%) rename {wgpu/examples/ray-cube-compute => examples/ray-cube-compute/src}/shader.wgsl (100%) create mode 100644 examples/ray-cube-fragment/Cargo.toml rename {wgpu/examples => examples}/ray-cube-fragment/README.md (100%) rename {wgpu/examples => examples}/ray-cube-fragment/screenshot.png (100%) rename {wgpu/examples/ray-cube-fragment => examples/ray-cube-fragment/src}/main.rs (94%) rename {wgpu/examples/ray-cube-fragment => examples/ray-cube-fragment/src}/shader.wgsl (100%) create mode 100644 examples/ray-scene/Cargo.toml rename {wgpu/examples => examples}/ray-scene/cube.mtl (100%) rename {wgpu/examples => examples}/ray-scene/cube.obj (100%) rename {wgpu/examples/ray-scene => examples/ray-scene/src}/main.rs (96%) rename {wgpu/examples/ray-scene => examples/ray-scene/src}/shader.wgsl (100%) diff --git a/Cargo.lock b/Cargo.lock index a492279cf0..42edc83e0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2233,6 +2233,46 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" +[[package]] +name = "ray-cube-compute" +version = "0.17.0" +dependencies = [ + "bytemuck", + "glam 0.24.1", + "wasm-bindgen-test", + "wgpu", + "wgpu-example", + "wgpu-test", + "winit 0.28.6", +] + +[[package]] +name = "ray-cube-fragment" +version = "0.17.0" +dependencies = [ + "bytemuck", + "glam 0.24.1", + "wasm-bindgen-test", + "wgpu", + "wgpu-example", + "wgpu-test", + "winit 0.28.6", +] + +[[package]] +name = "ray-scene" +version = "0.17.0" +dependencies = [ + "bytemuck", + "glam 0.24.1", + "obj", + "wasm-bindgen-test", + "wgpu", + "wgpu-example", + "wgpu-test", + "winit 0.28.6", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -2407,9 +2447,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.187" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7fe14252655bd1e578af19f5fa00fe02fd0013b100ca6b49fde31c41bae4c" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] @@ -2425,9 +2465,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.187" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46b2a6ca578b3f1d4501b12f78ed4692006d79d82a1a7c561c12dbc3d625eb8" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", diff --git a/examples/ray-cube-compute/Cargo.toml b/examples/ray-cube-compute/Cargo.toml new file mode 100644 index 0000000000..adeffa765b --- /dev/null +++ b/examples/ray-cube-compute/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "ray-cube-compute" +version.workspace = true +license.workspace = true +edition.workspace = true +description = "todo" +publish = false + +[[bin]] +name = "ray-cube-compute" +path = "src/main.rs" + +[dependencies] +bytemuck.workspace = true +glam.workspace = true +wasm-bindgen-test.workspace = true +wgpu-example.workspace = true +wgpu.workspace = true +winit.workspace = true + +[dev-dependencies] +wgpu-test.workspace = true diff --git a/wgpu/examples/ray-cube-compute/README.md b/examples/ray-cube-compute/README.md similarity index 100% rename from wgpu/examples/ray-cube-compute/README.md rename to examples/ray-cube-compute/README.md diff --git a/wgpu/examples/ray-cube-compute/screenshot.png b/examples/ray-cube-compute/screenshot.png similarity index 100% rename from wgpu/examples/ray-cube-compute/screenshot.png rename to examples/ray-cube-compute/screenshot.png diff --git a/wgpu/examples/ray-cube-compute/blit.wgsl b/examples/ray-cube-compute/src/blit.wgsl similarity index 100% rename from wgpu/examples/ray-cube-compute/blit.wgsl rename to examples/ray-cube-compute/src/blit.wgsl diff --git a/wgpu/examples/ray-cube-compute/main.rs b/examples/ray-cube-compute/src/main.rs similarity index 95% rename from wgpu/examples/ray-cube-compute/main.rs rename to examples/ray-cube-compute/src/main.rs index 9c564a5e88..44289df80c 100644 --- a/wgpu/examples/ray-cube-compute/main.rs +++ b/examples/ray-cube-compute/src/main.rs @@ -7,9 +7,6 @@ use wgpu::util::DeviceExt; use rt::traits::*; use wgpu::ray_tracing as rt; -#[path = "../framework.rs"] -mod framework; - // from cube #[repr(C)] #[derive(Clone, Copy, Pod, Zeroable)] @@ -262,7 +259,7 @@ struct Example { start_inst: Instant, } -impl framework::Example for Example { +impl wgpu_example::framework::Example for Example { fn required_features() -> wgpu::Features { wgpu::Features::TEXTURE_BINDING_ARRAY | wgpu::Features::STORAGE_RESOURCE_BINDING_ARRAY @@ -546,7 +543,7 @@ impl framework::Example for Example { view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue, - spawner: &framework::Spawner, + spawner: &wgpu_example::framework::Spawner, ) { device.push_error_scope(wgpu::ErrorFilter::Validation); @@ -578,8 +575,10 @@ impl framework::Example for Example { encoder.build_acceleration_structures(iter::empty(), iter::once(&self.tlas_package)); { - let mut cpass = - encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None }); + let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { + label: None, + timestamp_writes: None, + }); cpass.set_pipeline(&self.compute_pipeline); cpass.set_bind_group(0, &self.compute_bind_group, &[]); cpass.dispatch_workgroups(self.rt_target.width() / 8, self.rt_target.height() / 8, 1); @@ -597,6 +596,8 @@ impl framework::Example for Example { }, })], depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, }); rpass.set_pipeline(&self.blit_pipeline); @@ -614,24 +615,23 @@ impl framework::Example for Example { } fn main() { - framework::run::("ray-cube"); + wgpu_example::framework::run::("ray-cube"); } #[test] fn ray_cube_compute() { - framework::test::(framework::FrameworkRefTest { + wgpu_example::framework::test::(wgpu_example::framework::FrameworkRefTest { image_path: "/examples/ray-cube-compute/screenshot.png", width: 1024, height: 768, optional_features: wgpu::Features::default(), - base_test_parameters: framework::test_common::TestParameters { - required_features: ::required_features(), + base_test_parameters: wgpu_test::TestParameters { + required_features: ::required_features(), required_downlevel_properties: - ::required_downlevel_capabilities(), - required_limits: ::required_limits(), + ::required_downlevel_capabilities(), + required_limits: ::required_limits(), failures: Vec::new(), }, - tolerance: 1, - max_outliers: 1225, // Bounded by swiftshader + comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], }); } diff --git a/wgpu/examples/ray-cube-compute/shader.wgsl b/examples/ray-cube-compute/src/shader.wgsl similarity index 100% rename from wgpu/examples/ray-cube-compute/shader.wgsl rename to examples/ray-cube-compute/src/shader.wgsl diff --git a/examples/ray-cube-fragment/Cargo.toml b/examples/ray-cube-fragment/Cargo.toml new file mode 100644 index 0000000000..a81f7ab97d --- /dev/null +++ b/examples/ray-cube-fragment/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "ray-cube-fragment" +version.workspace = true +license.workspace = true +edition.workspace = true +description = "todo" +publish = false + +[[bin]] +name = "ray-cube-fragment" +path = "src/main.rs" + +[dependencies] +bytemuck.workspace = true +glam.workspace = true +wasm-bindgen-test.workspace = true +wgpu-example.workspace = true +wgpu.workspace = true +winit.workspace = true + +[dev-dependencies] +wgpu-test.workspace = true diff --git a/wgpu/examples/ray-cube-fragment/README.md b/examples/ray-cube-fragment/README.md similarity index 100% rename from wgpu/examples/ray-cube-fragment/README.md rename to examples/ray-cube-fragment/README.md diff --git a/wgpu/examples/ray-cube-fragment/screenshot.png b/examples/ray-cube-fragment/screenshot.png similarity index 100% rename from wgpu/examples/ray-cube-fragment/screenshot.png rename to examples/ray-cube-fragment/screenshot.png diff --git a/wgpu/examples/ray-cube-fragment/main.rs b/examples/ray-cube-fragment/src/main.rs similarity index 94% rename from wgpu/examples/ray-cube-fragment/main.rs rename to examples/ray-cube-fragment/src/main.rs index 488b827143..a642207fd3 100644 --- a/wgpu/examples/ray-cube-fragment/main.rs +++ b/examples/ray-cube-fragment/src/main.rs @@ -7,9 +7,6 @@ use wgpu::util::DeviceExt; use rt::traits::*; use wgpu::ray_tracing as rt; -#[path = "../framework.rs"] -mod framework; - // from cube #[repr(C)] #[derive(Clone, Copy, Pod, Zeroable)] @@ -113,7 +110,7 @@ struct Example { start_inst: Instant, } -impl framework::Example for Example { +impl wgpu_example::framework::Example for Example { fn required_features() -> wgpu::Features { wgpu::Features::RAY_QUERY | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE } @@ -303,7 +300,7 @@ impl framework::Example for Example { view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue, - spawner: &framework::Spawner, + spawner: &wgpu_example::framework::Spawner, ) { device.push_error_scope(wgpu::ErrorFilter::Validation); @@ -366,6 +363,8 @@ impl framework::Example for Example { }, })], depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, }); rpass.set_pipeline(&self.pipeline); @@ -383,24 +382,23 @@ impl framework::Example for Example { } fn main() { - framework::run::("ray-cube"); + wgpu_example::framework::run::("ray-cube"); } #[test] fn ray_cube_fragment() { - framework::test::(framework::FrameworkRefTest { + wgpu_example::framework::test::(wgpu_example::framework::FrameworkRefTest { image_path: "/examples/ray-cube-fragment/screenshot.png", width: 1024, height: 768, optional_features: wgpu::Features::default(), - base_test_parameters: framework::test_common::TestParameters { - required_features: ::required_features(), + base_test_parameters: wgpu_test::TestParameters { + required_features: ::required_features(), required_downlevel_properties: - ::required_downlevel_capabilities(), - required_limits: ::required_limits(), + ::required_downlevel_capabilities(), + required_limits: ::required_limits(), failures: Vec::new(), }, - tolerance: 1, - max_outliers: 1225, // Bounded by swiftshader + comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], }); } diff --git a/wgpu/examples/ray-cube-fragment/shader.wgsl b/examples/ray-cube-fragment/src/shader.wgsl similarity index 100% rename from wgpu/examples/ray-cube-fragment/shader.wgsl rename to examples/ray-cube-fragment/src/shader.wgsl diff --git a/examples/ray-scene/Cargo.toml b/examples/ray-scene/Cargo.toml new file mode 100644 index 0000000000..9fbeffab9f --- /dev/null +++ b/examples/ray-scene/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "ray-scene" +version.workspace = true +license.workspace = true +edition.workspace = true +description = "todo" +publish = false + +[[bin]] +name = "ray-scene" +path = "src/main.rs" + +[dependencies] +bytemuck.workspace = true +glam.workspace = true +obj.workspace = true +wasm-bindgen-test.workspace = true +wgpu-example.workspace = true +wgpu.workspace = true +winit.workspace = true + +[dev-dependencies] +wgpu-test.workspace = true diff --git a/wgpu/examples/ray-scene/cube.mtl b/examples/ray-scene/cube.mtl similarity index 100% rename from wgpu/examples/ray-scene/cube.mtl rename to examples/ray-scene/cube.mtl diff --git a/wgpu/examples/ray-scene/cube.obj b/examples/ray-scene/cube.obj similarity index 100% rename from wgpu/examples/ray-scene/cube.obj rename to examples/ray-scene/cube.obj diff --git a/wgpu/examples/ray-scene/main.rs b/examples/ray-scene/src/main.rs similarity index 96% rename from wgpu/examples/ray-scene/main.rs rename to examples/ray-scene/src/main.rs index 610a6d3b71..71c55617c3 100644 --- a/wgpu/examples/ray-scene/main.rs +++ b/examples/ray-scene/src/main.rs @@ -7,9 +7,6 @@ use wgpu::util::DeviceExt; use rt::traits::*; use wgpu::ray_tracing as rt; -#[path = "../framework.rs"] -mod framework; - // from cube #[repr(C)] #[derive(Debug, Clone, Copy, Pod, Zeroable, Default)] @@ -321,7 +318,7 @@ struct Example { scene_components: SceneComponents, } -impl framework::Example for Example { +impl wgpu_example::framework::Example for Example { fn required_features() -> wgpu::Features { wgpu::Features::RAY_QUERY | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE } @@ -471,7 +468,7 @@ impl framework::Example for Example { view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue, - spawner: &framework::Spawner, + spawner: &wgpu_example::framework::Spawner, ) { device.push_error_scope(wgpu::ErrorFilter::Validation); @@ -541,6 +538,8 @@ impl framework::Example for Example { }, })], depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, }); rpass.set_pipeline(&self.pipeline); @@ -558,24 +557,23 @@ impl framework::Example for Example { } fn main() { - framework::run::("ray-scene"); + wgpu_example::framework::run::("ray-scene"); } #[test] fn ray_cube_fragment() { - framework::test::(framework::FrameworkRefTest { + wgpu_example::framework::test::(wgpu_example::framework::FrameworkRefTest { image_path: "/examples/ray-cube-fragment/screenshot.png", width: 1024, height: 768, optional_features: wgpu::Features::default(), - base_test_parameters: framework::test_common::TestParameters { - required_features: ::required_features(), + base_test_parameters: wgpu_test::TestParameters { + required_features: ::required_features(), required_downlevel_properties: - ::required_downlevel_capabilities(), - required_limits: ::required_limits(), + ::required_downlevel_capabilities(), + required_limits: ::required_limits(), failures: Vec::new(), }, - tolerance: 1, - max_outliers: 1225, // Bounded by swiftshader + comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], }); } diff --git a/wgpu/examples/ray-scene/shader.wgsl b/examples/ray-scene/src/shader.wgsl similarity index 100% rename from wgpu/examples/ray-scene/shader.wgsl rename to examples/ray-scene/src/shader.wgsl diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 0ae6d7a2dd..23b7764cd3 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -21,6 +21,7 @@ use std::{iter, num::NonZeroU32, ptr}; pub mod global; mod life; pub mod queue; +pub mod ray_tracing; pub mod resource; #[cfg(any(feature = "trace", feature = "replay"))] pub mod trace; diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 50d963548d..5198559006 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -2,10 +2,15 @@ use crate::device::trace; use crate::{ device::{queue::TempResource, Device, DeviceError}, - hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Token}, + global::Global, + hal_api::HalApi, + hub::Token, id::{self, BlasId, TlasId}, + identity::{GlobalIdentityHandlerFactory, Input}, ray_tracing::{get_raw_tlas_instance_size, CreateBlasError, CreateTlasError}, - resource, LabelHelpers, LifeGuard, Stored, + resource, + storage::InvalidId, + LabelHelpers, LifeGuard, Stored, }; use hal::{AccelerationStructureTriangleIndices, Device as _}; @@ -293,7 +298,7 @@ impl Global { let last_submit_index = blas.life_guard.life_count(); (last_submit_index, blas.device_id.value, ref_count) } - Err(crate::hub::InvalidId) => { + Err(InvalidId) => { hub.blas_s.unregister_locked(blas_id, &mut *blas_guard); return; } @@ -378,7 +383,7 @@ impl Global { let last_submit_index = tlas.life_guard.life_count(); (last_submit_index, tlas.device_id.value, ref_count) } - Err(crate::hub::InvalidId) => { + Err(InvalidId) => { hub.tlas_s.unregister_locked(tlas_id, &mut *tlas_guard); return; } diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index e2fdd2f411..0fd157ba74 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -316,7 +316,9 @@ impl Device { let (buffer_guard, mut token) = hub.buffers.read(&mut token); let (texture_guard, mut token) = hub.textures.read(&mut token); let (texture_view_guard, mut token) = hub.texture_views.read(&mut token); - let (sampler_guard, _) = hub.samplers.read(&mut token); + let (sampler_guard, mut token) = hub.samplers.read(&mut token); + let (blas_guard, mut token) = hub.blas_s.read(&mut token); + let (tlas_guard, _) = hub.tlas_s.read(&mut token); for id in trackers.buffers.used() { if buffer_guard[id].life_guard.ref_count.is_none() { @@ -358,6 +360,16 @@ impl Device { self.temp_suspected.query_sets.push(id); } } + for id in trackers.blas_s.used() { + if blas_guard[id].life_guard.ref_count.is_none() { + self.temp_suspected.blas_s.push(id); + } + } + for id in trackers.tlas_s.used() { + if tlas_guard[id].life_guard.ref_count.is_none() { + self.temp_suspected.tlas_s.push(id); + } + } } self.lock_life(token) @@ -1278,6 +1290,10 @@ impl Device { .flags .contains(wgt::DownlevelFlags::MULTISAMPLED_SHADING), ); + caps.set( + Caps::RAY_QUERY, + self.features.contains(wgt::Features::RAY_QUERY), + ); let info = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), caps) .validate(&module) @@ -1542,7 +1558,7 @@ impl Device { }, ) } - Bt::AccelerationStructure => todo!(), + Bt::AccelerationStructure => (None, WritableStorage::No), }; // Validate the count parameter @@ -2045,7 +2061,7 @@ impl Device { buffers: &hal_buffers, samplers: &hal_samplers, textures: &hal_textures, - acceleration_structures: &[], + acceleration_structures: &hal_tlas_s, }; let raw = unsafe { self.raw From e1454529e208eb4ca2ddce4ff1575c06d83cf9fe Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 25 Aug 2023 20:35:23 -0700 Subject: [PATCH 094/146] Undo d02c99d13af80f9a9404e9fe667a4d173b334540 --- wgpu-core/src/device/ray_tracing.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 5198559006..1fa30b14ee 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -290,13 +290,12 @@ impl Global { let hub = A::hub(self); let mut token = Token::root(); - let (last_submit_index, device_id, ref_count) = { + let (last_submit_index, device_id) = { let (mut blas_guard, _) = hub.blas_s.write(&mut token); match blas_guard.get_mut(blas_id) { Ok(blas) => { - let ref_count = blas.life_guard.ref_count.take().unwrap(); let last_submit_index = blas.life_guard.life_count(); - (last_submit_index, blas.device_id.value, ref_count) + (last_submit_index, blas.device_id.value) } Err(InvalidId) => { hub.blas_s.unregister_locked(blas_id, &mut *blas_guard); @@ -308,7 +307,6 @@ impl Global { let (device_guard, mut token) = hub.devices.read(&mut token); let device = &device_guard[device_id]; { - drop(ref_count); let mut life_lock = device.lock_life(&mut token); life_lock .suspected_resources @@ -375,13 +373,12 @@ impl Global { let hub = A::hub(self); let mut token = Token::root(); - let (last_submit_index, device_id, ref_count) = { + let (last_submit_index, device_id) = { let (mut tlas_guard, _) = hub.tlas_s.write(&mut token); match tlas_guard.get_mut(tlas_id) { Ok(tlas) => { - let ref_count = tlas.life_guard.ref_count.take().unwrap(); let last_submit_index = tlas.life_guard.life_count(); - (last_submit_index, tlas.device_id.value, ref_count) + (last_submit_index, tlas.device_id.value) } Err(InvalidId) => { hub.tlas_s.unregister_locked(tlas_id, &mut *tlas_guard); @@ -393,7 +390,6 @@ impl Global { let (device_guard, mut token) = hub.devices.read(&mut token); let device = &device_guard[device_id]; { - drop(ref_count); let mut life_lock = device.lock_life(&mut token); life_lock .suspected_resources From 811aa2353bc8b5640675aa45b7d67d2cebdf47cf Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Mon, 4 Sep 2023 23:48:13 +0200 Subject: [PATCH 095/146] fixed ray-scene example --- examples/ray-scene/src/main.rs | 28 +++++++++++++--------------- examples/ray-scene/src/shader.wgsl | 8 ++++---- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/examples/ray-scene/src/main.rs b/examples/ray-scene/src/main.rs index 71c55617c3..2175b88976 100644 --- a/examples/ray-scene/src/main.rs +++ b/examples/ray-scene/src/main.rs @@ -94,7 +94,7 @@ struct Material { } fn load_model(scene: &mut RawSceneComponents, path: &str) { - let path = env!("CARGO_MANIFEST_DIR").to_string() + "/" + path; + let path = env!("CARGO_MANIFEST_DIR").to_string() + "/../../" + path; let mut object = obj::Obj::load(path).unwrap(); object.load_mtls().unwrap(); @@ -138,20 +138,18 @@ fn load_model(scene: &mut RawSceneComponents, path: &str) { let mut material: Material = Default::default(); - if let Some(mat) = group.material { - if let obj::ObjMaterial::Mtl(mat) = mat { - if let Some(kd) = mat.kd { - material.albedo = kd; - } - if let Some(ns) = mat.ns { - material.roughness_exponent = ns; - } - if let Some(ka) = mat.ka { - material.metalness = ka[0]; - } - if let Some(ks) = mat.ks { - material.specularity = ks[0]; - } + if let Some(obj::ObjMaterial::Mtl(mat)) = group.material { + if let Some(kd) = mat.kd { + material.albedo = kd; + } + if let Some(ns) = mat.ns { + material.roughness_exponent = ns; + } + if let Some(ka) = mat.ka { + material.metalness = ka[0]; + } + if let Some(ks) = mat.ks { + material.specularity = ks[0]; } } diff --git a/examples/ray-scene/src/shader.wgsl b/examples/ray-scene/src/shader.wgsl index ab8fc6e0b0..f3b1a61920 100644 --- a/examples/ray-scene/src/shader.wgsl +++ b/examples/ray-scene/src/shader.wgsl @@ -159,10 +159,10 @@ fn fs_main(vertex: VertexOutput) -> @location(0) vec4 { } } - let vertex = vertices[0]; - let index = indices[0]; - let geometry = geometries[0]; - let instance = instances[0]; + // let vertex = vertices[0]; + // let index = indices[0]; + // let geometry = geometries[0]; + // let instance = instances[0]; return color; // vec4(vertex.tex_coords, 1.0, 1.0); } From c789f7f2efcaff860e02a359c76d51988f32ce84 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Thu, 7 Sep 2023 01:03:32 +0200 Subject: [PATCH 096/146] first dedicated ray-tracing test --- Cargo.lock | 1 + tests/Cargo.toml | 1 + tests/tests/ray_tracing/mesh_gen.rs | 207 ++++++++++++++++++++++++++++ tests/tests/ray_tracing/mod.rs | 121 ++++++++++++++++ tests/tests/root.rs | 1 + 5 files changed, 331 insertions(+) create mode 100644 tests/tests/ray_tracing/mesh_gen.rs create mode 100644 tests/tests/ray_tracing/mod.rs diff --git a/Cargo.lock b/Cargo.lock index ae862be425..09080b1849 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3503,6 +3503,7 @@ dependencies = [ "cfg-if", "console_log", "env_logger", + "glam 0.24.1", "image", "js-sys", "log", diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 5738ed1bdb..ed2dc8d57d 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -29,6 +29,7 @@ png.workspace = true pollster.workspace = true wgpu.workspace = true wgt.workspace = true +glam.workspace = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies] nv-flip.workspace = true diff --git a/tests/tests/ray_tracing/mesh_gen.rs b/tests/tests/ray_tracing/mesh_gen.rs new file mode 100644 index 0000000000..0c7bb61132 --- /dev/null +++ b/tests/tests/ray_tracing/mesh_gen.rs @@ -0,0 +1,207 @@ +use bytemuck::{Pod, Zeroable}; +use glam::{Affine3A, Mat4, Quat, Vec3}; + +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +pub struct Vertex { + _pos: [f32; 4], + _tex_coord: [f32; 2], +} + +fn vertex(pos: [i8; 3], tc: [i8; 2]) -> Vertex { + Vertex { + _pos: [pos[0] as f32, pos[1] as f32, pos[2] as f32, 1.0], + _tex_coord: [tc[0] as f32, tc[1] as f32], + } +} + +pub fn create_vertices() -> (Vec, Vec) { + let vertex_data = [ + // top (0, 0, 1) + vertex([-1, -1, 1], [0, 0]), + vertex([1, -1, 1], [1, 0]), + vertex([1, 1, 1], [1, 1]), + vertex([-1, 1, 1], [0, 1]), + // bottom (0, 0, -1) + vertex([-1, 1, -1], [1, 0]), + vertex([1, 1, -1], [0, 0]), + vertex([1, -1, -1], [0, 1]), + vertex([-1, -1, -1], [1, 1]), + // right (1, 0, 0) + vertex([1, -1, -1], [0, 0]), + vertex([1, 1, -1], [1, 0]), + vertex([1, 1, 1], [1, 1]), + vertex([1, -1, 1], [0, 1]), + // left (-1, 0, 0) + vertex([-1, -1, 1], [1, 0]), + vertex([-1, 1, 1], [0, 0]), + vertex([-1, 1, -1], [0, 1]), + vertex([-1, -1, -1], [1, 1]), + // front (0, 1, 0) + vertex([1, 1, -1], [1, 0]), + vertex([-1, 1, -1], [0, 0]), + vertex([-1, 1, 1], [0, 1]), + vertex([1, 1, 1], [1, 1]), + // back (0, -1, 0) + vertex([1, -1, 1], [0, 0]), + vertex([-1, -1, 1], [1, 0]), + vertex([-1, -1, -1], [1, 1]), + vertex([1, -1, -1], [0, 1]), + ]; + + let index_data: &[u16] = &[ + 0, 1, 2, 2, 3, 0, // top + 4, 5, 6, 6, 7, 4, // bottom + 8, 9, 10, 10, 11, 8, // right + 12, 13, 14, 14, 15, 12, // left + 16, 17, 18, 18, 19, 16, // front + 20, 21, 22, 22, 23, 20, // back + ]; + + (vertex_data.to_vec(), index_data.to_vec()) +} + +#[repr(C)] +#[derive(Clone, Copy, Pod, Zeroable)] +pub struct AccelerationStructureInstance { + transform: [f32; 12], + custom_index_and_mask: u32, + shader_binding_table_record_offset_and_flags: u32, + acceleration_structure_reference: u64, +} + +impl std::fmt::Debug for AccelerationStructureInstance { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Instance") + .field("transform", &self.transform) + .field("custom_index()", &self.custom_index()) + .field("mask()", &self.mask()) + .field( + "shader_binding_table_record_offset()", + &self.shader_binding_table_record_offset(), + ) + .field("flags()", &self.flags()) + .field( + "acceleration_structure_reference", + &self.acceleration_structure_reference, + ) + .finish() + } +} + +#[allow(dead_code)] +impl AccelerationStructureInstance { + const LOW_24_MASK: u32 = 0x00ff_ffff; + const MAX_U24: u32 = (1u32 << 24u32) - 1u32; + + #[inline] + pub fn affine_to_rows(mat: &Affine3A) -> [f32; 12] { + let row_0 = mat.matrix3.row(0); + let row_1 = mat.matrix3.row(1); + let row_2 = mat.matrix3.row(2); + let translation = mat.translation; + [ + row_0.x, + row_0.y, + row_0.z, + translation.x, + row_1.x, + row_1.y, + row_1.z, + translation.y, + row_2.x, + row_2.y, + row_2.z, + translation.z, + ] + } + + #[inline] + fn rows_to_affine(rows: &[f32; 12]) -> Affine3A { + Affine3A::from_cols_array(&[ + rows[0], rows[3], rows[6], rows[9], rows[1], rows[4], rows[7], rows[10], rows[2], + rows[5], rows[8], rows[11], + ]) + } + + pub fn transform_as_affine(&self) -> Affine3A { + Self::rows_to_affine(&self.transform) + } + pub fn set_transform(&mut self, transform: &Affine3A) { + self.transform = Self::affine_to_rows(transform); + } + + pub fn custom_index(&self) -> u32 { + self.custom_index_and_mask & Self::LOW_24_MASK + } + + pub fn mask(&self) -> u8 { + (self.custom_index_and_mask >> 24) as u8 + } + + pub fn shader_binding_table_record_offset(&self) -> u32 { + self.shader_binding_table_record_offset_and_flags & Self::LOW_24_MASK + } + + pub fn flags(&self) -> u8 { + (self.shader_binding_table_record_offset_and_flags >> 24) as u8 + } + + pub fn set_custom_index(&mut self, custom_index: u32) { + debug_assert!( + custom_index <= Self::MAX_U24, + "custom_index uses more than 24 bits! {custom_index} > {}", + Self::MAX_U24 + ); + self.custom_index_and_mask = + (custom_index & Self::LOW_24_MASK) | (self.custom_index_and_mask & !Self::LOW_24_MASK) + } + + pub fn set_mask(&mut self, mask: u8) { + self.custom_index_and_mask = + (self.custom_index_and_mask & Self::LOW_24_MASK) | (u32::from(mask) << 24) + } + + pub fn set_shader_binding_table_record_offset( + &mut self, + shader_binding_table_record_offset: u32, + ) { + debug_assert!(shader_binding_table_record_offset <= Self::MAX_U24, "shader_binding_table_record_offset uses more than 24 bits! {shader_binding_table_record_offset} > {}", Self::MAX_U24); + self.shader_binding_table_record_offset_and_flags = (shader_binding_table_record_offset + & Self::LOW_24_MASK) + | (self.shader_binding_table_record_offset_and_flags & !Self::LOW_24_MASK) + } + + pub fn set_flags(&mut self, flags: u8) { + self.shader_binding_table_record_offset_and_flags = + (self.shader_binding_table_record_offset_and_flags & Self::LOW_24_MASK) + | (u32::from(flags) << 24) + } + + pub fn new( + transform: &Affine3A, + custom_index: u32, + mask: u8, + shader_binding_table_record_offset: u32, + flags: u8, + acceleration_structure_reference: u64, + ) -> Self { + debug_assert!( + custom_index <= Self::MAX_U24, + "custom_index uses more than 24 bits! {custom_index} > {}", + Self::MAX_U24 + ); + debug_assert!( + shader_binding_table_record_offset <= Self::MAX_U24, + "shader_binding_table_record_offset uses more than 24 bits! {shader_binding_table_record_offset} > {}", Self::MAX_U24 + ); + AccelerationStructureInstance { + transform: Self::affine_to_rows(transform), + custom_index_and_mask: (custom_index & Self::MAX_U24) | (u32::from(mask) << 24), + shader_binding_table_record_offset_and_flags: (shader_binding_table_record_offset + & Self::MAX_U24) + | (u32::from(flags) << 24), + acceleration_structure_reference, + } + } +} diff --git a/tests/tests/ray_tracing/mod.rs b/tests/tests/ray_tracing/mod.rs new file mode 100644 index 0000000000..e55da63fe8 --- /dev/null +++ b/tests/tests/ray_tracing/mod.rs @@ -0,0 +1,121 @@ +use std::{iter, mem}; + +use wgpu_test::{initialize_test, TestParameters}; + +use rt::traits::*; +use wgpu::ray_tracing as rt; +use wgpu::util::DeviceExt; + +use glam::{Affine3A, Quat, Vec3}; + +use mesh_gen::{AccelerationStructureInstance, Vertex}; + +mod mesh_gen; + +fn required_features() -> wgpu::Features { + wgpu::Features::TEXTURE_BINDING_ARRAY + | wgpu::Features::STORAGE_RESOURCE_BINDING_ARRAY + | wgpu::Features::VERTEX_WRITABLE_STORAGE + | wgpu::Features::RAY_QUERY + | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE +} + +#[test] +fn create_tests() { + initialize_test( + TestParameters::default().features(required_features()), + |ctx| { + let max_instances = 1000; + let device = &ctx.device; + + let (vertex_data, index_data) = mesh_gen::create_vertices(); + + let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(&vertex_data), + usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::BLAS_INPUT, + }); + + let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(&index_data), + usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::BLAS_INPUT, + }); + + let blas_geo_size_desc = rt::BlasTriangleGeometrySizeDescriptor { + vertex_format: wgpu::VertexFormat::Float32x4, + vertex_count: vertex_data.len() as u32, + index_format: Some(wgpu::IndexFormat::Uint16), + index_count: Some(index_data.len() as u32), + flags: rt::AccelerationStructureGeometryFlags::OPAQUE, + }; + + let blas = device.create_blas( + &rt::CreateBlasDescriptor { + label: None, + flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: rt::AccelerationStructureUpdateMode::Build, + }, + rt::BlasGeometrySizeDescriptors::Triangles { + desc: vec![blas_geo_size_desc.clone()], + }, + ); + + let tlas = device.create_tlas(&rt::CreateTlasDescriptor { + label: None, + flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: rt::AccelerationStructureUpdateMode::Build, + max_instances, + }); + + let mut tlas_package = rt::TlasPackage::new(tlas, max_instances); + + for i in 0..10000 { + for j in 0..max_instances { + *tlas_package.get_mut_single(0).unwrap() = Some(rt::TlasInstance::new( + &blas, + AccelerationStructureInstance::affine_to_rows( + &Affine3A::from_rotation_translation( + Quat::from_rotation_y(45.9_f32.to_radians()), + Vec3 { + x: j as f32, + y: i as f32, + z: 0.0, + }, + ), + ), + 0, + 0xff, + )); + } + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + encoder.build_acceleration_structures( + iter::once(&rt::BlasBuildEntry { + blas: &blas, + geometry: rt::BlasGeometries::TriangleGeometries(vec![ + rt::BlasTriangleGeometry { + size: &blas_geo_size_desc, + vertex_buffer: &vertex_buf, + first_vertex: 0, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&index_buf), + index_buffer_offset: Some(0), + transform_buffer: None, + transform_buffer_offset: None, + }, + ]), + }), + // iter::empty(), + iter::once(&tlas_package), + ); + + ctx.queue.submit(Some(encoder.finish())); + } + + ctx.device.poll(wgpu::Maintain::Wait); + }, + ); +} diff --git a/tests/tests/root.rs b/tests/tests/root.rs index 25df8eda90..1852636010 100644 --- a/tests/tests/root.rs +++ b/tests/tests/root.rs @@ -20,6 +20,7 @@ mod occlusion_query; mod partially_bounded_arrays; mod poll; mod queue_transfer; +mod ray_tracing; mod resource_descriptor_accessor; mod resource_error; mod scissor_tests; From a09d11637e7d53f127f8b68998ac0e2e4fe21868 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Sat, 16 Sep 2023 05:51:27 +0200 Subject: [PATCH 097/146] fixed rt hal example after trunk merge --- wgpu-hal/examples/ray-traced-triangle/main.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index cb29a53f44..5d66aa6cec 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -13,6 +13,7 @@ use std::{ ptr::{self, copy_nonoverlapping}, time::Instant, }; +use winit::window::WindowButtons; const COMMAND_BUFFER_PER_CONTEXT: usize = 100; const DESIRED_FRAMES: u32 = 3; @@ -237,14 +238,14 @@ impl Example { let (adapter, features) = unsafe { let mut adapters = instance.enumerate_adapters(); if adapters.is_empty() { - return Err(hal::InstanceError); + panic!("No adapters found"); } let exposed = adapters.swap_remove(0); dbg!(exposed.features); (exposed.adapter, exposed.features) }; - let surface_caps = - unsafe { adapter.surface_capabilities(&surface) }.ok_or(hal::InstanceError)?; + let surface_caps = unsafe { adapter.surface_capabilities(&surface) } + .expect("Surface doesn't support presentation"); log::info!("Surface caps: {:#?}", surface_caps); let hal::OpenDevice { device, mut queue } = @@ -1078,6 +1079,7 @@ fn main() { height: 512, }) .with_resizable(false) + .with_enabled_buttons(WindowButtons::CLOSE) .build(&event_loop) .unwrap(); From 77acca5334da0844fbe63fe331004340a88d8f51 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Fri, 1 Dec 2023 01:44:12 +0100 Subject: [PATCH 098/146] implemented requested changes --- wgpu-hal/Cargo.toml | 2 +- wgpu-hal/examples/ray-traced-triangle/main.rs | 40 +++++++++++----- .../examples/ray-traced-triangle/shader.comp | 44 ------------------ .../ray-traced-triangle/shader.comp.spv | Bin 3520 -> 0 bytes .../examples/ray-traced-triangle/shader.wgsl | 37 +++++++++++++++ wgpu-hal/src/vulkan/adapter.rs | 4 ++ wgpu-hal/src/vulkan/command.rs | 38 +++------------ wgpu-hal/src/vulkan/device.rs | 40 +++++++++------- 8 files changed, 100 insertions(+), 105 deletions(-) delete mode 100644 wgpu-hal/examples/ray-traced-triangle/shader.comp delete mode 100644 wgpu-hal/examples/ray-traced-triangle/shader.comp.spv create mode 100644 wgpu-hal/examples/ray-traced-triangle/shader.wgsl diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 09fbc67f17..67bb47a816 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -180,10 +180,10 @@ features = ["wgsl-in"] [dev-dependencies] cfg-if = "1" env_logger = "0.10" +glam = "0.21.3" # for ray-traced-triangle example winit = { version = "0.29.2", features = [ "android-native-activity", ] } # for "halmark" example -glam = "0.21.3" # for ray-traced-triangle example [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] glutin = "0.29.1" # for "gles" example diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index d5fee8bb2b..ac29004442 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -220,12 +220,11 @@ impl Example { fn init(window: &winit::window::Window) -> Result> { let instance_desc = hal::InstanceDescriptor { name: "example", - flags: if cfg!(debug_assertions) { - wgt::InstanceFlags::all() - } else { - wgt::InstanceFlags::empty() + flags: wgt::InstanceFlags::default(), + dx12_shader_compiler: wgt::Dx12Compiler::Dxc { + dxil_path: None, + dxc_path: None, }, - dx12_shader_compiler: wgt::Dx12Compiler::Fxc, gles_minor_version: wgt::Gles3MinorVersion::default(), }; let instance = unsafe { A::Instance::init(&instance_desc)? }; @@ -358,15 +357,32 @@ impl Example { words } + let naga_shader = { + let shader_file = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("examples") + .join("ray-traced-triangle") + .join("shader.wgsl"); + let source = std::fs::read_to_string(shader_file).unwrap(); + let module = naga::front::wgsl::Frontend::new().parse(&source).unwrap(); + let info = naga::valid::Validator::new( + naga::valid::ValidationFlags::all(), + naga::valid::Capabilities::RAY_QUERY, + ) + .validate(&module) + .unwrap(); + hal::NagaShader { + module: Cow::Owned(module), + info, + debug_source: None, + } + }; + let shader_desc = hal::ShaderModuleDescriptor { + label: None, + runtime_checks: false, + }; let shader_module = unsafe { device - .create_shader_module( - &hal::ShaderModuleDescriptor { - label: None, - runtime_checks: false, - }, - hal::ShaderInput::SpirV(&make_spirv_raw(include_bytes!("shader.comp.spv"))), - ) + .create_shader_module(&shader_desc, hal::ShaderInput::Naga(naga_shader)) .unwrap() }; diff --git a/wgpu-hal/examples/ray-traced-triangle/shader.comp b/wgpu-hal/examples/ray-traced-triangle/shader.comp deleted file mode 100644 index d31f29115f..0000000000 --- a/wgpu-hal/examples/ray-traced-triangle/shader.comp +++ /dev/null @@ -1,44 +0,0 @@ -#version 460 -#extension GL_EXT_ray_query : enable - -layout(set = 0, binding = 0) uniform Uniforms -{ - mat4 viewInverse; - mat4 projInverse; -} cam; -layout(set = 0, binding = 1, rgba8) uniform image2D image; -layout(set = 0, binding = 2) uniform accelerationStructureEXT tlas; - -layout(local_size_x = 8, local_size_y = 8) in; - -void main() -{ - uvec2 launch_id = gl_GlobalInvocationID.xy; - uvec2 launch_size = gl_NumWorkGroups.xy * 8; - - const vec2 pixelCenter = vec2(launch_id) + vec2(0.5); - const vec2 inUV = pixelCenter/vec2(launch_size); - vec2 d = inUV * 2.0 - 1.0; - - vec4 origin = cam.viewInverse * vec4(0,0,0,1); - vec4 target = cam.projInverse * vec4(d.x, d.y, 1, 1) ; - vec4 direction = cam.viewInverse*vec4(normalize(target.xyz), 0) ; - - float tmin = 0.001; - float tmax = 10000.0; - - rayQueryEXT rayQuery; - rayQueryInitializeEXT(rayQuery, tlas, gl_RayFlagsOpaqueEXT, 0xff, origin.xyz, tmin, direction.xyz, tmax); - - rayQueryProceedEXT(rayQuery); - - vec3 out_colour = vec3(0.0, 0.0, 0.0); - - if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT ) { - vec2 barycentrics = rayQueryGetIntersectionBarycentricsEXT(rayQuery, true); - - out_colour = vec3(barycentrics.x, barycentrics.y, 1.0 - barycentrics.x - barycentrics.y); - } - - imageStore(image, ivec2(launch_id), vec4(out_colour, 1.0)); -} \ No newline at end of file diff --git a/wgpu-hal/examples/ray-traced-triangle/shader.comp.spv b/wgpu-hal/examples/ray-traced-triangle/shader.comp.spv deleted file mode 100644 index 345085c948d1fab7ad065d6d92437f40c1c57440..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3520 zcmZ9O`F0dV6o)&>B#}ihYym|KizpHiWfcU%IsqaCLc$_443i-lm`sOG0tvDNL5=@- zj<4af_zFIU%Q+tXzV0p1UGiqyz7DsPIKS$ZbckJG?(+bO?Hbv@N9(6|T=mjuQ zt~KPBf_GAMq&!nFdj{*Z@z;v{9izY;#evevE0JY9<$r%$B*_GtO5oT=KwDmk6$+Q>OKGjTai?iQ1HW^#%! zeC^RXz%ldnb^#DgVwriC$wg=m9Lr&;ljMVQ}rr-L`Cx0-v?YUgA?V0v={N}C%)?GuDHOL-d z?e3I&HMeJ!&70*K>p3!x^wN3b-v@HS`o?SpjJ{xhoSO4ToMSt>F$LiIdy&o|zZQE( zuIt}`?Rm)w<98zMjlBEQ_8jHx=NHHx&;p!adlzt+zZ+?6Hcz(ReL5Mvti*Nf2XXfd;&mi@AcA+Poppru+(7>itfC8kqvnkvUAOD&rK++9!v2-p zShewYz&c*rM@aYL-kOKK4QKl}cNpt>wEadL_Tw4S^D)PH7b6#d_fy!rz1*`<6Ep4I zUod|6*7P3x_PhRIFK@EF!+w9kukD-NY;S3@y^p@z!LRK*+iVw`Y|nh?4cj+1#E+qm zH`&e~=k_7i@1EZVezWJvGH+SV$vf=vVRr65^@TitJN>pp-U@U%;V^HIPFZsm2z`B# zbF1OZ(Pw@8CTD$f-UZG%iQSESFXx_-ue~AXd;`q4&vNGL?*Ve5-bQri2=z9h%Pr*f ze7k#qy!AXMxlr#zbh%&h_>a)#wgUI*oZEokt9YJspP(D7&$^zs+)@0#2YY~T$S&Yq zz72bU{IA6LCVZK5`;pf0j>v@?U!hyW_aW3cgf4H4_oNRv_hDd+-_KFdm&z>WIJz;% zK!`bkE;?Ag-p&Dij=-Hq5AlH;%sFd@JzhXJ-+2A|K-l9&bk}T*dn_X5 z)cqEHQ`Lu&Bfx!KLw*ac=eGMS0nah)^JdP;JHkH0Ih5h7ANq6)-MK@41zk=!-pn6` zb4_zyi_-Vo^&A5?z)fI%YZ&*qtB}68x6!Wx_cM;Hfu~*m2Np$lfj;ltZ}hy1tOI%L z{z*;)>G+2p=$im?zM<+1-Pw0Di5_Y>SBxze?(RKwx#qi@V9SS?sXWHHL(its~LuEg$k8qMIu}nBUFs&|RnN&>#9J|2I7dy->Pl zf2*E?C%N5;oCk}*BmB>h--CHzyx+%j;Ms)x{37QNFS#Fb&N~s}e$2U6WVrV~p_^~K Te)~{i9@pf&`v2u-?Fat@FKh, + proj_inv: mat4x4, +}; +@group(0) @binding(0) +var uniforms: Uniforms; + +@group(0) @binding(1) +var output: texture_storage_2d; + +@group(0) @binding(2) +var acc_struct: acceleration_structure; + +@compute @workgroup_size(8, 8) +fn main(@builtin(global_invocation_id) global_id: vec3) { + let target_size = textureDimensions(output); + + let pixel_center = vec2(global_id.xy) + vec2(0.5); + let in_uv = pixel_center / vec2(target_size.xy); + let d = in_uv * 2.0 - 1.0; + + let origin = (uniforms.view_inv * vec4(0.0, 0.0, 0.0, 1.0)).xyz; + let temp = uniforms.proj_inv * vec4(d.x, d.y, 1.0, 1.0); + let direction = (uniforms.view_inv * vec4(normalize(temp.xyz), 0.0)).xyz; + + var rq: ray_query; + rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 0.1, 200.0, origin, direction)); + rayQueryProceed(&rq); + + var color = vec4(0.0, 0.0, 0.0, 1.0); + let intersection = rayQueryGetCommittedIntersection(&rq); + if intersection.kind != RAY_QUERY_INTERSECTION_NONE { + color = vec4(intersection.barycentrics, 1.0 - intersection.barycentrics.x - intersection.barycentrics.y, 1.0); + } + + textureStore(output, global_id.xy, color); +} \ No newline at end of file diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 1bb3bbfa46..ffd03ee80b 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1362,6 +1362,10 @@ impl super::Adapter { capabilities.push(spv::Capability::StorageImageWriteWithoutFormat); } + if features.contains(wgt::Features::RAY_QUERY) { + capabilities.push(spv::Capability::RayQueryKHR); + } + let mut flags = spv::WriterFlags::empty(); flags.set( spv::WriterFlags::DEBUG, diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index a90db2c16c..60ac175c4f 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -423,10 +423,12 @@ impl crate::CommandEncoder for super::CommandEncoder { const CAPACITY_INNER: usize = 1; let descriptor_count = descriptor_count as usize; - let ray_tracing_functions = match self.device.extension_fns.ray_tracing { - Some(ref functions) => functions, - None => panic!("Feature `RAY_TRACING` not enabled"), - }; + let ray_tracing_functions = self + .device + .extension_fns + .ray_tracing + .as_ref() + .expect("Feature `RAY_TRACING` not enabled"); let get_device_address = |buffer: Option<&super::Buffer>| unsafe { match buffer { @@ -618,39 +620,11 @@ impl crate::CommandEncoder for super::CommandEncoder { ranges_ptrs.push(&ranges_storage[i]); } - // let mut geometry_infos = - // Vec::::with_capacity(descriptors.len()); - - // let mut ranges_vec = - // Vec::<&[vk::AccelerationStructureBuildRangeInfoKHR]>::with_capacity(descriptors.len()); - - // let mut ranges_storage = - // Vec::>::with_capacity(descriptors.len()); - - // for desc in descriptors { - // let (ranges, geometry_info) = prepare_geometry_info_and_ranges(desc); - // geometry_infos.push(geometry_info); - // ranges_storage.push(ranges); - - // } - - // for i in 0..descriptors.len() { - // ranges_vec.push(&ranges_storage[i]); - // } - - // let (ranges, geometry_info) = prepare_geometry_info_and_ranges(descriptors[0]); - unsafe { ray_tracing_functions .acceleration_structure .cmd_build_acceleration_structures(self.active, &geometry_infos, &ranges_ptrs); } - - // unsafe { - // ray_tracing_functions - // .acceleration_structure - // .cmd_build_acceleration_structures(self.active, &geometry_infos, &ranges_vec); - // } } unsafe fn place_acceleration_structure_barrier( diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index dc6c52bc22..2d665bf7f9 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -2085,10 +2085,12 @@ impl crate::Device for super::Device { ) -> crate::AccelerationStructureBuildSizes { const CAPACITY: usize = 8; - let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { - Some(ref functions) => functions, - None => panic!("Feature `RAY_TRACING` not enabled"), - }; + let ray_tracing_functions = self + .shared + .extension_fns + .ray_tracing + .as_ref() + .expect("Feature `RAY_TRACING` not enabled"); let (geometries, primitive_counts) = match *desc.entries { crate::AccelerationStructureEntries::Instances(ref instances) => { @@ -2196,10 +2198,12 @@ impl crate::Device for super::Device { &self, acceleration_structure: &super::AccelerationStructure, ) -> wgt::BufferAddress { - let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { - Some(ref functions) => functions, - None => panic!("Feature `RAY_TRACING` not enabled"), - }; + let ray_tracing_functions = self + .shared + .extension_fns + .ray_tracing + .as_ref() + .expect("Feature `RAY_TRACING` not enabled"); unsafe { ray_tracing_functions @@ -2215,10 +2219,12 @@ impl crate::Device for super::Device { &self, desc: &crate::AccelerationStructureDescriptor, ) -> Result { - let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { - Some(ref functions) => functions, - None => panic!("Feature `RAY_TRACING` not enabled"), - }; + let ray_tracing_functions = self + .shared + .extension_fns + .ray_tracing + .as_ref() + .expect("Feature `RAY_TRACING` not enabled"); let vk_buffer_info = vk::BufferCreateInfo::builder() .size(desc.size) @@ -2278,10 +2284,12 @@ impl crate::Device for super::Device { &self, acceleration_structure: super::AccelerationStructure, ) { - let ray_tracing_functions = match self.shared.extension_fns.ray_tracing { - Some(ref functions) => functions, - None => panic!("Feature `RAY_TRACING` not enabled"), - }; + let ray_tracing_functions = self + .shared + .extension_fns + .ray_tracing + .as_ref() + .expect("Feature `RAY_TRACING` not enabled"); unsafe { ray_tracing_functions From bb316b18c36814e1c8263f811f1c9691d225199e Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 4 Dec 2023 16:07:20 +1300 Subject: [PATCH 099/146] fix unexpected build errors (not the expected ones) --- Cargo.lock | 576 ++++++++++++++------------------- wgpu-core/src/binding_model.rs | 5 +- wgpu-hal/src/lib.rs | 2 +- wgpu-types/src/lib.rs | 2 +- wgpu/src/context.rs | 114 +++++-- xtask/Cargo.lock | 56 ---- 6 files changed, 331 insertions(+), 424 deletions(-) delete mode 100644 xtask/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index cffe3ad273..52bdded951 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,47 +233,15 @@ dependencies = [ "libloading 0.7.4", ] -[[package]] -name = "async-executor" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" -dependencies = [ - "async-lock", - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-task" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" - [[package]] name = "async-trait" version = "0.1.74" -version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", "syn 2.0.39", - "syn 2.0.29", ] [[package]] @@ -407,7 +375,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -534,9 +502,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.8" +version = "4.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" +checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272" dependencies = [ "clap_builder", "clap_derive", @@ -544,9 +512,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.8" +version = "4.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" +checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1" dependencies = [ "anstream", "anstyle", @@ -597,6 +565,22 @@ dependencies = [ "objc", ] +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics 0.23.1", + "foreign-types 0.5.0", + "libc", + "objc", +] + [[package]] name = "cocoa-foundation" version = "0.1.2" @@ -676,9 +660,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" dependencies = [ "crossbeam-utils", ] @@ -717,9 +701,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -727,9 +711,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core-graphics" @@ -759,9 +743,9 @@ dependencies = [ [[package]] name = "core-graphics-types" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -770,13 +754,13 @@ dependencies = [ [[package]] name = "core-text" -version = "19.2.0" +version = "20.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" +checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5" dependencies = [ "core-foundation", - "core-graphics 0.22.3", - "foreign-types 0.3.2", + "core-graphics 0.23.1", + "foreign-types 0.5.0", "libc", ] @@ -860,14 +844,14 @@ dependencies = [ [[package]] name = "crossfont" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21fd3add36ea31aba1520aa5288714dd63be506106753226d0eb387a93bc9c45" +checksum = "3eb5a3822b594afc99b503cc1859b94686d3c3efdd60507a28587dab80ee1071" dependencies = [ - "cocoa", + "cocoa 0.25.0", "core-foundation", "core-foundation-sys", - "core-graphics 0.22.3", + "core-graphics 0.23.1", "core-text", "dwrote", "foreign-types 0.5.0", @@ -1154,9 +1138,30 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encase" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "8fce2eeef77fd4a293a54b62aa00ac9daebfbcda4bf8998c5a815635b004aa1c" +dependencies = [ + "const_panic", + "encase_derive", + "glam 0.24.2", + "thiserror", +] + +[[package]] +name = "encase_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e520cde08cbf4f7cc097f61573ec06ce467019803de8ae82fb2823fa1554a0e" +dependencies = [ + "encase_derive_impl", +] [[package]] name = "encase_derive_impl" @@ -1199,12 +1204,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.1" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1302,7 +1307,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -1408,14 +1413,13 @@ checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-lite" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3831c2651acb5177cbd83943f3d9c8912c5ad03c76afcc0e9511ba568ec5ebb" +checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" dependencies = [ "fastrand", "futures-core", "futures-io", - "memchr", "parking", "pin-project-lite", ] @@ -1428,7 +1432,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -1486,9 +1490,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "gl_generator" @@ -1531,7 +1535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "444c9ad294fdcaf20ccf6726b78f380b5450275540c9b68ab62f49726ad1c713" dependencies = [ "cgl", - "cocoa", + "cocoa 0.24.1", "core-foundation", "glutin_egl_sys", "glutin_gles2_sys", @@ -1659,9 +1663,9 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", "allocator-api2", @@ -1953,9 +1957,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lock_api" @@ -2380,7 +2384,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -2419,9 +2423,9 @@ dependencies = [ [[package]] name = "objc-sys" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e1d07c6eab1ce8b6382b8e3c7246fe117ff3f8b34be065f5ebace6749fe845" +checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459" [[package]] name = "objc2" @@ -2450,9 +2454,9 @@ dependencies = [ [[package]] name = "object" -version = "0.31.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -2471,9 +2475,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "orbclient" -version = "0.3.45" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "221d488cd70617f1bd599ed8ceb659df2147d9393717954d82a0f5e8032a6ab1" +checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" dependencies = [ "libredox", ] @@ -2530,7 +2534,8 @@ dependencies = [ "petgraph", "redox_syscall 0.4.1", "smallvec", - "windows-targets 0.48.1", + "thread-id", + "windows-targets 0.48.5", ] [[package]] @@ -2552,7 +2557,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 1.9.3", + "indexmap", ] [[package]] @@ -2578,7 +2583,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -2656,16 +2661,16 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53b6af1f60f36f8c2ac2aad5459d75a5a9b4be1e8cdd40264f315d78193e531" +checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" dependencies = [ "cfg-if", "concurrent-queue", "pin-project-lite", "rustix", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2720,10 +2725,10 @@ dependencies = [ ] [[package]] -name = "quote" -version = "1.0.31" +name = "proc-macro-rules-macros" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "207fffb0fe655d1d47f6af98cc2793405e85929bdbc420d685554ff07be27ac7" dependencies = [ "once_cell", "proc-macro2", @@ -2733,9 +2738,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -2809,6 +2814,32 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" +[[package]] +name = "raw-window-handle" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -2829,9 +2860,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.1" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", @@ -2841,9 +2872,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -2915,15 +2946,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.4" +version = "0.38.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" dependencies = [ "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3016,22 +3047,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.186" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.186" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -3118,9 +3149,9 @@ dependencies = [ [[package]] name = "slotmap" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" dependencies = [ "version_check", ] @@ -3196,9 +3227,9 @@ dependencies = [ [[package]] name = "sourcemap" -version = "6.3.0" +version = "7.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8df03d85f2767c45e61b4453eb6144153c80399e4fdd6407a6d16cb87cc0347" +checksum = "10da010a590ed2fa9ca8467b00ce7e9c5a8017742c0c09c45450efc172208c4b" dependencies = [ "data-encoding", "debugid", @@ -3291,9 +3322,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -3326,7 +3357,26 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", +] + +[[package]] +name = "thread-id" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0ec81c46e9eb50deaa257be2f148adf052d1fb7701cfd55ccfab2525280b70b" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", ] [[package]] @@ -3431,7 +3481,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -3678,7 +3728,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", "wasm-bindgen-shared", ] @@ -3712,7 +3762,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3725,9 +3775,9 @@ checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasm-bindgen-test" -version = "0.3.38" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6433b7c56db97397842c46b67e11873eda263170afeb3a2dc74a7cb370fee0d" +checksum = "2cf9242c0d27999b831eae4767b2a146feb0b27d332d553e605864acd2afd403" dependencies = [ "console_error_panic_hook", "js-sys", @@ -3739,9 +3789,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.38" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "493fcbab756bb764fa37e6bee8cec2dd709eb4273d06d0c282a5e74275ded735" +checksum = "794645f5408c9a039fd09f4d113cdfb2e7eba5ff1956b07bcf701cf4b394fe89" dependencies = [ "proc-macro2", "quote", @@ -3983,63 +4033,6 @@ dependencies = [ "wgpu-types", ] -[[package]] -name = "wgpu-boids-example" -version = "0.17.0" -dependencies = [ - "bytemuck", - "nanorand", - "wasm-bindgen-test", - "wgpu", - "wgpu-example", - "wgpu-test", - "winit 0.28.6", -] - -[[package]] -name = "wgpu-bunnymark-example" -version = "0.17.0" -dependencies = [ - "bytemuck", - "glam", - "nanorand", - "png", - "wasm-bindgen-test", - "wgpu", - "wgpu-example", - "wgpu-test", - "winit 0.28.6", -] - -[[package]] -name = "wgpu-capture-example" -version = "0.17.0" -dependencies = [ - "bytemuck", - "console_error_panic_hook", - "console_log", - "env_logger", - "futures-intrusive", - "png", - "pollster", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "wgpu", - "wgpu-example", - "winit 0.28.6", -] - -[[package]] -name = "wgpu-conservative-raster-example" -version = "0.17.0" -dependencies = [ - "wasm-bindgen-test", - "wgpu", - "wgpu-example", - "wgpu-test", - "winit 0.28.6", -] - [[package]] name = "wgpu-core" version = "0.18.0" @@ -4068,19 +4061,7 @@ name = "wgpu-examples" version = "0.18.0" dependencies = [ "bytemuck", - "glam", - "wasm-bindgen-test", - "wgpu", - "wgpu-example", - "wgpu-test", - "winit 0.28.6", -] - -[[package]] -name = "wgpu-example" -version = "0.17.0" -dependencies = [ - "async-executor", + "cfg-if", "console_error_panic_hook", "console_log", "encase", @@ -4088,7 +4069,7 @@ dependencies = [ "fern", "flume", "getrandom", - "glam", + "glam 0.24.2", "js-sys", "ktx2", "log", @@ -4151,67 +4132,7 @@ dependencies = [ "web-sys", "wgpu-types", "winapi", - "winit 0.28.6", -] - -[[package]] -name = "wgpu-hello-compute-example" -version = "0.17.0" -dependencies = [ - "bytemuck", - "console_error_panic_hook", - "console_log", - "env_logger", - "futures-intrusive", - "log", - "pollster", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "wgpu", - "wgpu-test", - "winit 0.28.6", -] - -[[package]] -name = "wgpu-hello-example" -version = "0.17.0" -dependencies = [ - "console_error_panic_hook", - "console_log", - "env_logger", - "glam", - "log", - "pollster", - "wasm-bindgen-futures", - "wgpu", - "wgpu-test", -] - -[[package]] -name = "wgpu-hello-triangle-example" -version = "0.17.0" -dependencies = [ - "bytemuck", - "console_error_panic_hook", - "console_log", - "env_logger", - "pollster", - "wasm-bindgen-futures", - "web-sys", - "wgpu", - "winit 0.28.6", -] - -[[package]] -name = "wgpu-hello-windows-example" -version = "0.17.0" -dependencies = [ - "bytemuck", - "console_error_panic_hook", - "env_logger", - "pollster", - "wgpu", - "winit 0.28.6", + "winit 0.29.4", ] [[package]] @@ -4232,68 +4153,9 @@ dependencies = [ name = "wgpu-macros" version = "0.18.0" dependencies = [ - "bytemuck", - "glam", - "wasm-bindgen-test", - "wgpu", - "wgpu-example", - "wgpu-test", - "winit 0.28.6", -] - -[[package]] -name = "wgpu-msaa-line-example" -version = "0.17.0" -dependencies = [ - "bytemuck", - "glam", - "log", - "wasm-bindgen-test", - "wgpu", - "wgpu-example", - "wgpu-test", - "winit 0.28.6", -] - -[[package]] -name = "wgpu-shadow-example" -version = "0.17.0" -dependencies = [ - "bytemuck", - "glam", - "wasm-bindgen-test", - "wgpu", - "wgpu-example", - "wgpu-test", - "winit 0.28.6", -] - -[[package]] -name = "wgpu-skybox-example" -version = "0.17.0" -dependencies = [ - "bytemuck", - "ddsfile", - "glam", - "log", - "obj", - "wasm-bindgen-test", - "wgpu", - "wgpu-example", - "wgpu-test", - "winit 0.28.6", -] - -[[package]] -name = "wgpu-stencil-triangle-example" -version = "0.17.0" -dependencies = [ - "bytemuck", - "wasm-bindgen-test", - "wgpu", - "wgpu-example", - "wgpu-test", - "winit 0.28.6", + "heck", + "quote", + "syn 2.0.39", ] [[package]] @@ -4308,6 +4170,9 @@ dependencies = [ "console_log", "ctor", "env_logger", + "futures-lite", + "glam 0.24.2", + "heck", "image", "js-sys", "libtest-mimic", @@ -4341,21 +4206,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wgpu-water-example" -version = "0.17.0" -dependencies = [ - "bytemuck", - "glam", - "nanorand", - "noise", - "wasm-bindgen-test", - "wgpu", - "wgpu-example", - "wgpu-test", - "winit 0.28.6", -] - [[package]] name = "which" version = "4.4.2" @@ -4464,6 +4314,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -4494,6 +4353,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -4506,6 +4380,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" @@ -4524,6 +4404,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.36.1" @@ -4542,6 +4428,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.36.1" @@ -4560,6 +4452,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" @@ -4578,6 +4476,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -4590,6 +4494,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" @@ -4608,6 +4518,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winit" version = "0.27.5" @@ -4615,7 +4531,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c" dependencies = [ "bitflags 1.3.2", - "cocoa", + "cocoa 0.24.1", "core-foundation", "core-graphics 0.22.3", "dispatch", @@ -4691,9 +4607,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.5.0" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" dependencies = [ "memchr", ] @@ -4780,18 +4696,18 @@ checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" [[package]] name = "zerocopy" -version = "0.7.26" +version = "0.7.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" +checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.26" +version = "0.7.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" +checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" dependencies = [ "proc-macro2", "quote", diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 93741d9d74..f11200f043 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -4,10 +4,7 @@ use crate::{ hal_api::HalApi, id::{ BindGroupId, BindGroupLayoutId, BufferId, PipelineLayoutId, SamplerId, TextureId, - TextureViewId, - }, - id::{ - BindGroupLayoutId, BufferId, DeviceId, SamplerId, TextureId, TextureViewId, TlasId, Valid, + TextureViewId, DeviceId, TlasId, Valid, }, init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction}, resource::{Resource, ResourceInfo, ResourceType}, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 4bc6ea6090..311788e50d 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -218,7 +218,7 @@ pub trait Api: Clone + fmt::Debug + Sized { type RenderPipeline: fmt::Debug + WasmNotSendSync; type ComputePipeline: fmt::Debug + WasmNotSendSync; - type AccelerationStructure: fmt::Debug + WasmNotSend + WasmNotSync + 'static; + type AccelerationStructure: fmt::Debug + WasmNotSendSync + 'static; } pub trait Instance: Sized + WasmNotSendSync { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 18cc9558d6..f7e26c9cc0 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -849,7 +849,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native-only feature. - const RAY_QUERY = 1 << 64; + const RAY_QUERY = 1 << 63; } } diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 7cdbcef968..8bdec9921b 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -1159,59 +1159,109 @@ pub(crate) struct DeviceRequest { } #[cfg(any( - not(target_arch = "wasm32"), - all( - feature = "fragile-send-sync-non-atomic-wasm", - not(target_feature = "atomics") - ) +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) ))] pub type BufferMapCallback = Box) + Send + 'static>; +#[cfg(not(any( +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) +)))] +pub type BufferMapCallback = Box) + 'static>; #[cfg(any( - not(target_arch = "wasm32"), - all( - feature = "fragile-send-sync-non-atomic-wasm", - not(target_feature = "atomics") - ) +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) ))] pub(crate) type AdapterRequestDeviceFuture = - Box> + Send>; +Box> + Send>; +#[cfg(not(any( +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) +)))] +pub(crate) type AdapterRequestDeviceFuture = +Box>>; #[cfg(any( - not(target_arch = "wasm32"), - all( - feature = "fragile-send-sync-non-atomic-wasm", - not(target_feature = "atomics") - ) +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) ))] pub type InstanceRequestAdapterFuture = - Box)>> + Send>; +Box)>> + Send>; +#[cfg(not(any( +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) +)))] +pub type InstanceRequestAdapterFuture = +Box)>>>; #[cfg(any( - not(target_arch = "wasm32"), - all( - feature = "fragile-send-sync-non-atomic-wasm", - not(target_feature = "atomics") - ) +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) ))] pub type DevicePopErrorFuture = Box> + Send>; +#[cfg(not(any( +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) +)))] +pub type DevicePopErrorFuture = Box>>; #[cfg(any( - not(target_arch = "wasm32"), - all( - feature = "fragile-send-sync-non-atomic-wasm", - not(target_feature = "atomics") - ) +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) ))] pub type SubmittedWorkDoneCallback = Box; +#[cfg(not(any( +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) +)))] +pub type SubmittedWorkDoneCallback = Box; #[cfg(any( - not(target_arch = "wasm32"), - all( - feature = "fragile-send-sync-non-atomic-wasm", - not(target_feature = "atomics") - ) +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) ))] pub type DeviceLostCallback = Box; +#[cfg(not(any( +not(target_arch = "wasm32"), +all( +feature = "fragile-send-sync-non-atomic-wasm", +not(target_feature = "atomics") +) +)))] +pub type DeviceLostCallback = Box; /// An object safe variant of [`Context`] implemented by all types that implement [`Context`]. pub(crate) trait DynContext: Debug + WasmNotSendSync { diff --git a/xtask/Cargo.lock b/xtask/Cargo.lock deleted file mode 100644 index 50b572cd03..0000000000 --- a/xtask/Cargo.lock +++ /dev/null @@ -1,56 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "anyhow" -version = "1.0.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" - -[[package]] -name = "env_logger" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" -dependencies = [ - "log", -] - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "pico-args" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" - -[[package]] -name = "xshell" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2107fe03e558353b4c71ad7626d58ed82efaf56c54134228608893c77023ad" -dependencies = [ - "xshell-macros", -] - -[[package]] -name = "xshell-macros" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e2c411759b501fb9501aac2b1b2d287a6e93e5bdcf13c25306b23e1b716dd0e" - -[[package]] -name = "xtask" -version = "0.1.0" -dependencies = [ - "anyhow", - "env_logger", - "log", - "pico-args", - "xshell", -] From d4868376625efe09f50ebbec941344fe284d75d7 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 4 Dec 2023 16:50:06 +1300 Subject: [PATCH 100/146] few more patches --- wgpu-core/src/binding_model.rs | 2 +- wgpu-core/src/hub.rs | 4 ++-- wgpu-core/src/resource.rs | 29 +++++++++++++++++++---------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index f11200f043..197d76c4a0 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -4,7 +4,7 @@ use crate::{ hal_api::HalApi, id::{ BindGroupId, BindGroupLayoutId, BufferId, PipelineLayoutId, SamplerId, TextureId, - TextureViewId, DeviceId, TlasId, Valid, + TextureViewId, TlasId, }, init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction}, resource::{Resource, ResourceInfo, ResourceType}, diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 6f0a984faa..f003b687b7 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -197,8 +197,8 @@ pub struct Hub { pub textures: Registry>, pub texture_views: Registry>, pub samplers: Registry>, - pub blas_s: Registry, id::BlasId, F>, - pub tlas_s: Registry, id::TlasId, F>, + pub blas_s: Registry, id::BlasId>, + pub tlas_s: Registry, id::TlasId>, } impl Hub { diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 9ae5b62af2..6f830d5f6e 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -38,6 +38,7 @@ use std::{ }; use std::num::NonZeroU64; +use crate::id::{BlasId, TlasId}; /// Information about the wgpu-core resource. /// @@ -1312,8 +1313,8 @@ pub type TlasDescriptor<'a> = wgt::CreateTlasDescriptor>; pub struct Blas { pub(crate) raw: Option, - pub(crate) device_id: Stored, - pub(crate) life_guard: LifeGuard, + pub(crate) device: Arc>, + pub(crate) info: ResourceInfo, pub(crate) size_info: hal::AccelerationStructureBuildSizes, pub(crate) sizes: wgt::BlasGeometrySizeDescriptors, pub(crate) flags: wgt::AccelerationStructureFlags, @@ -1322,18 +1323,22 @@ pub struct Blas { pub(crate) handle: u64, } -impl Resource for Blas { +impl Resource for Blas { const TYPE: &'static str = "Blas"; - fn life_guard(&self) -> &LifeGuard { - &self.life_guard + fn as_info(&self) -> &ResourceInfo { + &self.info + } + + fn as_info_mut(&mut self) -> &mut ResourceInfo { + &mut self.info } } pub struct Tlas { pub(crate) raw: Option, - pub(crate) device_id: Stored, - pub(crate) life_guard: LifeGuard, + pub(crate) device: Arc>, + pub(crate) info: ResourceInfo, pub(crate) size_info: hal::AccelerationStructureBuildSizes, pub(crate) max_instance_count: u32, pub(crate) flags: wgt::AccelerationStructureFlags, @@ -1343,10 +1348,14 @@ pub struct Tlas { pub(crate) instance_buffer: Option, } -impl Resource for Tlas { +impl Resource for Tlas { const TYPE: &'static str = "Tlas"; - fn life_guard(&self) -> &LifeGuard { - &self.life_guard + fn as_info(&self) -> &ResourceInfo { + &self.info + } + + fn as_info_mut(&mut self) -> &mut ResourceInfo { + &mut self.info } } From 96bb3e7da1f6bf8c53a4ca544f6f935ff9151904 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Fri, 8 Dec 2023 15:53:31 +1300 Subject: [PATCH 101/146] fix more compile errors --- Cargo.lock | 1 + wgpu-core/src/command/compute.rs | 19 +- wgpu-core/src/command/mod.rs | 4 +- wgpu-core/src/command/ray_tracing.rs | 321 +++++++++++++++++---------- wgpu-core/src/command/render.rs | 20 +- wgpu-core/src/device/life.rs | 14 +- wgpu-core/src/device/queue.rs | 30 +-- wgpu-core/src/device/ray_tracing.rs | 203 ++++++++--------- wgpu-core/src/device/resource.rs | 12 +- wgpu-core/src/hub.rs | 4 +- wgpu-core/src/resource.rs | 18 +- 11 files changed, 373 insertions(+), 273 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b557867719..4106356c6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4150,6 +4150,7 @@ dependencies = [ "ctor", "env_logger", "futures-lite", + "glam", "heck", "image", "js-sys", diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index c70a709172..7b5d2a451c 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -406,6 +406,7 @@ impl Global { let query_set_guard = hub.query_sets.read(); let buffer_guard = hub.buffers.read(); let texture_guard = hub.textures.read(); + let tlas_guard = hub.tlas_s.read(); let mut state = State { binder: Binder::new(), @@ -539,14 +540,16 @@ impl Global { .extend(texture_memory_actions.register_init_action(action)); } - cmd_buf.tlas_actions.extend( - bind_group.used.acceleration_structures.used().map(|id| { - cmd_buf.trackers.tlas_s.add_single(&tlas_guard, id.0); - crate::ray_tracing::TlasAction { - id: id.0, - kind: crate::ray_tracing::TlasActionKind::Use, - } - }), + let used_resource = bind_group.used.acceleration_structures.used_resources().map(|tlas| { + tracker.tlas_s.add_single(&tlas_guard, tlas.as_info().id()); + crate::ray_tracing::TlasAction { + id: tlas.as_info().id(), + kind: crate::ray_tracing::TlasActionKind::Use, + } + }); + + cmd_buf_data.tlas_actions.extend( + used_resource ); let pipeline_layout = state.binder.pipeline_layout.clone(); diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index e5cdf627c5..1314cfed26 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -276,8 +276,8 @@ impl CommandBuffer { trackers: data.trackers, buffer_memory_init_actions: data.buffer_memory_init_actions, texture_memory_actions: data.texture_memory_actions, - blas_actions: self.blas_actions, - tlas_actions: self.tlas_actions, + blas_actions: data.blas_actions, + tlas_actions: data.tlas_actions, } } diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 1098138e15..cabc5c85ad 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -3,7 +3,6 @@ use crate::{ device::queue::TempResource, global::Global, hal_api::HalApi, - hub::Token, id::{BlasId, CommandEncoderId, TlasId}, identity::GlobalIdentityHandlerFactory, init_tracker::MemoryInitKind, @@ -17,10 +16,15 @@ use crate::{ FastHashSet, }; -use hal::{CommandEncoder, Device}; use wgt::{math::align_to, BufferUsages}; use std::{cmp::max, iter, num::NonZeroU64, ops::Range, ptr}; +use std::ops::Deref; +use std::sync::Arc; +use parking_lot::Mutex; +use hal::{BufferUses, CommandEncoder, Device}; +use crate::resource::{Buffer, Resource, ResourceInfo, StagingBuffer}; +use crate::track::PendingTransition; use super::BakedCommands; @@ -37,16 +41,14 @@ impl Global { profiling::scope!("CommandEncoder::build_acceleration_structures_unsafe_tlas"); let hub = A::hub(self); - let mut token = Token::root(); - let (mut device_guard, mut token) = hub.devices.write(&mut token); - let (mut cmd_buf_guard, mut token) = hub.command_buffers.write(&mut token); - let cmd_buf = CommandBuffer::get_encoder_mut(&mut *cmd_buf_guard, command_encoder_id)?; - let (buffer_guard, mut token) = hub.buffers.read(&mut token); - let (blas_guard, mut token) = hub.blas_s.read(&mut token); - let (tlas_guard, _) = hub.tlas_s.read(&mut token); + let mut device_guard = hub.devices.write(); + let cmd_buf = CommandBuffer::get_encoder(hub, command_encoder_id)?; + let buffer_guard = hub.buffers.read(); + let blas_guard = hub.blas_s.read(); + let tlas_guard = hub.tlas_s.read(); - let device = &mut device_guard[cmd_buf.device_id.value]; + let device = &mut device_guard.get(cmd_buf.device.as_info().id()).unwrap(); let build_command_index = NonZeroU64::new( device @@ -86,9 +88,8 @@ impl Global { #[cfg(feature = "trace")] let trace_tlas: Vec = tlas_iter.collect(); - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf.commands { + 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(), @@ -134,9 +135,10 @@ impl Global { let mut scratch_buffer_blas_size = 0; let mut blas_storage = Vec::<(&Blas, hal::AccelerationStructureEntries, u64)>::new(); - + let mut cmd_buf_data = cmd_buf.data.lock(); + let cmd_buf_data = cmd_buf_data.as_mut().unwrap(); for entry in blas_iter { - let blas = cmd_buf + let blas = cmd_buf_data .trackers .blas_s .add_single(&blas_guard, entry.blas_id) @@ -146,7 +148,7 @@ impl Global { return Err(BuildAccelerationStructureError::InvalidBlas(entry.blas_id)); } - cmd_buf.blas_actions.push(BlasAction { + cmd_buf_data.blas_actions.push(BlasAction { id: entry.blas_id, kind: crate::ray_tracing::BlasActionKind::Build(build_command_index), }); @@ -173,11 +175,11 @@ impl Global { || size_desc.vertex_format != mesh.size.vertex_format || size_desc.index_count.is_none() != mesh.size.index_count.is_none() || (size_desc.index_count.is_none() - || size_desc.index_count.unwrap() < mesh.size.index_count.unwrap()) + || size_desc.index_count.unwrap() < mesh.size.index_count.unwrap()) || size_desc.index_format.is_none() != mesh.size.index_format.is_none() || (size_desc.index_format.is_none() - || size_desc.index_format.unwrap() - != mesh.size.index_format.unwrap()) + || size_desc.index_format.unwrap() + != mesh.size.index_format.unwrap()) { return Err( BuildAccelerationStructureError::IncompatibleBlasBuildSizes( @@ -193,13 +195,19 @@ impl Global { } let vertex_buffer = { - let (vertex_buffer, vertex_pending) = cmd_buf + let (vertex_buffer, vertex_pending) = cmd_buf_data .trackers .buffers .set_single( - &*buffer_guard, - mesh.vertex_buffer, - hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + &*match buffer_guard.get(mesh.vertex_buffer) { + Ok(buffer) => buffer, + Err(_) => { + return Err(BuildAccelerationStructureError::InvalidBuffer( + mesh.vertex_buffer, + )) + } + }, + BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer( mesh.vertex_buffer, @@ -215,7 +223,7 @@ impl Global { ); } if let Some(barrier) = - vertex_pending.map(|pending| pending.into_hal(vertex_buffer)) + vertex_pending.map(|pending| pending.into_hal(&vertex_buffer)) { input_barriers.push(barrier); } @@ -234,9 +242,9 @@ impl Global { } let vertex_buffer_offset = mesh.first_vertex as u64 * mesh.vertex_stride; - cmd_buf.buffer_memory_init_actions.extend( - vertex_buffer.initialization_status.create_action( - mesh.vertex_buffer, + cmd_buf_data.buffer_memory_init_actions.extend( + vertex_buffer.initialization_status.read().create_action( + buffer_guard.get(mesh.vertex_buffer).unwrap(), vertex_buffer_offset ..(vertex_buffer_offset + mesh.size.vertex_count as u64 * mesh.vertex_stride), @@ -256,12 +264,14 @@ impl Global { ), ); } - let (index_buffer, index_pending) = cmd_buf + let (index_buffer, index_pending) = cmd_buf_data .trackers .buffers .set_single( - &*buffer_guard, - index_id, + &*match buffer_guard.get(index_id) { + Ok(buffer) => buffer, + Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(index_id)) }, + }, hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer(index_id))?; @@ -277,7 +287,7 @@ impl Global { ); } if let Some(barrier) = - index_pending.map(|pending| pending.into_hal(index_buffer)) + index_pending.map(|pending| pending.into_hal(&index_buffer)) { input_barriers.push(barrier); } @@ -315,9 +325,12 @@ impl Global { ); } - cmd_buf.buffer_memory_init_actions.extend( - index_buffer.initialization_status.create_action( - index_id, + cmd_buf_data.buffer_memory_init_actions.extend( + index_buffer.initialization_status.read().create_action( + match buffer_guard.get(index_id) { + Ok(buffer) => buffer, + Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( index_id, )), + }, mesh.index_buffer_offset.unwrap() ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), MemoryInitKind::NeedsInitializedMemory, @@ -335,12 +348,14 @@ impl Global { ), ); } - let (transform_buffer, transform_pending) = cmd_buf + let (transform_buffer, transform_pending) = cmd_buf_data .trackers .buffers .set_single( - &*buffer_guard, - transform_id, + &*match buffer_guard.get(transform_id) { + Ok(buffer) => buffer, + Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(transform_id)) }, + }, hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer( @@ -357,7 +372,7 @@ impl Global { ); } if let Some(barrier) = - transform_pending.map(|pending| pending.into_hal(transform_buffer)) + transform_pending.map(|pending| pending.into_hal(&transform_buffer)) { input_barriers.push(barrier); } @@ -380,9 +395,9 @@ impl Global { ), ); } - cmd_buf.buffer_memory_init_actions.extend( - transform_buffer.initialization_status.create_action( - transform_id, + cmd_buf_data.buffer_memory_init_actions.extend( + transform_buffer.initialization_status.read().create_action( + buffer_guard.get(transform_id).unwrap(), mesh.transform_buffer_offset.unwrap() ..(mesh.index_buffer_offset.unwrap() + 48), MemoryInitKind::NeedsInitializedMemory, @@ -434,18 +449,21 @@ impl Global { } } + let mut scratch_buffer_tlas_size = 0; let mut tlas_storage = Vec::<(&Tlas, hal::AccelerationStructureEntries, u64)>::new(); for entry in tlas_iter { let instance_buffer = { - let (instance_buffer, instance_pending) = cmd_buf + let (instance_buffer, instance_pending) = cmd_buf_data .trackers .buffers .set_single( - &*buffer_guard, - entry.instance_buffer_id, - hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + &*match buffer_guard.get(entry.instance_buffer_id) { + Ok(buffer) => buffer, + Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer(entry.instance_buffer_id, )), + }, + BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer( entry.instance_buffer_id, @@ -459,14 +477,14 @@ impl Global { )); } if let Some(barrier) = - instance_pending.map(|pending| pending.into_hal(instance_buffer)) + instance_pending.map(|pending| pending.into_hal(instance_buffer.as_ref())) { input_barriers.push(barrier); } instance_raw }; - let tlas = cmd_buf + let tlas = cmd_buf_data .trackers .tlas_s .add_single(&tlas_guard, entry.tlas_id) @@ -476,7 +494,7 @@ impl Global { return Err(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id)); } - cmd_buf.tlas_actions.push(TlasAction { + cmd_buf_data.tlas_actions.push(TlasAction { id: entry.tlas_id, kind: crate::ray_tracing::TlasActionKind::Build { build_index: build_command_index, @@ -493,7 +511,7 @@ impl Global { tlas_storage.push(( tlas, hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { - buffer: Some(instance_buffer), + buffer: Some(&instance_buffer), offset: 0, count: entry.instance_count, }), @@ -507,7 +525,7 @@ impl Global { let scratch_buffer = unsafe { device - .raw + .raw() .create_buffer(&hal::BufferDescriptor { label: Some("(wgpu) scratch buffer"), size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), @@ -562,7 +580,7 @@ impl Global { let blas_present = !blas_storage.is_empty(); let tlas_present = !tlas_storage.is_empty(); - let cmd_buf_raw = cmd_buf.encoder.open(); + let cmd_buf_raw = cmd_buf_data.encoder.open(); unsafe { cmd_buf_raw.transition_buffers(input_barriers.into_iter()); @@ -609,11 +627,29 @@ impl Global { ); } } - + let scratch_mapping = unsafe { + device + .raw() + .map_buffer( + &scratch_buffer, + 0..max(scratch_buffer_blas_size, scratch_buffer_tlas_size), + ) + .map_err(crate::device::DeviceError::from)? + }; device .pending_writes + .lock() + .as_mut() + .unwrap() .temp_resources - .push(TempResource::Buffer(scratch_buffer)); + .push(TempResource::StagingBuffer( + Arc::new(StagingBuffer { + raw: Mutex::new(Some(scratch_buffer)), + device: device.clone(), + size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), + info: ResourceInfo::new("Ratracing scratch buffer"), + is_coherent: scratch_mapping.is_coherent, + }))); Ok(()) } @@ -627,16 +663,14 @@ impl Global { profiling::scope!("CommandEncoder::build_acceleration_structures"); let hub = A::hub(self); - let mut token = Token::root(); - let (mut device_guard, mut token) = hub.devices.write(&mut token); - let (mut cmd_buf_guard, mut token) = hub.command_buffers.write(&mut token); - let cmd_buf = CommandBuffer::get_encoder_mut(&mut *cmd_buf_guard, command_encoder_id)?; - let (buffer_guard, mut token) = hub.buffers.read(&mut token); - let (blas_guard, mut token) = hub.blas_s.read(&mut token); - let (tlas_guard, _) = hub.tlas_s.read(&mut token); + let mut device_guard = hub.devices.write(); + let cmd_buf = CommandBuffer::get_encoder(hub, command_encoder_id)?; + let buffer_guard = hub.buffers.read(); + let blas_guard = hub.blas_s.read(); + let tlas_guard = hub.tlas_s.read(); - let device = &mut device_guard[cmd_buf.device_id.value]; + let device = &cmd_buf.device; let build_command_index = NonZeroU64::new( device @@ -697,7 +731,7 @@ impl Global { .collect(); #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf.commands { + if let Some(ref mut list) = cmd_buf.data.lock().as_mut().unwrap().commands { list.push(crate::device::trace::Command::BuildAccelerationStructures { blas: trace_blas.clone(), tlas: trace_tlas.clone(), @@ -754,9 +788,10 @@ impl Global { let mut scratch_buffer_blas_size = 0; let mut blas_storage = Vec::<(&Blas, hal::AccelerationStructureEntries, u64)>::new(); - + let mut cmd_buf_data = cmd_buf.data.lock(); + let cmd_buf_data = cmd_buf_data.as_mut().unwrap(); for entry in blas_iter { - let blas = cmd_buf + let blas = cmd_buf_data .trackers .blas_s .add_single(&blas_guard, entry.blas_id) @@ -766,7 +801,7 @@ impl Global { return Err(BuildAccelerationStructureError::InvalidBlas(entry.blas_id)); } - cmd_buf.blas_actions.push(BlasAction { + cmd_buf_data.blas_actions.push(BlasAction { id: entry.blas_id, kind: crate::ray_tracing::BlasActionKind::Build(build_command_index), }); @@ -813,12 +848,14 @@ impl Global { } let vertex_buffer = { - let (vertex_buffer, vertex_pending) = cmd_buf + let (vertex_buffer, vertex_pending) = cmd_buf_data .trackers .buffers .set_single( - &*buffer_guard, - mesh.vertex_buffer, + &*match buffer_guard.get(mesh.vertex_buffer) { + Ok(buffer) => buffer, + Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( mesh.vertex_buffer, )), + }, hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer( @@ -835,7 +872,7 @@ impl Global { ); } if let Some(barrier) = - vertex_pending.map(|pending| pending.into_hal(vertex_buffer)) + vertex_pending.map(|pending| pending.into_hal(vertex_buffer.deref())) { input_barriers.push(barrier); } @@ -854,9 +891,12 @@ impl Global { } let vertex_buffer_offset = mesh.first_vertex as u64 * mesh.vertex_stride; - cmd_buf.buffer_memory_init_actions.extend( - vertex_buffer.initialization_status.create_action( - mesh.vertex_buffer, + cmd_buf_data.buffer_memory_init_actions.extend( + vertex_buffer.initialization_status.read().create_action( + match buffer_guard.get(mesh.vertex_buffer) { + Ok(buf) => buf, + Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer)), + }, vertex_buffer_offset ..(vertex_buffer_offset + mesh.size.vertex_count as u64 * mesh.vertex_stride), @@ -876,12 +916,14 @@ impl Global { ), ); } - let (index_buffer, index_pending) = cmd_buf + let (index_buffer, index_pending) = cmd_buf_data .trackers .buffers .set_single( - &*buffer_guard, - index_id, + &*match buffer_guard.get(index_id) { + Ok(buffer) => buffer, + Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( index_id, )), + }, hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer(index_id))?; @@ -897,7 +939,7 @@ impl Global { ); } if let Some(barrier) = - index_pending.map(|pending| pending.into_hal(index_buffer)) + index_pending.map(|pending| pending.into_hal(index_buffer.deref())) { input_barriers.push(barrier); } @@ -935,9 +977,12 @@ impl Global { ); } - cmd_buf.buffer_memory_init_actions.extend( - index_buffer.initialization_status.create_action( - index_id, + cmd_buf_data.buffer_memory_init_actions.extend( + index_buffer.initialization_status.read().create_action( + match buffer_guard.get(index_id) { + Ok(buffer) => buffer, + Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( index_id, )), + }, mesh.index_buffer_offset.unwrap() ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), MemoryInitKind::NeedsInitializedMemory, @@ -955,18 +1000,20 @@ impl Global { ), ); } - let (transform_buffer, transform_pending) = cmd_buf + let (transform_buffer, transform_pending) = cmd_buf_data .trackers .buffers .set_single( - &*buffer_guard, - transform_id, + &*match buffer_guard.get(transform_id) { + Ok(buffer) => buffer, + Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( transform_id, )), + }, hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer( transform_id, ))?; - let transform_raw = transform_buffer.raw.as_ref().ok_or( + let transform_raw = transform_buffer.raw.ok_or( BuildAccelerationStructureError::InvalidBuffer(transform_id), )?; if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { @@ -977,7 +1024,7 @@ impl Global { ); } if let Some(barrier) = - transform_pending.map(|pending| pending.into_hal(transform_buffer)) + transform_pending.map(|pending| pending.into_hal(transform_buffer.deref())) { input_barriers.push(barrier); } @@ -1000,9 +1047,12 @@ impl Global { ), ); } - cmd_buf.buffer_memory_init_actions.extend( - transform_buffer.initialization_status.create_action( - transform_id, + cmd_buf_data.buffer_memory_init_actions.extend( + transform_buffer.initialization_status.read().create_action( + match buffer_guard.get(transform_id) { + Ok(buf) => buf, + Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer(transform_id)), + }, mesh.transform_buffer_offset.unwrap() ..(mesh.index_buffer_offset.unwrap() + 48), MemoryInitKind::NeedsInitializedMemory, @@ -1027,7 +1077,7 @@ impl Global { count: mesh.size.index_count.unwrap(), } }), - transform: transform_buffer.map(|transform_buffer| { + transform: transform_buffer.as_ref().map(|transform_buffer| { hal::AccelerationStructureTriangleTransform { buffer: transform_buffer, offset: mesh.transform_buffer_offset.unwrap() as u32, @@ -1064,7 +1114,7 @@ impl Global { let mut instance_buffer_staging_source = Vec::::new(); for entry in tlas_iter { - let tlas = cmd_buf + let tlas = cmd_buf_data .trackers .tlas_s .add_single(&tlas_guard, entry.tlas_id) @@ -1091,7 +1141,7 @@ impl Global { entry.tlas_id, )); } - let blas = cmd_buf + let blas = cmd_buf_data .trackers .blas_s .add_single(&blas_guard, instance.blas_id) @@ -1106,13 +1156,13 @@ impl Global { dependencies.push(instance.blas_id); - cmd_buf.blas_actions.push(BlasAction { + cmd_buf_data.blas_actions.push(BlasAction { id: instance.blas_id, kind: crate::ray_tracing::BlasActionKind::Use, }); } - cmd_buf.tlas_actions.push(TlasAction { + cmd_buf_data.tlas_actions.push(TlasAction { id: entry.tlas_id, kind: crate::ray_tracing::TlasActionKind::Build { build_index: build_command_index, @@ -1131,7 +1181,7 @@ impl Global { tlas_storage.push(( tlas, hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { - buffer: Some(tlas.instance_buffer.as_ref().unwrap()), + buffer: Some(tlas.instance_buffer.read().as_ref().unwrap()), offset: 0, count: instance_count, }), @@ -1146,7 +1196,7 @@ impl Global { let scratch_buffer = unsafe { device - .raw + .raw() .create_buffer(&hal::BufferDescriptor { label: Some("(wgpu) scratch buffer"), size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), @@ -1159,7 +1209,7 @@ impl Global { let staging_buffer = if !instance_buffer_staging_source.is_empty() { unsafe { let staging_buffer = device - .raw + .raw() .create_buffer(&hal::BufferDescriptor { label: Some("(wgpu) instance staging buffer"), size: instance_buffer_staging_source.len() as u64, @@ -1167,9 +1217,8 @@ impl Global { memory_flags: hal::MemoryFlags::empty(), }) .map_err(crate::device::DeviceError::from)?; - let mapping = device - .raw + .raw() .map_buffer( &staging_buffer, 0..instance_buffer_staging_source.len() as u64, @@ -1182,12 +1231,18 @@ impl Global { instance_buffer_staging_source.len(), ); device - .raw + .raw() .unmap_buffer(&staging_buffer) .map_err(crate::device::DeviceError::from)?; assert!(mapping.is_coherent); - Some(staging_buffer) + Some(StagingBuffer { + raw: Mutex::new(Some(staging_buffer)), + device: device.clone(), + size: instance_buffer_staging_source.len() as u64, + info: ResourceInfo::new("Raytracing staging buffer"), + is_coherent: mapping.is_coherent, + }) } } else { None @@ -1230,8 +1285,8 @@ impl Global { let scratch_buffer_barrier = hal::BufferBarrier:: { buffer: &scratch_buffer, - usage: hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH - ..hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, + usage: BufferUses::ACCELERATION_STRUCTURE_SCRATCH + ..BufferUses::ACCELERATION_STRUCTURE_SCRATCH, }; let instance_buffer_barriers = tlas_storage.iter().filter_map( @@ -1241,9 +1296,9 @@ impl Global { None } else { Some(hal::BufferBarrier:: { - buffer: tlas.instance_buffer.as_ref().unwrap(), - usage: hal::BufferUses::COPY_DST - ..hal::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + buffer: tlas.instance_buffer.read().as_ref().unwrap(), + usage: BufferUses::COPY_DST + ..BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, }) } }, @@ -1252,7 +1307,8 @@ impl Global { let blas_present = !blas_storage.is_empty(); let tlas_present = !tlas_storage.is_empty(); - let cmd_buf_raw = cmd_buf.encoder.open(); + let mut binding = cmd_buf_data.as_mut().unwrap(); + let cmd_buf_raw = binding.encoder.open(); unsafe { cmd_buf_raw.transition_buffers(input_barriers.into_iter()); @@ -1298,7 +1354,7 @@ impl Global { unsafe { if let Some(ref staging_buffer) = staging_buffer { cmd_buf_raw.transition_buffers(iter::once(hal::BufferBarrier:: { - buffer: staging_buffer, + buffer: staging_buffer.raw.lock().as_ref().unwrap(), usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, })); } @@ -1316,8 +1372,8 @@ impl Global { size: NonZeroU64::new(size).unwrap(), }; cmd_buf_raw.copy_buffer_to_buffer( - staging_buffer.as_ref().unwrap(), - tlas.instance_buffer.as_ref().unwrap(), + staging_buffer.as_ref().unwrap().raw.lock().as_ref().unwrap(), + tlas.instance_buffer.read().as_ref().unwrap(), iter::once(temp), ); } @@ -1340,15 +1396,38 @@ impl Global { if let Some(staging_buffer) = staging_buffer { device .pending_writes + .lock() + .as_mut() + .unwrap() .temp_resources - .push(TempResource::Buffer(staging_buffer)); + .push(TempResource::StagingBuffer( + Arc::new(staging_buffer) + )); } } - + let scratch_mapping = unsafe { + device + .raw() + .map_buffer( + &scratch_buffer, + 0..instance_buffer_staging_source.len() as u64, + ) + .map_err(crate::device::DeviceError::from)? + }; device .pending_writes + .lock() + .as_mut() + .unwrap() .temp_resources - .push(TempResource::Buffer(scratch_buffer)); + .push(TempResource::StagingBuffer( + Arc::new(StagingBuffer { + raw: Mutex::new(Some(scratch_buffer)), + device: device.clone(), + size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), + info: ResourceInfo::new("Ratracing scratch buffer"), + is_coherent: scratch_mapping.is_coherent, + }))); Ok(()) } @@ -1367,16 +1446,16 @@ impl BakedCommands { crate::ray_tracing::BlasActionKind::Build(id) => { built.insert(action.id); let blas = blas_guard - .get_mut(action.id) + .get(action.id) .map_err(|_| ValidateBlasActionsError::InvalidBlas(action.id))?; - blas.built_index = Some(id); + *blas.built_index.write() = Some(id); } crate::ray_tracing::BlasActionKind::Use => { if !built.contains(&action.id) { let blas = blas_guard .get(action.id) .map_err(|_| ValidateBlasActionsError::InvalidBlas(action.id))?; - if blas.built_index == None { + if *blas.built_index.read() == None { return Err(ValidateBlasActionsError::UsedUnbuilt(action.id)); } } @@ -1400,28 +1479,28 @@ impl BakedCommands { dependencies, } => { let tlas = tlas_guard - .get_mut(action.id) + .get(action.id) .map_err(|_| ValidateTlasActionsError::InvalidTlas(action.id))?; - tlas.built_index = Some(build_index); - tlas.dependencies = dependencies; + *tlas.built_index.write() = Some(build_index); + *tlas.dependencies.write() = dependencies; } crate::ray_tracing::TlasActionKind::Use => { let tlas = tlas_guard .get(action.id) .map_err(|_| ValidateTlasActionsError::InvalidTlas(action.id))?; - let tlas_build_index = tlas.built_index; - let dependencies = &tlas.dependencies; + let tlas_build_index = tlas.built_index.read(); + let dependencies = tlas.dependencies.read(); - if tlas_build_index == None { + if *tlas_build_index == None { return Err(ValidateTlasActionsError::UsedUnbuilt(action.id)); } - for dependency in dependencies { + for dependency in dependencies.deref() { let blas = blas_guard.get(*dependency).map_err(|_| { ValidateTlasActionsError::InvalidBlas(*dependency, action.id) })?; - let blas_build_index = blas.built_index; + let blas_build_index = blas.built_index.read().clone(); if blas_build_index == None { return Err(ValidateTlasActionsError::UsedUnbuilt(action.id)); } diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index beaffea9d9..a1b6f158e0 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1474,21 +1474,23 @@ impl Global { .extend(texture_memory_actions.register_init_action(action)); } - cmd_buf.tlas_actions.extend( - bind_group.used.acceleration_structures.used().map(|id| { - cmd_buf.trackers.tlas_s.add_single(&tlas_guard, id.0); - crate::ray_tracing::TlasAction { - id: id.0, - kind: crate::ray_tracing::TlasActionKind::Use, - } - }), + let mapped_used_resources = bind_group.used.acceleration_structures.used_resources().map(|blas| { + tracker.tlas_s.add_single(&tlas_guard, blas.as_info().id()); + crate::ray_tracing::TlasAction { + id: blas.as_info().id(), + kind: crate::ray_tracing::TlasActionKind::Use, + } + }); + + cmd_buf_data.tlas_actions.extend( + mapped_used_resources, ); let pipeline_layout = state.binder.pipeline_layout.clone(); let entries = state .binder - .assign_group(index as usize, id::Valid(bind_group_id), bind_group, &temp_offsets); + .assign_group(index as usize, bind_group, &temp_offsets); if !entries.is_empty() && pipeline_layout.is_some() { let pipeline_layout = pipeline_layout.as_ref().unwrap().raw(); for (i, e) in entries.iter().enumerate() { diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 8889d2ad30..796d266ba6 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -287,8 +287,11 @@ impl LifetimeTracker { TempResource::Texture(raw) => { last_resources.insert(raw.as_info().id(), raw); } - TempResource::AccelerationStructure(raw) => { - last_resources.acceleration_structures.push(raw) + TempResource::Tlas(raw) => { + last_resources.insert(raw.as_info().id(),raw); + } + TempResource::Blas(raw) => { + last_resources.insert(raw.as_info().id(),raw); } } } @@ -391,7 +394,12 @@ impl LifetimeTracker { TempResource::Texture(raw) => { resources.insert(raw.as_info().id(), raw); } - TempResource::AccelerationStructure(raw) => resources.acceleration_structures.push(raw), + TempResource::Tlas(raw) => { + resources.insert(raw.as_info().id(), raw); + } + TempResource::Blas(raw) => { + resources.insert(raw.as_info().id(), raw); + } } } diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 22fc7177ed..f8290a2aee 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -30,6 +30,7 @@ use std::{ sync::{atomic::Ordering, Arc}, }; use thiserror::Error; +use crate::resource::{Blas, Tlas}; use super::Device; @@ -164,8 +165,8 @@ pub enum TempResource { Buffer(Arc>), StagingBuffer(Arc>), Texture(Arc>), - //TODO come back - AccelerationStructure(A::AccelerationStructure), + Tlas(Arc>), + Blas(Arc>) } /// A queue execution for a particular command encoder. @@ -1340,15 +1341,17 @@ impl Global { .insert(bundle.as_info().id(), bundle.clone()); } } - } - for id in cmdbuf.trackers.blas_s.used() { - if !blas_guard[id].life_guard.use_at(submit_index) { - device.temp_suspected.blas_s.push(id); + for blas in cmd_buf_trackers.blas_s.used_resources() { + blas.info.use_at(submit_index); + if blas.is_unique() { + temp_suspected.as_mut().unwrap().insert(blas.as_info().id(), blas.clone()); + } } - } - for id in cmdbuf.trackers.tlas_s.used() { - if !tlas_guard[id].life_guard.use_at(submit_index) { - device.temp_suspected.tlas_s.push(id); + for tlas in cmd_buf_trackers.tlas_s.used_resources() { + tlas.info.use_at(submit_index); + if tlas.is_unique() { + temp_suspected.as_mut().unwrap().insert(tlas.as_info().id(), tlas.clone()); + } } } @@ -1373,9 +1376,10 @@ impl Global { baked .initialize_texture_memory(&mut *trackers, device) .map_err(|err| QueueSubmitError::DestroyedTexture(err.0))?; - - baked.validate_blas_actions(&mut *blas_guard)?; - baked.validate_tlas_actions(&*blas_guard, &mut *tlas_guard)?; + let mut blas_guard = hub.blas_s.write(); + baked.validate_blas_actions(&mut blas_guard)?; + let mut tlas_guard = hub.tlas_s.write(); + baked.validate_tlas_actions(&blas_guard, &mut tlas_guard)?; //Note: stateless trackers are not merged: // device already knows these resources exist. diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 1fa30b14ee..47e6ca5aec 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -1,23 +1,25 @@ +use std::sync::Arc; +use parking_lot::{Mutex, RwLock}; #[cfg(feature = "trace")] use crate::device::trace; use crate::{ device::{queue::TempResource, Device, DeviceError}, global::Global, hal_api::HalApi, - hub::Token, id::{self, BlasId, TlasId}, identity::{GlobalIdentityHandlerFactory, Input}, ray_tracing::{get_raw_tlas_instance_size, CreateBlasError, CreateTlasError}, resource, storage::InvalidId, - LabelHelpers, LifeGuard, Stored, + LabelHelpers, }; use hal::{AccelerationStructureTriangleIndices, Device as _}; +use crate::resource::{ResourceInfo, StagingBuffer}; impl Device { fn create_blas( - &self, + self: &Arc, self_id: id::DeviceId, blas_desc: &resource::BlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, @@ -52,7 +54,7 @@ impl Device { }); } unsafe { - self.raw.get_acceleration_structure_build_sizes( + self.raw().get_acceleration_structure_build_sizes( &hal::GetAccelerationStructureBuildSizesDescriptor { entries: &hal::AccelerationStructureEntries::Triangles(entries), flags: blas_desc.flags, @@ -63,7 +65,7 @@ impl Device { }; let raw = unsafe { - self.raw + self.raw() .create_acceleration_structure(&hal::AccelerationStructureDescriptor { label: blas_desc.label.borrow_option(), size: size_info.acceleration_structure_size, @@ -72,33 +74,30 @@ impl Device { } .map_err(DeviceError::from)?; - let handle = unsafe { self.raw.get_acceleration_structure_device_address(&raw) }; + let handle = unsafe { self.raw().get_acceleration_structure_device_address(&raw) }; Ok(resource::Blas { raw: Some(raw), - device_id: Stored { - value: id::Valid(self_id), - ref_count: self.life_guard.add_ref(), - }, - life_guard: LifeGuard::new(blas_desc.label.borrow_or_default()), + device: self.clone(), + info: ResourceInfo::new(blas_desc.label.to_hal(self.instance_flags).unwrap_or("")), size_info, sizes, flags: blas_desc.flags, update_mode: blas_desc.update_mode, handle, - built_index: None, + built_index: RwLock::new(None), }) } fn create_tlas( - &self, + self: &Arc, self_id: id::DeviceId, desc: &resource::TlasDescriptor, ) -> Result, CreateTlasError> { debug_assert_eq!(self_id.backend(), A::VARIANT); let size_info = unsafe { - self.raw.get_acceleration_structure_build_sizes( + self.raw().get_acceleration_structure_build_sizes( &hal::GetAccelerationStructureBuildSizesDescriptor { entries: &hal::AccelerationStructureEntries::Instances( hal::AccelerationStructureInstances { @@ -113,7 +112,7 @@ impl Device { }; let raw = unsafe { - self.raw + self.raw() .create_acceleration_structure(&hal::AccelerationStructureDescriptor { label: desc.label.borrow_option(), size: size_info.acceleration_structure_size, @@ -125,7 +124,7 @@ impl Device { let instance_buffer_size = get_raw_tlas_instance_size::() * std::cmp::max(desc.max_instances, 1) as usize; let instance_buffer = unsafe { - self.raw.create_buffer(&hal::BufferDescriptor { + self.raw().create_buffer(&hal::BufferDescriptor { label: Some("(wgpu-core) instances_buffer"), size: instance_buffer_size as u64, usage: hal::BufferUses::COPY_DST @@ -137,17 +136,14 @@ impl Device { Ok(resource::Tlas { raw: Some(raw), - device_id: Stored { - value: id::Valid(self_id), - ref_count: self.life_guard.add_ref(), - }, - life_guard: LifeGuard::new(desc.label.borrow_or_default()), + device: self.clone(), + info: ResourceInfo::new(desc.label.to_hal(self.instance_flags).unwrap_or("")), size_info, flags: desc.flags, update_mode: desc.update_mode, - built_index: None, - dependencies: Vec::new(), - instance_buffer: Some(instance_buffer), + built_index: RwLock::new(None), + dependencies: RwLock::new(Vec::new()), + instance_buffer: RwLock::new(Some(instance_buffer)), max_instance_count: desc.max_instances, }) } @@ -164,18 +160,17 @@ impl Global { profiling::scope!("Device::create_blas"); let hub = A::hub(self); - let mut token = Token::root(); - let fid = hub.blas_s.prepare(id_in); + let fid = hub.blas_s.prepare::(id_in); - let (device_guard, mut token) = hub.devices.read(&mut token); + let device_guard = hub.devices.read(); let error = loop { let device = match device_guard.get(device_id) { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; #[cfg(feature = "trace")] - if let Some(ref trace) = device.trace { - trace.lock().add(trace::Action::CreateBlas { + if let Some(trace) = device.trace.lock().as_mut() { + trace.add(trace::Action::CreateBlas { id: fid.id(), desc: desc.clone(), sizes: sizes.clone(), @@ -188,17 +183,16 @@ impl Global { }; let handle = blas.handle; - let ref_count = blas.life_guard.add_ref(); - let id = fid.assign(blas, &mut token); - log::info!("Created blas {:?} with {:?}", id, desc); + let id = fid.assign(blas); + log::info!("Created blas {:?} with {:?}", id.0, desc); - device.trackers.lock().blas_s.insert_single(id, ref_count); + device.trackers.lock().blas_s.insert_single(id.0, id.1); return (id.0, Some(handle), None); }; - let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); + let id = fid.assign_error(desc.label.borrow_or_default()); (id, None, Some(error)) } @@ -211,18 +205,17 @@ impl Global { profiling::scope!("Device::create_tlas"); let hub = A::hub(self); - let mut token = Token::root(); - let fid = hub.tlas_s.prepare(id_in); + let fid = hub.tlas_s.prepare::(id_in); - let (device_guard, mut token) = hub.devices.read(&mut token); + let device_guard = hub.devices.read(); let error = loop { let device = match device_guard.get(device_id) { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; #[cfg(feature = "trace")] - if let Some(ref trace) = device.trace { - trace.lock().add(trace::Action::CreateTlas { + if let Some(trace) = device.trace.lock().as_mut() { + trace.add(trace::Action::CreateTlas { id: fid.id(), desc: desc.clone(), }); @@ -232,17 +225,16 @@ impl Global { Ok(tlas) => tlas, Err(e) => break e, }; - let ref_count = tlas.life_guard.add_ref(); - let id = fid.assign(tlas, &mut token); - log::info!("Created blas {:?} with {:?}", id, desc); + let id = fid.assign(tlas); + log::info!("Created blas {:?} with {:?}", id.0, desc); - device.trackers.lock().tlas_s.insert_single(id, ref_count); + device.trackers.lock().tlas_s.insert_single(id.0, id.1); return (id.0, None); }; - let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); + let id = fid.assign_error(desc.label.borrow_or_default()); (id, Some(error)) } @@ -250,33 +242,28 @@ impl Global { profiling::scope!("Blas::destroy"); let hub = A::hub(self); - let mut token = Token::root(); - let (mut device_guard, mut token) = hub.devices.write(&mut token); + let device_guard = hub.devices.write(); log::info!("Blas {:?} is destroyed", blas_id); - let (mut blas_guard, _) = hub.blas_s.write(&mut token); + let blas_guard = hub.blas_s.write(); let blas = blas_guard - .get_mut(blas_id) + .get(blas_id) .map_err(|_| resource::DestroyError::Invalid)?; - let device = &mut device_guard[blas.device_id.value]; + let device = device_guard.get(blas.device.info.id()).unwrap(); #[cfg(feature = "trace")] - if let Some(ref trace) = device.trace { - trace.lock().add(trace::Action::FreeBlas(blas_id)); + if let Some(trace) = device.trace.lock().as_mut() { + trace.add(trace::Action::FreeBlas(blas_id)); } - let raw = blas - .raw - .take() - .ok_or(resource::DestroyError::AlreadyDestroyed)?; - let temp = TempResource::AccelerationStructure(raw); + let temp = TempResource::Blas(blas.clone()); { - let last_submit_index = blas.life_guard.life_count(); + let last_submit_index = blas.info.submission_index(); drop(blas_guard); device - .lock_life(&mut token) + .lock_life() .schedule_resource_destruction(temp, last_submit_index); } @@ -288,34 +275,32 @@ impl Global { log::debug!("blas {:?} is dropped", blas_id); let hub = A::hub(self); - let mut token = Token::root(); - let (last_submit_index, device_id) = { - let (mut blas_guard, _) = hub.blas_s.write(&mut token); - match blas_guard.get_mut(blas_id) { + let (last_submit_index, device) = { + let mut blas_guard = hub.blas_s.write(); + match blas_guard.get(blas_id) { Ok(blas) => { - let last_submit_index = blas.life_guard.life_count(); - (last_submit_index, blas.device_id.value) + let last_submit_index = blas.info.submission_index(); + (last_submit_index, blas.device.clone()) } - Err(InvalidId) => { + Err(_) => { hub.blas_s.unregister_locked(blas_id, &mut *blas_guard); return; } } }; - let (device_guard, mut token) = hub.devices.read(&mut token); - let device = &device_guard[device_id]; + let blas_guard = hub.blas_s.read(); + let blas = blas_guard.get(blas_id).unwrap(); { - let mut life_lock = device.lock_life(&mut token); + let mut life_lock = device.lock_life(); life_lock .suspected_resources - .blas_s - .push(id::Valid(blas_id)); + .insert(blas_id, blas.clone()); } if wait { - match device.wait_for_submit(last_submit_index, &mut token) { + match device.wait_for_submit(last_submit_index) { Ok(()) => (), Err(e) => log::error!("Failed to wait for blas {:?}: {:?}", blas_id, e), } @@ -326,36 +311,53 @@ impl Global { profiling::scope!("Tlas::destroy"); let hub = A::hub(self); - let mut token = Token::root(); - let (mut device_guard, mut token) = hub.devices.write(&mut token); + let device_guard = hub.devices.write(); log::info!("Tlas {:?} is destroyed", tlas_id); - let (mut tlas_guard, _) = hub.tlas_s.write(&mut token); + let tlas_guard = hub.tlas_s.write(); let tlas = tlas_guard - .get_mut(tlas_id) + .get(tlas_id) .map_err(|_| resource::DestroyError::Invalid)?; - let device = &mut device_guard[tlas.device_id.value]; + let device = &mut device_guard.get(tlas.device.info.id()).unwrap(); #[cfg(feature = "trace")] - if let Some(ref trace) = device.trace { - trace.lock().add(trace::Action::FreeTlas(tlas_id)); + if let Some(trace) = device.trace.lock().as_mut() { + trace.add(trace::Action::FreeTlas(tlas_id)); } - let raw = tlas - .raw - .take() - .ok_or(resource::DestroyError::AlreadyDestroyed)?; - - let temp = TempResource::AccelerationStructure(raw); - - let raw_instance_buffer = tlas.instance_buffer.take(); - let temp_instance_buffer = raw_instance_buffer.map(|e| TempResource::Buffer(e)); + let temp = TempResource::Tlas(tlas.clone()); + + let raw_instance_buffer = tlas.instance_buffer.write().take(); + let temp_instance_buffer = match raw_instance_buffer { + None => {None} + Some(e) => { + let size = get_raw_tlas_instance_size::() as u64 * std::cmp::max(tlas.max_instance_count, 1) as u64; + let mapping = unsafe { + device + .raw() + .map_buffer( + &e, + 0..size, + ) + .map_err(|_| resource::DestroyError::Invalid)? + }; + Some(TempResource::StagingBuffer(Arc::new( + StagingBuffer { + raw: Mutex::new(Some(e)), + device: device.clone(), + size, + info: ResourceInfo::new("Ratracing scratch buffer"), + is_coherent: mapping.is_coherent, + } + ))) + } + }; { - let last_submit_index = tlas.life_guard.life_count(); + let last_submit_index = tlas.info.submission_index(); drop(tlas_guard); - let guard = &mut device.lock_life(&mut token); + let guard = &mut device.lock_life(); guard.schedule_resource_destruction(temp, last_submit_index); if let Some(temp_instance_buffer) = temp_instance_buffer { @@ -371,14 +373,14 @@ impl Global { log::debug!("tlas {:?} is dropped", tlas_id); let hub = A::hub(self); - let mut token = Token::root(); + let device_guard = hub.devices.write(); - let (last_submit_index, device_id) = { - let (mut tlas_guard, _) = hub.tlas_s.write(&mut token); - match tlas_guard.get_mut(tlas_id) { + let (last_submit_index, device) = { + let mut tlas_guard = hub.tlas_s.write(); + match tlas_guard.get(tlas_id) { Ok(tlas) => { - let last_submit_index = tlas.life_guard.life_count(); - (last_submit_index, tlas.device_id.value) + let last_submit_index = tlas.info.submission_index(); + (last_submit_index, device_guard.get(tlas.device.info.id()).unwrap()) } Err(InvalidId) => { hub.tlas_s.unregister_locked(tlas_id, &mut *tlas_guard); @@ -387,18 +389,17 @@ impl Global { } }; - let (device_guard, mut token) = hub.devices.read(&mut token); - let device = &device_guard[device_id]; + let tlas_guard = hub.tlas_s.read(); + let tlas = tlas_guard.get(tlas_id).unwrap(); { - let mut life_lock = device.lock_life(&mut token); + let mut life_lock = device.lock_life(); life_lock .suspected_resources - .tlas_s - .push(id::Valid(tlas_id)); + .insert(tlas_id, tlas.clone()); } if wait { - match device.wait_for_submit(last_submit_index, &mut token) { + match device.wait_for_submit(last_submit_index) { Ok(()) => (), Err(e) => log::error!("Failed to wait for tlas {:?}: {:?}", tlas_id, e), } diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 200522adbc..7d5865178b 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -449,14 +449,14 @@ impl Device { temp_suspected.insert(resource.as_info().id(), resource.clone()); } } - for id in trackers.blas_s.used() { - if blas_guard[id].life_guard.ref_count.is_none() { - self.temp_suspected.blas_s.push(id); + for resource in trackers.blas_s.used_resources() { + if resource.is_unique() { + temp_suspected.insert(resource.as_info().id(), resource.clone()); } } - for id in trackers.tlas_s.used() { - if tlas_guard[id].life_guard.ref_count.is_none() { - self.temp_suspected.tlas_s.push(id); + for resource in trackers.tlas_s.used_resources() { + if resource.is_unique() { + temp_suspected.insert(resource.as_info().id(), resource.clone()); } } } diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index f003b687b7..c5c3a56dec 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -197,8 +197,8 @@ pub struct Hub { pub textures: Registry>, pub texture_views: Registry>, pub samplers: Registry>, - pub blas_s: Registry, id::BlasId>, - pub tlas_s: Registry, id::TlasId>, + pub blas_s: Registry>, + pub tlas_s: Registry>, } impl Hub { diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 6f830d5f6e..ddadbe34cc 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -1311,7 +1311,8 @@ pub enum DestroyError { pub type BlasDescriptor<'a> = wgt::CreateBlasDescriptor>; pub type TlasDescriptor<'a> = wgt::CreateTlasDescriptor>; -pub struct Blas { +#[derive(Debug)] +pub struct Blas { pub(crate) raw: Option, pub(crate) device: Arc>, pub(crate) info: ResourceInfo, @@ -1319,11 +1320,11 @@ pub struct Blas { pub(crate) sizes: wgt::BlasGeometrySizeDescriptors, pub(crate) flags: wgt::AccelerationStructureFlags, pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, - pub(crate) built_index: Option, + pub(crate) built_index: RwLock>, pub(crate) handle: u64, } -impl Resource for Blas { +impl Resource for Blas { const TYPE: &'static str = "Blas"; fn as_info(&self) -> &ResourceInfo { @@ -1335,7 +1336,8 @@ impl Resource for Blas { } } -pub struct Tlas { +#[derive(Debug)] +pub struct Tlas { pub(crate) raw: Option, pub(crate) device: Arc>, pub(crate) info: ResourceInfo, @@ -1343,12 +1345,12 @@ pub struct Tlas { pub(crate) max_instance_count: u32, pub(crate) flags: wgt::AccelerationStructureFlags, pub(crate) update_mode: wgt::AccelerationStructureUpdateMode, - pub(crate) built_index: Option, - pub(crate) dependencies: Vec, - pub(crate) instance_buffer: Option, + pub(crate) built_index: RwLock>, + pub(crate) dependencies: RwLock>, + pub(crate) instance_buffer: RwLock>, } -impl Resource for Tlas { +impl Resource for Tlas { const TYPE: &'static str = "Tlas"; fn as_info(&self) -> &ResourceInfo { From 9b3266cf7c0a78e062dd017ec94c4e8ffc731fce Mon Sep 17 00:00:00 2001 From: Vecvec Date: Fri, 8 Dec 2023 16:53:09 +1300 Subject: [PATCH 102/146] fix err --- wgpu-core/src/command/ray_tracing.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index cabc5c85ad..6624d1d16f 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1307,8 +1307,7 @@ impl Global { let blas_present = !blas_storage.is_empty(); let tlas_present = !tlas_storage.is_empty(); - let mut binding = cmd_buf_data.as_mut().unwrap(); - let cmd_buf_raw = binding.encoder.open(); + let cmd_buf_raw = cmd_buf_data.encoder.open(); unsafe { cmd_buf_raw.transition_buffers(input_barriers.into_iter()); From 99f423621ff80236228bdbfd4f74fee2c98939a8 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Sun, 10 Dec 2023 16:05:53 +1300 Subject: [PATCH 103/146] fix all compile errors --- wgpu-core/src/command/ray_tracing.rs | 1002 ++++++++++++++------------ 1 file changed, 544 insertions(+), 458 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 6624d1d16f..967d963f4b 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -21,8 +21,9 @@ use wgt::{math::align_to, BufferUsages}; use std::{cmp::max, iter, num::NonZeroU64, ops::Range, ptr}; use std::ops::Deref; use std::sync::Arc; -use parking_lot::Mutex; +use parking_lot::{Mutex, RwLockReadGuard}; use hal::{BufferUses, CommandEncoder, Device}; +use crate::ray_tracing::BlasTriangleGeometry; use crate::resource::{Buffer, Resource, ResourceInfo, StagingBuffer}; use crate::track::PendingTransition; @@ -42,7 +43,7 @@ impl Global { let hub = A::hub(self); - let mut device_guard = hub.devices.write(); + let device_guard = hub.devices.write(); let cmd_buf = CommandBuffer::get_encoder(hub, command_encoder_id)?; let buffer_guard = hub.buffers.read(); let blas_guard = hub.blas_s.read(); @@ -108,7 +109,7 @@ impl Global { ref triangle_geometries, ) => { let iter = triangle_geometries.iter().map(|tg| { - crate::ray_tracing::BlasTriangleGeometry { + BlasTriangleGeometry { size: &tg.size, vertex_buffer: tg.vertex_buffer, index_buffer: tg.index_buffer, @@ -132,6 +133,7 @@ impl Global { let tlas_iter = trace_tlas.iter(); let mut input_barriers = Vec::>::new(); + let mut buf_storage = Vec::<(Arc>, Option>, Option<(Arc>, Option>)>, Option<(Arc>, Option>)>, BlasTriangleGeometry, Option>>)>::new(); let mut scratch_buffer_blas_size = 0; let mut blas_storage = Vec::<(&Blas, hal::AccelerationStructureEntries, u64)>::new(); @@ -155,7 +157,6 @@ impl Global { match entry.geometries { BlasGeometries::TriangleGeometries(triangle_geometries) => { - let mut triangle_entries = Vec::>::new(); for (i, mesh) in triangle_geometries.enumerate() { let size_desc = match &blas.sizes { @@ -193,67 +194,24 @@ impl Global { entry.blas_id, )); } - - let vertex_buffer = { - let (vertex_buffer, vertex_pending) = cmd_buf_data - .trackers - .buffers - .set_single( - &*match buffer_guard.get(mesh.vertex_buffer) { - Ok(buffer) => buffer, - Err(_) => { - return Err(BuildAccelerationStructureError::InvalidBuffer( - mesh.vertex_buffer, - )) - } - }, - BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, - ) - .ok_or(BuildAccelerationStructureError::InvalidBuffer( - mesh.vertex_buffer, - ))?; - let vertex_raw = vertex_buffer.raw.as_ref().ok_or( - BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer), - )?; - if !vertex_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - mesh.vertex_buffer, - ), - ); - } - if let Some(barrier) = - vertex_pending.map(|pending| pending.into_hal(&vertex_buffer)) - { - input_barriers.push(barrier); - } - if vertex_buffer.size - < (mesh.size.vertex_count + mesh.first_vertex) as u64 - * mesh.vertex_stride - { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - mesh.vertex_buffer, - vertex_buffer.size, - (mesh.size.vertex_count + mesh.first_vertex) as u64 - * mesh.vertex_stride, - ), - ); - } - let vertex_buffer_offset = - mesh.first_vertex as u64 * mesh.vertex_stride; - cmd_buf_data.buffer_memory_init_actions.extend( - vertex_buffer.initialization_status.read().create_action( - buffer_guard.get(mesh.vertex_buffer).unwrap(), - vertex_buffer_offset - ..(vertex_buffer_offset - + mesh.size.vertex_count as u64 * mesh.vertex_stride), - MemoryInitKind::NeedsInitializedMemory, - ), - ); - vertex_raw - }; - let index_buffer = if let Some(index_id) = mesh.index_buffer { + let (vertex_buffer, vertex_pending) = cmd_buf_data + .trackers + .buffers + .set_single( + &*match buffer_guard.get(mesh.vertex_buffer) { + Ok(buffer) => buffer, + Err(_) => { + return Err(BuildAccelerationStructureError::InvalidBuffer( + mesh.vertex_buffer, + )) + } + }, + BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) + .ok_or(BuildAccelerationStructureError::InvalidBuffer( + mesh.vertex_buffer, + ))?; + let index_data = if let Some(index_id) = mesh.index_buffer { if mesh.index_buffer_offset.is_none() || mesh.size.index_count.is_none() || mesh.size.index_count.is_none() @@ -264,7 +222,7 @@ impl Global { ), ); } - let (index_buffer, index_pending) = cmd_buf_data + let data = cmd_buf_data .trackers .buffers .set_single( @@ -275,72 +233,11 @@ impl Global { hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer(index_id))?; - let index_raw = index_buffer - .raw - .as_ref() - .ok_or(BuildAccelerationStructureError::InvalidBuffer(index_id))?; - if !index_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - index_id, - ), - ); - } - if let Some(barrier) = - index_pending.map(|pending| pending.into_hal(&index_buffer)) - { - input_barriers.push(barrier); - } - let index_stride = match mesh.size.index_format.unwrap() { - wgt::IndexFormat::Uint16 => 2, - wgt::IndexFormat::Uint32 => 4, - }; - if mesh.index_buffer_offset.unwrap() % index_stride != 0 { - return Err( - BuildAccelerationStructureError::UnalignedIndexBufferOffset( - index_id, - ), - ); - } - let index_buffer_size = - mesh.size.index_count.unwrap() as u64 * index_stride; - - if mesh.size.index_count.unwrap() % 3 != 0 { - return Err(BuildAccelerationStructureError::InvalidIndexCount( - index_id, - mesh.size.index_count.unwrap(), - )); - } - if index_buffer.size - < mesh.size.index_count.unwrap() as u64 * index_stride - + mesh.index_buffer_offset.unwrap() - { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - index_id, - index_buffer.size, - mesh.size.index_count.unwrap() as u64 * index_stride - + mesh.index_buffer_offset.unwrap(), - ), - ); - } - - cmd_buf_data.buffer_memory_init_actions.extend( - index_buffer.initialization_status.read().create_action( - match buffer_guard.get(index_id) { - Ok(buffer) => buffer, - Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( index_id, )), - }, - mesh.index_buffer_offset.unwrap() - ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), - MemoryInitKind::NeedsInitializedMemory, - ), - ); - Some(index_raw) + Some(data) } else { None }; - let transform_buffer = if let Some(transform_id) = mesh.transform_buffer { + let transform_data = if let Some(transform_id) = mesh.transform_buffer { if mesh.transform_buffer_offset.is_none() { return Err( BuildAccelerationStructureError::MissingAssociatedData( @@ -348,7 +245,7 @@ impl Global { ), ); } - let (transform_buffer, transform_pending) = cmd_buf_data + let data = cmd_buf_data .trackers .buffers .set_single( @@ -356,118 +253,264 @@ impl Global { Ok(buffer) => buffer, Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(transform_id)) }, }, - hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer( transform_id, ))?; - let transform_raw = transform_buffer.raw.as_ref().ok_or( - BuildAccelerationStructureError::InvalidBuffer(transform_id), - )?; - if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - transform_id, - ), - ); - } - if let Some(barrier) = - transform_pending.map(|pending| pending.into_hal(&transform_buffer)) - { - input_barriers.push(barrier); - } - if mesh.transform_buffer_offset.unwrap() - % wgt::TRANSFORM_BUFFER_ALIGNMENT - != 0 - { - return Err( - BuildAccelerationStructureError::UnalignedTransformBufferOffset( - transform_id, - ), - ); - } - if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - transform_id, - transform_buffer.size, - 48 + mesh.transform_buffer_offset.unwrap(), - ), - ); - } - cmd_buf_data.buffer_memory_init_actions.extend( - transform_buffer.initialization_status.read().create_action( - buffer_guard.get(transform_id).unwrap(), - mesh.transform_buffer_offset.unwrap() - ..(mesh.index_buffer_offset.unwrap() + 48), - MemoryInitKind::NeedsInitializedMemory, - ), - ); - Some(transform_raw) + Some(data) } else { None }; - let triangles = hal::AccelerationStructureTriangles { - vertex_buffer: Some(vertex_buffer), - vertex_format: mesh.size.vertex_format, - first_vertex: mesh.first_vertex, - vertex_count: mesh.size.vertex_count, - vertex_stride: mesh.vertex_stride, - indices: index_buffer.map(|index_buffer| { - hal::AccelerationStructureTriangleIndices { - format: mesh.size.index_format.unwrap(), - buffer: Some(index_buffer), - offset: mesh.index_buffer_offset.unwrap() as u32, - count: mesh.size.index_count.unwrap(), - } - }), - transform: transform_buffer.map(|transform_buffer| { - hal::AccelerationStructureTriangleTransform { - buffer: transform_buffer, - offset: mesh.transform_buffer_offset.unwrap() as u32, - } - }), - flags: mesh.size.flags, - }; - - triangle_entries.push(triangles); + buf_storage.push((vertex_buffer, vertex_pending, index_data, transform_data, mesh, None)) + } + if let Some(last) = buf_storage.last_mut() { + last.5 = Some(blas.clone()); } - - let scratch_buffer_offset = scratch_buffer_blas_size; - scratch_buffer_blas_size += align_to( - blas.size_info.build_scratch_size as u32, - SCRATCH_BUFFER_ALIGNMENT, - ) as u64; - - blas_storage.push(( - blas, - hal::AccelerationStructureEntries::Triangles(triangle_entries), - scratch_buffer_offset, - )) } } } + let mut triangle_entries = Vec::>::new(); + for buf in &mut buf_storage { + let mesh = &buf.4; + let vertex_buffer = { + let vertex_buffer = buf.0.as_ref(); + let vertex_raw = vertex_buffer.raw.as_ref().ok_or( + BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer), + )?; + if !vertex_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + mesh.vertex_buffer, + ), + ); + } + if let Some(barrier) = + buf.1.take().map(|pending| pending.into_hal(&vertex_buffer)) + { + input_barriers.push(barrier); + } + if vertex_buffer.size + < (mesh.size.vertex_count + mesh.first_vertex) as u64 + * mesh.vertex_stride + { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + mesh.vertex_buffer, + vertex_buffer.size, + (mesh.size.vertex_count + mesh.first_vertex) as u64 + * mesh.vertex_stride, + ), + ); + } + let vertex_buffer_offset = + mesh.first_vertex as u64 * mesh.vertex_stride; + cmd_buf_data.buffer_memory_init_actions.extend( + vertex_buffer.initialization_status.read().create_action( + buffer_guard.get(mesh.vertex_buffer).unwrap(), + vertex_buffer_offset + ..(vertex_buffer_offset + + mesh.size.vertex_count as u64 * mesh.vertex_stride), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + vertex_raw + }; + let index_buffer = if let Some((ref mut index_buffer, ref mut index_pending)) = buf.2 { + let index_id = mesh.index_buffer.as_ref().unwrap(); + let index_raw = index_buffer + .raw + .as_ref() + .ok_or(BuildAccelerationStructureError::InvalidBuffer(*index_id))?; + if !index_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + *index_id, + ), + ); + } + if let Some(barrier) = + index_pending.take().map(|pending| pending.into_hal(index_buffer)) + { + input_barriers.push(barrier); + } + let index_stride = match mesh.size.index_format.unwrap() { + wgt::IndexFormat::Uint16 => 2, + wgt::IndexFormat::Uint32 => 4, + }; + if mesh.index_buffer_offset.unwrap() % index_stride != 0 { + return Err( + BuildAccelerationStructureError::UnalignedIndexBufferOffset( + *index_id, + ), + ); + } + let index_buffer_size = + mesh.size.index_count.unwrap() as u64 * index_stride; + + if mesh.size.index_count.unwrap() % 3 != 0 { + return Err(BuildAccelerationStructureError::InvalidIndexCount( + *index_id, + mesh.size.index_count.unwrap(), + )); + } + if index_buffer.size + < mesh.size.index_count.unwrap() as u64 * index_stride + + mesh.index_buffer_offset.unwrap() + { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + *index_id, + index_buffer.size, + mesh.size.index_count.unwrap() as u64 * index_stride + + mesh.index_buffer_offset.unwrap(), + ), + ); + } + + cmd_buf_data.buffer_memory_init_actions.extend( + index_buffer.initialization_status.read().create_action( + match buffer_guard.get(*index_id) { + Ok(buffer) => buffer, + Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( *index_id, )), + }, + mesh.index_buffer_offset.unwrap() + ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + Some(index_raw) + } else { + None + }; + let transform_buffer = if let Some((ref mut transform_buffer, ref mut transform_pending)) = buf.3 { + let transform_id = mesh.transform_buffer.as_ref().unwrap(); + if mesh.transform_buffer_offset.is_none() { + return Err( + BuildAccelerationStructureError::MissingAssociatedData( + *transform_id, + ), + ); + } + let transform_raw = transform_buffer.raw.as_ref().ok_or( + BuildAccelerationStructureError::InvalidBuffer(*transform_id), + )?; + if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + *transform_id, + ), + ); + } + if let Some(barrier) = + transform_pending.take().map(|pending| pending.into_hal(transform_buffer)) + { + input_barriers.push(barrier); + } + if mesh.transform_buffer_offset.unwrap() + % wgt::TRANSFORM_BUFFER_ALIGNMENT + != 0 + { + return Err( + BuildAccelerationStructureError::UnalignedTransformBufferOffset( + *transform_id, + ), + ); + } + if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + *transform_id, + transform_buffer.size, + 48 + mesh.transform_buffer_offset.unwrap(), + ), + ); + } + cmd_buf_data.buffer_memory_init_actions.extend( + transform_buffer.initialization_status.read().create_action( + buffer_guard.get(*transform_id).unwrap(), + mesh.transform_buffer_offset.unwrap() + ..(mesh.index_buffer_offset.unwrap() + 48), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + Some(transform_raw) + } else { + None + }; + + let triangles = hal::AccelerationStructureTriangles { + vertex_buffer: Some(vertex_buffer), + vertex_format: mesh.size.vertex_format, + first_vertex: mesh.first_vertex, + vertex_count: mesh.size.vertex_count, + vertex_stride: mesh.vertex_stride, + indices: index_buffer.map(|index_buffer| { + hal::AccelerationStructureTriangleIndices:: { + format: mesh.size.index_format.unwrap(), + buffer: Some(index_buffer), + offset: mesh.index_buffer_offset.unwrap() as u32, + count: mesh.size.index_count.unwrap(), + } + }), + transform: transform_buffer.map(|transform_buffer| { + hal::AccelerationStructureTriangleTransform { + buffer: transform_buffer, + offset: mesh.transform_buffer_offset.unwrap() as u32, + } + }), + flags: mesh.size.flags, + }; + triangle_entries.push(triangles); + if let Some(blas) = buf.5.as_ref() { + let scratch_buffer_offset = scratch_buffer_blas_size; + scratch_buffer_blas_size += align_to( + blas.size_info.build_scratch_size as u32, + SCRATCH_BUFFER_ALIGNMENT, + ) as u64; + + blas_storage.push(( + &*blas, + hal::AccelerationStructureEntries::Triangles(triangle_entries), + scratch_buffer_offset, + )); + triangle_entries = Vec::new(); + } + } let mut scratch_buffer_tlas_size = 0; let mut tlas_storage = Vec::<(&Tlas, hal::AccelerationStructureEntries, u64)>::new(); + let mut tlas_buf_storage = Vec::<(Arc>, Option>, TlasBuildEntry)>::new(); for entry in tlas_iter { + let data = cmd_buf_data + .trackers + .buffers + .set_single( + &*match buffer_guard.get(entry.instance_buffer_id) { + Ok(buffer) => buffer, + Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer(entry.instance_buffer_id, )), + }, + BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) + .ok_or(BuildAccelerationStructureError::InvalidBuffer( + entry.instance_buffer_id, + ))?; + tlas_buf_storage.push( + ( + data.0, + data.1, + entry.clone() + ) + ); + } + + for tlas_buf in &mut tlas_buf_storage { + let entry = &tlas_buf.2; let instance_buffer = { - let (instance_buffer, instance_pending) = cmd_buf_data - .trackers - .buffers - .set_single( - &*match buffer_guard.get(entry.instance_buffer_id) { - Ok(buffer) => buffer, - Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer(entry.instance_buffer_id, )), - }, - BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, - ) - .ok_or(BuildAccelerationStructureError::InvalidBuffer( - entry.instance_buffer_id, - ))?; + let (instance_buffer, instance_pending) = (&mut tlas_buf.0, &mut tlas_buf.1); let instance_raw = instance_buffer.raw.as_ref().ok_or( BuildAccelerationStructureError::InvalidBuffer(entry.instance_buffer_id), )?; @@ -477,7 +520,7 @@ impl Global { )); } if let Some(barrier) = - instance_pending.map(|pending| pending.into_hal(instance_buffer.as_ref())) + instance_pending.take().map(|pending| pending.into_hal(instance_buffer)) { input_barriers.push(barrier); } @@ -664,7 +707,6 @@ impl Global { let hub = A::hub(self); - let mut device_guard = hub.devices.write(); let cmd_buf = CommandBuffer::get_encoder(hub, command_encoder_id)?; let buffer_guard = hub.buffers.read(); let blas_guard = hub.blas_s.read(); @@ -745,7 +787,7 @@ impl Global { ref triangle_geometries, ) => { let iter = triangle_geometries.iter().map(|tg| { - crate::ray_tracing::BlasTriangleGeometry { + BlasTriangleGeometry { size: &tg.size, vertex_buffer: tg.vertex_buffer, index_buffer: tg.index_buffer, @@ -785,6 +827,7 @@ impl Global { }); let mut input_barriers = Vec::>::new(); + let mut buf_storage = Vec::<(Arc>, Option>, Option<(Arc>, Option>)>, Option<(Arc>, Option>)>, BlasTriangleGeometry, Option>>)>::new(); let mut scratch_buffer_blas_size = 0; let mut blas_storage = Vec::<(&Blas, hal::AccelerationStructureEntries, u64)>::new(); @@ -808,7 +851,6 @@ impl Global { match entry.geometries { BlasGeometries::TriangleGeometries(triangle_geometries) => { - let mut triangle_entries = Vec::>::new(); for (i, mesh) in triangle_geometries.enumerate() { let size_desc = match &blas.sizes { @@ -846,66 +888,24 @@ impl Global { entry.blas_id, )); } - - let vertex_buffer = { - let (vertex_buffer, vertex_pending) = cmd_buf_data - .trackers - .buffers - .set_single( - &*match buffer_guard.get(mesh.vertex_buffer) { - Ok(buffer) => buffer, - Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( mesh.vertex_buffer, )), - }, - hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, - ) - .ok_or(BuildAccelerationStructureError::InvalidBuffer( - mesh.vertex_buffer, - ))?; - let vertex_raw = vertex_buffer.raw.as_ref().ok_or( - BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer), - )?; - if !vertex_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - mesh.vertex_buffer, - ), - ); - } - if let Some(barrier) = - vertex_pending.map(|pending| pending.into_hal(vertex_buffer.deref())) - { - input_barriers.push(barrier); - } - if vertex_buffer.size - < (mesh.size.vertex_count + mesh.first_vertex) as u64 - * mesh.vertex_stride - { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - mesh.vertex_buffer, - vertex_buffer.size, - (mesh.size.vertex_count + mesh.first_vertex) as u64 - * mesh.vertex_stride, - ), - ); - } - let vertex_buffer_offset = - mesh.first_vertex as u64 * mesh.vertex_stride; - cmd_buf_data.buffer_memory_init_actions.extend( - vertex_buffer.initialization_status.read().create_action( - match buffer_guard.get(mesh.vertex_buffer) { - Ok(buf) => buf, - Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer)), - }, - vertex_buffer_offset - ..(vertex_buffer_offset - + mesh.size.vertex_count as u64 * mesh.vertex_stride), - MemoryInitKind::NeedsInitializedMemory, - ), - ); - vertex_raw - }; - let index_buffer = if let Some(index_id) = mesh.index_buffer { + let (vertex_buffer, vertex_pending) = cmd_buf_data + .trackers + .buffers + .set_single( + &*match buffer_guard.get(mesh.vertex_buffer) { + Ok(buffer) => buffer, + Err(_) => { + return Err(BuildAccelerationStructureError::InvalidBuffer( + mesh.vertex_buffer, + )) + } + }, + BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + ) + .ok_or(BuildAccelerationStructureError::InvalidBuffer( + mesh.vertex_buffer, + ))?; + let index_data = if let Some(index_id) = mesh.index_buffer { if mesh.index_buffer_offset.is_none() || mesh.size.index_count.is_none() || mesh.size.index_count.is_none() @@ -916,83 +916,22 @@ impl Global { ), ); } - let (index_buffer, index_pending) = cmd_buf_data + let data = cmd_buf_data .trackers .buffers .set_single( &*match buffer_guard.get(index_id) { Ok(buffer) => buffer, - Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( index_id, )), + Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(index_id)) }, }, hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer(index_id))?; - let index_raw = index_buffer - .raw - .as_ref() - .ok_or(BuildAccelerationStructureError::InvalidBuffer(index_id))?; - if !index_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - index_id, - ), - ); - } - if let Some(barrier) = - index_pending.map(|pending| pending.into_hal(index_buffer.deref())) - { - input_barriers.push(barrier); - } - let index_stride = match mesh.size.index_format.unwrap() { - wgt::IndexFormat::Uint16 => 2, - wgt::IndexFormat::Uint32 => 4, - }; - if mesh.index_buffer_offset.unwrap() % index_stride != 0 { - return Err( - BuildAccelerationStructureError::UnalignedIndexBufferOffset( - index_id, - ), - ); - } - let index_buffer_size = - mesh.size.index_count.unwrap() as u64 * index_stride; - - if mesh.size.index_count.unwrap() % 3 != 0 { - return Err(BuildAccelerationStructureError::InvalidIndexCount( - index_id, - mesh.size.index_count.unwrap(), - )); - } - if index_buffer.size - < mesh.size.index_count.unwrap() as u64 * index_stride - + mesh.index_buffer_offset.unwrap() - { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - index_id, - index_buffer.size, - mesh.size.index_count.unwrap() as u64 * index_stride - + mesh.index_buffer_offset.unwrap(), - ), - ); - } - - cmd_buf_data.buffer_memory_init_actions.extend( - index_buffer.initialization_status.read().create_action( - match buffer_guard.get(index_id) { - Ok(buffer) => buffer, - Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( index_id, )), - }, - mesh.index_buffer_offset.unwrap() - ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), - MemoryInitKind::NeedsInitializedMemory, - ), - ); - Some(index_raw) + Some(data) } else { None }; - let transform_buffer = if let Some(transform_id) = mesh.transform_buffer { + let transform_data = if let Some(transform_id) = mesh.transform_buffer { if mesh.transform_buffer_offset.is_none() { return Err( BuildAccelerationStructureError::MissingAssociatedData( @@ -1000,110 +939,253 @@ impl Global { ), ); } - let (transform_buffer, transform_pending) = cmd_buf_data + let data = cmd_buf_data .trackers .buffers .set_single( &*match buffer_guard.get(transform_id) { Ok(buffer) => buffer, - Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( transform_id, )), + Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(transform_id)) }, }, - hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer( transform_id, ))?; - let transform_raw = transform_buffer.raw.ok_or( - BuildAccelerationStructureError::InvalidBuffer(transform_id), - )?; - if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - transform_id, - ), - ); - } - if let Some(barrier) = - transform_pending.map(|pending| pending.into_hal(transform_buffer.deref())) - { - input_barriers.push(barrier); - } - if mesh.transform_buffer_offset.unwrap() - % wgt::TRANSFORM_BUFFER_ALIGNMENT - != 0 - { - return Err( - BuildAccelerationStructureError::UnalignedTransformBufferOffset( - transform_id, - ), - ); - } - if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - transform_id, - transform_buffer.size, - 48 + mesh.transform_buffer_offset.unwrap(), - ), - ); - } - cmd_buf_data.buffer_memory_init_actions.extend( - transform_buffer.initialization_status.read().create_action( - match buffer_guard.get(transform_id) { - Ok(buf) => buf, - Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer(transform_id)), - }, - mesh.transform_buffer_offset.unwrap() - ..(mesh.index_buffer_offset.unwrap() + 48), - MemoryInitKind::NeedsInitializedMemory, - ), - ); - Some(transform_raw) + Some(data) } else { None }; - let triangles = hal::AccelerationStructureTriangles { - vertex_buffer: Some(vertex_buffer), - vertex_format: mesh.size.vertex_format, - first_vertex: mesh.first_vertex, - vertex_count: mesh.size.vertex_count, - vertex_stride: mesh.vertex_stride, - indices: index_buffer.map(|index_buffer| { - hal::AccelerationStructureTriangleIndices { - format: mesh.size.index_format.unwrap(), - buffer: Some(index_buffer), - offset: mesh.index_buffer_offset.unwrap() as u32, - count: mesh.size.index_count.unwrap(), - } - }), - transform: transform_buffer.as_ref().map(|transform_buffer| { - hal::AccelerationStructureTriangleTransform { - buffer: transform_buffer, - offset: mesh.transform_buffer_offset.unwrap() as u32, - } - }), - flags: mesh.size.flags, - }; + buf_storage.push((vertex_buffer, vertex_pending, index_data, transform_data, mesh, None)) + } - triangle_entries.push(triangles); + if let Some(last) = buf_storage.last_mut() { + last.5 = Some(blas.clone()); } + } + } + } - let scratch_buffer_offset = scratch_buffer_blas_size; - scratch_buffer_blas_size += align_to( - blas.size_info.build_scratch_size as u32, - SCRATCH_BUFFER_ALIGNMENT, - ) as u64; - - blas_storage.push(( - blas, - hal::AccelerationStructureEntries::Triangles(triangle_entries), - scratch_buffer_offset, - )) + let mut triangle_entries = Vec::>::new(); + for buf in &mut buf_storage { + let mesh = &buf.4; + let vertex_buffer = { + let vertex_buffer = buf.0.as_ref(); + let vertex_raw = vertex_buffer.raw.as_ref().ok_or( + BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer), + )?; + if !vertex_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + mesh.vertex_buffer, + ), + ); } + if let Some(barrier) = + buf.1.take().map(|pending| pending.into_hal(&vertex_buffer)) + { + input_barriers.push(barrier); + } + if vertex_buffer.size + < (mesh.size.vertex_count + mesh.first_vertex) as u64 + * mesh.vertex_stride + { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + mesh.vertex_buffer, + vertex_buffer.size, + (mesh.size.vertex_count + mesh.first_vertex) as u64 + * mesh.vertex_stride, + ), + ); + } + let vertex_buffer_offset = + mesh.first_vertex as u64 * mesh.vertex_stride; + cmd_buf_data.buffer_memory_init_actions.extend( + vertex_buffer.initialization_status.read().create_action( + buffer_guard.get(mesh.vertex_buffer).unwrap(), + vertex_buffer_offset + ..(vertex_buffer_offset + + mesh.size.vertex_count as u64 * mesh.vertex_stride), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + vertex_raw + }; + let index_buffer = if let Some((ref mut index_buffer, ref mut index_pending)) = buf.2 { + let index_id = mesh.index_buffer.as_ref().unwrap(); + let index_raw = index_buffer + .raw + .as_ref() + .ok_or(BuildAccelerationStructureError::InvalidBuffer(*index_id))?; + if !index_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + *index_id, + ), + ); + } + if let Some(barrier) = + index_pending.take().map(|pending| pending.into_hal(index_buffer)) + { + input_barriers.push(barrier); + } + let index_stride = match mesh.size.index_format.unwrap() { + wgt::IndexFormat::Uint16 => 2, + wgt::IndexFormat::Uint32 => 4, + }; + if mesh.index_buffer_offset.unwrap() % index_stride != 0 { + return Err( + BuildAccelerationStructureError::UnalignedIndexBufferOffset( + *index_id, + ), + ); + } + let index_buffer_size = + mesh.size.index_count.unwrap() as u64 * index_stride; + + if mesh.size.index_count.unwrap() % 3 != 0 { + return Err(BuildAccelerationStructureError::InvalidIndexCount( + *index_id, + mesh.size.index_count.unwrap(), + )); + } + if index_buffer.size + < mesh.size.index_count.unwrap() as u64 * index_stride + + mesh.index_buffer_offset.unwrap() + { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + *index_id, + index_buffer.size, + mesh.size.index_count.unwrap() as u64 * index_stride + + mesh.index_buffer_offset.unwrap(), + ), + ); + } + + cmd_buf_data.buffer_memory_init_actions.extend( + index_buffer.initialization_status.read().create_action( + match buffer_guard.get(*index_id) { + Ok(buffer) => buffer, + Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( *index_id, )), + }, + mesh.index_buffer_offset.unwrap() + ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + Some(index_raw) + } else { + None + }; + let transform_buffer = if let Some((ref mut transform_buffer, ref mut transform_pending)) = buf.3 { + let transform_id = mesh.transform_buffer.as_ref().unwrap(); + if mesh.transform_buffer_offset.is_none() { + return Err( + BuildAccelerationStructureError::MissingAssociatedData( + *transform_id, + ), + ); + } + let transform_raw = transform_buffer.raw.as_ref().ok_or( + BuildAccelerationStructureError::InvalidBuffer(*transform_id), + )?; + if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + *transform_id, + ), + ); + } + if let Some(barrier) = + transform_pending.take().map(|pending| pending.into_hal(transform_buffer)) + { + input_barriers.push(barrier); + } + if mesh.transform_buffer_offset.unwrap() + % wgt::TRANSFORM_BUFFER_ALIGNMENT + != 0 + { + return Err( + BuildAccelerationStructureError::UnalignedTransformBufferOffset( + *transform_id, + ), + ); + } + if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + *transform_id, + transform_buffer.size, + 48 + mesh.transform_buffer_offset.unwrap(), + ), + ); + } + cmd_buf_data.buffer_memory_init_actions.extend( + transform_buffer.initialization_status.read().create_action( + buffer_guard.get(*transform_id).unwrap(), + mesh.transform_buffer_offset.unwrap() + ..(mesh.index_buffer_offset.unwrap() + 48), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + Some(transform_raw) + } else { + None + }; + + let triangles = hal::AccelerationStructureTriangles { + vertex_buffer: Some(vertex_buffer), + vertex_format: mesh.size.vertex_format, + first_vertex: mesh.first_vertex, + vertex_count: mesh.size.vertex_count, + vertex_stride: mesh.vertex_stride, + indices: index_buffer.map(|index_buffer| { + hal::AccelerationStructureTriangleIndices:: { + format: mesh.size.index_format.unwrap(), + buffer: Some(index_buffer), + offset: mesh.index_buffer_offset.unwrap() as u32, + count: mesh.size.index_count.unwrap(), + } + }), + transform: transform_buffer.map(|transform_buffer| { + hal::AccelerationStructureTriangleTransform { + buffer: transform_buffer, + offset: mesh.transform_buffer_offset.unwrap() as u32, + } + }), + flags: mesh.size.flags, + }; + triangle_entries.push(triangles); + if let Some(blas) = buf.5.as_ref() { + let scratch_buffer_offset = scratch_buffer_blas_size; + scratch_buffer_blas_size += align_to( + blas.size_info.build_scratch_size as u32, + SCRATCH_BUFFER_ALIGNMENT, + ) as u64; + + blas_storage.push(( + &*blas, + hal::AccelerationStructureEntries::Triangles(triangle_entries), + scratch_buffer_offset, + )); + triangle_entries = Vec::new(); } } + let mut tlas_lock_store = Vec::<(RwLockReadGuard>, Option, Arc>)>::new(); + + for package in tlas_iter { + let tlas = cmd_buf_data + .trackers + .tlas_s + .add_single(&tlas_guard, package.tlas_id) + .ok_or(BuildAccelerationStructureError::InvalidTlas(package.tlas_id))?; + tlas_lock_store.push((tlas.instance_buffer.read(), Some(package), tlas.clone())) + } + let mut scratch_buffer_tlas_size = 0; let mut tlas_storage = Vec::<( &Tlas, @@ -1113,15 +1195,11 @@ impl Global { )>::new(); let mut instance_buffer_staging_source = Vec::::new(); - for entry in tlas_iter { - let tlas = cmd_buf_data - .trackers - .tlas_s - .add_single(&tlas_guard, entry.tlas_id) - .ok_or(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id))?; - + for entry in &mut tlas_lock_store { + let package = entry.1.take().unwrap(); + let tlas = &entry.2; if tlas.raw.is_none() { - return Err(BuildAccelerationStructureError::InvalidTlas(entry.tlas_id)); + return Err(BuildAccelerationStructureError::InvalidTlas(package.tlas_id)); } let scratch_buffer_offset = scratch_buffer_tlas_size; @@ -1135,10 +1213,10 @@ impl Global { let mut dependencies = Vec::new(); let mut instance_count = 0; - for instance in entry.instances.flatten() { + for instance in package.instances.flatten() { if instance.custom_index >= (1u32 << 24u32) { return Err(BuildAccelerationStructureError::TlasInvalidCustomIndex( - entry.tlas_id, + package.tlas_id, )); } let blas = cmd_buf_data @@ -1163,7 +1241,7 @@ impl Global { } cmd_buf_data.tlas_actions.push(TlasAction { - id: entry.tlas_id, + id: package .tlas_id, kind: crate::ray_tracing::TlasActionKind::Build { build_index: build_command_index, dependencies, @@ -1172,7 +1250,7 @@ impl Global { if instance_count > tlas.max_instance_count { return Err(BuildAccelerationStructureError::TlasInstanceCountExceeded( - entry.tlas_id, + package.tlas_id, instance_count, tlas.max_instance_count, )); @@ -1181,7 +1259,7 @@ impl Global { tlas_storage.push(( tlas, hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { - buffer: Some(tlas.instance_buffer.read().as_ref().unwrap()), + buffer: Some(entry.0.as_ref().unwrap()), offset: 0, count: instance_count, }), @@ -1289,18 +1367,26 @@ impl Global { ..BufferUses::ACCELERATION_STRUCTURE_SCRATCH, }; - let instance_buffer_barriers = tlas_storage.iter().filter_map( - |&(tlas, ref _entries, ref _scratch_buffer_offset, ref range)| { - let size = (range.end - range.start) as u64; - if size == 0 { - None - } else { - Some(hal::BufferBarrier:: { - buffer: tlas.instance_buffer.read().as_ref().unwrap(), + let mut lock_vec = Vec::::Buffer>>>>::new(); + + for tlas in &tlas_storage { + let size = (tlas.3.end - tlas.3.start) as u64; + lock_vec.push(if size == 0 { + None + } else { + Some(tlas.0.instance_buffer.read()) + }) + } + + let instance_buffer_barriers = lock_vec.iter().filter_map( + |lock| { + lock.as_ref().map(|lock| { + hal::BufferBarrier:: { + buffer: lock.as_ref().unwrap(), usage: BufferUses::COPY_DST ..BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, - }) - } + } + }) }, ); From 5efddd76a8da72be238b90e94e78cbf4131715fa Mon Sep 17 00:00:00 2001 From: Vecvec Date: Sun, 10 Dec 2023 18:22:07 +1300 Subject: [PATCH 104/146] fix clippy errors --- wgpu-core/src/command/ray_tracing.rs | 32 ++++++++++++++-------------- wgpu/src/backend/direct.rs | 17 ++++++--------- wgpu/src/context.rs | 26 +++++++++++----------- wgpu/src/ray_tracing.rs | 32 ++++++++++++++-------------- 4 files changed, 52 insertions(+), 55 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 967d963f4b..05f7c8a5d2 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -198,7 +198,7 @@ impl Global { .trackers .buffers .set_single( - &*match buffer_guard.get(mesh.vertex_buffer) { + match buffer_guard.get(mesh.vertex_buffer) { Ok(buffer) => buffer, Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer( @@ -226,7 +226,7 @@ impl Global { .trackers .buffers .set_single( - &*match buffer_guard.get(index_id) { + match buffer_guard.get(index_id) { Ok(buffer) => buffer, Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(index_id)) }, }, @@ -249,7 +249,7 @@ impl Global { .trackers .buffers .set_single( - &*match buffer_guard.get(transform_id) { + match buffer_guard.get(transform_id) { Ok(buffer) => buffer, Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(transform_id)) }, }, @@ -288,7 +288,7 @@ impl Global { ); } if let Some(barrier) = - buf.1.take().map(|pending| pending.into_hal(&vertex_buffer)) + buf.1.take().map(|pending| pending.into_hal(vertex_buffer)) { input_barriers.push(barrier); } @@ -472,7 +472,7 @@ impl Global { ) as u64; blas_storage.push(( - &*blas, + blas, hal::AccelerationStructureEntries::Triangles(triangle_entries), scratch_buffer_offset, )); @@ -489,7 +489,7 @@ impl Global { .trackers .buffers .set_single( - &*match buffer_guard.get(entry.instance_buffer_id) { + match buffer_guard.get(entry.instance_buffer_id) { Ok(buffer) => buffer, Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer(entry.instance_buffer_id, )), }, @@ -554,7 +554,7 @@ impl Global { tlas_storage.push(( tlas, hal::AccelerationStructureEntries::Instances(hal::AccelerationStructureInstances { - buffer: Some(&instance_buffer), + buffer: Some(instance_buffer), offset: 0, count: entry.instance_count, }), @@ -892,7 +892,7 @@ impl Global { .trackers .buffers .set_single( - &*match buffer_guard.get(mesh.vertex_buffer) { + match buffer_guard.get(mesh.vertex_buffer) { Ok(buffer) => buffer, Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer( @@ -920,7 +920,7 @@ impl Global { .trackers .buffers .set_single( - &*match buffer_guard.get(index_id) { + match buffer_guard.get(index_id) { Ok(buffer) => buffer, Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(index_id)) }, }, @@ -943,7 +943,7 @@ impl Global { .trackers .buffers .set_single( - &*match buffer_guard.get(transform_id) { + match buffer_guard.get(transform_id) { Ok(buffer) => buffer, Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(transform_id)) }, }, @@ -983,7 +983,7 @@ impl Global { ); } if let Some(barrier) = - buf.1.take().map(|pending| pending.into_hal(&vertex_buffer)) + buf.1.take().map(|pending| pending.into_hal(vertex_buffer)) { input_barriers.push(barrier); } @@ -1167,7 +1167,7 @@ impl Global { ) as u64; blas_storage.push(( - &*blas, + blas, hal::AccelerationStructureEntries::Triangles(triangle_entries), scratch_buffer_offset, )); @@ -1540,7 +1540,7 @@ impl BakedCommands { let blas = blas_guard .get(action.id) .map_err(|_| ValidateBlasActionsError::InvalidBlas(action.id))?; - if *blas.built_index.read() == None { + if (*blas.built_index.read()).is_none() { return Err(ValidateBlasActionsError::UsedUnbuilt(action.id)); } } @@ -1578,15 +1578,15 @@ impl BakedCommands { let tlas_build_index = tlas.built_index.read(); let dependencies = tlas.dependencies.read(); - if *tlas_build_index == None { + if (*tlas_build_index).is_none() { return Err(ValidateTlasActionsError::UsedUnbuilt(action.id)); } for dependency in dependencies.deref() { let blas = blas_guard.get(*dependency).map_err(|_| { ValidateTlasActionsError::InvalidBlas(*dependency, action.id) })?; - let blas_build_index = blas.built_index.read().clone(); - if blas_build_index == None { + let blas_build_index = *blas.built_index.read(); + if blas_build_index.is_none() { return Err(ValidateTlasActionsError::UsedUnbuilt(action.id)); } if blas_build_index.unwrap() > tlas_build_index.unwrap() { diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 2b52dcae3a..e4d2c1b299 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -3146,7 +3146,7 @@ impl crate::Context for Context { ) { let global = &self.0; - let blas = blas.map(|e: crate::ray_tracing::ContextBlasBuildEntry| { + let blas = blas.map(|e: crate::ray_tracing::ContextBlasBuildEntry<'_, Self>| { let geometries = match e.geometries { crate::ray_tracing::ContextBlasGeometries::TriangleGeometries( triangle_geometries, @@ -3204,7 +3204,7 @@ impl crate::Context for Context { ) { let global = &self.0; - let blas = blas.map(|e: crate::ray_tracing::ContextBlasBuildEntry| { + let blas = blas.map(|e: crate::ray_tracing::ContextBlasBuildEntry<'_, Self>| { let geometries = match e.geometries { crate::ray_tracing::ContextBlasGeometries::TriangleGeometries( triangle_geometries, @@ -3231,18 +3231,15 @@ impl crate::Context for Context { }); let tlas = tlas.into_iter().map(|e| { - let instances = e.instances.into_iter().map( - |instance: Option>| { - if let Some(instance) = instance { - Some(wgc::ray_tracing::TlasInstance { + let instances = e.instances.map( + |instance: Option>| { + instance.map(|instance| + wgc::ray_tracing::TlasInstance { blas_id: instance.blas_id, transform: instance.transform, custom_index: instance.custom_index, mask: instance.mask, - }) - } else { - None - } + }) }, ); wgc::ray_tracing::TlasPackage { diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 8189ff3b4b..b47654071e 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -74,9 +74,9 @@ pub trait Context: Debug + WasmNotSendSync + Sized { type SurfaceId: ContextId + WasmNotSendSync; type SurfaceData: ContextData; - type BlasId: ContextId + WasmNotSend + WasmNotSync; + type BlasId: ContextId + WasmNotSendSync; type BlasData: ContextData; - type TlasId: ContextId + WasmNotSend + WasmNotSync; + type TlasId: ContextId + WasmNotSendSync; type TlasData: ContextData; type SurfaceOutputDetail: WasmNotSendSync + 'static; @@ -1036,14 +1036,14 @@ pub trait Context: Debug + WasmNotSendSync + Sized { &self, device: &Self::DeviceId, device_data: &Self::DeviceData, - desc: &crate::ray_tracing::CreateBlasDescriptor, + desc: &crate::ray_tracing::CreateBlasDescriptor<'_>, sizes: wgt::BlasGeometrySizeDescriptors, ) -> (Self::BlasId, Option, Self::BlasData); fn device_create_tlas( &self, device: &Self::DeviceId, device_data: &Self::DeviceData, - desc: &crate::ray_tracing::CreateTlasDescriptor, + desc: &crate::ray_tracing::CreateTlasDescriptor<'_>, ) -> (Self::TlasId, Self::TlasData); fn command_encoder_build_acceleration_structures_unsafe_tlas<'a>( &'a self, @@ -2115,14 +2115,14 @@ pub(crate) trait DynContext: Debug + WasmNotSendSync { &self, device: &ObjectId, device_data: &crate::Data, - desc: &crate::ray_tracing::CreateBlasDescriptor, + desc: &crate::ray_tracing::CreateBlasDescriptor<'_>, sizes: wgt::BlasGeometrySizeDescriptors, ) -> (ObjectId, Option, Box); fn device_create_tlas( &self, device: &ObjectId, device_data: &crate::Data, - desc: &crate::ray_tracing::CreateTlasDescriptor, + desc: &crate::ray_tracing::CreateTlasDescriptor<'_>, ) -> (ObjectId, Box); fn command_encoder_build_acceleration_structures_unsafe_tlas<'a>( &self, @@ -2136,7 +2136,7 @@ pub(crate) trait DynContext: Debug + WasmNotSendSync { encoder: &ObjectId, encoder_data: &crate::Data, blas: &mut dyn Iterator>, - tlas: &mut dyn Iterator, + tlas: &mut dyn Iterator>, ); fn blas_destroy(&self, blas: &ObjectId, blas_data: &crate::Data); fn blas_drop(&self, blas: &ObjectId, blas_data: &crate::Data); @@ -4160,7 +4160,7 @@ where &self, device: &ObjectId, device_data: &crate::Data, - desc: &crate::ray_tracing::CreateBlasDescriptor, + desc: &crate::ray_tracing::CreateBlasDescriptor<'_>, sizes: wgt::BlasGeometrySizeDescriptors, ) -> (ObjectId, Option, Box) { let device = ::from(*device); @@ -4174,7 +4174,7 @@ where &self, device: &ObjectId, device_data: &crate::Data, - desc: &crate::ray_tracing::CreateTlasDescriptor, + desc: &crate::ray_tracing::CreateTlasDescriptor<'_>, ) -> (ObjectId, Box) { let device = ::from(*device); let device_data = downcast_ref(device_data); @@ -4245,7 +4245,7 @@ where encoder: &ObjectId, encoder_data: &crate::Data, blas: &mut dyn Iterator>, - tlas: &mut dyn Iterator, + tlas: &mut dyn Iterator>, ) { let encoder = ::from(*encoder); let encoder_data = downcast_ref(encoder_data); @@ -4279,9 +4279,9 @@ where let tlas = tlas .into_iter() - .map(|e: crate::ray_tracing::DynContextTlasPackage| { - let instances = e.instances.into_iter().map( - |instance: Option| { + .map(|e: crate::ray_tracing::DynContextTlasPackage<'_>| { + let instances = e.instances.map( + |instance: Option>| { instance.map(|instance| crate::ray_tracing::ContextTlasInstance { blas_id: ::from(instance.blas), transform: instance.transform, diff --git a/wgpu/src/ray_tracing.rs b/wgpu/src/ray_tracing.rs index e25e36fdcb..e6533dedc7 100644 --- a/wgpu/src/ray_tracing.rs +++ b/wgpu/src/ray_tracing.rs @@ -27,11 +27,11 @@ static_assertions::assert_impl_all!(AccelerationStructureUpdateMode: Send, Sync) /// Descriptor to create bottom level acceleration structures. pub type CreateBlasDescriptor<'a> = wgt::CreateBlasDescriptor>; -static_assertions::assert_impl_all!(CreateBlasDescriptor: Send, Sync); +static_assertions::assert_impl_all!(CreateBlasDescriptor<'_>: Send, Sync); /// Descriptor to create top level acceleration structures. pub type CreateTlasDescriptor<'a> = wgt::CreateTlasDescriptor>; -static_assertions::assert_impl_all!(CreateTlasDescriptor: Send, Sync); +static_assertions::assert_impl_all!(CreateTlasDescriptor<'_>: Send, Sync); #[derive(Debug)] /// Definition for a triangle geometry. @@ -55,14 +55,14 @@ pub struct BlasTriangleGeometry<'a> { /// Transform buffer offset in bytes (optional, required if transform buffer is present). pub transform_buffer_offset: Option, } -static_assertions::assert_impl_all!(BlasTriangleGeometry: Send, Sync); +static_assertions::assert_impl_all!(BlasTriangleGeometry<'_>: Send, Sync); /// Geometries for a bottom level acceleration structure. pub enum BlasGeometries<'a> { /// Triangle geometry variant. TriangleGeometries(Vec>), } -static_assertions::assert_impl_all!(BlasGeometries: Send, Sync); +static_assertions::assert_impl_all!(BlasGeometries<'_>: Send, Sync); /// Entry for a bottom level acceleration structure build. pub struct BlasBuildEntry<'a> { @@ -71,7 +71,7 @@ pub struct BlasBuildEntry<'a> { /// Geometries. pub geometry: BlasGeometries<'a>, } -static_assertions::assert_impl_all!(BlasBuildEntry: Send, Sync); +static_assertions::assert_impl_all!(BlasBuildEntry<'_>: Send, Sync); #[derive(Debug)] /// Bottom level acceleration structure. @@ -138,7 +138,7 @@ pub struct TlasBuildEntry<'a> { /// Number of instances in the instance buffer. pub instance_count: u32, } -static_assertions::assert_impl_all!(TlasBuildEntry: Send, Sync); +static_assertions::assert_impl_all!(TlasBuildEntry<'_>: Send, Sync); /// Safe instance for a top level acceleration structure. #[derive(Debug, Clone)] @@ -247,7 +247,7 @@ impl TlasPackage { } /// Get the binding resource for the underling acceleration structure, to be used in a - pub fn as_binding(&self) -> BindingResource { + pub fn as_binding(&self) -> BindingResource<'_> { BindingResource::AccelerationStructure(&self.tlas) } @@ -337,15 +337,15 @@ pub trait DeviceRayTracing { /// Create a bottom level acceleration structure, used inside a top level acceleration structure for ray tracing. /// - desc: The descriptor of the acceleration structure. /// - sizes: Size descriptor limiting what can be built into the acceleration structure. - fn create_blas(&self, desc: &CreateBlasDescriptor, sizes: BlasGeometrySizeDescriptors) -> Blas; + fn create_blas(&self, desc: &CreateBlasDescriptor<'_>, sizes: BlasGeometrySizeDescriptors) -> Blas; /// Create a top level acceleration structure, used for ray tracing. /// - desc: The descriptor of the acceleration structure. - fn create_tlas(&self, desc: &CreateTlasDescriptor) -> Tlas; + fn create_tlas(&self, desc: &CreateTlasDescriptor<'_>) -> Tlas; } impl DeviceRayTracing for Device { - fn create_blas(&self, desc: &CreateBlasDescriptor, sizes: BlasGeometrySizeDescriptors) -> Blas { + fn create_blas(&self, desc: &CreateBlasDescriptor<'_>, sizes: BlasGeometrySizeDescriptors) -> Blas { let (id, handle, data) = DynContext::device_create_blas( &*self.context, &self.id, @@ -362,7 +362,7 @@ impl DeviceRayTracing for Device { } } - fn create_tlas(&self, desc: &CreateTlasDescriptor) -> Tlas { + fn create_tlas(&self, desc: &CreateTlasDescriptor<'_>) -> Tlas { let (id, data) = DynContext::device_create_tlas(&*self.context, &self.id, self.data.as_ref(), desc); @@ -425,10 +425,10 @@ impl CommandEncoderRayTracing for CommandEncoder { ) { let id = self.id.as_ref().unwrap(); - let mut blas = blas.into_iter().map(|e: &BlasBuildEntry| { + let mut blas = blas.into_iter().map(|e: &BlasBuildEntry<'_>| { let geometries = match &e.geometry { BlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry| { + let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry<'_>| { DynContextBlasTriangleGeometry { size: tg.size, vertex_buffer: tg.vertex_buffer.id, @@ -486,10 +486,10 @@ impl CommandEncoderRayTracing for CommandEncoder { ) { let id = self.id.as_ref().unwrap(); - let mut blas = blas.into_iter().map(|e: &BlasBuildEntry| { + let mut blas = blas.into_iter().map(|e: &BlasBuildEntry<'_>| { let geometries = match &e.geometry { BlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry| { + let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry<'_>| { DynContextBlasTriangleGeometry { size: tg.size, vertex_buffer: tg.vertex_buffer.id, @@ -517,7 +517,7 @@ impl CommandEncoderRayTracing for CommandEncoder { let mut tlas = tlas .into_iter() - .map(|e: &TlasBuildEntry| DynContextTlasBuildEntry { + .map(|e: &TlasBuildEntry<'_>| DynContextTlasBuildEntry { tlas_id: e.tlas.id, instance_buffer_id: e.instance_buffer.id, instance_count: e.instance_count, From b7486bdcfcc458c7af067c05ac3e63714d871d91 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Sun, 10 Dec 2023 18:41:43 +1300 Subject: [PATCH 105/146] fix issues in ray-traced-triangle example --- wgpu-hal/examples/ray-traced-triangle/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 7202b35bee..6454cb8998 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -555,7 +555,6 @@ impl Example { dimension: wgt::TextureViewDimension::D2, usage: hal::TextureUses::STORAGE_READ_WRITE | hal::TextureUses::COPY_SRC, range: wgt::ImageSubresourceRange::default(), - plane: None, }; let texture_view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() }; @@ -888,7 +887,6 @@ impl Example { dimension: wgt::TextureViewDimension::D2, usage: hal::TextureUses::COPY_DST, range: wgt::ImageSubresourceRange::default(), - plane: None, }; let surface_tex_view = unsafe { self.device From 2f49af2a625ea74957e0d29755a4291bfd618751 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Sun, 10 Dec 2023 18:43:38 +1300 Subject: [PATCH 106/146] fix clippy warnings --- wgpu/src/context.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 577e6cfba1..dcd562fd4d 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -2124,18 +2124,18 @@ pub(crate) trait DynContext: Debug + WasmNotSendSync { device_data: &crate::Data, desc: &crate::ray_tracing::CreateTlasDescriptor<'_>, ) -> (ObjectId, Box); - fn command_encoder_build_acceleration_structures_unsafe_tlas<'a>( + fn command_encoder_build_acceleration_structures_unsafe_tlas( &self, encoder: &ObjectId, encoder_data: &crate::Data, - blas: &mut dyn Iterator>, + blas: &mut dyn Iterator>, tlas: &mut dyn Iterator, ); - fn command_encoder_build_acceleration_structures<'a>( + fn command_encoder_build_acceleration_structures( &self, encoder: &ObjectId, encoder_data: &crate::Data, - blas: &mut dyn Iterator>, + blas: &mut dyn Iterator>, tlas: &mut dyn Iterator>, ); fn blas_destroy(&self, blas: &ObjectId, blas_data: &crate::Data); @@ -4182,11 +4182,11 @@ where (tlas.into(), Box::new(data) as _) } - fn command_encoder_build_acceleration_structures_unsafe_tlas<'a>( + fn command_encoder_build_acceleration_structures_unsafe_tlas( &self, encoder: &ObjectId, encoder_data: &crate::Data, - blas: &mut dyn Iterator>, + blas: &mut dyn Iterator>, tlas: &mut dyn Iterator, ) { let encoder = ::from(*encoder); @@ -4240,11 +4240,11 @@ where ) } - fn command_encoder_build_acceleration_structures<'a>( + fn command_encoder_build_acceleration_structures( &self, encoder: &ObjectId, encoder_data: &crate::Data, - blas: &mut dyn Iterator>, + blas: &mut dyn Iterator>, tlas: &mut dyn Iterator>, ) { let encoder = ::from(*encoder); From 014d283df516751cdea1aa59c744d7fde5e6c8a0 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Sun, 10 Dec 2023 19:10:58 +1300 Subject: [PATCH 107/146] fix wasm not compiling --- wgpu/src/ray_tracing.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/wgpu/src/ray_tracing.rs b/wgpu/src/ray_tracing.rs index e6533dedc7..71e339b4a3 100644 --- a/wgpu/src/ray_tracing.rs +++ b/wgpu/src/ray_tracing.rs @@ -1,4 +1,5 @@ use std::{fmt::Debug, ops::Range, sync::Arc, thread}; +use wgt::WasmNotSendSync; use crate::{ context::{Context, DynContext, ObjectId}, @@ -55,14 +56,14 @@ pub struct BlasTriangleGeometry<'a> { /// Transform buffer offset in bytes (optional, required if transform buffer is present). pub transform_buffer_offset: Option, } -static_assertions::assert_impl_all!(BlasTriangleGeometry<'_>: Send, Sync); +static_assertions::assert_impl_all!(BlasTriangleGeometry<'_>: WasmNotSendSync); /// Geometries for a bottom level acceleration structure. pub enum BlasGeometries<'a> { /// Triangle geometry variant. TriangleGeometries(Vec>), } -static_assertions::assert_impl_all!(BlasGeometries<'_>: Send, Sync); +static_assertions::assert_impl_all!(BlasGeometries<'_>: WasmNotSendSync); /// Entry for a bottom level acceleration structure build. pub struct BlasBuildEntry<'a> { @@ -71,7 +72,7 @@ pub struct BlasBuildEntry<'a> { /// Geometries. pub geometry: BlasGeometries<'a>, } -static_assertions::assert_impl_all!(BlasBuildEntry<'_>: Send, Sync); +static_assertions::assert_impl_all!(BlasBuildEntry<'_>: WasmNotSendSync); #[derive(Debug)] /// Bottom level acceleration structure. @@ -82,7 +83,7 @@ pub struct Blas { pub(crate) data: Box, pub(crate) handle: Option, } -static_assertions::assert_impl_all!(Blas: Send, Sync); +static_assertions::assert_impl_all!(Blas: WasmNotSendSync); impl Blas { /// Raw handle to the acceleration structure, used inside raw instance buffers. @@ -111,7 +112,7 @@ pub struct Tlas { pub(crate) id: ObjectId, pub(crate) data: Box, } -static_assertions::assert_impl_all!(Tlas: Send, Sync); +static_assertions::assert_impl_all!(Tlas: WasmNotSendSync); impl Tlas { /// Destroy the associated native resources as soon as possible. @@ -138,7 +139,7 @@ pub struct TlasBuildEntry<'a> { /// Number of instances in the instance buffer. pub instance_count: u32, } -static_assertions::assert_impl_all!(TlasBuildEntry<'_>: Send, Sync); +static_assertions::assert_impl_all!(TlasBuildEntry<'_>: WasmNotSendSync); /// Safe instance for a top level acceleration structure. #[derive(Debug, Clone)] @@ -194,7 +195,7 @@ pub struct TlasPackage { pub(crate) instances: Vec>, pub(crate) lowest_unmodified: u32, } -static_assertions::assert_impl_all!(TlasPackage: Send, Sync); +static_assertions::assert_impl_all!(TlasPackage: WasmNotSendSync); impl TlasPackage { /// Construct TlasPackage consuming the Tlas (prevents modification of the Tlas without using this package). From 6a6345c60621670395cf22cb8255a8f2ea8b60b5 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Sun, 10 Dec 2023 19:29:21 +1300 Subject: [PATCH 108/146] fix test --- tests/tests/ray_tracing/mesh_gen.rs | 2 +- tests/tests/ray_tracing/mod.rs | 197 ++++++++++++++-------------- 2 files changed, 101 insertions(+), 98 deletions(-) diff --git a/tests/tests/ray_tracing/mesh_gen.rs b/tests/tests/ray_tracing/mesh_gen.rs index 0c7bb61132..8bc4b03b7d 100644 --- a/tests/tests/ray_tracing/mesh_gen.rs +++ b/tests/tests/ray_tracing/mesh_gen.rs @@ -1,5 +1,5 @@ use bytemuck::{Pod, Zeroable}; -use glam::{Affine3A, Mat4, Quat, Vec3}; +use glam::Affine3A; #[repr(C)] #[derive(Clone, Copy, Pod, Zeroable)] diff --git a/tests/tests/ray_tracing/mod.rs b/tests/tests/ray_tracing/mod.rs index e55da63fe8..2447c4f788 100644 --- a/tests/tests/ray_tracing/mod.rs +++ b/tests/tests/ray_tracing/mod.rs @@ -1,6 +1,6 @@ use std::{iter, mem}; -use wgpu_test::{initialize_test, TestParameters}; +use wgpu_test::{gpu_test, GpuTestConfiguration, TestingContext, TestParameters}; use rt::traits::*; use wgpu::ray_tracing as rt; @@ -20,102 +20,105 @@ fn required_features() -> wgpu::Features { | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE } -#[test] -fn create_tests() { - initialize_test( - TestParameters::default().features(required_features()), - |ctx| { - let max_instances = 1000; - let device = &ctx.device; - - let (vertex_data, index_data) = mesh_gen::create_vertices(); - - let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Vertex Buffer"), - contents: bytemuck::cast_slice(&vertex_data), - usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::BLAS_INPUT, - }); - - let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Index Buffer"), - contents: bytemuck::cast_slice(&index_data), - usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::BLAS_INPUT, - }); - - let blas_geo_size_desc = rt::BlasTriangleGeometrySizeDescriptor { - vertex_format: wgpu::VertexFormat::Float32x4, - vertex_count: vertex_data.len() as u32, - index_format: Some(wgpu::IndexFormat::Uint16), - index_count: Some(index_data.len() as u32), - flags: rt::AccelerationStructureGeometryFlags::OPAQUE, - }; - - let blas = device.create_blas( - &rt::CreateBlasDescriptor { - label: None, - flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, - update_mode: rt::AccelerationStructureUpdateMode::Build, - }, - rt::BlasGeometrySizeDescriptors::Triangles { - desc: vec![blas_geo_size_desc.clone()], - }, - ); - - let tlas = device.create_tlas(&rt::CreateTlasDescriptor { - label: None, - flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, - update_mode: rt::AccelerationStructureUpdateMode::Build, - max_instances, - }); - - let mut tlas_package = rt::TlasPackage::new(tlas, max_instances); - - for i in 0..10000 { - for j in 0..max_instances { - *tlas_package.get_mut_single(0).unwrap() = Some(rt::TlasInstance::new( - &blas, - AccelerationStructureInstance::affine_to_rows( - &Affine3A::from_rotation_translation( - Quat::from_rotation_y(45.9_f32.to_radians()), - Vec3 { - x: j as f32, - y: i as f32, - z: 0.0, - }, - ), - ), - 0, - 0xff, - )); - } - - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - - encoder.build_acceleration_structures( - iter::once(&rt::BlasBuildEntry { - blas: &blas, - geometry: rt::BlasGeometries::TriangleGeometries(vec![ - rt::BlasTriangleGeometry { - size: &blas_geo_size_desc, - vertex_buffer: &vertex_buf, - first_vertex: 0, - vertex_stride: mem::size_of::() as u64, - index_buffer: Some(&index_buf), - index_buffer_offset: Some(0), - transform_buffer: None, - transform_buffer_offset: None, - }, - ]), - }), - // iter::empty(), - iter::once(&tlas_package), - ); - - ctx.queue.submit(Some(encoder.finish())); - } - - ctx.device.poll(wgpu::Maintain::Wait); +fn execute(ctx:TestingContext) { + let max_instances = 1000; + let device = &ctx.device; + + let (vertex_data, index_data) = mesh_gen::create_vertices(); + + let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(&vertex_data), + usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::BLAS_INPUT, + }); + + let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(&index_data), + usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::BLAS_INPUT, + }); + + let blas_geo_size_desc = rt::BlasTriangleGeometrySizeDescriptor { + vertex_format: wgpu::VertexFormat::Float32x4, + vertex_count: vertex_data.len() as u32, + index_format: Some(wgpu::IndexFormat::Uint16), + index_count: Some(index_data.len() as u32), + flags: rt::AccelerationStructureGeometryFlags::OPAQUE, + }; + + let blas = device.create_blas( + &rt::CreateBlasDescriptor { + label: None, + flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: rt::AccelerationStructureUpdateMode::Build, + }, + rt::BlasGeometrySizeDescriptors::Triangles { + desc: vec![blas_geo_size_desc.clone()], }, ); + + let tlas = device.create_tlas(&rt::CreateTlasDescriptor { + label: None, + flags: rt::AccelerationStructureFlags::PREFER_FAST_TRACE, + update_mode: rt::AccelerationStructureUpdateMode::Build, + max_instances, + }); + + let mut tlas_package = rt::TlasPackage::new(tlas, max_instances); + + for i in 0..10000 { + for j in 0..max_instances { + *tlas_package.get_mut_single(0).unwrap() = Some(rt::TlasInstance::new( + &blas, + AccelerationStructureInstance::affine_to_rows( + &Affine3A::from_rotation_translation( + Quat::from_rotation_y(45.9_f32.to_radians()), + Vec3 { + x: j as f32, + y: i as f32, + z: 0.0, + }, + ), + ), + 0, + 0xff, + )); + } + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + encoder.build_acceleration_structures( + iter::once(&rt::BlasBuildEntry { + blas: &blas, + geometry: rt::BlasGeometries::TriangleGeometries(vec![ + rt::BlasTriangleGeometry { + size: &blas_geo_size_desc, + vertex_buffer: &vertex_buf, + first_vertex: 0, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&index_buf), + index_buffer_offset: Some(0), + transform_buffer: None, + transform_buffer_offset: None, + }, + ]), + }), + // iter::empty(), + iter::once(&tlas_package), + ); + + ctx.queue.submit(Some(encoder.finish())); + } + + ctx.device.poll(wgpu::Maintain::Wait); } + +#[gpu_test] +static RAY_TRACING: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .test_features_limits() + .features(required_features()), + ) + .run_sync(execute); \ No newline at end of file From a636d085edb493b0d396adc548a49e3b61837d9b Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 11 Dec 2023 07:00:23 +1300 Subject: [PATCH 109/146] fix clippy (again) --- wgpu/src/lib.rs | 2 +- wgpu/src/ray_tracing.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 94c457167c..abc549312c 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -14,7 +14,7 @@ mod macros; /// Module to add ray tracing support to wgpu. /// It adds support for acceleration structures and ray queries. -/// The features [`wgpu::Features::RAY_QUERY`] and [`wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE`] where added and are required to use this module. +/// The features [`Features::RAY_QUERY`] and [`Features::RAY_TRACING_ACCELERATION_STRUCTURE`] where added and are required to use this module. /// This is an experimental feature and is not available on all backends. /// It is not part of the WebGPU standard and is only natively supported with the Vulkan backend so far. /// DirectX 12 and Metal support are planned, the API is subject to change. diff --git a/wgpu/src/ray_tracing.rs b/wgpu/src/ray_tracing.rs index 71e339b4a3..9cb08d4ae7 100644 --- a/wgpu/src/ray_tracing.rs +++ b/wgpu/src/ray_tracing.rs @@ -402,7 +402,7 @@ pub trait CommandEncoderRayTracing { ); /// Build bottom and top level acceleration structures. - /// See [`build_acceleration_structures`] for the safe version and more details. + /// See [`CommandEncoderRayTracing::build_acceleration_structures`] for the safe version and more details. /// /// # Safety /// From 5ec17355b6a353e23995e2a93e54e061b66ce79d Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 11 Dec 2023 07:11:30 +1300 Subject: [PATCH 110/146] fix some rustfmt issues --- wgpu-core/src/device/ray_tracing.rs | 58 +++++++++++++++-------------- wgpu-core/src/hub.rs | 5 +-- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 47e6ca5aec..92fe7869ce 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -1,5 +1,3 @@ -use std::sync::Arc; -use parking_lot::{Mutex, RwLock}; #[cfg(feature = "trace")] use crate::device::trace; use crate::{ @@ -13,9 +11,11 @@ use crate::{ storage::InvalidId, LabelHelpers, }; +use std::sync::Arc; +use parking_lot::{Mutex, RwLock}; -use hal::{AccelerationStructureTriangleIndices, Device as _}; use crate::resource::{ResourceInfo, StagingBuffer}; +use hal::{AccelerationStructureTriangleIndices, Device as _}; impl Device { fn create_blas( @@ -79,7 +79,11 @@ impl Device { Ok(resource::Blas { raw: Some(raw), device: self.clone(), - info: ResourceInfo::new(blas_desc.label.to_hal(self.instance_flags).unwrap_or("")), + info: ResourceInfo::new( + blas_desc.label + .to_hal(self.instance_flags) + .unwrap_or("") + ), size_info, sizes, flags: blas_desc.flags, @@ -137,7 +141,11 @@ impl Device { Ok(resource::Tlas { raw: Some(raw), device: self.clone(), - info: ResourceInfo::new(desc.label.to_hal(self.instance_flags).unwrap_or("")), + info: ResourceInfo::new( + desc.label + .to_hal(self.instance_flags) + .unwrap_or("") + ), size_info, flags: desc.flags, update_mode: desc.update_mode, @@ -183,7 +191,6 @@ impl Global { }; let handle = blas.handle; - let id = fid.assign(blas); log::info!("Created blas {:?} with {:?}", id.0, desc); @@ -294,9 +301,7 @@ impl Global { let blas = blas_guard.get(blas_id).unwrap(); { let mut life_lock = device.lock_life(); - life_lock - .suspected_resources - .insert(blas_id, blas.clone()); + life_lock.suspected_resources.insert(blas_id, blas.clone()); } if wait { @@ -331,27 +336,23 @@ impl Global { let raw_instance_buffer = tlas.instance_buffer.write().take(); let temp_instance_buffer = match raw_instance_buffer { - None => {None} + None => None, Some(e) => { - let size = get_raw_tlas_instance_size::() as u64 * std::cmp::max(tlas.max_instance_count, 1) as u64; + let size = get_raw_tlas_instance_size::() as u64 + * std::cmp::max(tlas.max_instance_count, 1) as u64; let mapping = unsafe { device .raw() - .map_buffer( - &e, - 0..size, - ) + .map_buffer(&e, 0..size) .map_err(|_| resource::DestroyError::Invalid)? }; - Some(TempResource::StagingBuffer(Arc::new( - StagingBuffer { - raw: Mutex::new(Some(e)), - device: device.clone(), - size, - info: ResourceInfo::new("Ratracing scratch buffer"), - is_coherent: mapping.is_coherent, - } - ))) + Some(TempResource::StagingBuffer(Arc::new(StagingBuffer { + raw: Mutex::new(Some(e)), + device: device.clone(), + size, + info: ResourceInfo::new("Ratracing scratch buffer"), + is_coherent: mapping.is_coherent, + }))) } }; { @@ -380,7 +381,10 @@ impl Global { match tlas_guard.get(tlas_id) { Ok(tlas) => { let last_submit_index = tlas.info.submission_index(); - (last_submit_index, device_guard.get(tlas.device.info.id()).unwrap()) + ( + last_submit_index, + device_guard.get(tlas.device.info.id()).unwrap(), + ) } Err(InvalidId) => { hub.tlas_s.unregister_locked(tlas_id, &mut *tlas_guard); @@ -393,9 +397,7 @@ impl Global { let tlas = tlas_guard.get(tlas_id).unwrap(); { let mut life_lock = device.lock_life(); - life_lock - .suspected_resources - .insert(tlas_id, tlas.clone()); + life_lock.suspected_resources.insert(tlas_id, tlas.clone()); } if wait { diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index efb7e34cf6..fe7e836071 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -120,10 +120,7 @@ use crate::{ instance::{Adapter, HalSurface, Surface}, pipeline::{ComputePipeline, RenderPipeline, ShaderModule}, registry::{Registry, RegistryReport}, - resource::{ - Blas, Buffer, QuerySet, Sampler, StagingBuffer, Texture, TextureView, - Tlas, - }, + resource::{Blas, Buffer, QuerySet, Sampler, StagingBuffer, Texture, TextureView, Tlas}, storage::{Element, Storage}, }; use std::fmt::Debug; From 86047942d6ae384a4a10a7a049604a3da32aa16d Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 11 Dec 2023 07:31:23 +1300 Subject: [PATCH 111/146] fix more rustfmt issues --- wgpu-core/src/command/ray_tracing.rs | 54 ++++++++++++++-------------- wgpu-core/src/command/render.rs | 23 ++++++------ wgpu-core/src/device/life.rs | 4 +-- wgpu-core/src/device/queue.rs | 14 +++++--- wgpu-core/src/device/ray_tracing.rs | 7 ++-- wgpu-core/src/resource.rs | 2 +- 6 files changed, 56 insertions(+), 48 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 05f7c8a5d2..49f5fe9df9 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1378,17 +1378,12 @@ impl Global { }) } - let instance_buffer_barriers = lock_vec.iter().filter_map( - |lock| { - lock.as_ref().map(|lock| { - hal::BufferBarrier:: { - buffer: lock.as_ref().unwrap(), - usage: BufferUses::COPY_DST - ..BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, - } + let instance_buffer_barriers = lock_vec.iter().filter_map(|lock| { + lock.as_ref().map(|lock| hal::BufferBarrier:: { + buffer: lock.as_ref().unwrap(), + usage: BufferUses::COPY_DST..BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, }) - }, - ); + }); let blas_present = !blas_storage.is_empty(); let tlas_present = !tlas_storage.is_empty(); @@ -1457,7 +1452,13 @@ impl Global { size: NonZeroU64::new(size).unwrap(), }; cmd_buf_raw.copy_buffer_to_buffer( - staging_buffer.as_ref().unwrap().raw.lock().as_ref().unwrap(), + staging_buffer + .as_ref() + .unwrap() + .raw + .lock() + .as_ref() + .unwrap(), tlas.instance_buffer.read().as_ref().unwrap(), iter::once(temp), ); @@ -1485,19 +1486,17 @@ impl Global { .as_mut() .unwrap() .temp_resources - .push(TempResource::StagingBuffer( - Arc::new(staging_buffer) - )); + .push(TempResource::StagingBuffer(Arc::new(staging_buffer))); } } let scratch_mapping = unsafe { device - .raw() - .map_buffer( - &scratch_buffer, - 0..instance_buffer_staging_source.len() as u64, - ) - .map_err(crate::device::DeviceError::from)? + .raw() + .map_buffer( + &scratch_buffer, + 0..instance_buffer_staging_source.len() as u64, + ) + .map_err(crate::device::DeviceError::from)? }; device .pending_writes @@ -1505,14 +1504,13 @@ impl Global { .as_mut() .unwrap() .temp_resources - .push(TempResource::StagingBuffer( - Arc::new(StagingBuffer { - raw: Mutex::new(Some(scratch_buffer)), - device: device.clone(), - size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), - info: ResourceInfo::new("Ratracing scratch buffer"), - is_coherent: scratch_mapping.is_coherent, - }))); + .push(TempResource::StagingBuffer(Arc::new(StagingBuffer { + raw: Mutex::new(Some(scratch_buffer)), + device: device.clone(), + size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), + info: ResourceInfo::new("Ratracing scratch buffer"), + is_coherent: scratch_mapping.is_coherent, + }))); Ok(()) } diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index a1b6f158e0..c98f3382c8 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1474,17 +1474,20 @@ impl Global { .extend(texture_memory_actions.register_init_action(action)); } - let mapped_used_resources = bind_group.used.acceleration_structures.used_resources().map(|blas| { - tracker.tlas_s.add_single(&tlas_guard, blas.as_info().id()); - crate::ray_tracing::TlasAction { - id: blas.as_info().id(), - kind: crate::ray_tracing::TlasActionKind::Use, - } - }); + let mapped_used_resources = bind_group. + used + .acceleration_structures + .used_resources() + .map(|blas| { + tracker.tlas_s.add_single(&tlas_guard, blas.as_info().id()); + + crate::ray_tracing::TlasAction { + id: blas.as_info().id(), + kind: crate::ray_tracing::TlasActionKind::Use, + } + }); - cmd_buf_data.tlas_actions.extend( - mapped_used_resources, - ); + cmd_buf_data.tlas_actions.extend(mapped_used_resources); let pipeline_layout = state.binder.pipeline_layout.clone(); let entries = diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 8aa78b586a..8a2e22a8c6 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -288,10 +288,10 @@ impl LifetimeTracker { last_resources.insert(raw.as_info().id(), raw); } TempResource::Tlas(raw) => { - last_resources.insert(raw.as_info().id(),raw); + last_resources.insert(raw.as_info().id(), raw); } TempResource::Blas(raw) => { - last_resources.insert(raw.as_info().id(),raw); + last_resources.insert(raw.as_info().id(), raw); } } } diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index f8290a2aee..ef81ed28ad 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -25,12 +25,12 @@ use crate::{ use hal::{CommandEncoder as _, Device as _, Queue as _}; use parking_lot::Mutex; +use crate::resource::{Blas, Tlas}; use std::{ iter, mem, ptr, sync::{atomic::Ordering, Arc}, }; use thiserror::Error; -use crate::resource::{Blas, Tlas}; use super::Device; @@ -166,7 +166,7 @@ pub enum TempResource { StagingBuffer(Arc>), Texture(Arc>), Tlas(Arc>), - Blas(Arc>) + Blas(Arc>), } /// A queue execution for a particular command encoder. @@ -1344,13 +1344,19 @@ impl Global { for blas in cmd_buf_trackers.blas_s.used_resources() { blas.info.use_at(submit_index); if blas.is_unique() { - temp_suspected.as_mut().unwrap().insert(blas.as_info().id(), blas.clone()); + temp_suspected + .as_mut() + .unwrap() + .insert(blas.as_info().id(), blas.clone()); } } for tlas in cmd_buf_trackers.tlas_s.used_resources() { tlas.info.use_at(submit_index); if tlas.is_unique() { - temp_suspected.as_mut().unwrap().insert(tlas.as_info().id(), tlas.clone()); + temp_suspected + .as_mut() + .unwrap() + .insert(tlas.as_info().id(), tlas.clone()); } } } diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 92fe7869ce..c4768d0f64 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -11,8 +11,8 @@ use crate::{ storage::InvalidId, LabelHelpers, }; -use std::sync::Arc; use parking_lot::{Mutex, RwLock}; +use std::sync::Arc; use crate::resource::{ResourceInfo, StagingBuffer}; use hal::{AccelerationStructureTriangleIndices, Device as _}; @@ -142,9 +142,10 @@ impl Device { raw: Some(raw), device: self.clone(), info: ResourceInfo::new( - desc.label + desc + .label .to_hal(self.instance_flags) - .unwrap_or("") + .unwrap_or(""), ), size_info, flags: desc.flags, diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 5cc2b03e4c..6786f45424 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -37,8 +37,8 @@ use std::{ }, }; -use std::num::NonZeroU64; use crate::id::{BlasId, TlasId}; +use std::num::NonZeroU64; /// Information about the wgpu-core resource. /// From eb23a113a89734441f20d2281a462ae2b5699cb4 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 11 Dec 2023 09:42:13 +1300 Subject: [PATCH 112/146] fix even more rustfmt issues --- wgpu-core/src/command/ray_tracing.rs | 26 +++++++++++++++++--------- wgpu-core/src/command/render.rs | 4 ++-- wgpu-core/src/device/ray_tracing.rs | 8 ++++---- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 49f5fe9df9..b9c41ab0b2 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1175,14 +1175,20 @@ impl Global { } } - let mut tlas_lock_store = Vec::<(RwLockReadGuard>, Option, Arc>)>::new(); + let mut tlas_lock_store = Vec::<( + RwLockReadGuard>, + Option, + Arc>, + )>::new(); for package in tlas_iter { let tlas = cmd_buf_data .trackers .tlas_s .add_single(&tlas_guard, package.tlas_id) - .ok_or(BuildAccelerationStructureError::InvalidTlas(package.tlas_id))?; + .ok_or(BuildAccelerationStructureError::InvalidTlas( + package.tlas_id + ))?; tlas_lock_store.push((tlas.instance_buffer.read(), Some(package), tlas.clone())) } @@ -1199,7 +1205,9 @@ impl Global { let package = entry.1.take().unwrap(); let tlas = &entry.2; if tlas.raw.is_none() { - return Err(BuildAccelerationStructureError::InvalidTlas(package.tlas_id)); + return Err(BuildAccelerationStructureError::InvalidTlas( + package.tlas_id + )); } let scratch_buffer_offset = scratch_buffer_tlas_size; @@ -1241,7 +1249,7 @@ impl Global { } cmd_buf_data.tlas_actions.push(TlasAction { - id: package .tlas_id, + id: package.tlas_id, kind: crate::ray_tracing::TlasActionKind::Build { build_index: build_command_index, dependencies, @@ -1379,11 +1387,11 @@ impl Global { } let instance_buffer_barriers = lock_vec.iter().filter_map(|lock| { - lock.as_ref().map(|lock| hal::BufferBarrier:: { - buffer: lock.as_ref().unwrap(), - usage: BufferUses::COPY_DST..BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, - }) - }); + lock.as_ref().map(|lock| hal::BufferBarrier:: { + buffer: lock.as_ref().unwrap(), + usage: BufferUses::COPY_DST..BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + }) + }); let blas_present = !blas_storage.is_empty(); let tlas_present = !tlas_storage.is_empty(); diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index c98f3382c8..b55925e398 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1474,8 +1474,8 @@ impl Global { .extend(texture_memory_actions.register_init_action(action)); } - let mapped_used_resources = bind_group. - used + let mapped_used_resources = bind_group + .used .acceleration_structures .used_resources() .map(|blas| { diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index c4768d0f64..fde161c891 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -80,9 +80,10 @@ impl Device { raw: Some(raw), device: self.clone(), info: ResourceInfo::new( - blas_desc.label + blas_desc + .label .to_hal(self.instance_flags) - .unwrap_or("") + .unwrap_or(""), ), size_info, sizes, @@ -142,8 +143,7 @@ impl Device { raw: Some(raw), device: self.clone(), info: ResourceInfo::new( - desc - .label + desc.label .to_hal(self.instance_flags) .unwrap_or(""), ), From b48b66d885ca2a306388fc79b57cc14e9f81f9de Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 11 Dec 2023 14:40:26 +1300 Subject: [PATCH 113/146] fix yet more rustfmt issues --- tests/tests/ray_tracing/mod.rs | 26 +++--- wgpu-core/src/command/ray_tracing.rs | 4 +- wgpu/src/backend/direct.rs | 11 ++- wgpu/src/context.rs | 128 +++++++++++++-------------- 4 files changed, 83 insertions(+), 86 deletions(-) diff --git a/tests/tests/ray_tracing/mod.rs b/tests/tests/ray_tracing/mod.rs index 2447c4f788..38390fd80a 100644 --- a/tests/tests/ray_tracing/mod.rs +++ b/tests/tests/ray_tracing/mod.rs @@ -20,7 +20,7 @@ fn required_features() -> wgpu::Features { | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE } -fn execute(ctx:TestingContext) { +fn execute(ctx: TestingContext) { let max_instances = 1000; let device = &ctx.device; @@ -91,18 +91,16 @@ fn execute(ctx:TestingContext) { encoder.build_acceleration_structures( iter::once(&rt::BlasBuildEntry { blas: &blas, - geometry: rt::BlasGeometries::TriangleGeometries(vec![ - rt::BlasTriangleGeometry { - size: &blas_geo_size_desc, - vertex_buffer: &vertex_buf, - first_vertex: 0, - vertex_stride: mem::size_of::() as u64, - index_buffer: Some(&index_buf), - index_buffer_offset: Some(0), - transform_buffer: None, - transform_buffer_offset: None, - }, - ]), + geometry: rt::BlasGeometries::TriangleGeometries(vec![rt::BlasTriangleGeometry { + size: &blas_geo_size_desc, + vertex_buffer: &vertex_buf, + first_vertex: 0, + vertex_stride: mem::size_of::() as u64, + index_buffer: Some(&index_buf), + index_buffer_offset: Some(0), + transform_buffer: None, + transform_buffer_offset: None, + }]), }), // iter::empty(), iter::once(&tlas_package), @@ -121,4 +119,4 @@ static RAY_TRACING: GpuTestConfiguration = GpuTestConfiguration::new() .test_features_limits() .features(required_features()), ) - .run_sync(execute); \ No newline at end of file + .run_sync(execute); diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index b9c41ab0b2..27349e01e9 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1187,7 +1187,7 @@ impl Global { .tlas_s .add_single(&tlas_guard, package.tlas_id) .ok_or(BuildAccelerationStructureError::InvalidTlas( - package.tlas_id + package.tlas_id, ))?; tlas_lock_store.push((tlas.instance_buffer.read(), Some(package), tlas.clone())) } @@ -1206,7 +1206,7 @@ impl Global { let tlas = &entry.2; if tlas.raw.is_none() { return Err(BuildAccelerationStructureError::InvalidTlas( - package.tlas_id + package.tlas_id, )); } diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index e4d2c1b299..1178528275 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -3233,12 +3233,11 @@ impl crate::Context for Context { let tlas = tlas.into_iter().map(|e| { let instances = e.instances.map( |instance: Option>| { - instance.map(|instance| - wgc::ray_tracing::TlasInstance { - blas_id: instance.blas_id, - transform: instance.transform, - custom_index: instance.custom_index, - mask: instance.mask, + instance.map(|instance| wgc::ray_tracing::TlasInstance { + blas_id: instance.blas_id, + transform: instance.transform, + custom_index: instance.custom_index, + mask: instance.mask, }) }, ); diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index dcd562fd4d..6dadad6204 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -1153,107 +1153,107 @@ pub(crate) struct DeviceRequest { } #[cfg(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) ))] pub type BufferMapCallback = Box) + Send + 'static>; #[cfg(not(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) )))] pub type BufferMapCallback = Box) + 'static>; #[cfg(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) ))] pub(crate) type AdapterRequestDeviceFuture = -Box> + Send>; + Box> + Send>; #[cfg(not(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) )))] pub(crate) type AdapterRequestDeviceFuture = -Box>>; + Box>>; #[cfg(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) ))] pub type InstanceRequestAdapterFuture = -Box)>> + Send>; + Box)>> + Send>; #[cfg(not(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) )))] pub type InstanceRequestAdapterFuture = -Box)>>>; + Box)>>>; #[cfg(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) ))] pub type DevicePopErrorFuture = Box> + Send>; #[cfg(not(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) )))] pub type DevicePopErrorFuture = Box>>; #[cfg(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) ))] pub type SubmittedWorkDoneCallback = Box; #[cfg(not(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) )))] pub type SubmittedWorkDoneCallback = Box; #[cfg(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) ))] pub type DeviceLostCallback = Box; #[cfg(not(any( -not(target_arch = "wasm32"), -all( -feature = "fragile-send-sync-non-atomic-wasm", -not(target_feature = "atomics") -) + not(target_arch = "wasm32"), + all( + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") + ) )))] pub type DeviceLostCallback = Box; From 14e65dda7cf6462c74d5ba641ccc07b1a40ee1dc Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 11 Dec 2023 16:58:43 +1300 Subject: [PATCH 114/146] add #[allow(dead_code)] to some structs to fix clippy on web assembly --- wgpu/src/ray_tracing.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wgpu/src/ray_tracing.rs b/wgpu/src/ray_tracing.rs index 9cb08d4ae7..2720f3f07a 100644 --- a/wgpu/src/ray_tracing.rs +++ b/wgpu/src/ray_tracing.rs @@ -182,6 +182,7 @@ pub(crate) struct DynContextTlasInstance<'a> { } /// [Context version] see `TlasInstance`. +#[allow(dead_code)] pub struct ContextTlasInstance<'a, T: Context> { pub(crate) blas_id: T::BlasId, pub(crate) transform: &'a [f32; 12], @@ -291,6 +292,7 @@ pub(crate) struct DynContextTlasPackage<'a> { } /// [Context version] see `BlasTriangleGeometry`. +#[allow(dead_code)] pub struct ContextBlasTriangleGeometry<'a, T: Context> { pub(crate) size: &'a BlasTriangleGeometrySizeDescriptor, pub(crate) vertex_buffer: T::BufferId, @@ -309,12 +311,14 @@ pub enum ContextBlasGeometries<'a, T: Context> { } /// [Context version] see `BlasBuildEntry`. +#[allow(dead_code)] pub struct ContextBlasBuildEntry<'a, T: Context> { pub(crate) blas_id: T::BlasId, pub(crate) geometries: ContextBlasGeometries<'a, T>, } /// [Context version] see `TlasBuildEntry`. +#[allow(dead_code)] pub struct ContextTlasBuildEntry { pub(crate) tlas_id: T::TlasId, pub(crate) instance_buffer_id: T::BufferId, @@ -322,6 +326,7 @@ pub struct ContextTlasBuildEntry { } /// [Context version] see `TlasPackage`. +#[allow(dead_code)] pub struct ContextTlasPackage<'a, T: Context> { pub(crate) tlas_id: T::TlasId, pub(crate) instances: Box>> + 'a>, From c9c027e0805258c97eca86b035196076f4dfa325 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 11 Dec 2023 17:30:12 +1300 Subject: [PATCH 115/146] more format fixes --- tests/tests/ray_tracing/mod.rs | 2 +- wgpu-core/src/command/compute.rs | 16 +++-- wgpu-core/src/command/mod.rs | 2 +- wgpu-core/src/command/ray_tracing.rs | 100 +++++++++++++++------------ wgpu/src/context.rs | 12 ++-- wgpu/src/ray_tracing.rs | 84 ++++++++++++---------- 6 files changed, 123 insertions(+), 93 deletions(-) diff --git a/tests/tests/ray_tracing/mod.rs b/tests/tests/ray_tracing/mod.rs index 38390fd80a..e3440034df 100644 --- a/tests/tests/ray_tracing/mod.rs +++ b/tests/tests/ray_tracing/mod.rs @@ -1,6 +1,6 @@ use std::{iter, mem}; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestingContext, TestParameters}; +use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; use rt::traits::*; use wgpu::ray_tracing as rt; diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 7b5d2a451c..6df95e9dde 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -540,12 +540,16 @@ impl Global { .extend(texture_memory_actions.register_init_action(action)); } - let used_resource = bind_group.used.acceleration_structures.used_resources().map(|tlas| { - tracker.tlas_s.add_single(&tlas_guard, tlas.as_info().id()); - crate::ray_tracing::TlasAction { - id: tlas.as_info().id(), - kind: crate::ray_tracing::TlasActionKind::Use, - } + let used_resource = bind_group + .used + .acceleration_structures + .used_resources() + .map(|tlas| { + tracker.tlas_s.add_single(&tlas_guard, tlas.as_info().id()); + crate::ray_tracing::TlasAction { + id: tlas.as_info().id(), + kind: crate::ray_tracing::TlasActionKind::Use, + } }); cmd_buf_data.tlas_actions.extend( diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 1314cfed26..3e54e0bf7e 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -25,8 +25,8 @@ use crate::hub::Hub; use crate::id::CommandBufferId; use crate::init_tracker::BufferInitTrackerAction; -use crate::resource::{Resource, ResourceInfo, ResourceType}; use crate::ray_tracing::{BlasAction, TlasAction}; +use crate::resource::{Resource, ResourceInfo, ResourceType}; use crate::track::{Tracker, UsageScope}; use crate::{ api_log, global::Global, hal_api::HalApi, id, identity::GlobalIdentityHandlerFactory, diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 27349e01e9..d560af4d71 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -18,14 +18,14 @@ use crate::{ use wgt::{math::align_to, BufferUsages}; +use crate::ray_tracing::BlasTriangleGeometry; +use crate::resource::{Buffer, Resource, ResourceInfo, StagingBuffer}; +use crate::track::PendingTransition; use std::{cmp::max, iter, num::NonZeroU64, ops::Range, ptr}; use std::ops::Deref; use std::sync::Arc; use parking_lot::{Mutex, RwLockReadGuard}; use hal::{BufferUses, CommandEncoder, Device}; -use crate::ray_tracing::BlasTriangleGeometry; -use crate::resource::{Buffer, Resource, ResourceInfo, StagingBuffer}; -use crate::track::PendingTransition; use super::BakedCommands; @@ -108,17 +108,15 @@ impl Global { &crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( ref triangle_geometries, ) => { - let iter = triangle_geometries.iter().map(|tg| { - BlasTriangleGeometry { - size: &tg.size, - vertex_buffer: tg.vertex_buffer, - index_buffer: tg.index_buffer, - transform_buffer: tg.transform_buffer, - first_vertex: tg.first_vertex, - vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, - transform_buffer_offset: tg.transform_buffer_offset, - } + let iter = triangle_geometries.iter().map(|tg| BlasTriangleGeometry { + size: &tg.size, + vertex_buffer: tg.vertex_buffer, + index_buffer: tg.index_buffer, + transform_buffer: tg.transform_buffer, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, }); BlasGeometries::TriangleGeometries(Box::new(iter)) } @@ -133,7 +131,14 @@ impl Global { let tlas_iter = trace_tlas.iter(); let mut input_barriers = Vec::>::new(); - let mut buf_storage = Vec::<(Arc>, Option>, Option<(Arc>, Option>)>, Option<(Arc>, Option>)>, BlasTriangleGeometry, Option>>)>::new(); + let mut buf_storage = Vec::<( + Arc>, + Option>, + Option<(Arc>, Option>)>, + Option<(Arc>, Option>)>, + BlasTriangleGeometry, + Option>> + )>::new(); let mut scratch_buffer_blas_size = 0; let mut blas_storage = Vec::<(&Blas, hal::AccelerationStructureEntries, u64)>::new(); @@ -157,7 +162,6 @@ impl Global { match entry.geometries { BlasGeometries::TriangleGeometries(triangle_geometries) => { - for (i, mesh) in triangle_geometries.enumerate() { let size_desc = match &blas.sizes { &wgt::BlasGeometrySizeDescriptors::Triangles { ref desc } => desc, @@ -176,11 +180,11 @@ impl Global { || size_desc.vertex_format != mesh.size.vertex_format || size_desc.index_count.is_none() != mesh.size.index_count.is_none() || (size_desc.index_count.is_none() - || size_desc.index_count.unwrap() < mesh.size.index_count.unwrap()) + || size_desc.index_count.unwrap() < mesh.size.index_count.unwrap()) || size_desc.index_format.is_none() != mesh.size.index_format.is_none() || (size_desc.index_format.is_none() - || size_desc.index_format.unwrap() - != mesh.size.index_format.unwrap()) + || size_desc.index_format.unwrap() + != mesh.size.index_format.unwrap()) { return Err( BuildAccelerationStructureError::IncompatibleBlasBuildSizes( @@ -228,7 +232,13 @@ impl Global { .set_single( match buffer_guard.get(index_id) { Ok(buffer) => buffer, - Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(index_id)) }, + Err(_) => { + return Err( + BuildAccelerationStructureError::InvalidBuffer( + index_id, + ), + ) + }, }, hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) @@ -251,7 +261,13 @@ impl Global { .set_single( match buffer_guard.get(transform_id) { Ok(buffer) => buffer, - Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(transform_id)) }, + Err(_) => { + return Err( + BuildAccelerationStructureError::InvalidBuffer( + transform_id, + ), + ) + }, }, BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) @@ -281,32 +297,23 @@ impl Global { BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer), )?; if !vertex_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - mesh.vertex_buffer, - ), - ); + return Err(BuildAccelerationStructureError::MissingBlasInputUsageFlag( + mesh.vertex_buffer, + )); } - if let Some(barrier) = - buf.1.take().map(|pending| pending.into_hal(vertex_buffer)) - { + if let Some(barrier) = buf.1.take().map(|pending| pending.into_hal(vertex_buffer)) { input_barriers.push(barrier); } if vertex_buffer.size - < (mesh.size.vertex_count + mesh.first_vertex) as u64 - * mesh.vertex_stride + < (mesh.size.vertex_count + mesh.first_vertex) as u64 * mesh.vertex_stride { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - mesh.vertex_buffer, - vertex_buffer.size, - (mesh.size.vertex_count + mesh.first_vertex) as u64 - * mesh.vertex_stride, - ), - ); + return Err(BuildAccelerationStructureError::InsufficientBufferSize( + mesh.vertex_buffer, + vertex_buffer.size, + (mesh.size.vertex_count + mesh.first_vertex) as u64 * mesh.vertex_stride, + )); } - let vertex_buffer_offset = - mesh.first_vertex as u64 * mesh.vertex_stride; + let vertex_buffer_offset = mesh.first_vertex as u64 * mesh.vertex_stride; cmd_buf_data.buffer_memory_init_actions.extend( vertex_buffer.initialization_status.read().create_action( buffer_guard.get(mesh.vertex_buffer).unwrap(), @@ -957,7 +964,14 @@ impl Global { None }; - buf_storage.push((vertex_buffer, vertex_pending, index_data, transform_data, mesh, None)) + buf_storage.push(( + vertex_buffer, + vertex_pending, + index_data, + transform_data, + mesh, + None, + )) } if let Some(last) = buf_storage.last_mut() { @@ -1007,7 +1021,7 @@ impl Global { buffer_guard.get(mesh.vertex_buffer).unwrap(), vertex_buffer_offset ..(vertex_buffer_offset - + mesh.size.vertex_count as u64 * mesh.vertex_stride), + + mesh.size.vertex_count as u64 * mesh.vertex_stride), MemoryInitKind::NeedsInitializedMemory, ), ); diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 6dadad6204..0cd547b5ed 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -1156,7 +1156,7 @@ pub(crate) struct DeviceRequest { not(target_arch = "wasm32"), all( feature = "fragile-send-sync-non-atomic-wasm", - not(target_feature = "atomics") + not(target_feature = "atomics") ) ))] pub type BufferMapCallback = Box) + Send + 'static>; @@ -1172,8 +1172,8 @@ pub type BufferMapCallback = Box) + 'sta #[cfg(any( not(target_arch = "wasm32"), all( - feature = "fragile-send-sync-non-atomic-wasm", - not(target_feature = "atomics") + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") ) ))] pub(crate) type AdapterRequestDeviceFuture = @@ -1181,8 +1181,8 @@ pub(crate) type AdapterRequestDeviceFuture = #[cfg(not(any( not(target_arch = "wasm32"), all( - feature = "fragile-send-sync-non-atomic-wasm", - not(target_feature = "atomics") + feature = "fragile-send-sync-non-atomic-wasm", + not(target_feature = "atomics") ) )))] pub(crate) type AdapterRequestDeviceFuture = @@ -1219,7 +1219,7 @@ pub type DevicePopErrorFuture = Box> + Send>; not(target_arch = "wasm32"), all( feature = "fragile-send-sync-non-atomic-wasm", - not(target_feature = "atomics") + not(target_feature = "atomics") ) )))] pub type DevicePopErrorFuture = Box>>; diff --git a/wgpu/src/ray_tracing.rs b/wgpu/src/ray_tracing.rs index 2720f3f07a..feb2cf959e 100644 --- a/wgpu/src/ray_tracing.rs +++ b/wgpu/src/ray_tracing.rs @@ -343,7 +343,11 @@ pub trait DeviceRayTracing { /// Create a bottom level acceleration structure, used inside a top level acceleration structure for ray tracing. /// - desc: The descriptor of the acceleration structure. /// - sizes: Size descriptor limiting what can be built into the acceleration structure. - fn create_blas(&self, desc: &CreateBlasDescriptor<'_>, sizes: BlasGeometrySizeDescriptors) -> Blas; + fn create_blas( + &self, + desc: &CreateBlasDescriptor<'_>, + sizes: BlasGeometrySizeDescriptors, + ) -> Blas; /// Create a top level acceleration structure, used for ray tracing. /// - desc: The descriptor of the acceleration structure. @@ -351,7 +355,11 @@ pub trait DeviceRayTracing { } impl DeviceRayTracing for Device { - fn create_blas(&self, desc: &CreateBlasDescriptor<'_>, sizes: BlasGeometrySizeDescriptors) -> Blas { + fn create_blas( + &self, + desc: &CreateBlasDescriptor<'_>, + sizes: BlasGeometrySizeDescriptors, + ) -> Blas { let (id, handle, data) = DynContext::device_create_blas( &*self.context, &self.id, @@ -434,23 +442,25 @@ impl CommandEncoderRayTracing for CommandEncoder { let mut blas = blas.into_iter().map(|e: &BlasBuildEntry<'_>| { let geometries = match &e.geometry { BlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry<'_>| { - DynContextBlasTriangleGeometry { - size: tg.size, - vertex_buffer: tg.vertex_buffer.id, - - index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.id), - - transform_buffer: tg - .transform_buffer - .map(|transform_buffer| transform_buffer.id), - - first_vertex: tg.first_vertex, - vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, - transform_buffer_offset: tg.transform_buffer_offset, - } - }); + let iter = triangle_geometries + .iter() + .map( + |tg: &BlasTriangleGeometry<'_>| DynContextBlasTriangleGeometry { + size: tg.size, + vertex_buffer: tg.vertex_buffer.id, + + index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.id), + + transform_buffer: tg + .transform_buffer + .map(|transform_buffer| transform_buffer.id), + + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + }, + ); DynContextBlasGeometries::TriangleGeometries(Box::new(iter)) } }; @@ -495,23 +505,25 @@ impl CommandEncoderRayTracing for CommandEncoder { let mut blas = blas.into_iter().map(|e: &BlasBuildEntry<'_>| { let geometries = match &e.geometry { BlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = triangle_geometries.iter().map(|tg: &BlasTriangleGeometry<'_>| { - DynContextBlasTriangleGeometry { - size: tg.size, - vertex_buffer: tg.vertex_buffer.id, - - index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.id), - - transform_buffer: tg - .transform_buffer - .map(|transform_buffer| transform_buffer.id), - - first_vertex: tg.first_vertex, - vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, - transform_buffer_offset: tg.transform_buffer_offset, - } - }); + let iter = triangle_geometries + .iter() + .map( + |tg: &BlasTriangleGeometry<'_>| DynContextBlasTriangleGeometry { + size: tg.size, + vertex_buffer: tg.vertex_buffer.id, + + index_buffer: tg.index_buffer.map(|index_buffer| index_buffer.id), + + transform_buffer: tg + .transform_buffer + .map(|transform_buffer| transform_buffer.id), + + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, + }, + ); DynContextBlasGeometries::TriangleGeometries(Box::new(iter)) } }; From 9e9ae22c5090ae0e28eb5bb5f743ae3b9ac39310 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 11 Dec 2023 17:59:29 +1300 Subject: [PATCH 116/146] even more format fixes --- wgpu-core/src/command/compute.rs | 6 +- wgpu-core/src/command/ray_tracing.rs | 193 ++++++++++++++------------- 2 files changed, 103 insertions(+), 96 deletions(-) diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 6df95e9dde..29f7f39de5 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -550,11 +550,9 @@ impl Global { id: tlas.as_info().id(), kind: crate::ray_tracing::TlasActionKind::Use, } - }); + }); - cmd_buf_data.tlas_actions.extend( - used_resource - ); + cmd_buf_data.tlas_actions.extend(used_resource); let pipeline_layout = state.binder.pipeline_layout.clone(); let entries = diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index d560af4d71..2cb7c96c00 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -21,11 +21,11 @@ use wgt::{math::align_to, BufferUsages}; use crate::ray_tracing::BlasTriangleGeometry; use crate::resource::{Buffer, Resource, ResourceInfo, StagingBuffer}; use crate::track::PendingTransition; -use std::{cmp::max, iter, num::NonZeroU64, ops::Range, ptr}; -use std::ops::Deref; -use std::sync::Arc; use parking_lot::{Mutex, RwLockReadGuard}; use hal::{BufferUses, CommandEncoder, Device}; +use std::ops::Deref; +use std::sync::Arc; +use std::{cmp::max, iter, num::NonZeroU64, ops::Range, ptr}; use super::BakedCommands; @@ -137,7 +137,7 @@ impl Global { Option<(Arc>, Option>)>, Option<(Arc>, Option>)>, BlasTriangleGeometry, - Option>> + Option>>, )>::new(); let mut scratch_buffer_blas_size = 0; @@ -238,7 +238,7 @@ impl Global { index_id, ), ) - }, + } }, hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) @@ -267,7 +267,7 @@ impl Global { transform_id, ), ) - }, + } }, BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) @@ -279,7 +279,14 @@ impl Global { None }; - buf_storage.push((vertex_buffer, vertex_pending, index_data, transform_data, mesh, None)) + buf_storage.push(( + vertex_buffer, + vertex_pending, + index_data, + transform_data, + mesh, + None, + )) } if let Some(last) = buf_storage.last_mut() { last.5 = Some(blas.clone()); @@ -319,7 +326,7 @@ impl Global { buffer_guard.get(mesh.vertex_buffer).unwrap(), vertex_buffer_offset ..(vertex_buffer_offset - + mesh.size.vertex_count as u64 * mesh.vertex_stride), + + mesh.size.vertex_count as u64 * mesh.vertex_stride), MemoryInitKind::NeedsInitializedMemory, ), ); @@ -332,14 +339,13 @@ impl Global { .as_ref() .ok_or(BuildAccelerationStructureError::InvalidBuffer(*index_id))?; if !index_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - *index_id, - ), - ); + return Err(BuildAccelerationStructureError::MissingBlasInputUsageFlag( + *index_id, + )); } - if let Some(barrier) = - index_pending.take().map(|pending| pending.into_hal(index_buffer)) + if let Some(barrier) = index_pending + .take() + .map(|pending| pending.into_hal(index_buffer)) { input_barriers.push(barrier); } @@ -348,11 +354,9 @@ impl Global { wgt::IndexFormat::Uint32 => 4, }; if mesh.index_buffer_offset.unwrap() % index_stride != 0 { - return Err( - BuildAccelerationStructureError::UnalignedIndexBufferOffset( - *index_id, - ), - ); + return Err(BuildAccelerationStructureError::UnalignedIndexBufferOffset( + *index_id, + )); } let index_buffer_size = mesh.size.index_count.unwrap() as u64 * index_stride; @@ -365,23 +369,25 @@ impl Global { } if index_buffer.size < mesh.size.index_count.unwrap() as u64 * index_stride - + mesh.index_buffer_offset.unwrap() + + mesh.index_buffer_offset.unwrap() { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - *index_id, - index_buffer.size, - mesh.size.index_count.unwrap() as u64 * index_stride - + mesh.index_buffer_offset.unwrap(), - ), - ); + return Err(BuildAccelerationStructureError::InsufficientBufferSize( + *index_id, + index_buffer.size, + mesh.size.index_count.unwrap() as u64 * index_stride + + mesh.index_buffer_offset.unwrap(), + )); } cmd_buf_data.buffer_memory_init_actions.extend( index_buffer.initialization_status.read().create_action( match buffer_guard.get(*index_id) { Ok(buffer) => buffer, - Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( *index_id, )), + Err(_) => { + return Err(BuildAccelerationStructureError::InvalidBuffer( + *index_id + )) + }, }, mesh.index_buffer_offset.unwrap() ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), @@ -392,61 +398,62 @@ impl Global { } else { None }; - let transform_buffer = if let Some((ref mut transform_buffer, ref mut transform_pending)) = buf.3 { - let transform_id = mesh.transform_buffer.as_ref().unwrap(); - if mesh.transform_buffer_offset.is_none() { - return Err( - BuildAccelerationStructureError::MissingAssociatedData( - *transform_id, - ), - ); - } - let transform_raw = transform_buffer.raw.as_ref().ok_or( - BuildAccelerationStructureError::InvalidBuffer(*transform_id), - )?; - if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - *transform_id, - ), - ); - } - if let Some(barrier) = - transform_pending.take().map(|pending| pending.into_hal(transform_buffer)) - { - input_barriers.push(barrier); - } - if mesh.transform_buffer_offset.unwrap() - % wgt::TRANSFORM_BUFFER_ALIGNMENT - != 0 - { - return Err( - BuildAccelerationStructureError::UnalignedTransformBufferOffset( - *transform_id, - ), - ); - } - if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - *transform_id, - transform_buffer.size, - 48 + mesh.transform_buffer_offset.unwrap(), + let transform_buffer = + if let Some((ref mut transform_buffer, ref mut transform_pending)) = buf.3 { + let transform_id = mesh.transform_buffer.as_ref().unwrap(); + if mesh.transform_buffer_offset.is_none() { + return Err( + BuildAccelerationStructureError::MissingAssociatedData( + *transform_id, + ), + ); + } + let transform_raw = transform_buffer.raw.as_ref().ok_or( + BuildAccelerationStructureError::InvalidBuffer(*transform_id), + )?; + if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + *transform_id, + ), + ); + } + if let Some(barrier) = + transform_pending.take().map(|pending| pending.into_hal(transform_buffer)) + { + input_barriers.push(barrier); + } + if mesh.transform_buffer_offset.unwrap() + % wgt::TRANSFORM_BUFFER_ALIGNMENT + != 0 + { + return Err( + BuildAccelerationStructureError::UnalignedTransformBufferOffset( + *transform_id, + ), + ); + } + if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + *transform_id, + transform_buffer.size, + 48 + mesh.transform_buffer_offset.unwrap(), + ), + ); + } + cmd_buf_data.buffer_memory_init_actions.extend( + transform_buffer.initialization_status.read().create_action( + buffer_guard.get(*transform_id).unwrap(), + mesh.transform_buffer_offset.unwrap() + ..(mesh.index_buffer_offset.unwrap() + 48), + MemoryInitKind::NeedsInitializedMemory, ), ); - } - cmd_buf_data.buffer_memory_init_actions.extend( - transform_buffer.initialization_status.read().create_action( - buffer_guard.get(*transform_id).unwrap(), - mesh.transform_buffer_offset.unwrap() - ..(mesh.index_buffer_offset.unwrap() + 48), - MemoryInitKind::NeedsInitializedMemory, - ), - ); - Some(transform_raw) - } else { - None - }; + Some(transform_raw) + } else { + None + }; let triangles = hal::AccelerationStructureTriangles { vertex_buffer: Some(vertex_buffer), @@ -489,7 +496,11 @@ impl Global { let mut scratch_buffer_tlas_size = 0; let mut tlas_storage = Vec::<(&Tlas, hal::AccelerationStructureEntries, u64)>::new(); - let mut tlas_buf_storage = Vec::<(Arc>, Option>, TlasBuildEntry)>::new(); + let mut tlas_buf_storage = Vec::<( + Arc>, + Option>, + TlasBuildEntry, + )>::new(); for entry in tlas_iter { let data = cmd_buf_data @@ -498,20 +509,18 @@ impl Global { .set_single( match buffer_guard.get(entry.instance_buffer_id) { Ok(buffer) => buffer, - Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer(entry.instance_buffer_id, )), + Err(_) => { + return Err(BuildAccelerationStructureError::InvalidBuffer( + entry.instance_buffer_id, + )); + } }, BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) .ok_or(BuildAccelerationStructureError::InvalidBuffer( entry.instance_buffer_id, ))?; - tlas_buf_storage.push( - ( - data.0, - data.1, - entry.clone() - ) - ); + tlas_buf_storage.push((data.0, data.1, entry.clone())); } for tlas_buf in &mut tlas_buf_storage { From b00bc83297aafd86cb40e5a9c3a241600d0b5bc9 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 11 Dec 2023 18:23:04 +1300 Subject: [PATCH 117/146] close to final format fixes --- wgpu-core/src/command/ray_tracing.rs | 262 ++++++++++++++------------- 1 file changed, 135 insertions(+), 127 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 2cb7c96c00..3dc780a118 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -21,8 +21,8 @@ use wgt::{math::align_to, BufferUsages}; use crate::ray_tracing::BlasTriangleGeometry; use crate::resource::{Buffer, Resource, ResourceInfo, StagingBuffer}; use crate::track::PendingTransition; -use parking_lot::{Mutex, RwLockReadGuard}; use hal::{BufferUses, CommandEncoder, Device}; +use parking_lot::{Mutex, RwLockReadGuard}; use std::ops::Deref; use std::sync::Arc; use std::{cmp::max, iter, num::NonZeroU64, ops::Range, ptr}; @@ -358,8 +358,7 @@ impl Global { *index_id, )); } - let index_buffer_size = - mesh.size.index_count.unwrap() as u64 * index_stride; + let index_buffer_size = mesh.size.index_count.unwrap() as u64 * index_stride; if mesh.size.index_count.unwrap() % 3 != 0 { return Err(BuildAccelerationStructureError::InvalidIndexCount( @@ -385,7 +384,7 @@ impl Global { Ok(buffer) => buffer, Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer( - *index_id + *index_id, )) }, }, @@ -402,30 +401,25 @@ impl Global { if let Some((ref mut transform_buffer, ref mut transform_pending)) = buf.3 { let transform_id = mesh.transform_buffer.as_ref().unwrap(); if mesh.transform_buffer_offset.is_none() { - return Err( - BuildAccelerationStructureError::MissingAssociatedData( - *transform_id, - ), - ); + return Err(BuildAccelerationStructureError::MissingAssociatedData( + *transform_id, + )); } let transform_raw = transform_buffer.raw.as_ref().ok_or( BuildAccelerationStructureError::InvalidBuffer(*transform_id), )?; if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - *transform_id, - ), - ); + return Err(BuildAccelerationStructureError::MissingBlasInputUsageFlag( + *transform_id, + )); } - if let Some(barrier) = - transform_pending.take().map(|pending| pending.into_hal(transform_buffer)) + if let Some(barrier) = transform_pending + .take() + .map(|pending| pending.into_hal(transform_buffer)) { input_barriers.push(barrier); } - if mesh.transform_buffer_offset.unwrap() - % wgt::TRANSFORM_BUFFER_ALIGNMENT - != 0 + if mesh.transform_buffer_offset.unwrap() % wgt::TRANSFORM_BUFFER_ALIGNMENT != 0 { return Err( BuildAccelerationStructureError::UnalignedTransformBufferOffset( @@ -434,13 +428,11 @@ impl Global { ); } if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - *transform_id, - transform_buffer.size, - 48 + mesh.transform_buffer_offset.unwrap(), - ), - ); + return Err(BuildAccelerationStructureError::InsufficientBufferSize( + *transform_id, + transform_buffer.size, + 48 + mesh.transform_buffer_offset.unwrap(), + )); } cmd_buf_data.buffer_memory_init_actions.extend( transform_buffer.initialization_status.read().create_action( @@ -535,8 +527,9 @@ impl Global { entry.instance_buffer_id, )); } - if let Some(barrier) = - instance_pending.take().map(|pending| pending.into_hal(instance_buffer)) + if let Some(barrier) = instance_pending + .take() + .map(|pending| pending.into_hal(instance_buffer)) { input_barriers.push(barrier); } @@ -701,14 +694,13 @@ impl Global { .as_mut() .unwrap() .temp_resources - .push(TempResource::StagingBuffer( - Arc::new(StagingBuffer { - raw: Mutex::new(Some(scratch_buffer)), - device: device.clone(), - size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), - info: ResourceInfo::new("Ratracing scratch buffer"), - is_coherent: scratch_mapping.is_coherent, - }))); + .push(TempResource::StagingBuffer(Arc::new(StagingBuffer { + raw: Mutex::new(Some(scratch_buffer)), + device: device.clone(), + size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), + info: ResourceInfo::new("Ratracing scratch buffer"), + is_coherent: scratch_mapping.is_coherent, + }))); Ok(()) } @@ -843,7 +835,14 @@ impl Global { }); let mut input_barriers = Vec::>::new(); - let mut buf_storage = Vec::<(Arc>, Option>, Option<(Arc>, Option>)>, Option<(Arc>, Option>)>, BlasTriangleGeometry, Option>>)>::new(); + let mut buf_storage = Vec::<( + Arc>, + Option>, + Option<(Arc>, Option>)>, + Option<(Arc>, Option>)>, + BlasTriangleGeometry, + Option>>, + )>::new(); let mut scratch_buffer_blas_size = 0; let mut blas_storage = Vec::<(&Blas, hal::AccelerationStructureEntries, u64)>::new(); @@ -867,7 +866,6 @@ impl Global { match entry.geometries { BlasGeometries::TriangleGeometries(triangle_geometries) => { - for (i, mesh) in triangle_geometries.enumerate() { let size_desc = match &blas.sizes { &wgt::BlasGeometrySizeDescriptors::Triangles { ref desc } => desc, @@ -938,7 +936,13 @@ impl Global { .set_single( match buffer_guard.get(index_id) { Ok(buffer) => buffer, - Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(index_id)) }, + Err(_) => { + return Err( + BuildAccelerationStructureError::InvalidBuffer( + index_id, + ), + ) + }, }, hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) @@ -961,7 +965,13 @@ impl Global { .set_single( match buffer_guard.get(transform_id) { Ok(buffer) => buffer, - Err(_) => { return Err(BuildAccelerationStructureError::InvalidBuffer(transform_id)) }, + Err(_) => { + return Err( + BuildAccelerationStructureError::InvalidBuffer( + transform_id, + ), + ) + }, }, BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) @@ -1014,17 +1024,14 @@ impl Global { < (mesh.size.vertex_count + mesh.first_vertex) as u64 * mesh.vertex_stride { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - mesh.vertex_buffer, - vertex_buffer.size, - (mesh.size.vertex_count + mesh.first_vertex) as u64 - * mesh.vertex_stride, - ), - ); + return Err(BuildAccelerationStructureError::InsufficientBufferSize( + mesh.vertex_buffer, + vertex_buffer.size, + (mesh.size.vertex_count + mesh.first_vertex) as u64 + * mesh.vertex_stride, + )); } - let vertex_buffer_offset = - mesh.first_vertex as u64 * mesh.vertex_stride; + let vertex_buffer_offset = mesh.first_vertex as u64 * mesh.vertex_stride; cmd_buf_data.buffer_memory_init_actions.extend( vertex_buffer.initialization_status.read().create_action( buffer_guard.get(mesh.vertex_buffer).unwrap(), @@ -1043,14 +1050,13 @@ impl Global { .as_ref() .ok_or(BuildAccelerationStructureError::InvalidBuffer(*index_id))?; if !index_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - *index_id, - ), - ); + return Err(BuildAccelerationStructureError::MissingBlasInputUsageFlag( + *index_id, + )); } - if let Some(barrier) = - index_pending.take().map(|pending| pending.into_hal(index_buffer)) + if let Some(barrier) = index_pending + .take() + .map(|pending| pending.into_hal(index_buffer)) { input_barriers.push(barrier); } @@ -1059,14 +1065,11 @@ impl Global { wgt::IndexFormat::Uint32 => 4, }; if mesh.index_buffer_offset.unwrap() % index_stride != 0 { - return Err( - BuildAccelerationStructureError::UnalignedIndexBufferOffset( - *index_id, - ), - ); + return Err(BuildAccelerationStructureError::UnalignedIndexBufferOffset( + *index_id, + )); } - let index_buffer_size = - mesh.size.index_count.unwrap() as u64 * index_stride; + let index_buffer_size = mesh.size.index_count.unwrap() as u64 * index_stride; if mesh.size.index_count.unwrap() % 3 != 0 { return Err(BuildAccelerationStructureError::InvalidIndexCount( @@ -1076,23 +1079,27 @@ impl Global { } if index_buffer.size < mesh.size.index_count.unwrap() as u64 * index_stride - + mesh.index_buffer_offset.unwrap() + + mesh.index_buffer_offset.unwrap() { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - *index_id, - index_buffer.size, - mesh.size.index_count.unwrap() as u64 * index_stride - + mesh.index_buffer_offset.unwrap(), - ), - ); + return Err(BuildAccelerationStructureError::InsufficientBufferSize( + *index_id, + index_buffer.size, + mesh.size.index_count.unwrap() as u64 * index_stride + + mesh.index_buffer_offset.unwrap(), + )); } cmd_buf_data.buffer_memory_init_actions.extend( index_buffer.initialization_status.read().create_action( match buffer_guard.get(*index_id) { Ok(buffer) => buffer, - Err(_) => return Err(BuildAccelerationStructureError::InvalidBuffer( *index_id, )), + Err(_) => { + return Err( + BuildAccelerationStructureError::InvalidBuffer( + *index_id, + ), + ) + } }, mesh.index_buffer_offset.unwrap() ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), @@ -1103,61 +1110,62 @@ impl Global { } else { None }; - let transform_buffer = if let Some((ref mut transform_buffer, ref mut transform_pending)) = buf.3 { - let transform_id = mesh.transform_buffer.as_ref().unwrap(); - if mesh.transform_buffer_offset.is_none() { - return Err( - BuildAccelerationStructureError::MissingAssociatedData( - *transform_id, - ), - ); - } - let transform_raw = transform_buffer.raw.as_ref().ok_or( - BuildAccelerationStructureError::InvalidBuffer(*transform_id), - )?; - if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - *transform_id, - ), - ); - } - if let Some(barrier) = - transform_pending.take().map(|pending| pending.into_hal(transform_buffer)) - { - input_barriers.push(barrier); - } - if mesh.transform_buffer_offset.unwrap() - % wgt::TRANSFORM_BUFFER_ALIGNMENT - != 0 - { - return Err( - BuildAccelerationStructureError::UnalignedTransformBufferOffset( - *transform_id, - ), - ); - } - if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - *transform_id, - transform_buffer.size, - 48 + mesh.transform_buffer_offset.unwrap(), + let transform_buffer = + if let Some((ref mut transform_buffer, ref mut transform_pending)) = buf.3 { + let transform_id = mesh.transform_buffer.as_ref().unwrap(); + if mesh.transform_buffer_offset.is_none() { + return Err( + BuildAccelerationStructureError::MissingAssociatedData( + *transform_id, + ), + ); + } + let transform_raw = transform_buffer.raw.as_ref().ok_or( + BuildAccelerationStructureError::InvalidBuffer(*transform_id), + )?; + if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { + return Err( + BuildAccelerationStructureError::MissingBlasInputUsageFlag( + *transform_id, + ), + ); + } + if let Some(barrier) = + transform_pending.take().map(|pending| pending.into_hal(transform_buffer)) + { + input_barriers.push(barrier); + } + if mesh.transform_buffer_offset.unwrap() + % wgt::TRANSFORM_BUFFER_ALIGNMENT + != 0 + { + return Err( + BuildAccelerationStructureError::UnalignedTransformBufferOffset( + *transform_id, + ), + ); + } + if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { + return Err( + BuildAccelerationStructureError::InsufficientBufferSize( + *transform_id, + transform_buffer.size, + 48 + mesh.transform_buffer_offset.unwrap(), + ), + ); + } + cmd_buf_data.buffer_memory_init_actions.extend( + transform_buffer.initialization_status.read().create_action( + buffer_guard.get(*transform_id).unwrap(), + mesh.transform_buffer_offset.unwrap() + ..(mesh.index_buffer_offset.unwrap() + 48), + MemoryInitKind::NeedsInitializedMemory, ), ); - } - cmd_buf_data.buffer_memory_init_actions.extend( - transform_buffer.initialization_status.read().create_action( - buffer_guard.get(*transform_id).unwrap(), - mesh.transform_buffer_offset.unwrap() - ..(mesh.index_buffer_offset.unwrap() + 48), - MemoryInitKind::NeedsInitializedMemory, - ), - ); - Some(transform_raw) - } else { - None - }; + Some(transform_raw) + } else { + None + }; let triangles = hal::AccelerationStructureTriangles { vertex_buffer: Some(vertex_buffer), From 2971bca0ae828eb567b637a52c2dc87c099bf449 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 11 Dec 2023 18:36:19 +1300 Subject: [PATCH 118/146] final format fixes (hopefully) --- wgpu-core/src/command/ray_tracing.rs | 73 +++++++++++----------------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 3dc780a118..c9ef0b9263 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -386,7 +386,7 @@ impl Global { return Err(BuildAccelerationStructureError::InvalidBuffer( *index_id, )) - }, + } }, mesh.index_buffer_offset.unwrap() ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), @@ -794,17 +794,15 @@ impl Global { &crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( ref triangle_geometries, ) => { - let iter = triangle_geometries.iter().map(|tg| { - BlasTriangleGeometry { - size: &tg.size, - vertex_buffer: tg.vertex_buffer, - index_buffer: tg.index_buffer, - transform_buffer: tg.transform_buffer, - first_vertex: tg.first_vertex, - vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, - transform_buffer_offset: tg.transform_buffer_offset, - } + let iter = triangle_geometries.iter().map(|tg| BlasTriangleGeometry { + size: &tg.size, + vertex_buffer: tg.vertex_buffer, + index_buffer: tg.index_buffer, + transform_buffer: tg.transform_buffer, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + index_buffer_offset: tg.index_buffer_offset, + transform_buffer_offset: tg.transform_buffer_offset, }); BlasGeometries::TriangleGeometries(Box::new(iter)) } @@ -942,7 +940,7 @@ impl Global { index_id, ), ) - }, + } }, hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) @@ -971,7 +969,7 @@ impl Global { transform_id, ), ) - }, + } }, BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ) @@ -1009,20 +1007,15 @@ impl Global { BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer), )?; if !vertex_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - mesh.vertex_buffer, - ), - ); + return Err(BuildAccelerationStructureError::MissingBlasInputUsageFlag( + mesh.vertex_buffer, + )); } - if let Some(barrier) = - buf.1.take().map(|pending| pending.into_hal(vertex_buffer)) - { + if let Some(barrier) = buf.1.take().map(|pending| pending.into_hal(vertex_buffer)) { input_barriers.push(barrier); } if vertex_buffer.size - < (mesh.size.vertex_count + mesh.first_vertex) as u64 - * mesh.vertex_stride + < (mesh.size.vertex_count + mesh.first_vertex) as u64 * mesh.vertex_stride { return Err(BuildAccelerationStructureError::InsufficientBufferSize( mesh.vertex_buffer, @@ -1094,11 +1087,9 @@ impl Global { match buffer_guard.get(*index_id) { Ok(buffer) => buffer, Err(_) => { - return Err( - BuildAccelerationStructureError::InvalidBuffer( - *index_id, - ), - ) + return Err(BuildAccelerationStructureError::InvalidBuffer( + *index_id, + )) } }, mesh.index_buffer_offset.unwrap() @@ -1114,11 +1105,9 @@ impl Global { if let Some((ref mut transform_buffer, ref mut transform_pending)) = buf.3 { let transform_id = mesh.transform_buffer.as_ref().unwrap(); if mesh.transform_buffer_offset.is_none() { - return Err( - BuildAccelerationStructureError::MissingAssociatedData( - *transform_id, - ), - ); + return Err(BuildAccelerationStructureError::MissingAssociatedData( + *transform_id, + )); } let transform_raw = transform_buffer.raw.as_ref().ok_or( BuildAccelerationStructureError::InvalidBuffer(*transform_id), @@ -1135,9 +1124,7 @@ impl Global { { input_barriers.push(barrier); } - if mesh.transform_buffer_offset.unwrap() - % wgt::TRANSFORM_BUFFER_ALIGNMENT - != 0 + if mesh.transform_buffer_offset.unwrap() % wgt::TRANSFORM_BUFFER_ALIGNMENT != 0 { return Err( BuildAccelerationStructureError::UnalignedTransformBufferOffset( @@ -1146,13 +1133,11 @@ impl Global { ); } if transform_buffer.size < 48 + mesh.transform_buffer_offset.unwrap() { - return Err( - BuildAccelerationStructureError::InsufficientBufferSize( - *transform_id, - transform_buffer.size, - 48 + mesh.transform_buffer_offset.unwrap(), - ), - ); + return Err(BuildAccelerationStructureError::InsufficientBufferSize( + *transform_id, + transform_buffer.size, + 48 + mesh.transform_buffer_offset.unwrap(), + )); } cmd_buf_data.buffer_memory_init_actions.extend( transform_buffer.initialization_status.read().create_action( From 4280f29ead2a10eed9f5a990f3b109871a1fc87a Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 11 Dec 2023 18:39:46 +1300 Subject: [PATCH 119/146] actual final format fixes (hopefully) --- wgpu-core/src/command/ray_tracing.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index c9ef0b9263..aa597f39f2 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1020,8 +1020,7 @@ impl Global { return Err(BuildAccelerationStructureError::InsufficientBufferSize( mesh.vertex_buffer, vertex_buffer.size, - (mesh.size.vertex_count + mesh.first_vertex) as u64 - * mesh.vertex_stride, + (mesh.size.vertex_count + mesh.first_vertex) as u64 * mesh.vertex_stride, )); } let vertex_buffer_offset = mesh.first_vertex as u64 * mesh.vertex_stride; @@ -1113,14 +1112,13 @@ impl Global { BuildAccelerationStructureError::InvalidBuffer(*transform_id), )?; if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { - return Err( - BuildAccelerationStructureError::MissingBlasInputUsageFlag( - *transform_id, - ), - ); + return Err(BuildAccelerationStructureError::MissingBlasInputUsageFlag( + *transform_id, + )); } - if let Some(barrier) = - transform_pending.take().map(|pending| pending.into_hal(transform_buffer)) + if let Some(barrier) = transform_pending + .take() + .map(|pending| pending.into_hal(transform_buffer)) { input_barriers.push(barrier); } From 331625a2686d067f3f207d1d36188e9349b5225d Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 12 Dec 2023 15:41:25 +1300 Subject: [PATCH 120/146] move ray_cube_cube example and fix bugs --- examples/ray-cube-compute/Cargo.toml | 22 ----------- examples/src/lib.rs | 1 + examples/src/main.rs | 6 +++ .../ray_cube_compute}/README.md | 2 +- .../src => src/ray_cube_compute}/blit.wgsl | 0 .../main.rs => src/ray_cube_compute/mod.rs} | 17 +++----- .../ray_cube_compute}/screenshot.png | Bin .../src => src/ray_cube_compute}/shader.wgsl | 0 wgpu-core/src/command/ray_tracing.rs | 37 ++++++++++-------- 9 files changed, 35 insertions(+), 50 deletions(-) delete mode 100644 examples/ray-cube-compute/Cargo.toml rename examples/{ray-cube-compute => src/ray_cube_compute}/README.md (86%) rename examples/{ray-cube-compute/src => src/ray_cube_compute}/blit.wgsl (100%) rename examples/{ray-cube-compute/src/main.rs => src/ray_cube_compute/mod.rs} (97%) rename examples/{ray-cube-compute => src/ray_cube_compute}/screenshot.png (100%) rename examples/{ray-cube-compute/src => src/ray_cube_compute}/shader.wgsl (100%) diff --git a/examples/ray-cube-compute/Cargo.toml b/examples/ray-cube-compute/Cargo.toml deleted file mode 100644 index adeffa765b..0000000000 --- a/examples/ray-cube-compute/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "ray-cube-compute" -version.workspace = true -license.workspace = true -edition.workspace = true -description = "todo" -publish = false - -[[bin]] -name = "ray-cube-compute" -path = "src/main.rs" - -[dependencies] -bytemuck.workspace = true -glam.workspace = true -wasm-bindgen-test.workspace = true -wgpu-example.workspace = true -wgpu.workspace = true -winit.workspace = true - -[dev-dependencies] -wgpu-test.workspace = true diff --git a/examples/src/lib.rs b/examples/src/lib.rs index 1a55631097..f69430afb7 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -24,6 +24,7 @@ pub mod texture_arrays; pub mod timestamp_queries; pub mod uniform_values; pub mod water; +pub mod ray_cube_compute; #[cfg(test)] wgpu_test::gpu_test_main!(); diff --git a/examples/src/main.rs b/examples/src/main.rs index 948cfd4944..4a19a4d7fb 100644 --- a/examples/src/main.rs +++ b/examples/src/main.rs @@ -146,6 +146,12 @@ const EXAMPLES: &[ExampleDesc] = &[ webgl: false, // No RODS webgpu: true, }, + ExampleDesc { + name: "ray_cube_compute", + function: wgpu_examples::ray_cube_compute::main, + webgl: false, // No Ray-tracing extensions + webgpu: false, // No Ray-tracing extensions (yet) + } ]; fn get_example_name() -> Option { diff --git a/examples/ray-cube-compute/README.md b/examples/src/ray_cube_compute/README.md similarity index 86% rename from examples/ray-cube-compute/README.md rename to examples/src/ray_cube_compute/README.md index 7020f6a37c..9110787e38 100644 --- a/examples/ray-cube-compute/README.md +++ b/examples/src/ray_cube_compute/README.md @@ -11,4 +11,4 @@ cargo run --example ray-cube-compute ## Screenshots -![Cube example](./screenshot.png) +![Cube example](screenshot.png) diff --git a/examples/ray-cube-compute/src/blit.wgsl b/examples/src/ray_cube_compute/blit.wgsl similarity index 100% rename from examples/ray-cube-compute/src/blit.wgsl rename to examples/src/ray_cube_compute/blit.wgsl diff --git a/examples/ray-cube-compute/src/main.rs b/examples/src/ray_cube_compute/mod.rs similarity index 97% rename from examples/ray-cube-compute/src/main.rs rename to examples/src/ray_cube_compute/mod.rs index 44289df80c..5730f44bc9 100644 --- a/examples/ray-cube-compute/src/main.rs +++ b/examples/src/ray_cube_compute/mod.rs @@ -5,7 +5,7 @@ use glam::{Affine3A, Mat4, Quat, Vec3}; use wgpu::util::DeviceExt; use rt::traits::*; -use wgpu::ray_tracing as rt; +use wgpu::{ray_tracing as rt, StoreOp}; // from cube #[repr(C)] @@ -259,7 +259,7 @@ struct Example { start_inst: Instant, } -impl wgpu_example::framework::Example for Example { +impl crate::framework::Example for Example { fn required_features() -> wgpu::Features { wgpu::Features::TEXTURE_BINDING_ARRAY | wgpu::Features::STORAGE_RESOURCE_BINDING_ARRAY @@ -543,7 +543,6 @@ impl wgpu_example::framework::Example for Example { view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue, - spawner: &wgpu_example::framework::Spawner, ) { device.push_error_scope(wgpu::ErrorFilter::Validation); @@ -592,7 +591,7 @@ impl wgpu_example::framework::Example for Example { resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), - store: true, + store: StoreOp::Store, }, })], depth_stencil_attachment: None, @@ -607,20 +606,16 @@ impl wgpu_example::framework::Example for Example { queue.submit(Some(encoder.finish())); - // If an error occurs, report it and panic. - spawner.spawn_local(ErrorFuture { - inner: device.pop_error_scope(), - }); } } -fn main() { - wgpu_example::framework::run::("ray-cube"); +pub fn main() { + crate::framework::run::("ray-cube"); } #[test] fn ray_cube_compute() { - wgpu_example::framework::test::(wgpu_example::framework::FrameworkRefTest { + crate::framework::test::(wgpu_example::framework::FrameworkRefTest { image_path: "/examples/ray-cube-compute/screenshot.png", width: 1024, height: 768, diff --git a/examples/ray-cube-compute/screenshot.png b/examples/src/ray_cube_compute/screenshot.png similarity index 100% rename from examples/ray-cube-compute/screenshot.png rename to examples/src/ray_cube_compute/screenshot.png diff --git a/examples/ray-cube-compute/src/shader.wgsl b/examples/src/ray_cube_compute/shader.wgsl similarity index 100% rename from examples/ray-cube-compute/src/shader.wgsl rename to examples/src/ray_cube_compute/shader.wgsl diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index aa597f39f2..6297570d6a 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -698,7 +698,7 @@ impl Global { raw: Mutex::new(Some(scratch_buffer)), device: device.clone(), size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), - info: ResourceInfo::new("Ratracing scratch buffer"), + info: ResourceInfo::new("Raytracing scratch buffer"), is_coherent: scratch_mapping.is_coherent, }))); @@ -1300,12 +1300,11 @@ impl Global { .create_buffer(&hal::BufferDescriptor { label: Some("(wgpu) scratch buffer"), size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), - usage: hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH, + usage: hal::BufferUses::ACCELERATION_STRUCTURE_SCRATCH | BufferUses::MAP_WRITE, memory_flags: hal::MemoryFlags::empty(), }) .map_err(crate::device::DeviceError::from)? }; - let staging_buffer = if !instance_buffer_staging_source.is_empty() { unsafe { let staging_buffer = device @@ -1324,7 +1323,6 @@ impl Global { 0..instance_buffer_staging_source.len() as u64, ) .map_err(crate::device::DeviceError::from)?; - ptr::copy_nonoverlapping( instance_buffer_staging_source.as_ptr(), mapping.ptr.as_ptr(), @@ -1335,14 +1333,16 @@ impl Global { .unmap_buffer(&staging_buffer) .map_err(crate::device::DeviceError::from)?; assert!(mapping.is_coherent); - - Some(StagingBuffer { + let buf = StagingBuffer { raw: Mutex::new(Some(staging_buffer)), device: device.clone(), size: instance_buffer_staging_source.len() as u64, info: ResourceInfo::new("Raytracing staging buffer"), is_coherent: mapping.is_coherent, - }) + }; + let staging_fid = hub.staging_buffers.request(); + let stage_buf = staging_fid.init(buf); + Some(stage_buf) } } else { None @@ -1508,7 +1508,7 @@ impl Global { .as_mut() .unwrap() .temp_resources - .push(TempResource::StagingBuffer(Arc::new(staging_buffer))); + .push(TempResource::StagingBuffer(staging_buffer)); } } let scratch_mapping = unsafe { @@ -1516,23 +1516,28 @@ impl Global { .raw() .map_buffer( &scratch_buffer, - 0..instance_buffer_staging_source.len() as u64, + 0..max(scratch_buffer_blas_size, scratch_buffer_tlas_size), ) .map_err(crate::device::DeviceError::from)? }; + + let buf = StagingBuffer { + raw: Mutex::new(Some(scratch_buffer)), + device: device.clone(), + size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), + info: ResourceInfo::new("Ratracing scratch buffer"), + is_coherent: scratch_mapping.is_coherent, + }; + let staging_fid = hub.staging_buffers.request(); + let stage_buf = staging_fid.init(buf); + device .pending_writes .lock() .as_mut() .unwrap() .temp_resources - .push(TempResource::StagingBuffer(Arc::new(StagingBuffer { - raw: Mutex::new(Some(scratch_buffer)), - device: device.clone(), - size: max(scratch_buffer_blas_size, scratch_buffer_tlas_size), - info: ResourceInfo::new("Ratracing scratch buffer"), - is_coherent: scratch_mapping.is_coherent, - }))); + .push(TempResource::StagingBuffer(stage_buf)); Ok(()) } From 49b65e4a9a142bf4779cb005bf3c6234350ab161 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 12 Dec 2023 16:45:59 +1300 Subject: [PATCH 121/146] move other examples --- examples/ray-cube-fragment/Cargo.toml | 22 ------- examples/ray-scene/Cargo.toml | 23 ------- examples/src/lib.rs | 2 + examples/src/main.rs | 12 ++++ examples/src/ray_cube_compute/mod.rs | 35 +++++----- .../ray_cube_fragment}/README.md | 2 +- .../main.rs => src/ray_cube_fragment/mod.rs} | 49 ++++++-------- .../ray_cube_fragment}/screenshot.png | Bin .../src => src/ray_cube_fragment}/shader.wgsl | 0 .../{ray-scene => src/ray_scene}/cube.mtl | 0 .../{ray-scene => src/ray_scene}/cube.obj | 0 .../src/main.rs => src/ray_scene/mod.rs} | 60 ++++++++---------- .../src => src/ray_scene}/shader.wgsl | 0 wgpu-core/src/device/ray_tracing.rs | 2 +- 14 files changed, 80 insertions(+), 127 deletions(-) delete mode 100644 examples/ray-cube-fragment/Cargo.toml delete mode 100644 examples/ray-scene/Cargo.toml rename examples/{ray-cube-fragment => src/ray_cube_fragment}/README.md (81%) rename examples/{ray-cube-fragment/src/main.rs => src/ray_cube_fragment/mod.rs} (91%) rename examples/{ray-cube-fragment => src/ray_cube_fragment}/screenshot.png (100%) rename examples/{ray-cube-fragment/src => src/ray_cube_fragment}/shader.wgsl (100%) rename examples/{ray-scene => src/ray_scene}/cube.mtl (100%) rename examples/{ray-scene => src/ray_scene}/cube.obj (100%) rename examples/{ray-scene/src/main.rs => src/ray_scene/mod.rs} (92%) rename examples/{ray-scene/src => src/ray_scene}/shader.wgsl (100%) diff --git a/examples/ray-cube-fragment/Cargo.toml b/examples/ray-cube-fragment/Cargo.toml deleted file mode 100644 index a81f7ab97d..0000000000 --- a/examples/ray-cube-fragment/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "ray-cube-fragment" -version.workspace = true -license.workspace = true -edition.workspace = true -description = "todo" -publish = false - -[[bin]] -name = "ray-cube-fragment" -path = "src/main.rs" - -[dependencies] -bytemuck.workspace = true -glam.workspace = true -wasm-bindgen-test.workspace = true -wgpu-example.workspace = true -wgpu.workspace = true -winit.workspace = true - -[dev-dependencies] -wgpu-test.workspace = true diff --git a/examples/ray-scene/Cargo.toml b/examples/ray-scene/Cargo.toml deleted file mode 100644 index 9fbeffab9f..0000000000 --- a/examples/ray-scene/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "ray-scene" -version.workspace = true -license.workspace = true -edition.workspace = true -description = "todo" -publish = false - -[[bin]] -name = "ray-scene" -path = "src/main.rs" - -[dependencies] -bytemuck.workspace = true -glam.workspace = true -obj.workspace = true -wasm-bindgen-test.workspace = true -wgpu-example.workspace = true -wgpu.workspace = true -winit.workspace = true - -[dev-dependencies] -wgpu-test.workspace = true diff --git a/examples/src/lib.rs b/examples/src/lib.rs index f69430afb7..e92660f39c 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -25,6 +25,8 @@ pub mod timestamp_queries; pub mod uniform_values; pub mod water; pub mod ray_cube_compute; +pub mod ray_cube_fragment; +pub mod ray_scene; #[cfg(test)] wgpu_test::gpu_test_main!(); diff --git a/examples/src/main.rs b/examples/src/main.rs index 4a19a4d7fb..74ddccf117 100644 --- a/examples/src/main.rs +++ b/examples/src/main.rs @@ -151,6 +151,18 @@ const EXAMPLES: &[ExampleDesc] = &[ function: wgpu_examples::ray_cube_compute::main, webgl: false, // No Ray-tracing extensions webgpu: false, // No Ray-tracing extensions (yet) + }, + ExampleDesc { + name: "ray_cube_fragment", + function: wgpu_examples::ray_cube_fragment::main, + webgl: false, // No Ray-tracing extensions + webgpu: false, // No Ray-tracing extensions (yet) + }, + ExampleDesc { + name: "ray_scene", + function: wgpu_examples::ray_scene::main, + webgl: false, // No Ray-tracing extensions + webgpu: false, // No Ray-tracing extensions (yet) } ]; diff --git a/examples/src/ray_cube_compute/mod.rs b/examples/src/ray_cube_compute/mod.rs index 5730f44bc9..f9db1d265e 100644 --- a/examples/src/ray_cube_compute/mod.rs +++ b/examples/src/ray_cube_compute/mod.rs @@ -236,7 +236,7 @@ impl>> Future for ErrorFuture { let inner = unsafe { self.map_unchecked_mut(|me| &mut me.inner) }; inner.poll(cx).map(|error| { if let Some(e) = error { - panic!("Rendering {e}"); + panic!("Rendering {}", e); } }) } @@ -613,20 +613,19 @@ pub fn main() { crate::framework::run::("ray-cube"); } -#[test] -fn ray_cube_compute() { - crate::framework::test::(wgpu_example::framework::FrameworkRefTest { - image_path: "/examples/ray-cube-compute/screenshot.png", - width: 1024, - height: 768, - optional_features: wgpu::Features::default(), - base_test_parameters: wgpu_test::TestParameters { - required_features: ::required_features(), - required_downlevel_properties: - ::required_downlevel_capabilities(), - required_limits: ::required_limits(), - failures: Vec::new(), - }, - comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], - }); -} +#[cfg(test)] +#[wgpu_test::gpu_test] +static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { + image_path: "/examples/ray_cube_compute/screenshot.png", + width: 1024, + height: 768, + optional_features: wgpu::Features::default(), + base_test_parameters: wgpu_test::TestParameters { + required_features: ::required_features(), + required_limits: ::required_limits(), + skips: vec![], + failures: Vec::new(), + required_downlevel_caps: ::required_downlevel_capabilities(), + }, + comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], +}; \ No newline at end of file diff --git a/examples/ray-cube-fragment/README.md b/examples/src/ray_cube_fragment/README.md similarity index 81% rename from examples/ray-cube-fragment/README.md rename to examples/src/ray_cube_fragment/README.md index f101fb5eaa..fba22bc6d6 100644 --- a/examples/ray-cube-fragment/README.md +++ b/examples/src/ray_cube_fragment/README.md @@ -10,4 +10,4 @@ cargo run --example ray-cube-fragment ## Screenshots -![Cube example](./screenshot.png) +![Cube example](screenshot.png) diff --git a/examples/ray-cube-fragment/src/main.rs b/examples/src/ray_cube_fragment/mod.rs similarity index 91% rename from examples/ray-cube-fragment/src/main.rs rename to examples/src/ray_cube_fragment/mod.rs index a642207fd3..07ed4ddfa8 100644 --- a/examples/ray-cube-fragment/src/main.rs +++ b/examples/src/ray_cube_fragment/mod.rs @@ -91,7 +91,7 @@ impl>> Future for ErrorFuture { let inner = unsafe { self.map_unchecked_mut(|me| &mut me.inner) }; inner.poll(cx).map(|error| { if let Some(e) = error { - panic!("Rendering {e}"); + panic!("Rendering {}", e); } }) } @@ -110,7 +110,7 @@ struct Example { start_inst: Instant, } -impl wgpu_example::framework::Example for Example { +impl crate::framework::Example for Example { fn required_features() -> wgpu::Features { wgpu::Features::RAY_QUERY | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE } @@ -300,7 +300,6 @@ impl wgpu_example::framework::Example for Example { view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue, - spawner: &wgpu_example::framework::Spawner, ) { device.push_error_scope(wgpu::ErrorFilter::Validation); @@ -359,7 +358,7 @@ impl wgpu_example::framework::Example for Example { resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), - store: true, + store: wgpu::StoreOp::Store, }, })], depth_stencil_attachment: None, @@ -373,32 +372,26 @@ impl wgpu_example::framework::Example for Example { } queue.submit(Some(encoder.finish())); - - // If an error occurs, report it and panic. - spawner.spawn_local(ErrorFuture { - inner: device.pop_error_scope(), - }); } } -fn main() { - wgpu_example::framework::run::("ray-cube"); +pub fn main() { + crate::framework::run::("ray-cube"); } -#[test] -fn ray_cube_fragment() { - wgpu_example::framework::test::(wgpu_example::framework::FrameworkRefTest { - image_path: "/examples/ray-cube-fragment/screenshot.png", - width: 1024, - height: 768, - optional_features: wgpu::Features::default(), - base_test_parameters: wgpu_test::TestParameters { - required_features: ::required_features(), - required_downlevel_properties: - ::required_downlevel_capabilities(), - required_limits: ::required_limits(), - failures: Vec::new(), - }, - comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], - }); -} +#[cfg(test)] +#[wgpu_test::gpu_test] +static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { + image_path: "/examples/ray_cube_fragment/screenshot.png", + width: 1024, + height: 768, + optional_features: wgpu::Features::default(), + base_test_parameters: wgpu_test::TestParameters { + required_features: ::required_features(), + required_limits: ::required_limits(), + skips: vec![], + failures: Vec::new(), + required_downlevel_caps: ::required_downlevel_capabilities(), + }, + comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], +}; \ No newline at end of file diff --git a/examples/ray-cube-fragment/screenshot.png b/examples/src/ray_cube_fragment/screenshot.png similarity index 100% rename from examples/ray-cube-fragment/screenshot.png rename to examples/src/ray_cube_fragment/screenshot.png diff --git a/examples/ray-cube-fragment/src/shader.wgsl b/examples/src/ray_cube_fragment/shader.wgsl similarity index 100% rename from examples/ray-cube-fragment/src/shader.wgsl rename to examples/src/ray_cube_fragment/shader.wgsl diff --git a/examples/ray-scene/cube.mtl b/examples/src/ray_scene/cube.mtl similarity index 100% rename from examples/ray-scene/cube.mtl rename to examples/src/ray_scene/cube.mtl diff --git a/examples/ray-scene/cube.obj b/examples/src/ray_scene/cube.obj similarity index 100% rename from examples/ray-scene/cube.obj rename to examples/src/ray_scene/cube.obj diff --git a/examples/ray-scene/src/main.rs b/examples/src/ray_scene/mod.rs similarity index 92% rename from examples/ray-scene/src/main.rs rename to examples/src/ray_scene/mod.rs index 2175b88976..fd267d4244 100644 --- a/examples/ray-scene/src/main.rs +++ b/examples/src/ray_scene/mod.rs @@ -42,7 +42,7 @@ impl>> Future for ErrorFuture { let inner = unsafe { self.map_unchecked_mut(|me| &mut me.inner) }; inner.poll(cx).map(|error| { if let Some(e) = error { - panic!("Rendering {e}"); + panic!("Rendering {}", e); } }) } @@ -94,7 +94,8 @@ struct Material { } fn load_model(scene: &mut RawSceneComponents, path: &str) { - let path = env!("CARGO_MANIFEST_DIR").to_string() + "/../../" + path; + let path = env!("CARGO_MANIFEST_DIR").to_string() + "/src" + path; + println!("{}", path); let mut object = obj::Obj::load(path).unwrap(); object.load_mtls().unwrap(); @@ -298,9 +299,8 @@ fn upload_scene_components( fn load_scene(device: &wgpu::Device, queue: &wgpu::Queue) -> SceneComponents { let mut scene = RawSceneComponents::default(); - load_model(&mut scene, "/examples/skybox/models/teslacyberv3.0.obj"); - load_model(&mut scene, "/examples/ray-scene/cube.obj"); + load_model(&mut scene, "/ray_scene/cube.obj"); upload_scene_components(device, queue, &scene) } @@ -316,7 +316,7 @@ struct Example { scene_components: SceneComponents, } -impl wgpu_example::framework::Example for Example { +impl crate::framework::Example for Example { fn required_features() -> wgpu::Features { wgpu::Features::RAY_QUERY | wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE } @@ -466,7 +466,6 @@ impl wgpu_example::framework::Example for Example { view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue, - spawner: &wgpu_example::framework::Spawner, ) { device.push_error_scope(wgpu::ErrorFilter::Validation); @@ -482,10 +481,10 @@ impl wgpu_example::framework::Example for Example { for y in 0..side_count { let instance = self .tlas_package - .get_mut_single((x + y * side_count) as usize) + .get_mut_single(((x + y) * side_count) as usize) .unwrap(); - let blas_index = (x + y) % 2; + let blas_index = (x + y) % self.scene_components.bottom_level_acceleration_structures.len(); let x = x as f32 / (side_count - 1) as f32; let y = y as f32 / (side_count - 1) as f32; @@ -508,7 +507,6 @@ impl wgpu_example::framework::Example for Example { let transform = transform.transpose().to_cols_array()[..12] .try_into() .unwrap(); - *instance = Some(rt::TlasInstance::new( &self.scene_components.bottom_level_acceleration_structures[blas_index], transform, @@ -532,7 +530,7 @@ impl wgpu_example::framework::Example for Example { resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), - store: true, + store: wgpu::StoreOp::Store, }, })], depth_stencil_attachment: None, @@ -546,32 +544,26 @@ impl wgpu_example::framework::Example for Example { } queue.submit(Some(encoder.finish())); - - // If an error occurs, report it and panic. - spawner.spawn_local(ErrorFuture { - inner: device.pop_error_scope(), - }); } } -fn main() { - wgpu_example::framework::run::("ray-scene"); +pub fn main() { + crate::framework::run::("ray_scene"); } -#[test] -fn ray_cube_fragment() { - wgpu_example::framework::test::(wgpu_example::framework::FrameworkRefTest { - image_path: "/examples/ray-cube-fragment/screenshot.png", - width: 1024, - height: 768, - optional_features: wgpu::Features::default(), - base_test_parameters: wgpu_test::TestParameters { - required_features: ::required_features(), - required_downlevel_properties: - ::required_downlevel_capabilities(), - required_limits: ::required_limits(), - failures: Vec::new(), - }, - comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], - }); -} +#[cfg(test)] +#[wgpu_test::gpu_test] +static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { + image_path: "/examples/ray_cube_fragment/screenshot.png", + width: 1024, + height: 768, + optional_features: wgpu::Features::default(), + base_test_parameters: wgpu_test::TestParameters { + required_features: ::required_features(), + required_limits: ::required_limits(), + skips: vec![], + failures: Vec::new(), + required_downlevel_caps: ::required_downlevel_capabilities(), + }, + comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], +}; diff --git a/examples/ray-scene/src/shader.wgsl b/examples/src/ray_scene/shader.wgsl similarity index 100% rename from examples/ray-scene/src/shader.wgsl rename to examples/src/ray_scene/shader.wgsl diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index fde161c891..745c10c94e 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -351,7 +351,7 @@ impl Global { raw: Mutex::new(Some(e)), device: device.clone(), size, - info: ResourceInfo::new("Ratracing scratch buffer"), + info: ResourceInfo::new("Raytracing scratch buffer"), is_coherent: mapping.is_coherent, }))) } From 2f25773354610e06ed45058ea3fded630c17357e Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 12 Dec 2023 18:35:52 +1300 Subject: [PATCH 122/146] fix crash when dropping --- wgpu-core/src/device/ray_tracing.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 745c10c94e..2b5b62fc56 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -318,15 +318,13 @@ impl Global { let hub = A::hub(self); - let device_guard = hub.devices.write(); - log::info!("Tlas {:?} is destroyed", tlas_id); let tlas_guard = hub.tlas_s.write(); let tlas = tlas_guard .get(tlas_id) .map_err(|_| resource::DestroyError::Invalid)?; - let device = &mut device_guard.get(tlas.device.info.id()).unwrap(); + let device = &mut tlas.device.clone(); #[cfg(feature = "trace")] if let Some(trace) = device.trace.lock().as_mut() { @@ -375,7 +373,6 @@ impl Global { log::debug!("tlas {:?} is dropped", tlas_id); let hub = A::hub(self); - let device_guard = hub.devices.write(); let (last_submit_index, device) = { let mut tlas_guard = hub.tlas_s.write(); @@ -384,7 +381,7 @@ impl Global { let last_submit_index = tlas.info.submission_index(); ( last_submit_index, - device_guard.get(tlas.device.info.id()).unwrap(), + tlas.device.clone() ) } Err(InvalidId) => { From 74ce4143aa29b7558e052f5118c40246785a50ef Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 12 Dec 2023 19:07:04 +1300 Subject: [PATCH 123/146] fix test --- examples/src/ray_cube_compute/mod.rs | 2 ++ examples/src/ray_cube_fragment/mod.rs | 2 ++ examples/src/ray_scene/mod.rs | 2 ++ 3 files changed, 6 insertions(+) diff --git a/examples/src/ray_cube_compute/mod.rs b/examples/src/ray_cube_compute/mod.rs index f9db1d265e..68505c43f6 100644 --- a/examples/src/ray_cube_compute/mod.rs +++ b/examples/src/ray_cube_compute/mod.rs @@ -616,6 +616,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { + name: "ray_cube_compute", image_path: "/examples/ray_cube_compute/screenshot.png", width: 1024, height: 768, @@ -628,4 +629,5 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest required_downlevel_caps: ::required_downlevel_capabilities(), }, comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], + _phantom: std::marker::PhantomData::, }; \ No newline at end of file diff --git a/examples/src/ray_cube_fragment/mod.rs b/examples/src/ray_cube_fragment/mod.rs index 07ed4ddfa8..2d9f14a66f 100644 --- a/examples/src/ray_cube_fragment/mod.rs +++ b/examples/src/ray_cube_fragment/mod.rs @@ -382,6 +382,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { + name: "ray_cube_fragment", image_path: "/examples/ray_cube_fragment/screenshot.png", width: 1024, height: 768, @@ -394,4 +395,5 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest required_downlevel_caps: ::required_downlevel_capabilities(), }, comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], + _phantom: std::marker::PhantomData::, }; \ No newline at end of file diff --git a/examples/src/ray_scene/mod.rs b/examples/src/ray_scene/mod.rs index fd267d4244..4bb2f2115d 100644 --- a/examples/src/ray_scene/mod.rs +++ b/examples/src/ray_scene/mod.rs @@ -554,6 +554,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { + name: "ray_cube_fragment", image_path: "/examples/ray_cube_fragment/screenshot.png", width: 1024, height: 768, @@ -566,4 +567,5 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest required_downlevel_caps: ::required_downlevel_capabilities(), }, comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], + _phantom: std::marker::PhantomData::, }; From 3765defdc455876a1e2dfd8eda75f48feab185ba Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 12 Dec 2023 19:21:07 +1300 Subject: [PATCH 124/146] apply clippy and rustfmt changes --- examples/src/lib.rs | 6 +++--- examples/src/main.rs | 8 ++++---- examples/src/ray_cube_compute/mod.rs | 13 ++++--------- examples/src/ray_cube_fragment/mod.rs | 12 ++++-------- examples/src/ray_scene/mod.rs | 21 ++++++++++----------- wgpu-core/src/device/ray_tracing.rs | 5 +---- 6 files changed, 26 insertions(+), 39 deletions(-) diff --git a/examples/src/lib.rs b/examples/src/lib.rs index e92660f39c..d6a18c0f11 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -13,6 +13,9 @@ pub mod hello_windows; pub mod hello_workgroups; pub mod mipmap; pub mod msaa_line; +pub mod ray_cube_compute; +pub mod ray_cube_fragment; +pub mod ray_scene; pub mod render_to_texture; pub mod repeated_compute; pub mod shadow; @@ -24,9 +27,6 @@ pub mod texture_arrays; pub mod timestamp_queries; pub mod uniform_values; pub mod water; -pub mod ray_cube_compute; -pub mod ray_cube_fragment; -pub mod ray_scene; #[cfg(test)] wgpu_test::gpu_test_main!(); diff --git a/examples/src/main.rs b/examples/src/main.rs index 74ddccf117..9e3df36e23 100644 --- a/examples/src/main.rs +++ b/examples/src/main.rs @@ -149,21 +149,21 @@ const EXAMPLES: &[ExampleDesc] = &[ ExampleDesc { name: "ray_cube_compute", function: wgpu_examples::ray_cube_compute::main, - webgl: false, // No Ray-tracing extensions + webgl: false, // No Ray-tracing extensions webgpu: false, // No Ray-tracing extensions (yet) }, ExampleDesc { name: "ray_cube_fragment", function: wgpu_examples::ray_cube_fragment::main, - webgl: false, // No Ray-tracing extensions + webgl: false, // No Ray-tracing extensions webgpu: false, // No Ray-tracing extensions (yet) }, ExampleDesc { name: "ray_scene", function: wgpu_examples::ray_scene::main, - webgl: false, // No Ray-tracing extensions + webgl: false, // No Ray-tracing extensions webgpu: false, // No Ray-tracing extensions (yet) - } + }, ]; fn get_example_name() -> Option { diff --git a/examples/src/ray_cube_compute/mod.rs b/examples/src/ray_cube_compute/mod.rs index 68505c43f6..97c68255ae 100644 --- a/examples/src/ray_cube_compute/mod.rs +++ b/examples/src/ray_cube_compute/mod.rs @@ -538,12 +538,7 @@ impl crate::framework::Example for Example { ) { } - fn render( - &mut self, - view: &wgpu::TextureView, - device: &wgpu::Device, - queue: &wgpu::Queue, - ) { + fn render(&mut self, view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue) { device.push_error_scope(wgpu::ErrorFilter::Validation); let anim_time = self.start_inst.elapsed().as_secs_f64() as f32; @@ -605,7 +600,6 @@ impl crate::framework::Example for Example { } queue.submit(Some(encoder.finish())); - } } @@ -626,8 +620,9 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest required_limits: ::required_limits(), skips: vec![], failures: Vec::new(), - required_downlevel_caps: ::required_downlevel_capabilities(), + required_downlevel_caps: + ::required_downlevel_capabilities(), }, comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], _phantom: std::marker::PhantomData::, -}; \ No newline at end of file +}; diff --git a/examples/src/ray_cube_fragment/mod.rs b/examples/src/ray_cube_fragment/mod.rs index 2d9f14a66f..8aa81a1810 100644 --- a/examples/src/ray_cube_fragment/mod.rs +++ b/examples/src/ray_cube_fragment/mod.rs @@ -295,12 +295,7 @@ impl crate::framework::Example for Example { queue.write_buffer(&self.uniform_buf, 0, bytemuck::cast_slice(&[self.uniforms])); } - fn render( - &mut self, - view: &wgpu::TextureView, - device: &wgpu::Device, - queue: &wgpu::Queue, - ) { + fn render(&mut self, view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue) { device.push_error_scope(wgpu::ErrorFilter::Validation); // scene update @@ -392,8 +387,9 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest required_limits: ::required_limits(), skips: vec![], failures: Vec::new(), - required_downlevel_caps: ::required_downlevel_capabilities(), + required_downlevel_caps: + ::required_downlevel_capabilities(), }, comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], _phantom: std::marker::PhantomData::, -}; \ No newline at end of file +}; diff --git a/examples/src/ray_scene/mod.rs b/examples/src/ray_scene/mod.rs index 4bb2f2115d..da8877f437 100644 --- a/examples/src/ray_scene/mod.rs +++ b/examples/src/ray_scene/mod.rs @@ -227,7 +227,6 @@ fn upload_scene_components( .map(|(vertex_range, geometry_range)| { let size_desc: Vec = (*geometry_range) .clone() - .into_iter() .map(|i| rt::BlasTriangleGeometrySizeDescriptor { vertex_format: wgpu::VertexFormat::Float32x3, vertex_count: vertex_range.end as u32 - vertex_range.start as u32, @@ -261,7 +260,7 @@ fn upload_scene_components( .map(|(((vertex_range, geometry_range), size_desc), blas)| { let triangle_geometries: Vec<_> = size_desc .iter() - .zip(geometry_range.clone().into_iter()) + .zip(geometry_range.clone()) .map(|(size, i)| rt::BlasTriangleGeometry { size, vertex_buffer: &vertices, @@ -461,12 +460,7 @@ impl crate::framework::Example for Example { queue.write_buffer(&self.uniform_buf, 0, bytemuck::cast_slice(&[self.uniforms])); } - fn render( - &mut self, - view: &wgpu::TextureView, - device: &wgpu::Device, - queue: &wgpu::Queue, - ) { + fn render(&mut self, view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue) { device.push_error_scope(wgpu::ErrorFilter::Validation); // scene update @@ -481,10 +475,14 @@ impl crate::framework::Example for Example { for y in 0..side_count { let instance = self .tlas_package - .get_mut_single(((x + y) * side_count) as usize) + .get_mut_single((x + y) * side_count) .unwrap(); - let blas_index = (x + y) % self.scene_components.bottom_level_acceleration_structures.len(); + let blas_index = (x + y) + % self + .scene_components + .bottom_level_acceleration_structures + .len(); let x = x as f32 / (side_count - 1) as f32; let y = y as f32 / (side_count - 1) as f32; @@ -564,7 +562,8 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest required_limits: ::required_limits(), skips: vec![], failures: Vec::new(), - required_downlevel_caps: ::required_downlevel_capabilities(), + required_downlevel_caps: + ::required_downlevel_capabilities(), }, comparisons: &[wgpu_test::ComparisonType::Mean(0.02)], _phantom: std::marker::PhantomData::, diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 2b5b62fc56..5c16e9fbb2 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -379,10 +379,7 @@ impl Global { match tlas_guard.get(tlas_id) { Ok(tlas) => { let last_submit_index = tlas.info.submission_index(); - ( - last_submit_index, - tlas.device.clone() - ) + (last_submit_index, tlas.device.clone()) } Err(InvalidId) => { hub.tlas_s.unregister_locked(tlas_id, &mut *tlas_guard); From 986d52012b89ab5bb96c9b43b507dfd13c11b6f6 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Wed, 13 Dec 2023 17:10:20 +1300 Subject: [PATCH 125/146] fix some memory leaks --- wgpu-core/src/device/life.rs | 57 ++++++++++++++++++++ wgpu-core/src/device/ray_tracing.rs | 84 +++++++++++------------------ wgpu-core/src/registry.rs | 5 +- wgpu-core/src/resource.rs | 25 +++++++++ 4 files changed, 116 insertions(+), 55 deletions(-) diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 8a2e22a8c6..c68aaa8df4 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -520,6 +520,9 @@ impl LifetimeTracker { for v in bind_group.used.samplers.drain_resources() { self.suspected_resources.insert(v.as_info().id(), v); } + for v in bind_group.used.acceleration_structures.drain_resources() { + self.suspected_resources.insert(v.as_info().id(), v); + } //Releasing safely unused resources to decrement refcount bind_group.used_buffer_ranges.write().clear(); bind_group.used_texture_ranges.write().clear(); @@ -737,6 +740,50 @@ impl LifetimeTracker { self } + fn triage_suspected_blas( + &mut self, + trackers: &Mutex>, + #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, + ) -> &mut Self { + let mut trackers = trackers.lock(); + let resource_map = self.suspected_resources.map_mut(); + let _ = Self::triage_resources( + resource_map, + self.active.as_mut_slice(), + &mut self.free_resources, + &mut trackers.blas_s, + |_blas_id, _blas| { + #[cfg(feature = "trace")] + if let Some(ref mut t) = *trace { + t.add(trace::Action::DestroyBlas(*_blas_id)); + } + }, + ); + self + } + + fn triage_suspected_tlas( + &mut self, + trackers: &Mutex>, + #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, + ) -> &mut Self { + let mut trackers = trackers.lock(); + let resource_map = self.suspected_resources.map_mut(); + let _ = Self::triage_resources( + resource_map, + self.active.as_mut_slice(), + &mut self.free_resources, + &mut trackers.tlas_s, + |_tlas_id, _tlas| { + #[cfg(feature = "trace")] + if let Some(ref mut t) = *trace { + t.add(trace::Action::DestroyTlas(*_tlas_id)); + } + }, + ); + self + } + fn triage_suspected_query_sets(&mut self, trackers: &Mutex>) -> &mut Self { let mut trackers = trackers.lock(); let resource_map = self.suspected_resources.map_mut(); @@ -859,6 +906,16 @@ impl LifetimeTracker { #[cfg(feature = "trace")] &mut trace, ); + self.triage_suspected_tlas( + trackers, + #[cfg(feature = "trace")] + &mut trace, + ); + self.triage_suspected_blas( + trackers, + #[cfg(feature = "trace")] + &mut trace, + ); } /// Determine which buffers are ready to map, and which must wait for the diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 5c16e9fbb2..2f17d7dcc1 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -7,9 +7,7 @@ use crate::{ id::{self, BlasId, TlasId}, identity::{GlobalIdentityHandlerFactory, Input}, ray_tracing::{get_raw_tlas_instance_size, CreateBlasError, CreateTlasError}, - resource, - storage::InvalidId, - LabelHelpers, + resource, LabelHelpers, }; use parking_lot::{Mutex, RwLock}; use std::sync::Arc; @@ -177,6 +175,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.is_valid() { + break DeviceError::Lost.into(); + } + #[cfg(feature = "trace")] if let Some(trace) = device.trace.lock().as_mut() { trace.add(trace::Action::CreateBlas { @@ -192,12 +194,12 @@ impl Global { }; let handle = blas.handle; - let id = fid.assign(blas); - log::info!("Created blas {:?} with {:?}", id.0, desc); + let (id, resource) = fid.assign(blas); + log::info!("Created blas {:?} with {:?}", id, desc); - device.trackers.lock().blas_s.insert_single(id.0, id.1); + device.trackers.lock().blas_s.insert_single(id, resource); - return (id.0, Some(handle), None); + return (id, Some(handle), None); }; let id = fid.assign_error(desc.label.borrow_or_default()); @@ -284,31 +286,19 @@ impl Global { let hub = A::hub(self); - let (last_submit_index, device) = { - let mut blas_guard = hub.blas_s.write(); - match blas_guard.get(blas_id) { - Ok(blas) => { - let last_submit_index = blas.info.submission_index(); - (last_submit_index, blas.device.clone()) - } - Err(_) => { - hub.blas_s.unregister_locked(blas_id, &mut *blas_guard); - return; - } - } - }; + if let Some(blas) = hub.blas_s.unregister(blas_id) { + let last_submit_index = blas.info.submission_index(); - let blas_guard = hub.blas_s.read(); - let blas = blas_guard.get(blas_id).unwrap(); - { - let mut life_lock = device.lock_life(); - life_lock.suspected_resources.insert(blas_id, blas.clone()); - } + blas.device + .lock_life() + .suspected_resources + .insert(blas_id, blas.clone()); - if wait { - match device.wait_for_submit(last_submit_index) { - Ok(()) => (), - Err(e) => log::error!("Failed to wait for blas {:?}: {:?}", blas_id, e), + if wait { + match blas.device.wait_for_submit(last_submit_index) { + Ok(()) => (), + Err(e) => log::error!("Failed to wait for blas {:?}: {:?}", blas_id, e), + } } } } @@ -374,31 +364,19 @@ impl Global { let hub = A::hub(self); - let (last_submit_index, device) = { - let mut tlas_guard = hub.tlas_s.write(); - match tlas_guard.get(tlas_id) { - Ok(tlas) => { - let last_submit_index = tlas.info.submission_index(); - (last_submit_index, tlas.device.clone()) - } - Err(InvalidId) => { - hub.tlas_s.unregister_locked(tlas_id, &mut *tlas_guard); - return; - } - } - }; + if let Some(tlas) = hub.tlas_s.unregister(tlas_id) { + let last_submit_index = tlas.info.submission_index(); - let tlas_guard = hub.tlas_s.read(); - let tlas = tlas_guard.get(tlas_id).unwrap(); - { - let mut life_lock = device.lock_life(); - life_lock.suspected_resources.insert(tlas_id, tlas.clone()); - } + tlas.device + .lock_life() + .suspected_resources + .insert(tlas_id, tlas.clone()); - if wait { - match device.wait_for_submit(last_submit_index) { - Ok(()) => (), - Err(e) => log::error!("Failed to wait for tlas {:?}: {:?}", tlas_id, e), + if wait { + match tlas.device.wait_for_submit(last_submit_index) { + Ok(()) => (), + Err(e) => log::error!("Failed to wait for blas {:?}: {:?}", tlas_id, e), + } } } } diff --git a/wgpu-core/src/registry.rs b/wgpu-core/src/registry.rs index 0fe3b7dd13..f9ec2120c8 100644 --- a/wgpu-core/src/registry.rs +++ b/wgpu-core/src/registry.rs @@ -82,8 +82,9 @@ impl> FutureId<'_, I, T> { pub fn assign(self, value: T) -> (I, Arc) { let mut data = self.data.write(); - data.insert(self.id, self.init(value)); - (self.id, data.get(self.id).unwrap().clone()) + let inited_val = self.init(value); + data.insert(self.id, inited_val.clone()); + (self.id, inited_val) } pub fn assign_existing(self, value: &Arc) -> I { diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 6786f45424..37286085e7 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -1317,6 +1317,17 @@ pub struct Blas { pub(crate) handle: u64, } +impl Drop for Blas { + fn drop(&mut self) { + unsafe { + if let Some(structure) = self.raw.take() { + use hal::Device; + self.device.raw().destroy_acceleration_structure(structure); + } + } + } +} + impl Resource for Blas { const TYPE: &'static str = "Blas"; @@ -1343,6 +1354,20 @@ pub struct Tlas { pub(crate) instance_buffer: RwLock>, } +impl Drop for Tlas { + fn drop(&mut self) { + unsafe { + use hal::Device; + if let Some(structure) = self.raw.take() { + self.device.raw().destroy_acceleration_structure(structure); + } + if let Some(buffer) = self.instance_buffer.write().take() { + self.device.raw().destroy_buffer(buffer) + } + } + } +} + impl Resource for Tlas { const TYPE: &'static str = "Tlas"; From 817e5459882168bf6692c98c3a1dba5433644577 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 18 Dec 2023 09:54:35 +1300 Subject: [PATCH 126/146] fix incompatibility with new wgpu trunk changes --- wgpu-core/src/command/ray_tracing.rs | 30 +++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 6297570d6a..b904dff19a 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -296,11 +296,12 @@ impl Global { } let mut triangle_entries = Vec::>::new(); + let snatch_guard = device.snatchable_lock.read(); for buf in &mut buf_storage { let mesh = &buf.4; let vertex_buffer = { let vertex_buffer = buf.0.as_ref(); - let vertex_raw = vertex_buffer.raw.as_ref().ok_or( + let vertex_raw = vertex_buffer.raw.get(&snatch_guard).ok_or( BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer), )?; if !vertex_buffer.usage.contains(BufferUsages::BLAS_INPUT) { @@ -308,7 +309,7 @@ impl Global { mesh.vertex_buffer, )); } - if let Some(barrier) = buf.1.take().map(|pending| pending.into_hal(vertex_buffer)) { + if let Some(barrier) = buf.1.take().map(|pending| pending.into_hal(vertex_buffer, &snatch_guard)) { input_barriers.push(barrier); } if vertex_buffer.size @@ -336,7 +337,7 @@ impl Global { let index_id = mesh.index_buffer.as_ref().unwrap(); let index_raw = index_buffer .raw - .as_ref() + .get(&snatch_guard) .ok_or(BuildAccelerationStructureError::InvalidBuffer(*index_id))?; if !index_buffer.usage.contains(BufferUsages::BLAS_INPUT) { return Err(BuildAccelerationStructureError::MissingBlasInputUsageFlag( @@ -345,7 +346,7 @@ impl Global { } if let Some(barrier) = index_pending .take() - .map(|pending| pending.into_hal(index_buffer)) + .map(|pending| pending.into_hal(index_buffer, &snatch_guard)) { input_barriers.push(barrier); } @@ -405,7 +406,7 @@ impl Global { *transform_id, )); } - let transform_raw = transform_buffer.raw.as_ref().ok_or( + let transform_raw = transform_buffer.raw.get(&snatch_guard).ok_or( BuildAccelerationStructureError::InvalidBuffer(*transform_id), )?; if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { @@ -415,7 +416,7 @@ impl Global { } if let Some(barrier) = transform_pending .take() - .map(|pending| pending.into_hal(transform_buffer)) + .map(|pending| pending.into_hal(transform_buffer, &snatch_guard)) { input_barriers.push(barrier); } @@ -519,7 +520,7 @@ impl Global { let entry = &tlas_buf.2; let instance_buffer = { let (instance_buffer, instance_pending) = (&mut tlas_buf.0, &mut tlas_buf.1); - let instance_raw = instance_buffer.raw.as_ref().ok_or( + let instance_raw = instance_buffer.raw.get(&snatch_guard).ok_or( BuildAccelerationStructureError::InvalidBuffer(entry.instance_buffer_id), )?; if !instance_buffer.usage.contains(BufferUsages::TLAS_INPUT) { @@ -529,7 +530,7 @@ impl Global { } if let Some(barrier) = instance_pending .take() - .map(|pending| pending.into_hal(instance_buffer)) + .map(|pending| pending.into_hal(instance_buffer, &snatch_guard)) { input_barriers.push(barrier); } @@ -999,11 +1000,12 @@ impl Global { } let mut triangle_entries = Vec::>::new(); + let snatch_guard = device.snatchable_lock.read(); for buf in &mut buf_storage { let mesh = &buf.4; let vertex_buffer = { let vertex_buffer = buf.0.as_ref(); - let vertex_raw = vertex_buffer.raw.as_ref().ok_or( + let vertex_raw = vertex_buffer.raw.get(&snatch_guard).ok_or( BuildAccelerationStructureError::InvalidBuffer(mesh.vertex_buffer), )?; if !vertex_buffer.usage.contains(BufferUsages::BLAS_INPUT) { @@ -1011,7 +1013,7 @@ impl Global { mesh.vertex_buffer, )); } - if let Some(barrier) = buf.1.take().map(|pending| pending.into_hal(vertex_buffer)) { + if let Some(barrier) = buf.1.take().map(|pending| pending.into_hal(vertex_buffer, &snatch_guard)) { input_barriers.push(barrier); } if vertex_buffer.size @@ -1039,7 +1041,7 @@ impl Global { let index_id = mesh.index_buffer.as_ref().unwrap(); let index_raw = index_buffer .raw - .as_ref() + .get(&snatch_guard) .ok_or(BuildAccelerationStructureError::InvalidBuffer(*index_id))?; if !index_buffer.usage.contains(BufferUsages::BLAS_INPUT) { return Err(BuildAccelerationStructureError::MissingBlasInputUsageFlag( @@ -1048,7 +1050,7 @@ impl Global { } if let Some(barrier) = index_pending .take() - .map(|pending| pending.into_hal(index_buffer)) + .map(|pending| pending.into_hal(index_buffer, &snatch_guard)) { input_barriers.push(barrier); } @@ -1108,7 +1110,7 @@ impl Global { *transform_id, )); } - let transform_raw = transform_buffer.raw.as_ref().ok_or( + let transform_raw = transform_buffer.raw.get(&snatch_guard).ok_or( BuildAccelerationStructureError::InvalidBuffer(*transform_id), )?; if !transform_buffer.usage.contains(BufferUsages::BLAS_INPUT) { @@ -1118,7 +1120,7 @@ impl Global { } if let Some(barrier) = transform_pending .take() - .map(|pending| pending.into_hal(transform_buffer)) + .map(|pending| pending.into_hal(transform_buffer, &snatch_guard)) { input_barriers.push(barrier); } From e0b672468d8459c5380f7a487d047aad1e15fdec Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 18 Dec 2023 10:04:45 +1300 Subject: [PATCH 127/146] fix clippy & fmt --- wgpu-core/src/command/ray_tracing.rs | 16 ++++++++++++---- wgpu-core/src/device/ray_tracing.rs | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index b904dff19a..ca0b71cd55 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -164,7 +164,7 @@ impl Global { BlasGeometries::TriangleGeometries(triangle_geometries) => { for (i, mesh) in triangle_geometries.enumerate() { let size_desc = match &blas.sizes { - &wgt::BlasGeometrySizeDescriptors::Triangles { ref desc } => desc, + wgt::BlasGeometrySizeDescriptors::Triangles { desc } => desc, }; if i >= size_desc.len() { return Err( @@ -309,7 +309,11 @@ impl Global { mesh.vertex_buffer, )); } - if let Some(barrier) = buf.1.take().map(|pending| pending.into_hal(vertex_buffer, &snatch_guard)) { + if let Some(barrier) = buf + .1 + .take() + .map(|pending| pending.into_hal(vertex_buffer, &snatch_guard)) + { input_barriers.push(barrier); } if vertex_buffer.size @@ -867,7 +871,7 @@ impl Global { BlasGeometries::TriangleGeometries(triangle_geometries) => { for (i, mesh) in triangle_geometries.enumerate() { let size_desc = match &blas.sizes { - &wgt::BlasGeometrySizeDescriptors::Triangles { ref desc } => desc, + wgt::BlasGeometrySizeDescriptors::Triangles { desc } => desc, }; if i >= size_desc.len() { return Err( @@ -1013,7 +1017,11 @@ impl Global { mesh.vertex_buffer, )); } - if let Some(barrier) = buf.1.take().map(|pending| pending.into_hal(vertex_buffer, &snatch_guard)) { + if let Some(barrier) = buf + .1 + .take() + .map(|pending| pending.into_hal(vertex_buffer, &snatch_guard)) + { input_barriers.push(barrier); } if vertex_buffer.size diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 2f17d7dcc1..9a9b50d94f 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -25,7 +25,7 @@ impl Device { debug_assert_eq!(self_id.backend(), A::VARIANT); let size_info = match &sizes { - &wgt::BlasGeometrySizeDescriptors::Triangles { ref desc } => { + wgt::BlasGeometrySizeDescriptors::Triangles { desc } => { let mut entries = Vec::>::with_capacity(desc.len()); for x in desc { From d66fcaa2434776e841ecf89ffe3d0bfa787817f9 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 18 Dec 2023 10:58:10 +1300 Subject: [PATCH 128/146] fix clippy errors on github --- wgpu-core/src/command/ray_tracing.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index ca0b71cd55..9d1707705e 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -105,8 +105,8 @@ impl Global { #[cfg(feature = "trace")] let blas_iter = trace_blas.iter().map(|x| { let geometries = match &x.geometries { - &crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( - ref triangle_geometries, + crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( + triangle_geometries, ) => { let iter = triangle_geometries.iter().map(|tg| BlasTriangleGeometry { size: &tg.size, @@ -796,8 +796,8 @@ impl Global { #[cfg(feature = "trace")] let blas_iter = trace_blas.iter().map(|x| { let geometries = match &x.geometries { - &crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( - ref triangle_geometries, + crate::ray_tracing::TraceBlasGeometries::TriangleGeometries( + triangle_geometries, ) => { let iter = triangle_geometries.iter().map(|tg| BlasTriangleGeometry { size: &tg.size, From c288e08aa25cd17b619ccafcbf6765f3ea409a2b Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 19 Dec 2023 07:52:31 +1300 Subject: [PATCH 129/146] update to trunk --- wgpu-core/src/device/life.rs | 30 ++++++++++++++++++++++------- wgpu-core/src/device/queue.rs | 2 ++ wgpu-core/src/device/ray_tracing.rs | 2 ++ wgpu-core/src/device/resource.rs | 8 ++++++-- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index a7448bd99a..06c92ee319 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -20,6 +20,8 @@ use crate::{ }; use smallvec::SmallVec; +use crate::id::{BlasId, TlasId}; +use crate::resource::{Blas, Tlas}; use parking_lot::Mutex; use std::sync::Arc; use thiserror::Error; @@ -39,6 +41,8 @@ pub(crate) struct ResourceMaps { pub pipeline_layouts: FastHashMap>>, pub render_bundles: FastHashMap>>, pub query_sets: FastHashMap>>, + pub blas_s: FastHashMap>>, + pub tlas_s: FastHashMap>>, } impl ResourceMaps { @@ -56,6 +60,8 @@ impl ResourceMaps { pipeline_layouts: FastHashMap::default(), render_bundles: FastHashMap::default(), query_sets: FastHashMap::default(), + blas_s: FastHashMap::default(), + tlas_s: FastHashMap::default(), } } @@ -73,6 +79,8 @@ impl ResourceMaps { pipeline_layouts, render_bundles, query_sets, + tlas_s, + blas_s, } = self; buffers.clear(); staging_buffers.clear(); @@ -86,6 +94,8 @@ impl ResourceMaps { pipeline_layouts.clear(); render_bundles.clear(); query_sets.clear(); + blas_s.clear(); + tlas_s.clear(); } pub(crate) fn extend(&mut self, mut other: Self) { @@ -102,6 +112,8 @@ impl ResourceMaps { pipeline_layouts, render_bundles, query_sets, + tlas_s, + blas_s, } = self; buffers.extend(other.buffers.drain()); staging_buffers.extend(other.staging_buffers.drain()); @@ -115,6 +127,8 @@ impl ResourceMaps { pipeline_layouts.extend(other.pipeline_layouts.drain()); render_bundles.extend(other.render_bundles.drain()); query_sets.extend(other.query_sets.drain()); + tlas_s.extend(other.tlas_s.drain()); + blas_s.extend(other.blas_s.drain()); } } @@ -285,10 +299,10 @@ impl LifetimeTracker { last_resources.textures.insert(raw.as_info().id(), raw); } TempResource::Tlas(raw) => { - last_resources.insert(raw.as_info().id(), raw); + last_resources.tlas_s.insert(raw.as_info().id(), raw); } TempResource::Blas(raw) => { - last_resources.insert(raw.as_info().id(), raw); + last_resources.blas_s.insert(raw.as_info().id(), raw); } } } @@ -394,10 +408,10 @@ impl LifetimeTracker { resources.textures.insert(raw.as_info().id(), raw); } TempResource::Tlas(raw) => { - resources.insert(raw.as_info().id(), raw); + resources.tlas_s.insert(raw.as_info().id(), raw); } TempResource::Blas(raw) => { - resources.insert(raw.as_info().id(), raw); + resources.blas_s.insert(raw.as_info().id(), raw); } } } @@ -537,7 +551,7 @@ impl LifetimeTracker { .insert(v.as_info().id(), v); } for v in bind_group.used.acceleration_structures.drain_resources() { - self.suspected_resources.insert(v.as_info().id(), v); + self.suspected_resources.tlas_s.insert(v.as_info().id(), v); } //Releasing safely unused resources to decrement refcount bind_group.used_buffer_ranges.write().clear(); @@ -773,12 +787,13 @@ impl LifetimeTracker { #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, ) -> &mut Self { let mut trackers = trackers.lock(); - let resource_map = self.suspected_resources.map_mut(); + let resource_map = &mut self.suspected_resources.blas_s; let _ = Self::triage_resources( resource_map, self.active.as_mut_slice(), &mut self.free_resources, &mut trackers.blas_s, + |maps| &mut maps.blas_s, |_blas_id, _blas| { #[cfg(feature = "trace")] if let Some(ref mut t) = *trace { @@ -795,12 +810,13 @@ impl LifetimeTracker { #[cfg(feature = "trace")] trace: &mut Option<&mut trace::Trace>, ) -> &mut Self { let mut trackers = trackers.lock(); - let resource_map = self.suspected_resources.map_mut(); + let resource_map = &mut self.suspected_resources.tlas_s; let _ = Self::triage_resources( resource_map, self.active.as_mut_slice(), &mut self.free_resources, &mut trackers.tlas_s, + |maps| &mut maps.tlas_s, |_tlas_id, _tlas| { #[cfg(feature = "trace")] if let Some(ref mut t) = *trace { diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 64d18f4438..215c390201 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -1361,6 +1361,7 @@ impl Global { temp_suspected .as_mut() .unwrap() + .blas_s .insert(blas.as_info().id(), blas.clone()); } } @@ -1370,6 +1371,7 @@ impl Global { temp_suspected .as_mut() .unwrap() + .tlas_s .insert(tlas.as_info().id(), tlas.clone()); } } diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 9a9b50d94f..f1fcf7c9f9 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -292,6 +292,7 @@ impl Global { blas.device .lock_life() .suspected_resources + .blas_s .insert(blas_id, blas.clone()); if wait { @@ -370,6 +371,7 @@ impl Global { tlas.device .lock_life() .suspected_resources + .tlas_s .insert(tlas_id, tlas.clone()); if wait { diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 852afea4e9..07514a5624 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -470,12 +470,16 @@ impl Device { } for resource in trackers.blas_s.used_resources() { if resource.is_unique() { - temp_suspected.insert(resource.as_info().id(), resource.clone()); + temp_suspected + .blas_s + .insert(resource.as_info().id(), resource.clone()); } } for resource in trackers.tlas_s.used_resources() { if resource.is_unique() { - temp_suspected.insert(resource.as_info().id(), resource.clone()); + temp_suspected + .tlas_s + .insert(resource.as_info().id(), resource.clone()); } } } From 8e606c2619d0e92b51cdb7e0064cf0ca4cf7f323 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 19 Dec 2023 08:00:00 +1300 Subject: [PATCH 130/146] remove a line that printed log "Created blas ..." in device create tlas --- wgpu-core/src/device/ray_tracing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index f1fcf7c9f9..f329847f3c 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -237,7 +237,7 @@ impl Global { }; let id = fid.assign(tlas); - log::info!("Created blas {:?} with {:?}", id.0, desc); + log::info!("Created tlas {:?} with {:?}", id.0, desc); device.trackers.lock().tlas_s.insert_single(id.0, id.1); From ccc69698187a0d267af557f87c20ae352d2c9a7c Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 8 Jan 2024 09:22:34 +1300 Subject: [PATCH 131/146] fix merge issues --- Cargo.lock | 2 +- wgpu-core/src/command/ray_tracing.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10cd49c8aa..bbfa9f6b66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4146,7 +4146,7 @@ dependencies = [ "ctor", "env_logger", "futures-lite", - "glam", + "glam 0.25.0", "heck", "image", "js-sys", diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 9d1707705e..c161686597 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -637,7 +637,7 @@ impl Global { let blas_present = !blas_storage.is_empty(); let tlas_present = !tlas_storage.is_empty(); - let cmd_buf_raw = cmd_buf_data.encoder.open(); + let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { cmd_buf_raw.transition_buffers(input_barriers.into_iter()); @@ -1420,7 +1420,7 @@ impl Global { let blas_present = !blas_storage.is_empty(); let tlas_present = !tlas_storage.is_empty(); - let cmd_buf_raw = cmd_buf_data.encoder.open(); + let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { cmd_buf_raw.transition_buffers(input_barriers.into_iter()); From 8734e032fa4a8f10567ed44c7b74fe9aadd7e50a Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 15 Jan 2024 09:20:18 +1300 Subject: [PATCH 132/146] fix merge --- Cargo.lock | 2 +- wgpu-core/src/device/life.rs | 26 ++++++-------------------- wgpu-core/src/resource.rs | 10 ++++++++++ wgpu/src/backend/wgpu_core.rs | 2 +- 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fdbb145c3b..75347d7808 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4136,7 +4136,7 @@ dependencies = [ "ctor", "env_logger", "futures-lite", - "glam 0.25.0", + "glam", "heck", "image", "js-sys", diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 1a7684627e..537ea3be0d 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -420,12 +420,12 @@ impl LifetimeTracker { TempResource::DestroyedTexture(destroyed) => { resources.destroyed_textures.insert(destroyed.id, destroyed); } - } - TempResource::Tlas(raw) => { - resources.tlas_s.insert(raw.as_info().id(), raw); - } - TempResource::Blas(raw) => { - resources.blas_s.insert(raw.as_info().id(), raw); + TempResource::Tlas(raw) => { + resources.tlas_s.insert(raw.as_info().id(), raw); + } + TempResource::Blas(raw) => { + resources.blas_s.insert(raw.as_info().id(), raw); + } } } } @@ -701,15 +701,8 @@ impl LifetimeTracker { let _ = Self::triage_resources( resource_map, self.active.as_mut_slice(), - &mut self.free_resources, &mut trackers.blas_s, |maps| &mut maps.blas_s, - |_blas_id, _blas| { - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyBlas(*_blas_id)); - } - }, ); self } @@ -720,15 +713,8 @@ impl LifetimeTracker { let _ = Self::triage_resources( resource_map, self.active.as_mut_slice(), - &mut self.free_resources, &mut trackers.tlas_s, |maps| &mut maps.tlas_s, - |_tlas_id, _tlas| { - #[cfg(feature = "trace")] - if let Some(ref mut t) = *trace { - t.add(trace::Action::DestroyTlas(*_tlas_id)); - } - }, ); self } diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 28d718dc10..024bdcd2c9 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -1479,8 +1479,13 @@ pub struct Blas { impl Drop for Blas { fn drop(&mut self) { + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyBlas(self.info.id())); + } unsafe { if let Some(structure) = self.raw.take() { + resource_log!("Destroy raw Blas {:?}", self.info.label()); use hal::Device; self.device.raw().destroy_acceleration_structure(structure); } @@ -1516,9 +1521,14 @@ pub struct Tlas { impl Drop for Tlas { fn drop(&mut self) { + #[cfg(feature = "trace")] + if let Some(t) = self.device.trace.lock().as_mut() { + t.add(trace::Action::DestroyTlas(self.info.id())); + } unsafe { use hal::Device; if let Some(structure) = self.raw.take() { + resource_log!("Destroy raw Tlas {:?}", self.info.label()); self.device.raw().destroy_acceleration_structure(structure); } if let Some(buffer) = self.instance_buffer.write().take() { diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index e7945c234a..05c5805c51 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -3129,7 +3129,7 @@ impl crate::Context for ContextWgpuCore { let tlas = tlas .into_iter() - .map(|e: crate::ray_tracing::ContextTlasBuildEntry| { + .map(|e: crate::ray_tracing::ContextTlasBuildEntry| { wgc::ray_tracing::TlasBuildEntry { tlas_id: e.tlas_id, instance_buffer_id: e.instance_buffer_id, From 316f0e22e3c44b1fbd0573ceeef65481e6e4f281 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Mon, 15 Jan 2024 09:47:20 +1300 Subject: [PATCH 133/146] fix fmt --- wgpu/src/backend/wgpu_core.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 05c5805c51..faa7c26835 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -3127,15 +3127,15 @@ impl crate::Context for ContextWgpuCore { } }); - let tlas = tlas - .into_iter() - .map(|e: crate::ray_tracing::ContextTlasBuildEntry| { + let tlas = tlas.into_iter().map( + |e: crate::ray_tracing::ContextTlasBuildEntry| { wgc::ray_tracing::TlasBuildEntry { tlas_id: e.tlas_id, instance_buffer_id: e.instance_buffer_id, instance_count: e.instance_count, } - }); + }, + ); if let Err(cause) = wgc::gfx_select!(encoder => global.command_encoder_build_acceleration_structures_unsafe_tlas( *encoder, From 1b4f2208f424615d441218d8929d9c5e31f72287 Mon Sep 17 00:00:00 2001 From: Daniel Keitel Date: Wed, 17 Jan 2024 03:32:29 +0100 Subject: [PATCH 134/146] restored example ray scene functionality --- examples/src/ray_scene/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/src/ray_scene/mod.rs b/examples/src/ray_scene/mod.rs index da8877f437..db1772820a 100644 --- a/examples/src/ray_scene/mod.rs +++ b/examples/src/ray_scene/mod.rs @@ -299,6 +299,7 @@ fn upload_scene_components( fn load_scene(device: &wgpu::Device, queue: &wgpu::Queue) -> SceneComponents { let mut scene = RawSceneComponents::default(); + load_model(&mut scene, "/skybox/models/teslacyberv3.0.obj"); load_model(&mut scene, "/ray_scene/cube.obj"); upload_scene_components(device, queue, &scene) @@ -475,7 +476,7 @@ impl crate::framework::Example for Example { for y in 0..side_count { let instance = self .tlas_package - .get_mut_single((x + y) * side_count) + .get_mut_single(x + y * side_count) .unwrap(); let blas_index = (x + y) From 41133c4579d680ee2e4b39a9f3d7a3846eae75de Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 3 Feb 2024 14:48:45 -0800 Subject: [PATCH 135/146] WIP fix rebase --- wgpu-core/src/command/ray_tracing.rs | 11 +++-- wgpu-core/src/device/ray_tracing.rs | 11 +++-- wgpu-core/src/hub.rs | 40 +++++++++-------- wgpu-core/src/id.rs | 6 +-- wgpu-core/src/identity.rs | 66 ---------------------------- wgpu-core/src/resource.rs | 22 ++++++---- wgpu-core/src/track/mod.rs | 38 +++++++++------- 7 files changed, 67 insertions(+), 127 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index c161686597..8324fb99f6 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -3,8 +3,7 @@ use crate::{ device::queue::TempResource, global::Global, hal_api::HalApi, - id::{BlasId, CommandEncoderId, TlasId}, - identity::GlobalIdentityHandlerFactory, + id::CommandEncoderId, init_tracker::MemoryInitKind, ray_tracing::{ tlas_instance_into_bytes, BlasAction, BlasBuildEntry, BlasGeometries, @@ -32,7 +31,7 @@ use super::BakedCommands; // This should be queried from the device, maybe the the hal api should pre aline it, since I am unsure how else we can idiomatically get this value. const SCRATCH_BUFFER_ALIGNMENT: u32 = 256; -impl Global { +impl Global { pub fn command_encoder_build_acceleration_structures_unsafe_tlas<'a, A: HalApi>( &self, command_encoder_id: CommandEncoderId, @@ -1557,7 +1556,7 @@ impl BakedCommands { // makes sure a blas is build before it is used pub(crate) fn validate_blas_actions( &mut self, - blas_guard: &mut Storage, BlasId>, + blas_guard: &mut Storage>, ) -> Result<(), ValidateBlasActionsError> { profiling::scope!("CommandEncoder::[submission]::validate_blas_actions"); let mut built = FastHashSet::default(); @@ -1588,8 +1587,8 @@ impl BakedCommands { // makes sure a tlas is build before it is used pub(crate) fn validate_tlas_actions( &mut self, - blas_guard: &Storage, BlasId>, - tlas_guard: &mut Storage, TlasId>, + blas_guard: &Storage>, + tlas_guard: &mut Storage>, ) -> Result<(), ValidateTlasActionsError> { profiling::scope!("CommandEncoder::[submission]::validate_tlas_actions"); for action in self.tlas_actions.drain(..) { diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index f329847f3c..1925b06b64 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -5,7 +5,6 @@ use crate::{ global::Global, hal_api::HalApi, id::{self, BlasId, TlasId}, - identity::{GlobalIdentityHandlerFactory, Input}, ray_tracing::{get_raw_tlas_instance_size, CreateBlasError, CreateTlasError}, resource, LabelHelpers, }; @@ -156,18 +155,18 @@ impl Device { } } -impl Global { +impl Global { pub fn device_create_blas( &self, device_id: id::DeviceId, desc: &resource::BlasDescriptor, sizes: wgt::BlasGeometrySizeDescriptors, - id_in: Input, + id_in: Option, ) -> (BlasId, Option, Option) { profiling::scope!("Device::create_blas"); let hub = A::hub(self); - let fid = hub.blas_s.prepare::(id_in); + let fid = hub.blas_s.prepare(id_in); let device_guard = hub.devices.read(); let error = loop { @@ -210,12 +209,12 @@ impl Global { &self, device_id: id::DeviceId, desc: &resource::TlasDescriptor, - id_in: Input, + id_in: Option, ) -> (TlasId, Option) { profiling::scope!("Device::create_tlas"); let hub = A::hub(self); - let fid = hub.tlas_s.prepare::(id_in); + let fid = hub.tlas_s.prepare(id_in); let device_guard = hub.devices.read(); let error = loop { diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index f9c55f43df..b88b710382 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -186,30 +186,32 @@ pub struct Hub { pub textures: Registry>, pub texture_views: Registry>, pub samplers: Registry>, - pub blas_s: Registry>, - pub tlas_s: Registry>, + pub blas_s: Registry>, + pub tlas_s: Registry>, } impl Hub { fn new() -> Self { Self { - adapters: Registry::new(A::VARIANT, factory), - devices: Registry::new(A::VARIANT, factory), - queues: Registry::new(A::VARIANT, factory), - pipeline_layouts: Registry::new(A::VARIANT, factory), - shader_modules: Registry::new(A::VARIANT, factory), - bind_group_layouts: Registry::new(A::VARIANT, factory), - bind_groups: Registry::new(A::VARIANT, factory), - command_buffers: Registry::new(A::VARIANT, factory), - render_bundles: Registry::new(A::VARIANT, factory), - render_pipelines: Registry::new(A::VARIANT, factory), - compute_pipelines: Registry::new(A::VARIANT, factory), - query_sets: Registry::new(A::VARIANT, factory), - buffers: Registry::new(A::VARIANT, factory), - staging_buffers: Registry::new(A::VARIANT, factory), - textures: Registry::new(A::VARIANT, factory), - texture_views: Registry::new(A::VARIANT, factory), - samplers: Registry::new(A::VARIANT, factory), + adapters: Registry::new(A::VARIANT), + devices: Registry::new(A::VARIANT), + queues: Registry::new(A::VARIANT), + pipeline_layouts: Registry::new(A::VARIANT), + shader_modules: Registry::new(A::VARIANT), + bind_group_layouts: Registry::new(A::VARIANT), + bind_groups: Registry::new(A::VARIANT), + command_buffers: Registry::new(A::VARIANT), + render_bundles: Registry::new(A::VARIANT), + render_pipelines: Registry::new(A::VARIANT), + compute_pipelines: Registry::new(A::VARIANT), + query_sets: Registry::new(A::VARIANT), + buffers: Registry::new(A::VARIANT), + staging_buffers: Registry::new(A::VARIANT), + textures: Registry::new(A::VARIANT), + texture_views: Registry::new(A::VARIANT), + samplers: Registry::new(A::VARIANT), + blas_s: Registry::new(A::VARIANT), + tlas_s: Registry::new(A::VARIANT), } } diff --git a/wgpu-core/src/id.rs b/wgpu-core/src/id.rs index d40e7423bd..cb7fe9dc88 100644 --- a/wgpu-core/src/id.rs +++ b/wgpu-core/src/id.rs @@ -347,12 +347,10 @@ ids! { pub type RenderBundleEncoderId RenderBundleEncoder; pub type RenderBundleId RenderBundle; pub type QuerySetId QuerySet; + pub type BlasId Blas; + pub type TlasId Tlas; } -// Ray tracing -pub type BlasId = Id>; -pub type TlasId = Id>; - #[test] fn test_id_backend() { for &b in &[ diff --git a/wgpu-core/src/identity.rs b/wgpu-core/src/identity.rs index c0175c582e..0e34055c74 100644 --- a/wgpu-core/src/identity.rs +++ b/wgpu-core/src/identity.rs @@ -112,72 +112,6 @@ impl IdentityManager { } } -/// A type that can produce [`IdentityManager`] filters for ids of type `I`. -/// -/// See the module-level documentation for details. -pub trait IdentityHandlerFactory { - type Input: Copy; - /// Create an [`IdentityManager`] implementation that can - /// transform proto-ids into ids of type `I`. - /// It can return None if ids are passed from outside - /// and are not generated by wgpu - /// - /// [`IdentityManager`]: IdentityManager - fn spawn(&self) -> Arc> { - Arc::new(IdentityManager::new()) - } - fn autogenerate_ids() -> bool; - fn input_to_id(id_in: Self::Input) -> I; -} - -/// A global identity handler factory based on [`IdentityManager`]. -/// -/// Each of this type's `IdentityHandlerFactory::spawn` methods -/// returns a `Mutex>`, which allocates fresh `I` -/// ids itself, and takes `()` as its proto-id type. -#[derive(Debug)] -pub struct IdentityManagerFactory; - -impl IdentityHandlerFactory for IdentityManagerFactory { - type Input = (); - fn autogenerate_ids() -> bool { - true - } - - fn input_to_id(_id_in: Self::Input) -> I { - unreachable!("It should not be called") - } -} - -/// A factory that can build [`IdentityManager`]s for all resource -/// types. -pub trait GlobalIdentityHandlerFactory: - IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory -{ -} - -impl GlobalIdentityHandlerFactory for IdentityManagerFactory {} - -pub type Input = >::Input; - #[test] fn test_epoch_end_of_life() { use crate::id; diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 3a1663e032..f9763687a9 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -36,7 +36,7 @@ use std::{ }, }; -use crate::id::{BlasId, TlasId}; +use crate::id::BlasId; use std::num::NonZeroU64; /// Information about the wgpu-core resource. @@ -1544,7 +1544,7 @@ pub type TlasDescriptor<'a> = wgt::CreateTlasDescriptor>; pub struct Blas { pub(crate) raw: Option, pub(crate) device: Arc>, - pub(crate) info: ResourceInfo, + pub(crate) info: ResourceInfo>, pub(crate) size_info: hal::AccelerationStructureBuildSizes, pub(crate) sizes: wgt::BlasGeometrySizeDescriptors, pub(crate) flags: wgt::AccelerationStructureFlags, @@ -1569,14 +1569,16 @@ impl Drop for Blas { } } -impl Resource for Blas { +impl Resource for Blas { const TYPE: &'static str = "Blas"; - fn as_info(&self) -> &ResourceInfo { + type Marker = crate::id::markers::Blas; + + fn as_info(&self) -> &ResourceInfo { &self.info } - fn as_info_mut(&mut self) -> &mut ResourceInfo { + fn as_info_mut(&mut self) -> &mut ResourceInfo { &mut self.info } } @@ -1585,7 +1587,7 @@ impl Resource for Blas { pub struct Tlas { pub(crate) raw: Option, pub(crate) device: Arc>, - pub(crate) info: ResourceInfo, + pub(crate) info: ResourceInfo>, pub(crate) size_info: hal::AccelerationStructureBuildSizes, pub(crate) max_instance_count: u32, pub(crate) flags: wgt::AccelerationStructureFlags, @@ -1614,14 +1616,16 @@ impl Drop for Tlas { } } -impl Resource for Tlas { +impl Resource for Tlas { const TYPE: &'static str = "Tlas"; - fn as_info(&self) -> &ResourceInfo { + type Marker = crate::id::markers::Tlas; + + fn as_info(&self) -> &ResourceInfo { &self.info } - fn as_info_mut(&mut self) -> &mut ResourceInfo { + fn as_info_mut(&mut self) -> &mut ResourceInfo { &mut self.info } } diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index d39abc06a0..0fa3647350 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -320,7 +320,7 @@ pub(crate) struct BindGroupStates { pub textures: TextureBindGroupState, pub views: StatelessBindGroupSate>, pub samplers: StatelessBindGroupSate>, - pub acceleration_structures: StatelessBindGroupSate>, + pub acceleration_structures: StatelessBindGroupSate>, } impl BindGroupStates { @@ -492,13 +492,15 @@ where pub(crate) struct Tracker { pub buffers: BufferTracker, pub textures: TextureTracker, - pub views: StatelessTracker>, - pub samplers: StatelessTracker>, - pub bind_groups: StatelessTracker>, - pub compute_pipelines: StatelessTracker>, - pub render_pipelines: StatelessTracker>, - pub bundles: StatelessTracker>, - pub query_sets: StatelessTracker>, + pub views: StatelessTracker>, + pub samplers: StatelessTracker>, + pub bind_groups: StatelessTracker>, + pub compute_pipelines: StatelessTracker>, + pub render_pipelines: StatelessTracker>, + pub bundles: StatelessTracker>, + pub query_sets: StatelessTracker>, + pub blas_s: StatelessTracker>, + pub tlas_s: StatelessTracker>, } impl Tracker { @@ -521,15 +523,17 @@ impl Tracker { /// Pull the maximum IDs from the hubs. pub fn set_size( &mut self, - buffers: Option<&Storage, id::BufferId>>, - textures: Option<&Storage, id::TextureId>>, - views: Option<&Storage, id::TextureViewId>>, - samplers: Option<&Storage, id::SamplerId>>, - bind_groups: Option<&Storage, id::BindGroupId>>, - compute_pipelines: Option<&Storage, id::ComputePipelineId>>, - render_pipelines: Option<&Storage, id::RenderPipelineId>>, - bundles: Option<&Storage, id::RenderBundleId>>, - query_sets: Option<&Storage, id::QuerySetId>>, + buffers: Option<&Storage>>, + textures: Option<&Storage>>, + views: Option<&Storage>>, + samplers: Option<&Storage>>, + bind_groups: Option<&Storage>>, + compute_pipelines: Option<&Storage>>, + render_pipelines: Option<&Storage>>, + bundles: Option<&Storage>>, + query_sets: Option<&Storage>>, + blas_s: Option<&Storage>>, + tlas_s: Option<&Storage>>, ) { if let Some(buffers) = buffers { self.buffers.set_size(buffers.len()); From 41fe261bb4040781c57f5ccaa775405e726c7179 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 3 Feb 2024 22:30:23 -0800 Subject: [PATCH 136/146] Fix compile issues --- player/src/lib.rs | 4 +-- wgpu-types/src/lib.rs | 57 ++++++++++++++++------------------- wgpu/src/backend/wgpu_core.rs | 4 +-- 3 files changed, 30 insertions(+), 35 deletions(-) diff --git a/player/src/lib.rs b/player/src/lib.rs index b471f393a1..9913ba6d17 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -460,7 +460,7 @@ impl GlobalPlay for wgc::global::Global { } Action::CreateBlas { id, desc, sizes } => { self.device_maintain_ids::(device).unwrap(); - self.device_create_blas::(device, &desc, sizes, id); + self.device_create_blas::(device, &desc, sizes, Some(id)); } Action::FreeBlas(id) => { self.blas_destroy::(id).unwrap(); @@ -470,7 +470,7 @@ impl GlobalPlay for wgc::global::Global { } Action::CreateTlas { id, desc } => { self.device_maintain_ids::(device).unwrap(); - self.device_create_tlas::(device, &desc, id); + self.device_create_tlas::(device, &desc, Some(id)); } Action::FreeTlas(id) => { self.tlas_destroy::(id).unwrap(); diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index ac09dffcc0..a9ca11ee69 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -94,7 +94,7 @@ pub const QUERY_SIZE: u32 = 8; /// Backends supported by wgpu. #[repr(u8)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum Backend { /// Dummy backend, used for testing. Empty = 0, @@ -1385,7 +1385,7 @@ impl Limits { /// Represents the sets of additional limits on an adapter, /// which take place when running on downlevel backends. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct DownlevelLimits {} #[allow(unknown_lints)] // derivable_impls is nightly only currently @@ -1398,7 +1398,7 @@ impl Default for DownlevelLimits { /// Lists various ways the underlying platform does not conform to the WebGPU standard. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct DownlevelCapabilities { /// Combined boolean flags. pub flags: DownlevelFlags, @@ -1607,7 +1607,7 @@ impl DownlevelFlags { /// Collections of shader features a device supports if they support less than WebGPU normally allows. // TODO: Fill out the differences between shader models more completely #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum ShaderModel { /// Extremely limited shaders, including a total instruction limit. Sm2, @@ -1620,7 +1620,7 @@ pub enum ShaderModel { /// Supported physical device types. #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum DeviceType { /// Other or Unknown. Other, @@ -1638,7 +1638,7 @@ pub enum DeviceType { /// Information about an adapter. #[derive(Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct AdapterInfo { /// Adapter name pub name: String, @@ -2216,7 +2216,7 @@ impl_bitflags!(TextureFormatFeatureFlags); /// /// Features are defined by WebGPU specification unless `Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES` is enabled. #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct TextureFormatFeatures { /// Valid bits for `TextureDescriptor::Usage` provided for format creation. pub allowed_usages: TextureUsages, @@ -2227,7 +2227,7 @@ pub struct TextureFormatFeatures { /// ASTC block dimensions #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum AstcBlock { /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). B4x4, @@ -2262,7 +2262,7 @@ pub enum AstcBlock { /// ASTC RGBA channel #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum AstcChannel { /// 8 bit integer RGBA, [0, 255] converted to/from linear-color float [0, 1] in shader. /// @@ -5255,7 +5255,7 @@ impl PresentationTimestamp { /// This is not to be used as a generic color type, only for specific wgpu interfaces. #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Color { /// Red component of the color @@ -5850,7 +5850,7 @@ impl CommandBufferDescriptor { /// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderbundleencoderdescriptor). #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct RenderBundleDepthStencil { /// Format of the attachment. pub format: TextureFormat, @@ -5913,7 +5913,7 @@ impl Default for RenderBundleDescriptor> { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagedatalayout). #[repr(C)] #[derive(Clone, Copy, Debug, Default)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ImageDataLayout { /// Offset into the buffer that is the start of the texture. Must be a multiple of texture block size. /// For non-compressed textures, this is 1. @@ -6355,7 +6355,7 @@ pub struct BindGroupLayoutEntry { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopybuffer). #[repr(C)] #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ImageCopyBuffer { /// The buffer to be copied to/from. pub buffer: B, @@ -6369,7 +6369,7 @@ pub struct ImageCopyBuffer { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopytexture). #[repr(C)] #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ImageCopyTexture { /// The texture to be copied to/from. pub texture: T, @@ -6501,7 +6501,7 @@ unsafe impl Sync for ExternalImageSource {} /// Corresponds to [HTML Canvas `PredefinedColorSpace`]( /// https://html.spec.whatwg.org/multipage/canvas.html#predefinedcolorspace). #[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum PredefinedColorSpace { /// sRGB color space @@ -6516,7 +6516,7 @@ pub enum PredefinedColorSpace { /// Corresponds to [WebGPU `GPUImageCopyTextureTagged`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopytexturetagged). #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ImageCopyTextureTagged { /// The texture to be copied to/from. pub texture: T, @@ -6547,7 +6547,7 @@ impl ImageCopyTextureTagged { /// Subresource range within an image #[repr(C)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct ImageSubresourceRange { /// Aspect of the texture. Color textures must be [`TextureAspect::All`][TAA]. @@ -6648,7 +6648,7 @@ impl ImageSubresourceRange { /// Color variation to use when sampler addressing mode is [`AddressMode::ClampToBorder`] #[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum SamplerBorderColor { /// [0, 0, 0, 0] TransparentBlack, @@ -6670,7 +6670,7 @@ pub enum SamplerBorderColor { /// Corresponds to [WebGPU `GPUQuerySetDescriptor`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpuquerysetdescriptor). #[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct QuerySetDescriptor { /// Debug label for the query set. pub label: L, @@ -6697,7 +6697,7 @@ impl QuerySetDescriptor { /// Corresponds to [WebGPU `GPUQueryType`]( /// https://gpuweb.github.io/gpuweb/#enumdef-gpuquerytype). #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum QueryType { /// Query returns a single 64-bit number, serving as an occlusion boolean. Occlusion, @@ -6843,7 +6843,7 @@ impl DispatchIndirectArgs { /// Describes how shader bound checks should be performed. #[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ShaderBoundChecks { runtime_checks: bool, } @@ -6953,8 +6953,7 @@ impl Default for InstanceDescriptor { } #[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "trace", derive(serde::Serialize))] -#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Descriptor for all size definiing attributes of a single triangle geometry inside a bottom level acceleration structure. pub struct BlasTriangleGeometrySizeDescriptor { /// Format of a vertex position. @@ -6972,8 +6971,7 @@ pub struct BlasTriangleGeometrySizeDescriptor { } #[derive(Clone, Debug)] -#[cfg_attr(feature = "trace", derive(serde::Serialize))] -#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Descriptor for all size definiing attributes of all geometries inside a bottom level acceleration structure. pub enum BlasGeometrySizeDescriptors { /// Triangle geometry version. @@ -6985,8 +6983,7 @@ pub enum BlasGeometrySizeDescriptors { #[repr(u8)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "trace", derive(serde::Serialize))] -#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Update mode for acceleration structure builds. pub enum AccelerationStructureUpdateMode { /// Allwasy perform a full build. @@ -6999,8 +6996,7 @@ pub enum AccelerationStructureUpdateMode { #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "trace", derive(Serialize))] -#[cfg_attr(feature = "replay", derive(Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Descriptor for creating a bottom level acceleration structure. pub struct CreateBlasDescriptor { /// Label for the bottom level acceleration structure. @@ -7024,8 +7020,7 @@ impl CreateBlasDescriptor { #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "trace", derive(Serialize))] -#[cfg_attr(feature = "replay", derive(Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Descriptor for creating a top level acceleration structure. pub struct CreateTlasDescriptor { /// Label for the top level acceleration structure. diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 525c49dec4..51853513f2 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -2938,7 +2938,7 @@ impl crate::Context for ContextWgpuCore { *device, &desc.map_label(|l| l.map(Borrowed)), sizes, - () + None, )); if let Some(cause) = error { self.handle_error( @@ -2968,7 +2968,7 @@ impl crate::Context for ContextWgpuCore { let (id, error) = wgc::gfx_select!(device => global.device_create_tlas( *device, &desc.map_label(|l| l.map(Borrowed)), - () + None, )); if let Some(cause) = error { self.handle_error( From d94cbebfdb9e5dfd07795b86d15e0c0f71291a3d Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 3 Feb 2024 22:35:14 -0800 Subject: [PATCH 137/146] More fixes --- wgpu-core/src/ray_tracing.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 2ae30a2491..4dba07cb52 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -153,8 +153,7 @@ pub struct BlasBuildEntry<'a> { } #[derive(Debug, Clone)] -#[cfg_attr(feature = "trace", derive(serde::Serialize))] -#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TlasBuildEntry { pub tlas_id: TlasId, pub instance_buffer_id: BufferId, @@ -203,8 +202,7 @@ pub(crate) struct TlasAction { } #[derive(Debug, Clone)] -#[cfg_attr(feature = "trace", derive(serde::Serialize))] -#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TraceBlasTriangleGeometry { pub size: wgt::BlasTriangleGeometrySizeDescriptor, pub vertex_buffer: BufferId, @@ -217,23 +215,20 @@ pub struct TraceBlasTriangleGeometry { } #[derive(Debug, Clone)] -#[cfg_attr(feature = "trace", derive(serde::Serialize))] -#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum TraceBlasGeometries { TriangleGeometries(Vec), } #[derive(Debug, Clone)] -#[cfg_attr(feature = "trace", derive(serde::Serialize))] -#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TraceBlasBuildEntry { pub blas_id: BlasId, pub geometries: TraceBlasGeometries, } #[derive(Debug, Clone)] -#[cfg_attr(feature = "trace", derive(serde::Serialize))] -#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TraceTlasInstance { pub blas_id: BlasId, pub transform: [f32; 12], @@ -242,8 +237,7 @@ pub struct TraceTlasInstance { } #[derive(Debug, Clone)] -#[cfg_attr(feature = "trace", derive(serde::Serialize))] -#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TraceTlasPackage { pub tlas_id: TlasId, pub instances: Vec>, From b60f318f9bdab95d960bc83278b139e655c5eeb0 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 17 Feb 2024 19:38:26 -0800 Subject: [PATCH 138/146] Fix rebase --- wgpu-core/src/device/resource.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 858deaed37..27bdf835c9 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -294,6 +294,8 @@ impl Device { downlevel, instance_flags, pending_writes: Mutex::new(Some(pending_writes)), + deferred_destroy: Mutex::new(Vec::new()), + last_acceleration_structure_build_command_index: AtomicU64::new(0), }) } From 91b7546a5e2e13466d700ebdf1b51a11239a4f37 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 17 Feb 2024 19:52:35 -0800 Subject: [PATCH 139/146] Add wgls backend write_value_type AccelerationStructure --- naga/src/back/wgsl/writer.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/naga/src/back/wgsl/writer.rs b/naga/src/back/wgsl/writer.rs index c737934f5e..8c548912d9 100644 --- a/naga/src/back/wgsl/writer.rs +++ b/naga/src/back/wgsl/writer.rs @@ -593,6 +593,7 @@ impl Writer { } write!(self.out, ">")?; } + TypeInner::AccelerationStructure => write!(self.out, "acceleration_structure")?, _ => { return Err(Error::Unimplemented(format!("write_value_type {inner:?}"))); } From 2bc105ddb286728dd09e230164a08acf00550b9a Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 24 Feb 2024 18:39:11 -0800 Subject: [PATCH 140/146] Add back xtask Cargo.lock --- xtask/Cargo.lock | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 xtask/Cargo.lock diff --git a/xtask/Cargo.lock b/xtask/Cargo.lock new file mode 100644 index 0000000000..50b572cd03 --- /dev/null +++ b/xtask/Cargo.lock @@ -0,0 +1,56 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "log", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "xshell" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce2107fe03e558353b4c71ad7626d58ed82efaf56c54134228608893c77023ad" +dependencies = [ + "xshell-macros", +] + +[[package]] +name = "xshell-macros" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e2c411759b501fb9501aac2b1b2d287a6e93e5bdcf13c25306b23e1b716dd0e" + +[[package]] +name = "xtask" +version = "0.1.0" +dependencies = [ + "anyhow", + "env_logger", + "log", + "pico-args", + "xshell", +] From f3fa301fd665f06edf0c63219cda7c07ed9eaf40 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 24 Feb 2024 18:42:06 -0800 Subject: [PATCH 141/146] Revert serde path --- wgpu-types/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index c468132ae7..56c7bd9798 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -94,7 +94,7 @@ pub const QUERY_SIZE: u32 = 8; /// Backends supported by wgpu. #[repr(u8)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum Backend { /// Dummy backend, used for testing. Empty = 0, From 96877cc86c83ce5f876b28db01382f295e79692e Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 24 Feb 2024 18:43:44 -0800 Subject: [PATCH 142/146] Doc typos --- wgpu-types/src/lib.rs | 4 ++-- wgpu/src/ray_tracing.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 56c7bd9798..eca632ee7b 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -7101,11 +7101,11 @@ pub enum BlasGeometrySizeDescriptors { #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Update mode for acceleration structure builds. pub enum AccelerationStructureUpdateMode { - /// Allwasy perform a full build. + /// Always perform a full build. Build, /// If possible, perform an incremental update. /// Not advised for major topology changes. - /// (Usefull for e.g. skinning) + /// (Useful for e.g. skinning) PreferUpdate, } diff --git a/wgpu/src/ray_tracing.rs b/wgpu/src/ray_tracing.rs index feb2cf959e..9f762a70e7 100644 --- a/wgpu/src/ray_tracing.rs +++ b/wgpu/src/ray_tracing.rs @@ -206,7 +206,7 @@ impl TlasPackage { } /// Construct TlasPackage consuming the Tlas (prevents modification of the Tlas without using this package). - /// This contructor moves the instances into the package (the number of instances needs to fit into tlas). + /// This constructor moves the instances into the package (the number of instances needs to fit into tlas). pub fn new_with_instances(tlas: Tlas, instances: Vec>) -> Self { Self { tlas, @@ -333,7 +333,7 @@ pub struct ContextTlasPackage<'a, T: Context> { pub(crate) lowest_unmodified: u32, } -/// Utility module to add traits for the device and command encoder. +/// Utility module to add traits for the device and command encoder. pub mod traits { pub use super::{CommandEncoderRayTracing as _, DeviceRayTracing as _}; } From b459f373b3f4892150b7c943199e235fa724097f Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 24 Feb 2024 19:50:49 -0800 Subject: [PATCH 143/146] Add -diff --- .gitattributes | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index 149b5351f2..d6b8922131 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ -*.mtl binary -*.obj binary +*.mtl binary -diff +*.obj binary -diff From 4a1080adeca1525d07cb22a4cf7c100cc7e7cc5b Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 24 Feb 2024 19:51:57 -0800 Subject: [PATCH 144/146] Revert more serde --- wgpu-types/src/lib.rs | 146 +++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index eca632ee7b..55def0232a 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -136,7 +136,7 @@ impl std::fmt::Display for Backend { /// https://gpuweb.github.io/gpuweb/#enumdef-gpupowerpreference). #[repr(C)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum PowerPreference { #[default] @@ -207,7 +207,7 @@ impl From for Backends { /// https://gpuweb.github.io/gpuweb/#dictdef-gpurequestadapteroptions). #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct RequestAdapterOptions { /// Power preference for the adapter. pub power_preference: PowerPreference, @@ -1027,7 +1027,7 @@ impl InstanceFlags { /// [`downlevel_defaults()`]: Limits::downlevel_defaults #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase", default))] pub struct Limits { /// Maximum allowed value for the `size.width` of a texture created with `TextureDimension::D1`. @@ -1419,7 +1419,7 @@ impl Limits { /// Represents the sets of additional limits on an adapter, /// which take place when running on downlevel backends. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DownlevelLimits {} #[allow(unknown_lints)] // derivable_impls is nightly only currently @@ -1432,7 +1432,7 @@ impl Default for DownlevelLimits { /// Lists various ways the underlying platform does not conform to the WebGPU standard. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DownlevelCapabilities { /// Combined boolean flags. pub flags: DownlevelFlags, @@ -1641,7 +1641,7 @@ impl DownlevelFlags { /// Collections of shader features a device supports if they support less than WebGPU normally allows. // TODO: Fill out the differences between shader models more completely #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum ShaderModel { /// Extremely limited shaders, including a total instruction limit. Sm2, @@ -1654,7 +1654,7 @@ pub enum ShaderModel { /// Supported physical device types. #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum DeviceType { /// Other or Unknown. Other, @@ -1672,7 +1672,7 @@ pub enum DeviceType { /// Information about an adapter. #[derive(Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AdapterInfo { /// Adapter name pub name: String, @@ -1715,7 +1715,7 @@ pub struct AdapterInfo { /// https://gpuweb.github.io/gpuweb/#gpudevicedescriptor). #[repr(C)] #[derive(Clone, Debug, Default)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DeviceDescriptor { /// Debug label for the device. pub label: L, @@ -1777,7 +1777,7 @@ impl_bitflags!(ShaderStages); /// https://gpuweb.github.io/gpuweb/#enumdef-gputextureviewdimension). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum TextureViewDimension { /// A one dimensional texture. `texture_1d` in WGSL and `texture1D` in GLSL. #[cfg_attr(feature = "serde", serde(rename = "1d"))] @@ -1821,7 +1821,7 @@ impl TextureViewDimension { /// used with the first render target. #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum BlendFactor { /// 0.0 @@ -1883,7 +1883,7 @@ impl BlendFactor { /// https://gpuweb.github.io/gpuweb/#enumdef-gpublendoperation). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum BlendOperation { /// Src + Dst @@ -1905,7 +1905,7 @@ pub enum BlendOperation { /// https://gpuweb.github.io/gpuweb/#dictdef-gpublendcomponent). #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct BlendComponent { /// Multiplier for the source, which is produced by the fragment shader. @@ -1960,7 +1960,7 @@ impl Default for BlendComponent { /// https://gpuweb.github.io/gpuweb/#dictdef-gpublendstate). #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct BlendState { /// Color equation. @@ -1999,7 +1999,7 @@ impl BlendState { /// https://gpuweb.github.io/gpuweb/#dictdef-gpucolortargetstate). #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct ColorTargetState { /// The [`TextureFormat`] of the image that this pipeline will render to. Must match the format @@ -2031,7 +2031,7 @@ impl From for ColorTargetState { /// https://gpuweb.github.io/gpuweb/#enumdef-gpuprimitivetopology). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum PrimitiveTopology { /// Vertex data is a list of points. Each vertex is a new point. @@ -2071,7 +2071,7 @@ impl PrimitiveTopology { /// https://gpuweb.github.io/gpuweb/#enumdef-gpufrontface). #[repr(C)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum FrontFace { /// Triangles with vertices in counter clockwise order are considered the front face. @@ -2092,7 +2092,7 @@ pub enum FrontFace { /// except that the `"none"` value is represented using `Option` instead. #[repr(C)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum Face { /// Front face @@ -2104,7 +2104,7 @@ pub enum Face { /// Type of drawing mode for polygons #[repr(C)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum PolygonMode { /// Polygons are filled @@ -2122,7 +2122,7 @@ pub enum PolygonMode { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuprimitivestate). #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct PrimitiveState { /// The primitive topology used to interpret vertices. @@ -2162,7 +2162,7 @@ pub struct PrimitiveState { /// https://gpuweb.github.io/gpuweb/#dictdef-gpumultisamplestate). #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct MultisampleState { /// The number of samples calculated per pixel (for MSAA). For non-multisampled textures, @@ -2250,7 +2250,7 @@ impl_bitflags!(TextureFormatFeatureFlags); /// /// Features are defined by WebGPU specification unless `Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES` is enabled. #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TextureFormatFeatures { /// Valid bits for `TextureDescriptor::Usage` provided for format creation. pub allowed_usages: TextureUsages, @@ -2261,7 +2261,7 @@ pub struct TextureFormatFeatures { /// ASTC block dimensions #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum AstcBlock { /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). B4x4, @@ -2296,7 +2296,7 @@ pub enum AstcBlock { /// ASTC RGBA channel #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum AstcChannel { /// 8 bit integer RGBA, [0, 255] converted to/from linear-color float [0, 1] in shader. /// @@ -4485,7 +4485,7 @@ impl MaintainResult { /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate). #[repr(C)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct StencilState { /// Front face mode. pub front: StencilFaceState, @@ -4532,7 +4532,7 @@ impl StencilState { /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate). #[repr(C)] #[derive(Clone, Copy, Debug, Default)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DepthBiasState { /// Constant depth biasing factor, in basic units of the depth format. pub constant: i32, @@ -4573,7 +4573,7 @@ impl Eq for DepthBiasState {} /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate). #[repr(C)] #[derive(Clone, Debug, Hash, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct DepthStencilState { /// Format of the depth/stencil buffer, must be special depth format. Must match the format /// of the depth/stencil attachment in [`CommandEncoder::begin_render_pass`][CEbrp]. @@ -4620,7 +4620,7 @@ impl DepthStencilState { /// https://gpuweb.github.io/gpuweb/#enumdef-gpuindexformat). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum IndexFormat { /// Indices are 16 bit unsigned integers. @@ -4636,7 +4636,7 @@ pub enum IndexFormat { /// https://gpuweb.github.io/gpuweb/#enumdef-gpustenciloperation). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum StencilOperation { /// Keep stencil value unchanged. @@ -4669,7 +4669,7 @@ pub enum StencilOperation { /// https://gpuweb.github.io/gpuweb/#dictdef-gpustencilfacestate). #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct StencilFaceState { /// Comparison function that determines if the fail_op or pass_op is used on the stencil buffer. @@ -4719,7 +4719,7 @@ impl Default for StencilFaceState { /// https://gpuweb.github.io/gpuweb/#enumdef-gpucomparefunction). #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum CompareFunction { /// Function never passes @@ -4813,7 +4813,7 @@ impl CompareFunction { /// [`Instance`]: VertexStepMode::Instance #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum VertexStepMode { /// Vertex data is advanced every vertex. @@ -4834,7 +4834,7 @@ pub enum VertexStepMode { /// [`vertex_attr_array`]: ../wgpu/macro.vertex_attr_array.html #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct VertexAttribute { /// Format of the input @@ -4851,7 +4851,7 @@ pub struct VertexAttribute { /// https://gpuweb.github.io/gpuweb/#enumdef-gpuvertexformat). #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] pub enum VertexFormat { /// Two unsigned bytes (u8). `vec2` in shaders. @@ -5014,7 +5014,7 @@ impl_bitflags!(BufferUsages); /// https://gpuweb.github.io/gpuweb/#dictdef-gpubufferdescriptor). #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BufferDescriptor { /// Debug label of a buffer. This will show up in graphics debuggers for easy identification. pub label: L, @@ -5048,7 +5048,7 @@ impl BufferDescriptor { /// Corresponds to [WebGPU `GPUCommandEncoderDescriptor`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandencoderdescriptor). #[repr(C)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct CommandEncoderDescriptor { /// Debug label for the command encoder. This will show up in graphics debuggers for easy identification. @@ -5073,7 +5073,7 @@ impl Default for CommandEncoderDescriptor> { /// Behavior of the presentation engine based on frame rate. #[repr(C)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum PresentMode { /// Chooses FifoRelaxed -> Fifo based on availability. /// @@ -5145,7 +5145,7 @@ pub enum PresentMode { /// compositing. #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] pub enum CompositeAlphaMode { /// Chooses either `Opaque` or `Inherit` automatically,depending on the @@ -5244,7 +5244,7 @@ impl Default for SurfaceCapabilities { /// [`Surface`]: ../wgpu/struct.Surface.html #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SurfaceConfiguration { /// The usage of the swap chain. The only supported usage is `RENDER_ATTACHMENT`. pub usage: TextureUsages, @@ -5370,7 +5370,7 @@ impl PresentationTimestamp { /// This is not to be used as a generic color type, only for specific wgpu interfaces. #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Color { /// Red component of the color @@ -5429,7 +5429,7 @@ impl Color { /// https://gpuweb.github.io/gpuweb/#enumdef-gputexturedimension). #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum TextureDimension { /// 1D texture #[cfg_attr(feature = "serde", serde(rename = "1d"))] @@ -5448,7 +5448,7 @@ pub enum TextureDimension { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuorigin2ddict). #[repr(C)] #[derive(Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Origin2d { /// @@ -5483,7 +5483,7 @@ impl std::fmt::Debug for Origin2d { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuorigin3ddict). #[repr(C)] #[derive(Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Origin3d { /// X position of the origin @@ -5525,7 +5525,7 @@ impl std::fmt::Debug for Origin3d { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuextent3ddict). #[repr(C)] #[derive(Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Extent3d { /// Width of the extent @@ -5724,7 +5724,7 @@ fn test_max_mips() { /// https://gpuweb.github.io/gpuweb/#dictdef-gputexturedescriptor). #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TextureDescriptor { /// Debug label of the texture. This will show up in graphics debuggers for easy identification. pub label: L, @@ -5855,7 +5855,7 @@ impl TextureDescriptor { /// https://gpuweb.github.io/gpuweb/#enumdef-gputextureaspect). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum TextureAspect { /// Depth, Stencil, and Color. @@ -5879,7 +5879,7 @@ pub enum TextureAspect { /// https://gpuweb.github.io/gpuweb/#enumdef-gpuaddressmode). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum AddressMode { /// Clamp the value to the edge of the texture @@ -5912,7 +5912,7 @@ pub enum AddressMode { /// https://gpuweb.github.io/gpuweb/#enumdef-gpufiltermode). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum FilterMode { /// Nearest neighbor sampling. @@ -5928,7 +5928,7 @@ pub enum FilterMode { /// A range of push constant memory to pass to a shader stage. #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct PushConstantRange { /// Stage push constant range is visible from. Each stage can only be served by at most one range. /// One range can serve multiple stages however. @@ -5944,7 +5944,7 @@ pub struct PushConstantRange { /// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandbufferdescriptor). #[repr(C)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct CommandBufferDescriptor { /// Debug label of this command buffer. pub label: L, @@ -5965,7 +5965,7 @@ impl CommandBufferDescriptor { /// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderbundleencoderdescriptor). #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct RenderBundleDepthStencil { /// Format of the attachment. pub format: TextureFormat, @@ -5992,7 +5992,7 @@ pub struct RenderBundleDepthStencil { /// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderbundledescriptor). #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct RenderBundleDescriptor { /// Debug label of the render bundle encoder. This will show up in graphics debuggers for easy identification. pub label: L, @@ -6028,7 +6028,7 @@ impl Default for RenderBundleDescriptor> { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagedatalayout). #[repr(C)] #[derive(Clone, Copy, Debug, Default)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ImageDataLayout { /// Offset into the buffer that is the start of the texture. Must be a multiple of texture block size. /// For non-compressed textures, this is 1. @@ -6068,7 +6068,7 @@ pub struct ImageDataLayout { /// Corresponds to [WebGPU `GPUBufferBindingType`]( /// https://gpuweb.github.io/gpuweb/#enumdef-gpubufferbindingtype). #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum BufferBindingType { /// A buffer for uniform values. /// @@ -6133,7 +6133,7 @@ pub enum BufferBindingType { /// Corresponds to [WebGPU `GPUTextureSampleType`]( /// https://gpuweb.github.io/gpuweb/#enumdef-gputexturesampletype). #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum TextureSampleType { /// Sampling returns floats. /// @@ -6215,7 +6215,7 @@ impl Default for TextureSampleType { /// Corresponds to [WebGPU `GPUStorageTextureAccess`]( /// https://gpuweb.github.io/gpuweb/#enumdef-gpustoragetextureaccess). #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum StorageTextureAccess { /// The texture can only be written in the shader and it: @@ -6277,7 +6277,7 @@ pub enum StorageTextureAccess { /// https://gpuweb.github.io/gpuweb/#enumdef-gpusamplerbindingtype). #[repr(C)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum SamplerBindingType { /// The sampling result is produced based on more than a single color sample from a texture, @@ -6297,7 +6297,7 @@ pub enum SamplerBindingType { /// Corresponds to WebGPU's mutually exclusive fields within [`GPUBindGroupLayoutEntry`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry). #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum BindingType { /// A buffer binding. /// @@ -6446,7 +6446,7 @@ impl BindingType { /// Corresponds to [WebGPU `GPUBindGroupLayoutEntry`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry). #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BindGroupLayoutEntry { /// Binding index. Must match shader index and be unique inside a BindGroupLayout. A binding /// of index 1, would be described as `layout(set = 0, binding = 1) uniform` in shaders. @@ -6470,7 +6470,7 @@ pub struct BindGroupLayoutEntry { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopybuffer). #[repr(C)] #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ImageCopyBuffer { /// The buffer to be copied to/from. pub buffer: B, @@ -6484,7 +6484,7 @@ pub struct ImageCopyBuffer { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopytexture). #[repr(C)] #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ImageCopyTexture { /// The texture to be copied to/from. pub texture: T, @@ -6616,7 +6616,7 @@ unsafe impl Sync for ExternalImageSource {} /// Corresponds to [HTML Canvas `PredefinedColorSpace`]( /// https://html.spec.whatwg.org/multipage/canvas.html#predefinedcolorspace). #[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum PredefinedColorSpace { /// sRGB color space @@ -6631,7 +6631,7 @@ pub enum PredefinedColorSpace { /// Corresponds to [WebGPU `GPUImageCopyTextureTagged`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopytexturetagged). #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ImageCopyTextureTagged { /// The texture to be copied to/from. pub texture: T, @@ -6662,7 +6662,7 @@ impl ImageCopyTextureTagged { /// Subresource range within an image #[repr(C)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct ImageSubresourceRange { /// Aspect of the texture. Color textures must be [`TextureAspect::All`][TAA]. @@ -6763,7 +6763,7 @@ impl ImageSubresourceRange { /// Color variation to use when sampler addressing mode is [`AddressMode::ClampToBorder`] #[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum SamplerBorderColor { /// [0, 0, 0, 0] TransparentBlack, @@ -6785,7 +6785,7 @@ pub enum SamplerBorderColor { /// Corresponds to [WebGPU `GPUQuerySetDescriptor`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpuquerysetdescriptor). #[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct QuerySetDescriptor { /// Debug label for the query set. pub label: L, @@ -6812,7 +6812,7 @@ impl QuerySetDescriptor { /// Corresponds to [WebGPU `GPUQueryType`]( /// https://gpuweb.github.io/gpuweb/#enumdef-gpuquerytype). #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum QueryType { /// Query returns a single 64-bit number, serving as an occlusion boolean. Occlusion, @@ -6958,7 +6958,7 @@ impl DispatchIndirectArgs { /// Describes how shader bound checks should be performed. #[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ShaderBoundChecks { runtime_checks: bool, } @@ -7068,7 +7068,7 @@ impl Default for InstanceDescriptor { } #[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] /// Descriptor for all size definiing attributes of a single triangle geometry inside a bottom level acceleration structure. pub struct BlasTriangleGeometrySizeDescriptor { /// Format of a vertex position. @@ -7086,7 +7086,7 @@ pub struct BlasTriangleGeometrySizeDescriptor { } #[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] /// Descriptor for all size definiing attributes of all geometries inside a bottom level acceleration structure. pub enum BlasGeometrySizeDescriptors { /// Triangle geometry version. @@ -7098,7 +7098,7 @@ pub enum BlasGeometrySizeDescriptors { #[repr(u8)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] /// Update mode for acceleration structure builds. pub enum AccelerationStructureUpdateMode { /// Always perform a full build. @@ -7111,7 +7111,7 @@ pub enum AccelerationStructureUpdateMode { #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] /// Descriptor for creating a bottom level acceleration structure. pub struct CreateBlasDescriptor { /// Label for the bottom level acceleration structure. @@ -7135,7 +7135,7 @@ impl CreateBlasDescriptor { #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] /// Descriptor for creating a top level acceleration structure. pub struct CreateTlasDescriptor { /// Label for the top level acceleration structure. From 991c2c4ff00ffe00b328cc3aebd1e37c374df978 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 24 Feb 2024 19:53:06 -0800 Subject: [PATCH 145/146] Revert serde again? --- wgpu-types/src/lib.rs | 148 +++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 55def0232a..ba8bd498ee 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -94,7 +94,7 @@ pub const QUERY_SIZE: u32 = 8; /// Backends supported by wgpu. #[repr(u8)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum Backend { /// Dummy backend, used for testing. Empty = 0, @@ -136,7 +136,7 @@ impl std::fmt::Display for Backend { /// https://gpuweb.github.io/gpuweb/#enumdef-gpupowerpreference). #[repr(C)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum PowerPreference { #[default] @@ -207,7 +207,7 @@ impl From for Backends { /// https://gpuweb.github.io/gpuweb/#dictdef-gpurequestadapteroptions). #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct RequestAdapterOptions { /// Power preference for the adapter. pub power_preference: PowerPreference, @@ -1027,7 +1027,7 @@ impl InstanceFlags { /// [`downlevel_defaults()`]: Limits::downlevel_defaults #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase", default))] pub struct Limits { /// Maximum allowed value for the `size.width` of a texture created with `TextureDimension::D1`. @@ -1419,7 +1419,7 @@ impl Limits { /// Represents the sets of additional limits on an adapter, /// which take place when running on downlevel backends. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct DownlevelLimits {} #[allow(unknown_lints)] // derivable_impls is nightly only currently @@ -1432,7 +1432,7 @@ impl Default for DownlevelLimits { /// Lists various ways the underlying platform does not conform to the WebGPU standard. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct DownlevelCapabilities { /// Combined boolean flags. pub flags: DownlevelFlags, @@ -1641,7 +1641,7 @@ impl DownlevelFlags { /// Collections of shader features a device supports if they support less than WebGPU normally allows. // TODO: Fill out the differences between shader models more completely #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum ShaderModel { /// Extremely limited shaders, including a total instruction limit. Sm2, @@ -1654,7 +1654,7 @@ pub enum ShaderModel { /// Supported physical device types. #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum DeviceType { /// Other or Unknown. Other, @@ -1672,7 +1672,7 @@ pub enum DeviceType { /// Information about an adapter. #[derive(Clone, Debug, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct AdapterInfo { /// Adapter name pub name: String, @@ -1715,7 +1715,7 @@ pub struct AdapterInfo { /// https://gpuweb.github.io/gpuweb/#gpudevicedescriptor). #[repr(C)] #[derive(Clone, Debug, Default)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct DeviceDescriptor { /// Debug label for the device. pub label: L, @@ -1777,7 +1777,7 @@ impl_bitflags!(ShaderStages); /// https://gpuweb.github.io/gpuweb/#enumdef-gputextureviewdimension). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum TextureViewDimension { /// A one dimensional texture. `texture_1d` in WGSL and `texture1D` in GLSL. #[cfg_attr(feature = "serde", serde(rename = "1d"))] @@ -1821,7 +1821,7 @@ impl TextureViewDimension { /// used with the first render target. #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum BlendFactor { /// 0.0 @@ -1883,7 +1883,7 @@ impl BlendFactor { /// https://gpuweb.github.io/gpuweb/#enumdef-gpublendoperation). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum BlendOperation { /// Src + Dst @@ -1905,7 +1905,7 @@ pub enum BlendOperation { /// https://gpuweb.github.io/gpuweb/#dictdef-gpublendcomponent). #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct BlendComponent { /// Multiplier for the source, which is produced by the fragment shader. @@ -1960,7 +1960,7 @@ impl Default for BlendComponent { /// https://gpuweb.github.io/gpuweb/#dictdef-gpublendstate). #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct BlendState { /// Color equation. @@ -1999,7 +1999,7 @@ impl BlendState { /// https://gpuweb.github.io/gpuweb/#dictdef-gpucolortargetstate). #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct ColorTargetState { /// The [`TextureFormat`] of the image that this pipeline will render to. Must match the format @@ -2031,7 +2031,7 @@ impl From for ColorTargetState { /// https://gpuweb.github.io/gpuweb/#enumdef-gpuprimitivetopology). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum PrimitiveTopology { /// Vertex data is a list of points. Each vertex is a new point. @@ -2071,7 +2071,7 @@ impl PrimitiveTopology { /// https://gpuweb.github.io/gpuweb/#enumdef-gpufrontface). #[repr(C)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum FrontFace { /// Triangles with vertices in counter clockwise order are considered the front face. @@ -2092,7 +2092,7 @@ pub enum FrontFace { /// except that the `"none"` value is represented using `Option` instead. #[repr(C)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum Face { /// Front face @@ -2104,7 +2104,7 @@ pub enum Face { /// Type of drawing mode for polygons #[repr(C)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum PolygonMode { /// Polygons are filled @@ -2122,7 +2122,7 @@ pub enum PolygonMode { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuprimitivestate). #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct PrimitiveState { /// The primitive topology used to interpret vertices. @@ -2162,7 +2162,7 @@ pub struct PrimitiveState { /// https://gpuweb.github.io/gpuweb/#dictdef-gpumultisamplestate). #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct MultisampleState { /// The number of samples calculated per pixel (for MSAA). For non-multisampled textures, @@ -2250,7 +2250,7 @@ impl_bitflags!(TextureFormatFeatureFlags); /// /// Features are defined by WebGPU specification unless `Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES` is enabled. #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct TextureFormatFeatures { /// Valid bits for `TextureDescriptor::Usage` provided for format creation. pub allowed_usages: TextureUsages, @@ -2261,7 +2261,7 @@ pub struct TextureFormatFeatures { /// ASTC block dimensions #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum AstcBlock { /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). B4x4, @@ -2296,7 +2296,7 @@ pub enum AstcBlock { /// ASTC RGBA channel #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum AstcChannel { /// 8 bit integer RGBA, [0, 255] converted to/from linear-color float [0, 1] in shader. /// @@ -4485,7 +4485,7 @@ impl MaintainResult { /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate). #[repr(C)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct StencilState { /// Front face mode. pub front: StencilFaceState, @@ -4532,7 +4532,7 @@ impl StencilState { /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate). #[repr(C)] #[derive(Clone, Copy, Debug, Default)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct DepthBiasState { /// Constant depth biasing factor, in basic units of the depth format. pub constant: i32, @@ -4573,7 +4573,7 @@ impl Eq for DepthBiasState {} /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate). #[repr(C)] #[derive(Clone, Debug, Hash, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct DepthStencilState { /// Format of the depth/stencil buffer, must be special depth format. Must match the format /// of the depth/stencil attachment in [`CommandEncoder::begin_render_pass`][CEbrp]. @@ -4620,7 +4620,7 @@ impl DepthStencilState { /// https://gpuweb.github.io/gpuweb/#enumdef-gpuindexformat). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum IndexFormat { /// Indices are 16 bit unsigned integers. @@ -4636,7 +4636,7 @@ pub enum IndexFormat { /// https://gpuweb.github.io/gpuweb/#enumdef-gpustenciloperation). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum StencilOperation { /// Keep stencil value unchanged. @@ -4669,7 +4669,7 @@ pub enum StencilOperation { /// https://gpuweb.github.io/gpuweb/#dictdef-gpustencilfacestate). #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct StencilFaceState { /// Comparison function that determines if the fail_op or pass_op is used on the stencil buffer. @@ -4719,7 +4719,7 @@ impl Default for StencilFaceState { /// https://gpuweb.github.io/gpuweb/#enumdef-gpucomparefunction). #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum CompareFunction { /// Function never passes @@ -4813,7 +4813,7 @@ impl CompareFunction { /// [`Instance`]: VertexStepMode::Instance #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum VertexStepMode { /// Vertex data is advanced every vertex. @@ -4834,7 +4834,7 @@ pub enum VertexStepMode { /// [`vertex_attr_array`]: ../wgpu/macro.vertex_attr_array.html #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct VertexAttribute { /// Format of the input @@ -4851,7 +4851,7 @@ pub struct VertexAttribute { /// https://gpuweb.github.io/gpuweb/#enumdef-gpuvertexformat). #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] pub enum VertexFormat { /// Two unsigned bytes (u8). `vec2` in shaders. @@ -5014,7 +5014,7 @@ impl_bitflags!(BufferUsages); /// https://gpuweb.github.io/gpuweb/#dictdef-gpubufferdescriptor). #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct BufferDescriptor { /// Debug label of a buffer. This will show up in graphics debuggers for easy identification. pub label: L, @@ -5048,7 +5048,7 @@ impl BufferDescriptor { /// Corresponds to [WebGPU `GPUCommandEncoderDescriptor`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandencoderdescriptor). #[repr(C)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct CommandEncoderDescriptor { /// Debug label for the command encoder. This will show up in graphics debuggers for easy identification. @@ -5073,7 +5073,7 @@ impl Default for CommandEncoderDescriptor> { /// Behavior of the presentation engine based on frame rate. #[repr(C)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum PresentMode { /// Chooses FifoRelaxed -> Fifo based on availability. /// @@ -5145,7 +5145,7 @@ pub enum PresentMode { /// compositing. #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] pub enum CompositeAlphaMode { /// Chooses either `Opaque` or `Inherit` automatically,depending on the @@ -5244,7 +5244,7 @@ impl Default for SurfaceCapabilities { /// [`Surface`]: ../wgpu/struct.Surface.html #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct SurfaceConfiguration { /// The usage of the swap chain. The only supported usage is `RENDER_ATTACHMENT`. pub usage: TextureUsages, @@ -5370,7 +5370,7 @@ impl PresentationTimestamp { /// This is not to be used as a generic color type, only for specific wgpu interfaces. #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Color { /// Red component of the color @@ -5429,7 +5429,7 @@ impl Color { /// https://gpuweb.github.io/gpuweb/#enumdef-gputexturedimension). #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum TextureDimension { /// 1D texture #[cfg_attr(feature = "serde", serde(rename = "1d"))] @@ -5448,7 +5448,7 @@ pub enum TextureDimension { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuorigin2ddict). #[repr(C)] #[derive(Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Origin2d { /// @@ -5483,7 +5483,7 @@ impl std::fmt::Debug for Origin2d { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuorigin3ddict). #[repr(C)] #[derive(Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Origin3d { /// X position of the origin @@ -5525,7 +5525,7 @@ impl std::fmt::Debug for Origin3d { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuextent3ddict). #[repr(C)] #[derive(Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Extent3d { /// Width of the extent @@ -5724,7 +5724,7 @@ fn test_max_mips() { /// https://gpuweb.github.io/gpuweb/#dictdef-gputexturedescriptor). #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct TextureDescriptor { /// Debug label of the texture. This will show up in graphics debuggers for easy identification. pub label: L, @@ -5855,7 +5855,7 @@ impl TextureDescriptor { /// https://gpuweb.github.io/gpuweb/#enumdef-gputextureaspect). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum TextureAspect { /// Depth, Stencil, and Color. @@ -5879,7 +5879,7 @@ pub enum TextureAspect { /// https://gpuweb.github.io/gpuweb/#enumdef-gpuaddressmode). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum AddressMode { /// Clamp the value to the edge of the texture @@ -5912,7 +5912,7 @@ pub enum AddressMode { /// https://gpuweb.github.io/gpuweb/#enumdef-gpufiltermode). #[repr(C)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum FilterMode { /// Nearest neighbor sampling. @@ -5928,7 +5928,7 @@ pub enum FilterMode { /// A range of push constant memory to pass to a shader stage. #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct PushConstantRange { /// Stage push constant range is visible from. Each stage can only be served by at most one range. /// One range can serve multiple stages however. @@ -5944,7 +5944,7 @@ pub struct PushConstantRange { /// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandbufferdescriptor). #[repr(C)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CommandBufferDescriptor { /// Debug label of this command buffer. pub label: L, @@ -5965,7 +5965,7 @@ impl CommandBufferDescriptor { /// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderbundleencoderdescriptor). #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct RenderBundleDepthStencil { /// Format of the attachment. pub format: TextureFormat, @@ -5992,7 +5992,7 @@ pub struct RenderBundleDepthStencil { /// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderbundledescriptor). #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct RenderBundleDescriptor { /// Debug label of the render bundle encoder. This will show up in graphics debuggers for easy identification. pub label: L, @@ -6028,7 +6028,7 @@ impl Default for RenderBundleDescriptor> { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagedatalayout). #[repr(C)] #[derive(Clone, Copy, Debug, Default)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ImageDataLayout { /// Offset into the buffer that is the start of the texture. Must be a multiple of texture block size. /// For non-compressed textures, this is 1. @@ -6068,7 +6068,7 @@ pub struct ImageDataLayout { /// Corresponds to [WebGPU `GPUBufferBindingType`]( /// https://gpuweb.github.io/gpuweb/#enumdef-gpubufferbindingtype). #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum BufferBindingType { /// A buffer for uniform values. /// @@ -6133,7 +6133,7 @@ pub enum BufferBindingType { /// Corresponds to [WebGPU `GPUTextureSampleType`]( /// https://gpuweb.github.io/gpuweb/#enumdef-gputexturesampletype). #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum TextureSampleType { /// Sampling returns floats. /// @@ -6215,7 +6215,7 @@ impl Default for TextureSampleType { /// Corresponds to [WebGPU `GPUStorageTextureAccess`]( /// https://gpuweb.github.io/gpuweb/#enumdef-gpustoragetextureaccess). #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum StorageTextureAccess { /// The texture can only be written in the shader and it: @@ -6277,7 +6277,7 @@ pub enum StorageTextureAccess { /// https://gpuweb.github.io/gpuweb/#enumdef-gpusamplerbindingtype). #[repr(C)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum SamplerBindingType { /// The sampling result is produced based on more than a single color sample from a texture, @@ -6297,7 +6297,7 @@ pub enum SamplerBindingType { /// Corresponds to WebGPU's mutually exclusive fields within [`GPUBindGroupLayoutEntry`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry). #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum BindingType { /// A buffer binding. /// @@ -6446,7 +6446,7 @@ impl BindingType { /// Corresponds to [WebGPU `GPUBindGroupLayoutEntry`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry). #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct BindGroupLayoutEntry { /// Binding index. Must match shader index and be unique inside a BindGroupLayout. A binding /// of index 1, would be described as `layout(set = 0, binding = 1) uniform` in shaders. @@ -6470,7 +6470,7 @@ pub struct BindGroupLayoutEntry { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopybuffer). #[repr(C)] #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ImageCopyBuffer { /// The buffer to be copied to/from. pub buffer: B, @@ -6484,7 +6484,7 @@ pub struct ImageCopyBuffer { /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopytexture). #[repr(C)] #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ImageCopyTexture { /// The texture to be copied to/from. pub texture: T, @@ -6616,7 +6616,7 @@ unsafe impl Sync for ExternalImageSource {} /// Corresponds to [HTML Canvas `PredefinedColorSpace`]( /// https://html.spec.whatwg.org/multipage/canvas.html#predefinedcolorspace). #[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] pub enum PredefinedColorSpace { /// sRGB color space @@ -6631,7 +6631,7 @@ pub enum PredefinedColorSpace { /// Corresponds to [WebGPU `GPUImageCopyTextureTagged`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopytexturetagged). #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ImageCopyTextureTagged { /// The texture to be copied to/from. pub texture: T, @@ -6662,7 +6662,7 @@ impl ImageCopyTextureTagged { /// Subresource range within an image #[repr(C)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct ImageSubresourceRange { /// Aspect of the texture. Color textures must be [`TextureAspect::All`][TAA]. @@ -6763,7 +6763,7 @@ impl ImageSubresourceRange { /// Color variation to use when sampler addressing mode is [`AddressMode::ClampToBorder`] #[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum SamplerBorderColor { /// [0, 0, 0, 0] TransparentBlack, @@ -6785,7 +6785,7 @@ pub enum SamplerBorderColor { /// Corresponds to [WebGPU `GPUQuerySetDescriptor`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpuquerysetdescriptor). #[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct QuerySetDescriptor { /// Debug label for the query set. pub label: L, @@ -6812,7 +6812,7 @@ impl QuerySetDescriptor { /// Corresponds to [WebGPU `GPUQueryType`]( /// https://gpuweb.github.io/gpuweb/#enumdef-gpuquerytype). #[derive(Copy, Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum QueryType { /// Query returns a single 64-bit number, serving as an occlusion boolean. Occlusion, @@ -6958,7 +6958,7 @@ impl DispatchIndirectArgs { /// Describes how shader bound checks should be performed. #[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ShaderBoundChecks { runtime_checks: bool, } @@ -7068,7 +7068,7 @@ impl Default for InstanceDescriptor { } #[derive(Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Descriptor for all size definiing attributes of a single triangle geometry inside a bottom level acceleration structure. pub struct BlasTriangleGeometrySizeDescriptor { /// Format of a vertex position. @@ -7086,7 +7086,7 @@ pub struct BlasTriangleGeometrySizeDescriptor { } #[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Descriptor for all size definiing attributes of all geometries inside a bottom level acceleration structure. pub enum BlasGeometrySizeDescriptors { /// Triangle geometry version. @@ -7098,7 +7098,7 @@ pub enum BlasGeometrySizeDescriptors { #[repr(u8)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Update mode for acceleration structure builds. pub enum AccelerationStructureUpdateMode { /// Always perform a full build. @@ -7111,7 +7111,7 @@ pub enum AccelerationStructureUpdateMode { #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Descriptor for creating a bottom level acceleration structure. pub struct CreateBlasDescriptor { /// Label for the bottom level acceleration structure. @@ -7135,7 +7135,7 @@ impl CreateBlasDescriptor { #[repr(C)] #[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] /// Descriptor for creating a top level acceleration structure. pub struct CreateTlasDescriptor { /// Label for the top level acceleration structure. From e042a86375f9320518cd49ab55c2985d22606966 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 24 Feb 2024 19:54:54 -0800 Subject: [PATCH 146/146] Fix doc typo --- wgpu-types/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index ba8bd498ee..1aaa5550f5 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -7190,10 +7190,10 @@ bitflags::bitflags!( ); impl_bitflags!(AccelerationStructureGeometryFlags); -/// Alignemnet requirement for transform buffers used in acceleration structure builds +/// Alignment requirement for transform buffers used in acceleration structure builds pub const TRANSFORM_BUFFER_ALIGNMENT: BufferAddress = 16; -/// Alignemnet requirement for instanc buffers used in acceleration structure builds +/// Alignment requirement for instance buffers used in acceleration structure builds pub const INSTANCE_BUFFER_ALIGNMENT: BufferAddress = 16; pub use send_sync::*;