#[cfg(wgpu_core)]
use core::ops::Deref;
use alloc::{boxed::Box, vec::Vec};
use wgt::{WasmNotSend, WasmNotSendSync};
use crate::dispatch;
use crate::{Buffer, Label};
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<Label<'a>>;
static_assertions::assert_impl_all!(CreateBlasDescriptor<'_>: Send, Sync);
#[derive(Debug, Clone)]
pub struct TlasInstance {
pub(crate) blas: dispatch::DispatchBlas,
pub transform: [f32; 12],
pub custom_data: u32,
pub mask: u8,
}
impl TlasInstance {
pub fn new(blas: &Blas, transform: [f32; 12], custom_data: u32, mask: u8) -> Self {
Self {
blas: blas.inner.clone(),
transform,
custom_data,
mask,
}
}
pub fn set_blas(&mut self, blas: &Blas) {
self.blas = blas.inner.clone();
}
}
#[derive(Debug)]
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<&'a Buffer>,
pub first_index: Option<u32>,
pub transform_buffer: Option<&'a Buffer>,
pub transform_buffer_offset: Option<wgt::BufferAddress>,
}
static_assertions::assert_impl_all!(BlasTriangleGeometry<'_>: WasmNotSendSync);
pub enum BlasGeometries<'a> {
TriangleGeometries(Vec<BlasTriangleGeometry<'a>>),
}
static_assertions::assert_impl_all!(BlasGeometries<'_>: WasmNotSendSync);
pub struct BlasBuildEntry<'a> {
pub blas: &'a Blas,
pub geometry: BlasGeometries<'a>,
}
static_assertions::assert_impl_all!(BlasBuildEntry<'_>: WasmNotSendSync);
#[derive(Debug, Clone)]
pub struct Blas {
pub(crate) handle: Option<u64>,
pub(crate) inner: dispatch::DispatchBlas,
}
static_assertions::assert_impl_all!(Blas: WasmNotSendSync);
crate::cmp::impl_eq_ord_hash_proxy!(Blas => .inner);
impl Blas {
pub fn handle(&self) -> Option<u64> {
self.handle
}
#[doc = crate::hal_type_vulkan!("AccelerationStructure")]
#[doc = crate::hal_type_metal!("AccelerationStructure")]
#[doc = crate::hal_type_dx12!("AccelerationStructure")]
#[doc = crate::hal_type_gles!("AccelerationStructure")]
#[cfg(wgpu_core)]
pub unsafe fn as_hal<A: hal::Api>(
&mut self,
) -> Option<impl Deref<Target = A::AccelerationStructure> + WasmNotSendSync> {
let blas = self.inner.as_core_opt()?;
unsafe { blas.context.blas_as_hal::<A>(blas) }
}
#[cfg(custom)]
pub fn as_custom<T: crate::custom::BlasInterface>(&self) -> Option<&T> {
self.inner.as_custom()
}
}
pub struct ContextBlasTriangleGeometry<'a> {
#[expect(dead_code)]
pub(crate) size: &'a BlasTriangleGeometrySizeDescriptor,
#[expect(dead_code)]
pub(crate) vertex_buffer: &'a dispatch::DispatchBuffer,
#[expect(dead_code)]
pub(crate) index_buffer: Option<&'a dispatch::DispatchBuffer>,
#[expect(dead_code)]
pub(crate) transform_buffer: Option<&'a dispatch::DispatchBuffer>,
#[expect(dead_code)]
pub(crate) first_vertex: u32,
#[expect(dead_code)]
pub(crate) vertex_stride: wgt::BufferAddress,
#[expect(dead_code)]
pub(crate) index_buffer_offset: Option<wgt::BufferAddress>,
#[expect(dead_code)]
pub(crate) transform_buffer_offset: Option<wgt::BufferAddress>,
}
pub enum ContextBlasGeometries<'a> {
TriangleGeometries(Box<dyn Iterator<Item = ContextBlasTriangleGeometry<'a>> + 'a>),
}
pub struct ContextBlasBuildEntry<'a> {
#[expect(dead_code)]
pub(crate) blas: &'a dispatch::DispatchBlas,
#[expect(dead_code)]
pub(crate) geometries: ContextBlasGeometries<'a>,
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct BlasAsyncError;
static_assertions::assert_impl_all!(BlasAsyncError: Send, Sync);
impl core::fmt::Display for BlasAsyncError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"Error occurred when trying to asynchronously prepare a blas for compaction"
)
}
}
impl core::error::Error for BlasAsyncError {}
impl Blas {
pub fn prepare_compaction_async(
&self,
callback: impl FnOnce(Result<(), BlasAsyncError>) + WasmNotSend + 'static,
) {
self.inner.prepare_compact_async(Box::new(callback));
}
pub fn ready_for_compaction(&self) -> bool {
self.inner.ready_for_compaction()
}
}