@@ -17,10 +17,6 @@ extern crate gfx_backend_metal as back;
1717#[ cfg( feature = "vulkan" ) ]
1818extern crate gfx_backend_vulkan as back;
1919
20- use accel:: { CreateDesc , GeometryInstances } ;
21- use buffer:: Access ;
22- use mem:: { size_of, MaybeUninit } ;
23- use memory:: { Barrier , Dependencies } ;
2420#[ cfg( target_arch = "wasm32" ) ]
2521use wasm_bindgen:: prelude:: * ;
2622
@@ -32,22 +28,11 @@ pub fn wasm_main() {
3228}
3329
3430use hal:: {
35- acceleration_structure as accel, adapter,
36- buffer:: { self } ,
37- command, format, memory, pool,
38- prelude:: * ,
39- pso:: PipelineStage ,
40- window, Backend , IndexType ,
31+ acceleration_structure as accel, adapter, buffer, command, format, memory, pool, prelude:: * ,
32+ pso, window, IndexType ,
4133} ;
4234
43- use std:: {
44- borrow:: Borrow ,
45- io:: Cursor ,
46- iter,
47- mem:: { self , ManuallyDrop } ,
48- ops:: { Deref , DerefMut } ,
49- ptr,
50- } ;
35+ use std:: { iter, mem, ops, ptr} ;
5136
5237#[ cfg_attr( rustfmt, rustfmt_skip) ]
5338const DIMS : window:: Extent2D = window:: Extent2D { width : 1024 , height : 768 } ;
@@ -243,12 +228,14 @@ fn main() {
243228 } ] ,
244229 } ;
245230
246- let cube_primitive_count = ( teapot_indices. len ( ) / 3 ) as u32 ;
247- let teapot_blas_requirements = device
248- . get_acceleration_structure_build_requirements ( & geometry_desc, & [ cube_primitive_count] ) ;
231+ let teapot_primitive_count = ( teapot_indices. len ( ) / 3 ) as u32 ;
232+ let teapot_blas_requirements = device. get_acceleration_structure_build_requirements (
233+ & geometry_desc,
234+ & [ teapot_primitive_count] ,
235+ ) ;
249236
250- let raw_size =
251- teapot_vertices . len ( ) * size_of :: < Vertex > ( ) + teapot_vertices. len ( ) * size_of :: < u16 > ( ) ;
237+ let raw_size = teapot_vertices . len ( ) * mem :: size_of :: < Vertex > ( )
238+ + teapot_vertices. len ( ) * mem :: size_of :: < u16 > ( ) ;
252239 dbg ! ( teapot_vertices. len( ) ) ;
253240 dbg ! ( teapot_indices. len( ) ) ;
254241 dbg ! ( raw_size) ;
@@ -292,6 +279,8 @@ fn main() {
292279 device. set_acceleration_structure_name ( & mut teapot_blas. accel_struct , "teapot" ) ;
293280
294281 {
282+ // build the blas + get the compacted size
283+
295284 let query_count = 1 ;
296285 let compacted_size_pool = device
297286 . create_query_pool (
@@ -319,19 +308,20 @@ fn main() {
319308 scratch_offset : 0 ,
320309 } ,
321310 & [ accel:: BuildRangeDesc {
322- primitive_count : cube_primitive_count ,
311+ primitive_count : teapot_primitive_count ,
323312 primitive_offset : 0 ,
324313 first_vertex : 0 ,
325314 transform_offset : 0 ,
326315 } ] [ ..] ,
327316 ) ] ) ;
328317
329318 cmd_buffer. pipeline_barrier (
330- PipelineStage :: ACCELERATION_STRUCTURE_BUILD
331- ..PipelineStage :: ACCELERATION_STRUCTURE_BUILD ,
332- Dependencies :: empty ( ) ,
333- & [ Barrier :: AllBuffers (
334- Access :: ACCELERATION_STRUCTURE_WRITE ..Access :: ACCELERATION_STRUCTURE_READ ,
319+ pso:: PipelineStage :: ACCELERATION_STRUCTURE_BUILD
320+ ..pso:: PipelineStage :: ACCELERATION_STRUCTURE_BUILD ,
321+ memory:: Dependencies :: empty ( ) ,
322+ & [ memory:: Barrier :: AllBuffers (
323+ buffer:: Access :: ACCELERATION_STRUCTURE_WRITE
324+ ..buffer:: Access :: ACCELERATION_STRUCTURE_READ ,
335325 ) ] ,
336326 ) ;
337327
@@ -370,8 +360,13 @@ fn main() {
370360 hal:: query:: ResultFlags :: WAIT ,
371361 )
372362 . unwrap ( ) ;
373- let teapot_blas_compacted_size = ( data. as_ptr ( ) as * const u32 ) . read ( ) ;
374- dbg ! ( teapot_blas_compacted_size) ;
363+ let teapot_blas_compacted_size = ( data. as_ptr ( ) as * const u32 ) . read ( ) as u64 ;
364+ dbg ! (
365+ teapot_blas_compacted_size,
366+ teapot_blas_requirements. acceleration_structure_size - teapot_blas_compacted_size,
367+ teapot_blas_compacted_size as f64
368+ / teapot_blas_requirements. acceleration_structure_size as f64
369+ ) ;
375370
376371 let mut data = std:: iter:: repeat ( 0 )
377372 . take ( 1 * mem:: size_of :: < u32 > ( ) )
@@ -387,11 +382,62 @@ fn main() {
387382 . unwrap ( ) ;
388383 let teapot_blas_serialized_size = ( data. as_ptr ( ) as * const u32 ) . read ( ) ;
389384 dbg ! ( teapot_blas_serialized_size) ;
385+
386+ {
387+ // compact it!
388+
389+ let accel_struct_bottom_buffer_compact = create_empty_buffer :: < back:: Backend > (
390+ & device,
391+ limits. non_coherent_atom_size as u64 ,
392+ & memory_types,
393+ buffer:: Usage :: ACCELERATION_STRUCTURE_STORAGE
394+ | buffer:: Usage :: SHADER_DEVICE_ADDRESS ,
395+ teapot_blas_compacted_size,
396+ ) ;
397+ let mut teapot_blas_compact = AccelerationStructure :: < back:: Backend > {
398+ accel_struct : device
399+ . create_acceleration_structure ( & accel:: CreateDesc {
400+ buffer : & accel_struct_bottom_buffer_compact. 0 ,
401+ buffer_offset : 0 ,
402+ size : teapot_blas_compacted_size,
403+ ty : accel:: Type :: BottomLevel ,
404+ } )
405+ . unwrap ( ) ,
406+ backing : accel_struct_bottom_buffer_compact,
407+ } ;
408+ device. set_acceleration_structure_name (
409+ & mut teapot_blas_compact. accel_struct ,
410+ "teapot_compact" ,
411+ ) ;
412+
413+ let mut build_fence = device. create_fence ( false ) . unwrap ( ) ;
414+ let mut cmd_buffer = command_pool. allocate_one ( command:: Level :: Primary ) ;
415+ cmd_buffer. begin_primary ( command:: CommandBufferFlags :: ONE_TIME_SUBMIT ) ;
416+
417+ cmd_buffer. copy_acceleration_structure (
418+ & teapot_blas. accel_struct ,
419+ & teapot_blas_compact. accel_struct ,
420+ accel:: CopyMode :: Compact ,
421+ ) ;
422+
423+ cmd_buffer. finish ( ) ;
424+
425+ queue_group. queues [ 0 ]
426+ . submit_without_semaphores ( Some ( & cmd_buffer) , Some ( & mut build_fence) ) ;
427+
428+ device
429+ . wait_for_fence ( & build_fence, !0 )
430+ . expect ( "Can't wait for fence" ) ;
431+
432+ let _ = mem:: replace ( & mut teapot_blas, teapot_blas_compact) ;
433+ }
390434 }
391435
392436 let instances = [ {
393- let mut instance =
394- accel:: Instance :: new ( device. get_buffer_address ( & teapot_blas. backing . 0 ) ) ;
437+ let mut instance = accel:: Instance :: new (
438+ device. get_acceleration_structure_address ( & teapot_blas. accel_struct ) ,
439+ ) ;
440+ // instance.set_flags(accel::InstanceFlags::FORCE_OPAQUE);
395441 instance
396442 } ] ;
397443
@@ -411,7 +457,7 @@ fn main() {
411457 ty : accel:: Type :: TopLevel ,
412458 geometries : & [ & accel:: Geometry {
413459 flags : accel:: GeometryFlags :: OPAQUE ,
414- geometry : accel:: GeometryData :: Instances ( GeometryInstances {
460+ geometry : accel:: GeometryData :: Instances ( accel :: GeometryInstances {
415461 buffer : & instances_buffer. 0 ,
416462 buffer_offset : 0 ,
417463 } ) ,
@@ -450,6 +496,8 @@ fn main() {
450496 backing : tlas_buffer,
451497 } ;
452498
499+ device. set_acceleration_structure_name ( & mut tlas. accel_struct , "tlas" ) ;
500+
453501 {
454502 let query_count = 1 ;
455503 let compacted_size_pool = device
@@ -486,11 +534,12 @@ fn main() {
486534 ) ] ) ;
487535
488536 cmd_buffer. pipeline_barrier (
489- PipelineStage :: ACCELERATION_STRUCTURE_BUILD
490- ..PipelineStage :: ACCELERATION_STRUCTURE_BUILD ,
491- Dependencies :: empty ( ) ,
492- & [ Barrier :: AllBuffers (
493- Access :: ACCELERATION_STRUCTURE_WRITE ..Access :: ACCELERATION_STRUCTURE_READ ,
537+ pso:: PipelineStage :: ACCELERATION_STRUCTURE_BUILD
538+ ..pso:: PipelineStage :: ACCELERATION_STRUCTURE_BUILD ,
539+ memory:: Dependencies :: empty ( ) ,
540+ & [ memory:: Barrier :: AllBuffers (
541+ buffer:: Access :: ACCELERATION_STRUCTURE_WRITE
542+ ..buffer:: Access :: ACCELERATION_STRUCTURE_READ ,
494543 ) ] ,
495544 ) ;
496545
@@ -547,6 +596,42 @@ fn main() {
547596 let tlas_serialized_size = ( data. as_ptr ( ) as * const u32 ) . read ( ) ;
548597 dbg ! ( tlas_serialized_size) ;
549598 }
599+
600+ {
601+ // do a dummy descriptor write
602+
603+ let mut descriptor_pool = device
604+ . create_descriptor_pool (
605+ 1 ,
606+ & [ pso:: DescriptorRangeDesc {
607+ ty : pso:: DescriptorType :: AccelerationStructure ,
608+ count : 1 ,
609+ } ] ,
610+ pso:: DescriptorPoolCreateFlags :: empty ( ) ,
611+ )
612+ . unwrap ( ) ;
613+
614+ let layout = device
615+ . create_descriptor_set_layout (
616+ & [ pso:: DescriptorSetLayoutBinding {
617+ binding : 0 ,
618+ ty : pso:: DescriptorType :: AccelerationStructure ,
619+ count : 1 ,
620+ stage_flags : pso:: ShaderStageFlags :: ALL ,
621+ immutable_samplers : false ,
622+ } ] ,
623+ & [ ] ,
624+ )
625+ . unwrap ( ) ;
626+ let descriptor_set = descriptor_pool. allocate_set ( & layout) . unwrap ( ) ;
627+
628+ device. write_descriptor_sets ( iter:: once ( pso:: DescriptorSetWrite {
629+ set : & descriptor_set,
630+ binding : 0 ,
631+ array_offset : 0 ,
632+ descriptors : vec ! [ pso:: Descriptor :: AccelerationStructure ( & tlas. accel_struct) ] ,
633+ } ) ) ;
634+ }
550635 }
551636}
552637
0 commit comments