@@ -18,20 +18,66 @@ mod sealed {
1818 }
1919
2020 pub trait Loadable {
21- fn load_from_buf ( & mut self , buffer : & buf , what : Range < usize > , into : usize ) ;
22- fn load_from_cell ( & mut self , buffer : & cell_buf , what : Range < usize > , into : usize ) ;
23- fn load_from_atomic ( & mut self , buffer : & atomic_buf , what : Range < usize > , into : usize ) ;
21+ fn load_from_buf ( & mut self , buffer : & buf , what : Range < usize > , at : usize ) ;
22+ fn load_from_cell ( & mut self , buffer : & cell_buf , what : Range < usize > , at : usize ) ;
23+ fn load_from_atomic ( & mut self , buffer : & atomic_buf , what : Range < usize > , at : usize ) ;
2424 }
2525
2626 pub trait Storable {
27- fn store_to_buf ( & self , buffer : & mut buf , what : Range < usize > , into : usize ) ;
28- fn store_to_cell ( & self , buffer : & cell_buf , what : Range < usize > , into : usize ) ;
29- fn store_to_atomic ( & self , buffer : & atomic_buf , what : Range < usize > , into : usize ) ;
27+ fn store_to_buf ( & self , buffer : & mut buf , what : Range < usize > , at : usize ) ;
28+ fn store_to_cell ( & self , buffer : & cell_buf , what : Range < usize > , at : usize ) ;
29+ fn store_to_atomic ( & self , buffer : & atomic_buf , what : Range < usize > , at : usize ) ;
30+ }
31+
32+ /// So we can abstract over the invocations of `Loadable::load_from_{buf,cell,atomic}`.
33+ pub ( crate ) trait LoadSource {
34+ fn load ( & mut self , into : & mut dyn Loadable , what : Range < usize > , at : usize ) ;
35+ }
36+
37+ /// So we can abstract over the invocations of `Storable::store_to_{buf,cell,atomic}`.
38+ pub ( crate ) trait StoreTarget {
39+ fn store ( & mut self , into : & dyn Storable , what : Range < usize > , at : usize ) ;
40+ }
41+
42+ impl LoadSource for & ' _ buf {
43+ fn load ( & mut self , into : & mut dyn Loadable , what : Range < usize > , at : usize ) {
44+ into. load_from_buf ( self , what, at)
45+ }
46+ }
47+
48+ impl LoadSource for & ' _ cell_buf {
49+ fn load ( & mut self , into : & mut dyn Loadable , what : Range < usize > , at : usize ) {
50+ into. load_from_cell ( self , what, at)
51+ }
52+ }
53+
54+ impl LoadSource for & ' _ atomic_buf {
55+ fn load ( & mut self , into : & mut dyn Loadable , what : Range < usize > , at : usize ) {
56+ into. load_from_atomic ( self , what, at)
57+ }
58+ }
59+
60+ impl StoreTarget for & ' _ mut buf {
61+ fn store ( & mut self , into : & dyn Storable , what : Range < usize > , at : usize ) {
62+ into. store_to_buf ( self , what, at)
63+ }
64+ }
65+
66+ impl StoreTarget for & ' _ cell_buf {
67+ fn store ( & mut self , into : & dyn Storable , what : Range < usize > , at : usize ) {
68+ into. store_to_cell ( self , what, at)
69+ }
70+ }
71+
72+ impl StoreTarget for & ' _ atomic_buf {
73+ fn store ( & mut self , into : & dyn Storable , what : Range < usize > , at : usize ) {
74+ into. store_to_atomic ( self , what, at)
75+ }
3076 }
3177}
3278
3379use core:: { cell:: Cell , ops:: Range } ;
34- use sealed:: { LayoutEngineCore , Loadable , Storable } ;
80+ use sealed:: { Loadable , Storable } ;
3581
3682use crate :: buf:: { atomic_buf, buf, cell_buf} ;
3783use crate :: image:: {
@@ -40,18 +86,21 @@ use crate::image::{
4086use crate :: layout:: { Bytes , Layout } ;
4187use crate :: texels;
4288
89+ /// A buffer with layout, not aligned to any particular boundary.
4390pub struct DataRef < ' lt , Layout = Bytes > {
4491 data : & ' lt [ u8 ] ,
4592 layout : Layout ,
4693 offset : usize ,
4794}
4895
96+ /// A mutable buffer with layout, not aligned to any particular boundary.
4997pub struct DataMut < ' lt , Layout = Bytes > {
5098 data : & ' lt mut [ u8 ] ,
5199 layout : Layout ,
52100 offset : usize ,
53101}
54102
103+ /// A cell buffer with layout, not aligned to any particular boundary.
55104pub struct DataCells < ' lt , Layout = Bytes > {
56105 data : & ' lt [ Cell < u8 > ] ,
57106 layout : Layout ,
@@ -145,6 +194,22 @@ impl<'lt, L> DataRef<'lt, L> {
145194 let len = buffer. len ( ) . min ( core:: mem:: size_of_val ( self . data ) ) ;
146195 buffer[ ..len] . copy_from_slice ( self . data ) ;
147196 }
197+
198+ /// An adapter reading from the data as one contiguous chunk.
199+ ///
200+ /// See [`WholeLayout`] for more explanations.
201+ pub fn as_source ( & self ) -> AsCopySource < ' _ , WholeLayout < ' _ , L > >
202+ where
203+ L : Layout ,
204+ {
205+ AsCopySource {
206+ inner : & self . data ,
207+ engine : WholeLayout {
208+ inner : & self . layout ,
209+ offset : self . offset ,
210+ } ,
211+ }
212+ }
148213}
149214
150215impl Storable for & ' _ [ u8 ] {
@@ -199,6 +264,38 @@ impl<'lt, L> DataMut<'lt, L> {
199264 let len = buffer. len ( ) . min ( core:: mem:: size_of_val ( self . data ) ) ;
200265 self . data [ ..len] . copy_from_slice ( buffer) ;
201266 }
267+
268+ /// An adapter reading from the data as one contiguous chunk.
269+ ///
270+ /// See [`WholeLayout`] for more explanations.
271+ pub fn as_source ( & self ) -> AsCopySource < ' _ , WholeLayout < ' _ , L > >
272+ where
273+ L : Layout ,
274+ {
275+ AsCopySource {
276+ inner : & self . data ,
277+ engine : WholeLayout {
278+ inner : & self . layout ,
279+ offset : self . offset ,
280+ } ,
281+ }
282+ }
283+
284+ /// An adapter writing to this buffer in one contiguous chunk.
285+ ///
286+ /// See [`WholeLayout`] for more explanations.
287+ pub fn as_target ( & mut self ) -> AsCopyTarget < ' _ , WholeLayout < ' _ , L > >
288+ where
289+ L : Layout ,
290+ {
291+ AsCopyTarget {
292+ inner : & mut self . data ,
293+ engine : WholeLayout {
294+ inner : & self . layout ,
295+ offset : self . offset ,
296+ } ,
297+ }
298+ }
202299}
203300
204301impl Storable for & ' _ mut [ u8 ] {
@@ -279,7 +376,9 @@ impl<'lt, L> DataCells<'lt, L> {
279376 self . data . load_from_buf ( buffer, 0 ..len, 0 ) ;
280377 }
281378
282- /// Copy all bytes contained in this layout.
379+ /// An adapter reading from the data as one contiguous chunk.
380+ ///
381+ /// See [`WholeLayout`] for more explanations.
283382 pub fn as_source ( & self ) -> AsCopySource < ' _ , WholeLayout < ' _ , L > >
284383 where
285384 L : Layout ,
@@ -293,7 +392,9 @@ impl<'lt, L> DataCells<'lt, L> {
293392 }
294393 }
295394
296- /// Copy all bytes contained in this layout.
395+ /// An adapter writing to this buffer in one contiguous chunk.
396+ ///
397+ /// See [`WholeLayout`] for more explanations.
297398 pub fn as_target ( & mut self ) -> AsCopyTarget < ' _ , WholeLayout < ' _ , L > >
298399 where
299400 L : Layout ,
@@ -327,7 +428,10 @@ impl Storable for &'_ [Cell<u8>] {
327428
328429 #[ track_caller]
329430 fn store_to_atomic ( & self , buffer : & atomic_buf , what : Range < usize > , into : usize ) {
330- todo ! ( )
431+ let len = what. len ( ) ;
432+ let target = buffer. index ( texels:: U8 . to_range ( into..into + len) . unwrap ( ) ) ;
433+ let source = & self [ what. start ..what. end ] ;
434+ texels:: U8 . store_atomic_from_cells ( target, source) ;
331435 }
332436}
333437
@@ -350,59 +454,25 @@ impl Loadable for &'_ [Cell<u8>] {
350454 fn load_from_atomic ( & mut self , buffer : & atomic_buf , what : Range < usize > , into : usize ) {
351455 let len = what. len ( ) ;
352456 let source = buffer. index ( texels:: U8 . to_range ( into..into + len) . unwrap ( ) ) ;
353- todo ! ( )
457+ let target = & self [ what. start ..what. end ] ;
458+ texels:: U8 . load_atomic_to_cells ( source, target) ;
354459 }
355460}
356461
357462impl < E : LayoutEngine > AsCopySource < ' _ , E > {
358- fn engine_to_buf_at ( & self , buffer : & mut buf , offset : usize ) {
359- // Make sure we compile this once per iterator type. Then for instance there is only one
360- // such instance for all LayoutEngine types instead of one per different layout
361- #[ inline( never) ]
362- fn ranges_to_buf_at (
363- ranges : impl Iterator < Item = Range < usize > > ,
364- store : & dyn Storable ,
365- buffer : & mut buf ,
366- offset : usize ,
367- ) {
368- for range in ranges {
369- store. store_to_buf ( buffer, range, offset)
370- }
371- }
372-
373- ranges_to_buf_at ( self . engine . ranges ( ) , self . inner , buffer, offset) ;
374- }
375-
376- fn engine_to_cell_buf_at ( & self , buffer : & cell_buf , offset : usize ) {
377- // Make sure we compile this once per iterator type. Then for instance there is only one
378- // such instance for all LayoutEngine types instead of one per different layout
463+ fn engine_to_buf_at ( & self , buffer : impl sealed:: StoreTarget , offset : usize ) {
464+ // Make sure we compile this once per iterator type and buffer type combination. Then for
465+ // instance there is only one such instance for all LayoutEngine types instead of one per
466+ // different layout.
379467 #[ inline( never) ]
380468 fn ranges_to_buf_at (
381469 ranges : impl Iterator < Item = Range < usize > > ,
382470 store : & dyn Storable ,
383- buffer : & cell_buf ,
471+ mut buffer : impl sealed :: StoreTarget ,
384472 offset : usize ,
385473 ) {
386474 for range in ranges {
387- store. store_to_cell ( buffer, range, offset)
388- }
389- }
390-
391- ranges_to_buf_at ( self . engine . ranges ( ) , self . inner , buffer, offset) ;
392- }
393-
394- fn engine_to_atomic_buf_at ( & self , buffer : & atomic_buf , offset : usize ) {
395- // Make sure we compile this once per iterator type. Then for instance there is only one
396- // such instance for all LayoutEngine types instead of one per different layout
397- #[ inline( never) ]
398- fn ranges_to_buf_at (
399- ranges : impl Iterator < Item = Range < usize > > ,
400- store : & dyn Storable ,
401- buffer : & atomic_buf ,
402- offset : usize ,
403- ) {
404- for range in ranges {
405- store. store_to_atomic ( buffer, range, offset)
475+ buffer. store ( store, range, offset)
406476 }
407477 }
408478
@@ -458,6 +528,21 @@ impl<E: LayoutEngine> AsCopySource<'_, E> {
458528 Some ( buffer)
459529 }
460530
531+ /// Write to an image, changing the layout in the process.
532+ ///
533+ /// Fails when allocated buffer does not fits the new data's layout.
534+ pub fn write_to_cell_image (
535+ & self ,
536+ buffer : CellImage < impl Layout > ,
537+ ) -> Option < CellImage < E :: Layout > >
538+ where
539+ E :: Layout : Clone + Layout ,
540+ {
541+ let buffer = buffer. try_with_layout ( self . engine . layout ( ) . clone ( ) ) . ok ( ) ?;
542+ self . engine_to_buf_at ( buffer. as_capacity_cell_buf ( ) , 0 ) ;
543+ Some ( buffer)
544+ }
545+
461546 /// Write to a locally shared buffer with layout.
462547 ///
463548 /// First verifies that the data will fit into the target. Then returns `Some` with a new
@@ -470,7 +555,22 @@ impl<E: LayoutEngine> AsCopySource<'_, E> {
470555 E :: Layout : Clone + Layout ,
471556 {
472557 let buffer = buffer. checked_with_layout ( self . engine . layout ( ) . clone ( ) ) ?;
473- self . engine_to_cell_buf_at ( buffer. as_cell_buf ( ) , 0 ) ;
558+ self . engine_to_buf_at ( buffer. as_cell_buf ( ) , 0 ) ;
559+ Some ( buffer)
560+ }
561+
562+ /// Write to an image, changing the layout in the process.
563+ ///
564+ /// Fails when allocated buffer does not fits the new data's layout.
565+ pub fn write_to_atomic_image (
566+ & self ,
567+ buffer : AtomicImage < impl Layout > ,
568+ ) -> Option < AtomicImage < E :: Layout > >
569+ where
570+ E :: Layout : Clone + Layout ,
571+ {
572+ let buffer = buffer. try_with_layout ( self . engine . layout ( ) . clone ( ) ) . ok ( ) ?;
573+ self . engine_to_buf_at ( buffer. as_capacity_atomic_buf ( ) , 0 ) ;
474574 Some ( buffer)
475575 }
476576
@@ -486,24 +586,25 @@ impl<E: LayoutEngine> AsCopySource<'_, E> {
486586 E :: Layout : Clone + Layout ,
487587 {
488588 let buffer = buffer. checked_with_layout ( self . engine . layout ( ) . clone ( ) ) ?;
489- self . engine_to_atomic_buf_at ( buffer. as_capacity_atomic_buf ( ) , 0 ) ;
589+ self . engine_to_buf_at ( buffer. as_capacity_atomic_buf ( ) , 0 ) ;
490590 Some ( buffer)
491591 }
492592}
493593
494594impl < E : LayoutEngine > AsCopyTarget < ' _ , E > {
495- fn engine_from_buf_at ( & mut self , buffer : & buf , offset : usize ) {
496- // Make sure we compile this once per iterator type. Then for instance there is only one
497- // such instance for all LayoutEngine types instead of one per different layout
595+ fn engine_from_buf_at ( & mut self , buffer : impl sealed:: LoadSource , offset : usize ) {
596+ // Make sure we compile this once per iterator type and buffer type combination. Then for
597+ // instance there is only one such instance for all LayoutEngine types instead of one per
598+ // different layout.
498599 #[ inline( never) ]
499600 fn ranges_from_buf_at (
500601 ranges : impl Iterator < Item = Range < usize > > ,
501602 store : & mut dyn Loadable ,
502- buffer : & buf ,
603+ mut buffer : impl sealed :: LoadSource ,
503604 offset : usize ,
504605 ) {
505606 for range in ranges {
506- store . load_from_buf ( buffer , range, offset)
607+ buffer . load ( store , range, offset)
507608 }
508609 }
509610
@@ -517,4 +618,20 @@ impl<E: LayoutEngine> AsCopyTarget<'_, E> {
517618 pub fn read_from_ref ( & mut self , buffer : ImageRef < ' _ , impl Layout > ) {
518619 self . engine_from_buf_at ( buffer. as_buf ( ) , 0 ) ;
519620 }
621+
622+ /// Read out data from a borrowed buffer.
623+ ///
624+ /// This reads data up to our layout. It does not interpret the data with the layout of
625+ /// the argument buffer.
626+ pub fn read_from_cell_ref ( & mut self , buffer : CellImageRef < ' _ , impl Layout > ) {
627+ self . engine_from_buf_at ( buffer. as_cell_buf ( ) , 0 ) ;
628+ }
629+
630+ /// Read out data from a borrowed buffer.
631+ ///
632+ /// This reads data up to our layout. It does not interpret the data with the layout of
633+ /// the argument buffer.
634+ pub fn read_from_atomic_ref ( & mut self , buffer : CellImageRef < ' _ , impl Layout > ) {
635+ self . engine_from_buf_at ( buffer. as_cell_buf ( ) , 0 ) ;
636+ }
520637}
0 commit comments