use crate::grid::grid::{GpuGrid, indirect_dispatch_tensor};
use crate::mpm_shaders::grid::sort::{
GpuCopyParticlesLenToScanValue, GpuCopyRigidParticlesLenToScanValue,
GpuCopyScanValuesToFirstParticles, GpuCopyScanValuesToFirstRigidParticles,
GpuFinalizeParticlesSort, GpuFinalizeRigidParticlesSort, GpuMarkRigidParticlesNeedingBlock,
GpuTouchNeighborBlocks, GpuTouchParticleBlocks, GpuTouchPrimaryBlocks,
GpuTouchRigidParticleBlocks, GpuUpdateBlockParticleCount, GpuUpdateBlockRigidParticleCount,
GpuUpdateNbhBlockIds,
};
use crate::solver::GpuRigidParticles;
use khal::Shader;
use khal::backend::{GpuBackend, GpuBackendError, GpuPass};
use nexus_rbd::utils::{GpuPrefixSum, PrefixSumWorkspace};
#[derive(Shader)]
pub struct WgSort {
pub(crate) touch_particle_blocks: GpuTouchParticleBlocks,
pub(crate) touch_primary_blocks: GpuTouchPrimaryBlocks,
pub(crate) touch_neighbor_blocks: GpuTouchNeighborBlocks,
pub(crate) touch_rigid_particle_blocks: GpuTouchRigidParticleBlocks,
pub(crate) mark_rigid_particles_needing_block: GpuMarkRigidParticlesNeedingBlock,
pub(crate) update_block_particle_count: GpuUpdateBlockParticleCount,
pub(crate) update_nbh_block_ids: GpuUpdateNbhBlockIds,
pub(crate) copy_particles_len_to_scan_value: GpuCopyParticlesLenToScanValue,
pub(crate) copy_scan_values_to_first_particles: GpuCopyScanValuesToFirstParticles,
pub(crate) finalize_particles_sort: GpuFinalizeParticlesSort,
pub(crate) update_block_rigid_particle_count: GpuUpdateBlockRigidParticleCount,
pub(crate) copy_rigid_particles_len_to_scan_value: GpuCopyRigidParticlesLenToScanValue,
pub(crate) copy_scan_values_to_first_rigid_particles: GpuCopyScanValuesToFirstRigidParticles,
pub(crate) finalize_rigid_particles_sort: GpuFinalizeRigidParticlesSort,
}
impl WgSort {
pub fn launch_sort_rigid_particles(
&self,
backend: &GpuBackend,
pass: &mut GpuPass,
rigid_particles: &mut GpuRigidParticles,
grid: &mut GpuGrid,
prefix_sum: &mut PrefixSumWorkspace,
prefix_sum_module: &GpuPrefixSum,
) -> Result<(), GpuBackendError> {
if rigid_particles.is_empty() {
return Ok(());
}
let rigid_particles_len = rigid_particles.len() as u32;
self.update_block_rigid_particle_count.call(
pass,
rigid_particles_len,
&grid.meta,
&grid.hmap_entries,
&rigid_particles.sample_points,
&mut grid.active_blocks,
)?;
self.copy_rigid_particles_len_to_scan_value.call(
pass,
indirect_dispatch_tensor(&grid.indirect_n_blocks_groups),
&grid.meta,
&grid.active_blocks,
&mut grid.scan_values,
)?;
prefix_sum_module.launch(backend, pass, prefix_sum, &mut grid.scan_values, 1)?;
self.copy_scan_values_to_first_rigid_particles.call(
pass,
indirect_dispatch_tensor(&grid.indirect_n_blocks_groups),
&grid.meta,
&grid.scan_values,
&mut grid.active_blocks,
)?;
self.finalize_rigid_particles_sort.call(
pass,
rigid_particles_len,
&grid.meta,
&grid.hmap_entries,
&rigid_particles.sample_points,
&mut grid.active_blocks,
&mut rigid_particles.sorted_ids,
)?;
Ok(())
}
}