@@ -7,7 +7,7 @@ use arrayvec::ArrayVec;
77use glow:: HasContext ;
88use naga:: FastHashMap ;
99
10- use super :: { conv, lock, MaybeMutex , PrivateCapabilities } ;
10+ use super :: { conv, lock, BufferBacking , MaybeMutex , PrivateCapabilities } ;
1111use crate :: auxil:: map_naga_stage;
1212use crate :: TlasInstance ;
1313
@@ -526,13 +526,16 @@ impl crate::Device for super::Device {
526526 . private_caps
527527 . contains ( PrivateCapabilities :: BUFFER_ALLOCATION ) ;
528528
529+ let host_backed_bytes = || Arc :: new ( MaybeMutex :: new ( vec ! [ 0 ; desc. size as usize ] ) ) ;
530+
529531 if emulate_map && desc. usage . intersects ( wgt:: BufferUses :: MAP_WRITE ) {
530532 return Ok ( super :: Buffer {
531- raw : None ,
533+ backing : BufferBacking :: Host {
534+ data : host_backed_bytes ( ) ,
535+ } ,
532536 target,
533537 size : desc. size ,
534538 map_flags : 0 ,
535- data : Some ( Arc :: new ( MaybeMutex :: new ( vec ! [ 0 ; desc. size as usize ] ) ) ) ,
536539 offset_of_current_mapping : Arc :: new ( MaybeMutex :: new ( 0 ) ) ,
537540 } ) ;
538541 }
@@ -560,8 +563,8 @@ impl crate::Device for super::Device {
560563 map_flags |= glow:: MAP_WRITE_BIT ;
561564 }
562565
563- let raw = Some ( unsafe { gl. create_buffer ( ) } . map_err ( |_| crate :: DeviceError :: OutOfMemory ) ?) ;
564- unsafe { gl. bind_buffer ( target, raw) } ;
566+ let raw = unsafe { gl. create_buffer ( ) } . map_err ( |_| crate :: DeviceError :: OutOfMemory ) ?;
567+ unsafe { gl. bind_buffer ( target, Some ( raw) ) } ;
565568 let raw_size = desc
566569 . size
567570 . try_into ( )
@@ -614,33 +617,38 @@ impl crate::Device for super::Device {
614617 . private_caps
615618 . contains ( PrivateCapabilities :: DEBUG_FNS )
616619 {
617- let name = raw. map_or ( 0 , |buf| buf . 0 . get ( ) ) ;
620+ let name = raw. 0 . get ( ) ;
618621 unsafe { gl. object_label ( glow:: BUFFER , name, Some ( label) ) } ;
619622 }
620623 }
621624
622- let data = if emulate_map && desc. usage . contains ( wgt:: BufferUses :: MAP_READ ) {
623- Some ( Arc :: new ( MaybeMutex :: new ( vec ! [ 0 ; desc. size as usize ] ) ) )
625+ let backing = if emulate_map && desc. usage . contains ( wgt:: BufferUses :: MAP_READ ) {
626+ BufferBacking :: GlCachedOnHost {
627+ cache : host_backed_bytes ( ) ,
628+ raw,
629+ }
624630 } else {
625- None
631+ BufferBacking :: Gl { raw }
626632 } ;
627633
628634 self . counters . buffers . add ( 1 ) ;
629635
630636 Ok ( super :: Buffer {
631- raw ,
637+ backing ,
632638 target,
633639 size : desc. size ,
634640 map_flags,
635- data,
636641 offset_of_current_mapping : Arc :: new ( MaybeMutex :: new ( 0 ) ) ,
637642 } )
638643 }
639644
640645 unsafe fn destroy_buffer ( & self , buffer : super :: Buffer ) {
641- if let Some ( raw) = buffer. raw {
642- let gl = & self . shared . context . lock ( ) ;
643- unsafe { gl. delete_buffer ( raw) } ;
646+ match buffer. backing {
647+ BufferBacking :: Gl { raw } | BufferBacking :: GlCachedOnHost { raw, cache : _ } => {
648+ let gl = & self . shared . context . lock ( ) ;
649+ unsafe { gl. delete_buffer ( raw) } ;
650+ }
651+ BufferBacking :: Host { data : _ } => { }
644652 }
645653
646654 self . counters . buffers . sub ( 1 ) ;
@@ -656,33 +664,32 @@ impl crate::Device for super::Device {
656664 range : crate :: MemoryRange ,
657665 ) -> Result < crate :: BufferMapping , crate :: DeviceError > {
658666 let is_coherent = buffer. map_flags & glow:: MAP_COHERENT_BIT != 0 ;
659- let ptr = match buffer. raw {
660- None => {
661- let mut vec = lock ( buffer . data . as_ref ( ) . unwrap ( ) ) ;
667+ let ptr = match & buffer. backing {
668+ BufferBacking :: Host { data } => {
669+ let mut vec = lock ( data) ;
662670 let slice = & mut vec. as_mut_slice ( ) [ range. start as usize ..range. end as usize ] ;
663671 slice. as_mut_ptr ( )
664672 }
665- Some ( raw) => {
673+ & BufferBacking :: Gl { raw } => {
666674 let gl = & self . shared . context . lock ( ) ;
667675 unsafe { gl. bind_buffer ( buffer. target , Some ( raw) ) } ;
668- let ptr = if let Some ( ref map_read_allocation) = buffer. data {
669- let mut guard = lock ( map_read_allocation) ;
670- let slice = guard. as_mut_slice ( ) ;
671- unsafe { self . shared . get_buffer_sub_data ( gl, buffer. target , 0 , slice) } ;
672- slice. as_mut_ptr ( )
673- } else {
674- * lock ( & buffer. offset_of_current_mapping ) = range. start ;
675- unsafe {
676- gl. map_buffer_range (
677- buffer. target ,
678- range. start as i32 ,
679- ( range. end - range. start ) as i32 ,
680- buffer. map_flags ,
681- )
682- }
683- } ;
684- unsafe { gl. bind_buffer ( buffer. target , None ) } ;
685- ptr
676+ * lock ( & buffer. offset_of_current_mapping ) = range. start ;
677+ unsafe {
678+ gl. map_buffer_range (
679+ buffer. target ,
680+ range. start as i32 ,
681+ ( range. end - range. start ) as i32 ,
682+ buffer. map_flags ,
683+ )
684+ }
685+ }
686+ & BufferBacking :: GlCachedOnHost { raw, ref cache } => {
687+ let gl = & self . shared . context . lock ( ) ;
688+ unsafe { gl. bind_buffer ( buffer. target , Some ( raw) ) } ;
689+ let mut guard = lock ( cache) ;
690+ let slice = guard. as_mut_slice ( ) ;
691+ unsafe { self . shared . get_buffer_sub_data ( gl, buffer. target , 0 , slice) } ;
692+ slice. as_mut_ptr ( )
686693 }
687694 } ;
688695 Ok ( crate :: BufferMapping {
@@ -691,22 +698,23 @@ impl crate::Device for super::Device {
691698 } )
692699 }
693700 unsafe fn unmap_buffer ( & self , buffer : & super :: Buffer ) {
694- if let Some ( raw ) = buffer. raw {
695- if buffer . data . is_none ( ) {
701+ match & buffer. backing {
702+ & BufferBacking :: Gl { raw } => {
696703 let gl = & self . shared . context . lock ( ) ;
697704 unsafe { gl. bind_buffer ( buffer. target , Some ( raw) ) } ;
698705 unsafe { gl. unmap_buffer ( buffer. target ) } ;
699706 unsafe { gl. bind_buffer ( buffer. target , None ) } ;
700707 * lock ( & buffer. offset_of_current_mapping ) = 0 ;
701708 }
709+ & BufferBacking :: Host { .. } | & BufferBacking :: GlCachedOnHost { .. } => { }
702710 }
703711 }
704712 unsafe fn flush_mapped_ranges < I > ( & self , buffer : & super :: Buffer , ranges : I )
705713 where
706714 I : Iterator < Item = crate :: MemoryRange > ,
707715 {
708- if let Some ( raw ) = buffer. raw {
709- if buffer . data . is_none ( ) {
716+ match & buffer. backing {
717+ & BufferBacking :: Gl { raw } => {
710718 let gl = & self . shared . context . lock ( ) ;
711719 unsafe { gl. bind_buffer ( buffer. target , Some ( raw) ) } ;
712720 for range in ranges {
@@ -720,6 +728,7 @@ impl crate::Device for super::Device {
720728 } ;
721729 }
722730 }
731+ & BufferBacking :: Host { .. } | & BufferBacking :: GlCachedOnHost { .. } => { }
723732 }
724733 }
725734 unsafe fn invalidate_mapped_ranges < I > ( & self , _buffer : & super :: Buffer , _ranges : I ) {
@@ -1261,7 +1270,11 @@ impl crate::Device for super::Device {
12611270 wgt:: BindingType :: Buffer { .. } => {
12621271 let bb = & desc. buffers [ entry. resource_index as usize ] ;
12631272 super :: RawBinding :: Buffer {
1264- raw : bb. buffer . raw . unwrap ( ) ,
1273+ raw : match & bb. buffer . backing {
1274+ & BufferBacking :: Gl { raw }
1275+ | & BufferBacking :: GlCachedOnHost { raw, .. } => raw,
1276+ & BufferBacking :: Host { .. } => unreachable ! ( ) ,
1277+ } ,
12651278 offset : bb. offset as i32 ,
12661279 size : match bb. size {
12671280 Some ( s) => s. get ( ) as i32 ,
0 commit comments