1mod sealed {
51 use crate::buf::{atomic_buf, buf, cell_buf};
52 use crate::layout::Layout;
53 use core::ops::Range;
54
55 pub trait LayoutEngineCore {
56 type Layout: Layout;
57
58 fn consume_layout(&mut self) -> Self::Layout;
59
60 fn buffer_ranges(&self) -> impl Iterator<Item = Range<usize>>;
62
63 fn image_offset(&self) -> usize;
67 }
68
69 pub trait Loadable {
70 fn load_from_buf(&mut self, buffer: &buf, what: Range<usize>, at: usize);
71 fn load_from_cell(&mut self, buffer: &cell_buf, what: Range<usize>, at: usize);
72 fn load_from_atomic(&mut self, buffer: &atomic_buf, what: Range<usize>, at: usize);
73 }
74
75 pub trait Storable {
76 fn store_to_buf(&self, buffer: &mut buf, what: Range<usize>, at: usize);
77 fn store_to_cell(&self, buffer: &cell_buf, what: Range<usize>, at: usize);
78 fn store_to_atomic(&self, buffer: &atomic_buf, what: Range<usize>, at: usize);
79 }
80
81 pub(crate) trait LoadSource {
83 fn load(&mut self, into: &mut dyn Loadable, what: Range<usize>, at: usize);
84 }
85
86 pub(crate) trait StoreTarget {
88 fn store(&mut self, into: &dyn Storable, what: Range<usize>, at: usize);
89 }
90
91 impl LoadSource for &'_ buf {
92 fn load(&mut self, into: &mut dyn Loadable, what: Range<usize>, at: usize) {
93 into.load_from_buf(self, what, at)
94 }
95 }
96
97 impl LoadSource for &'_ cell_buf {
98 fn load(&mut self, into: &mut dyn Loadable, what: Range<usize>, at: usize) {
99 into.load_from_cell(self, what, at)
100 }
101 }
102
103 impl LoadSource for &'_ atomic_buf {
104 fn load(&mut self, into: &mut dyn Loadable, what: Range<usize>, at: usize) {
105 into.load_from_atomic(self, what, at)
106 }
107 }
108
109 impl StoreTarget for &'_ mut buf {
110 fn store(&mut self, into: &dyn Storable, what: Range<usize>, at: usize) {
111 into.store_to_buf(self, what, at)
112 }
113 }
114
115 impl StoreTarget for &'_ cell_buf {
116 fn store(&mut self, into: &dyn Storable, what: Range<usize>, at: usize) {
117 into.store_to_cell(self, what, at)
118 }
119 }
120
121 impl StoreTarget for &'_ atomic_buf {
122 fn store(&mut self, into: &dyn Storable, what: Range<usize>, at: usize) {
123 into.store_to_atomic(self, what, at)
124 }
125 }
126}
127
128use core::{cell::Cell, ops::Range};
129use sealed::{Loadable, Storable};
130
131use crate::buf::{atomic_buf, buf, cell_buf, AtomicBuffer, Buffer, CellBuffer};
132use crate::image::{
133 AtomicImage, AtomicImageRef, CellImage, CellImageRef, Image, ImageMut, ImageRef,
134};
135use crate::layout::{AlignedOffset, Bytes, Layout, Relocated};
136use crate::{texels, BufferReuseError};
137
138pub struct DataRef<'lt, Layout = Bytes> {
140 data: &'lt [u8],
141 layout: Layout,
142 offset: usize,
143}
144
145pub struct DataMut<'lt, Layout = Bytes> {
147 data: &'lt mut [u8],
148 layout: Layout,
149 offset: usize,
150}
151
152pub struct DataCells<'lt, Layout = Bytes> {
154 data: &'lt [Cell<u8>],
155 layout: Layout,
156 offset: usize,
157}
158
159pub struct AsCopySource<'lt, E> {
166 inner: &'lt dyn Storable,
167 engine: E,
168}
169
170pub struct AsCopyTarget<'lt, E> {
177 inner: &'lt mut dyn Loadable,
178 engine: E,
179}
180
181pub trait LayoutEngine: sealed::LayoutEngineCore {}
185
186impl<'lt> DataRef<'lt, Bytes> {
187 pub fn new(data: &'lt [u8]) -> Self {
189 DataRef {
190 data,
191 layout: Bytes(core::mem::size_of_val(data)),
192 offset: 0,
193 }
194 }
195}
196
197impl<'lt, L> DataRef<'lt, L> {
198 pub fn with_layout_at(data: &'lt [u8], layout: L, start: usize) -> Option<Self>
203 where
204 L: Layout,
205 {
206 Some(data)
207 .filter(|data| {
208 if let Some(partial) = data.get(start..) {
209 <dyn Layout>::fits_data(&layout, partial)
210 } else {
211 false
212 }
213 })
214 .map(|data| DataRef {
215 data,
216 layout,
217 offset: Default::default(),
218 })
219 }
220
221 pub fn as_source(&self) -> AsCopySource<'_, RangeEngine<L>>
225 where
226 L: Clone + Layout,
227 {
228 AsCopySource {
229 inner: &self.data,
230 engine: RangeEngine::new(&self.layout, self.offset),
231 }
232 }
233}
234
235impl Storable for &'_ [u8] {
236 #[track_caller]
237 fn store_to_buf(&self, buffer: &mut buf, what: Range<usize>, into: usize) {
238 let len = what.len();
239 let target = &mut buffer.as_bytes_mut()[into..][..len];
240 let source = &self[what.start..what.end];
241 target.copy_from_slice(source);
242 }
243
244 fn store_to_cell(&self, buffer: &cell_buf, what: Range<usize>, into: usize) {
245 let len = what.len();
246 let target = &buffer.as_texels(texels::U8).as_slice_of_cells()[into..][..len];
247 let source = &self[what.start..what.end];
248 texels::U8.store_cell_slice(target, source);
249 }
250
251 fn store_to_atomic(&self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
252 let len = what.len();
253 let target = buffer.index(texels::U8.to_range(into..into + len).unwrap());
254 let source = &self[what.start..what.end];
255 texels::U8.store_atomic_slice(target, source);
256 }
257}
258
259impl<'lt> DataMut<'lt, Bytes> {
260 pub fn new(data: &'lt mut [u8]) -> Self {
262 DataMut {
263 layout: Bytes(core::mem::size_of_val(data)),
264 data,
265 offset: 0,
266 }
267 }
268}
269
270impl<'lt, L> DataMut<'lt, L> {
271 pub fn with_layout_at(data: &'lt mut [u8], layout: L, start: usize) -> Option<Self>
276 where
277 L: Layout,
278 {
279 Some(data)
280 .filter(|data| {
281 if let Some(partial) = data.get(start..) {
282 <dyn Layout>::fits_data(&layout, partial)
283 } else {
284 false
285 }
286 })
287 .map(|data| DataMut {
288 data,
289 layout,
290 offset: start,
291 })
292 }
293
294 pub fn as_source(&self) -> AsCopySource<'_, RangeEngine<L>>
298 where
299 L: Clone + Layout,
300 {
301 AsCopySource {
302 inner: &self.data,
303 engine: RangeEngine::new(&self.layout, self.offset),
304 }
305 }
306
307 pub fn as_target(&mut self) -> AsCopyTarget<'_, RangeEngine<L>>
311 where
312 L: Clone + Layout,
313 {
314 AsCopyTarget {
315 inner: &mut self.data,
316 engine: RangeEngine::new(&self.layout, self.offset),
317 }
318 }
319}
320
321impl Storable for &'_ mut [u8] {
322 #[track_caller]
323 fn store_to_buf(&self, buffer: &mut buf, what: Range<usize>, into: usize) {
324 let len = what.len();
325 let target = &mut buffer.as_bytes_mut()[into..][..len];
326 let source = &self[what.start..what.end];
327 target.copy_from_slice(source);
328 }
329
330 fn store_to_cell(&self, buffer: &cell_buf, what: Range<usize>, into: usize) {
331 let len = what.len();
332 let source = &buffer.as_texels(texels::U8).as_slice_of_cells()[into..][..len];
333 let target = &self[what.start..what.end];
334 texels::U8.store_cell_slice(source, target);
335 }
336
337 fn store_to_atomic(&self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
338 let len = what.len();
339 let target = buffer.index(texels::U8.to_range(into..into + len).unwrap());
340 let source = &self[what.start..what.end];
341 texels::U8.store_atomic_slice(target, source);
342 }
343}
344
345impl Loadable for &'_ mut [u8] {
346 #[track_caller]
347 fn load_from_buf(&mut self, buffer: &buf, what: Range<usize>, into: usize) {
348 let len = what.len();
349 let source = &buffer.as_bytes()[into..][..len];
350 let target = &mut self[what.start..what.end];
351 target.copy_from_slice(source);
352 }
353
354 fn load_from_cell(&mut self, buffer: &cell_buf, what: Range<usize>, into: usize) {
355 let len = what.len();
356 let source = &buffer.as_texels(texels::U8).as_slice_of_cells()[into..][..len];
357 let target = &mut self[what.start..what.end];
358 texels::U8.load_cell_slice(source, target);
359 }
360
361 fn load_from_atomic(&mut self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
362 let len = what.len();
363 let source = buffer.index(texels::U8.to_range(into..into + len).unwrap());
364 let target = &mut self[what.start..what.end];
365 texels::U8.load_atomic_slice(source, target);
366 }
367}
368
369impl<'lt> DataCells<'lt, Bytes> {
370 pub fn new(data: &'lt [Cell<u8>]) -> Self {
372 DataCells {
373 layout: Bytes(core::mem::size_of_val(data)),
374 data,
375 offset: 0,
376 }
377 }
378}
379
380impl<'lt, L> DataCells<'lt, L> {
381 pub fn with_layout_at(data: &'lt [Cell<u8>], layout: L, start: usize) -> Option<Self>
386 where
387 L: Layout,
388 {
389 Some(data)
390 .filter(|data| {
391 if let Some(partial) = data.get(start..) {
392 <dyn Layout>::fits_data(&layout, partial)
393 } else {
394 false
395 }
396 })
397 .map(|data| DataCells {
398 data,
399 layout,
400 offset: Default::default(),
401 })
402 }
403
404 pub fn as_source(&self) -> AsCopySource<'_, RangeEngine<L>>
408 where
409 L: Clone + Layout,
410 {
411 AsCopySource {
412 inner: &self.data,
413 engine: RangeEngine::new(&self.layout, self.offset),
414 }
415 }
416
417 pub fn as_target(&mut self) -> AsCopyTarget<'_, RangeEngine<L>>
421 where
422 L: Clone + Layout,
423 {
424 AsCopyTarget {
425 inner: &mut self.data,
426 engine: RangeEngine::new(&self.layout, self.offset),
427 }
428 }
429}
430
431impl Storable for &'_ [Cell<u8>] {
432 #[track_caller]
433 fn store_to_buf(&self, buffer: &mut buf, what: Range<usize>, into: usize) {
434 let len = what.len();
435 let target = &mut buffer.as_bytes_mut()[into..][..len];
436 let source = &self[what.start..what.end];
437 crate::texels::U8.load_cell_slice(source, target);
438 }
439
440 #[track_caller]
441 fn store_to_cell(&self, buffer: &cell_buf, what: Range<usize>, into: usize) {
442 let len = what.len();
443 let source = &buffer.as_texels(texels::U8).as_slice_of_cells()[into..][..len];
444 let target = &self[what.start..what.end];
445 texels::U8.cell_memory_copy(source, target);
446 }
447
448 #[track_caller]
449 fn store_to_atomic(&self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
450 let len = what.len();
451 let target = buffer.index(texels::U8.to_range(into..into + len).unwrap());
452 let source = &self[what.start..what.end];
453 texels::U8.store_atomic_from_cells(target, source);
454 }
455}
456
457impl Loadable for &'_ [Cell<u8>] {
458 #[track_caller]
459 fn load_from_buf(&mut self, buffer: &buf, what: Range<usize>, into: usize) {
460 let len = what.len();
461 let source = &buffer.as_bytes()[into..][..len];
462 let target = &self[what.start..what.end];
463 texels::U8.store_cell_slice(target, source);
464 }
465
466 fn load_from_cell(&mut self, buffer: &cell_buf, what: Range<usize>, into: usize) {
467 let len = what.len();
468 let source = &buffer.as_texels(texels::U8).as_slice_of_cells()[into..][..len];
469 let target = &self[what.start..what.end];
470 texels::U8.cell_memory_copy(source, target);
471 }
472
473 fn load_from_atomic(&mut self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
474 let len = what.len();
475 let source = buffer.index(texels::U8.to_range(into..into + len).unwrap());
476 let target = &self[what.start..what.end];
477 texels::U8.load_atomic_to_cells(source, target);
478 }
479}
480
481impl<'buf, E: LayoutEngine> AsCopySource<'buf, E> {
482 pub fn and_relocated(self, offset: AlignedOffset) -> AsCopySource<'buf, RelocateEngine<E>>
484 where
485 E::Layout: Clone,
486 {
487 AsCopySource {
488 inner: self.inner,
489 engine: RelocateEngine {
490 inner: self.engine,
491 offset,
492 },
493 }
494 }
495}
496
497impl<E: LayoutEngine> AsCopySource<'_, E> {
498 fn engine_to_buf_at(&self, buffer: impl sealed::StoreTarget) {
499 #[inline(never)]
503 fn ranges_to_buf_at(
504 ranges: impl Iterator<Item = Range<usize>>,
505 store: &dyn Storable,
506 mut buffer: impl sealed::StoreTarget,
507 offset: usize,
508 ) {
509 for range in ranges {
510 buffer.store(store, range, offset)
511 }
512 }
513
514 ranges_to_buf_at(
515 self.engine.buffer_ranges(),
516 self.inner,
517 buffer,
518 self.engine.image_offset(),
519 );
520 }
521
522 pub fn write_to_image(mut self, buffer: Image<Bytes>) -> Image<E::Layout> {
527 let mut buffer = buffer.with_layout(self.engine.consume_layout());
528 self.engine_to_buf_at(buffer.as_capacity_buf_mut());
529 buffer
530 }
531
532 pub fn write_to_mut<'data>(
537 mut self,
538 buffer: ImageMut<'data, Bytes>,
539 ) -> Option<ImageMut<'data, E::Layout>> {
540 let mut buffer = buffer.with_layout(self.engine.consume_layout())?;
541 self.engine_to_buf_at(buffer.as_mut_buf());
542 Some(buffer)
543 }
544
545 pub fn write_to_cell_image(mut self, buffer: CellImage<Bytes>) -> Option<CellImage<E::Layout>>
549 where
550 E::Layout: Clone + Layout,
551 {
552 let buffer = buffer.try_with_layout(self.engine.consume_layout()).ok()?;
553 self.engine_to_buf_at(buffer.as_capacity_cell_buf());
554 Some(buffer)
555 }
556
557 pub fn write_to_cell_ref<'data>(
562 mut self,
563 buffer: CellImageRef<'data, Bytes>,
564 ) -> Option<CellImageRef<'data, E::Layout>> {
565 let buffer = buffer.checked_with_layout(self.engine.consume_layout())?;
566 self.engine_to_buf_at(buffer.as_cell_buf());
567 Some(buffer)
568 }
569
570 pub fn write_to_atomic_image(
574 mut self,
575 buffer: AtomicImage<Bytes>,
576 ) -> Option<AtomicImage<E::Layout>>
577 where
578 E::Layout: Clone + Layout,
579 {
580 let buffer = buffer.try_with_layout(self.engine.consume_layout()).ok()?;
581 self.engine_to_buf_at(buffer.as_capacity_atomic_buf());
582 Some(buffer)
583 }
584
585 pub fn write_to_atomic_ref<'data>(
590 mut self,
591 buffer: AtomicImageRef<'data, Bytes>,
592 ) -> Option<AtomicImageRef<'data, E::Layout>>
593 where
594 E::Layout: Clone + Layout,
595 {
596 let buffer = buffer.checked_with_layout(self.engine.consume_layout())?;
597 self.engine_to_buf_at(buffer.as_capacity_atomic_buf());
598 Some(buffer)
599 }
600}
601
602impl Storable for Buffer {
603 #[track_caller]
604 fn store_to_buf(&self, buffer: &mut buf, what: Range<usize>, into: usize) {
605 <&'_ [u8]>::store_to_buf(&self.as_bytes(), buffer, what, into)
606 }
607
608 #[track_caller]
609 fn store_to_cell(&self, buffer: &cell_buf, what: Range<usize>, into: usize) {
610 <&'_ [u8]>::store_to_cell(&self.as_bytes(), buffer, what, into)
611 }
612
613 #[track_caller]
614 fn store_to_atomic(&self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
615 <&'_ [u8]>::store_to_atomic(&self.as_bytes(), buffer, what, into)
616 }
617}
618
619impl Loadable for Buffer {
620 #[track_caller]
621 fn load_from_buf(&mut self, buffer: &buf, what: Range<usize>, into: usize) {
622 <&'_ mut [u8]>::load_from_buf(&mut self.as_bytes_mut(), buffer, what, into)
623 }
624
625 fn load_from_cell(&mut self, buffer: &cell_buf, what: Range<usize>, into: usize) {
626 <&'_ mut [u8]>::load_from_cell(&mut self.as_bytes_mut(), buffer, what, into)
627 }
628
629 fn load_from_atomic(&mut self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
630 <&'_ mut [u8]>::load_from_atomic(&mut self.as_bytes_mut(), buffer, what, into)
631 }
632}
633
634impl<L> Image<L> {
635 pub fn assign<E>(&mut self, mut data: AsCopySource<'_, E>)
645 where
646 E: LayoutEngine<Layout = L>,
647 L: Layout,
648 {
649 let layout = data.engine.consume_layout();
650 *self.layout_mut_unguarded() = layout;
651 self.ensure_layout();
652 data.engine_to_buf_at(self.as_capacity_buf_mut());
653 }
654
655 pub fn as_source(&self) -> AsCopySource<'_, RangeEngine<L>>
659 where
660 L: Clone + Layout,
661 {
662 AsCopySource {
663 inner: self.inner.get(),
664 engine: RangeEngine::new(self.layout(), 0),
665 }
666 }
667
668 pub fn as_target(&mut self) -> AsCopyTarget<'_, RangeEngine<L>>
672 where
673 L: Clone + Layout,
674 {
675 AsCopyTarget {
676 engine: RangeEngine::new(self.layout(), 0),
677 inner: self.inner.get_mut(),
678 }
679 }
680}
681
682impl Storable for &'_ buf {
683 #[track_caller]
684 fn store_to_buf(&self, buffer: &mut buf, what: Range<usize>, into: usize) {
685 <&'_ [u8]>::store_to_buf(&self.as_bytes(), buffer, what, into)
686 }
687
688 #[track_caller]
689 fn store_to_cell(&self, buffer: &cell_buf, what: Range<usize>, into: usize) {
690 <&'_ [u8]>::store_to_cell(&self.as_bytes(), buffer, what, into)
691 }
692
693 #[track_caller]
694 fn store_to_atomic(&self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
695 <&'_ [u8]>::store_to_atomic(&self.as_bytes(), buffer, what, into)
696 }
697}
698
699impl Storable for &'_ mut buf {
700 #[track_caller]
701 fn store_to_buf(&self, buffer: &mut buf, what: Range<usize>, into: usize) {
702 <&'_ [u8]>::store_to_buf(&self.as_bytes(), buffer, what, into)
703 }
704
705 #[track_caller]
706 fn store_to_cell(&self, buffer: &cell_buf, what: Range<usize>, into: usize) {
707 <&'_ [u8]>::store_to_cell(&self.as_bytes(), buffer, what, into)
708 }
709
710 #[track_caller]
711 fn store_to_atomic(&self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
712 <&'_ [u8]>::store_to_atomic(&self.as_bytes(), buffer, what, into)
713 }
714}
715
716impl Loadable for &'_ mut buf {
717 #[track_caller]
718 fn load_from_buf(&mut self, buffer: &buf, what: Range<usize>, into: usize) {
719 <&'_ mut [u8]>::load_from_buf(&mut self.as_bytes_mut(), buffer, what, into)
720 }
721
722 fn load_from_cell(&mut self, buffer: &cell_buf, what: Range<usize>, into: usize) {
723 <&'_ mut [u8]>::load_from_cell(&mut self.as_bytes_mut(), buffer, what, into)
724 }
725
726 fn load_from_atomic(&mut self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
727 <&'_ mut [u8]>::load_from_atomic(&mut self.as_bytes_mut(), buffer, what, into)
728 }
729}
730
731impl<L> ImageMut<'_, L> {
732 pub fn assign<E>(&mut self, mut data: AsCopySource<'_, E>) -> Result<(), BufferReuseError>
740 where
741 E: LayoutEngine<Layout = L>,
742 L: Layout,
743 {
744 let layout = data.engine.consume_layout();
745 self.try_set_layout(layout)?;
746 data.engine_to_buf_at(self.as_capacity_buf_mut());
747 Ok(())
748 }
749
750 pub fn as_source(&self) -> AsCopySource<'_, RangeEngine<L>>
754 where
755 L: Clone + Layout,
756 {
757 AsCopySource {
758 inner: self.inner.get(),
759 engine: RangeEngine::new(self.layout(), 0),
760 }
761 }
762
763 pub fn as_target(&mut self) -> AsCopyTarget<'_, RangeEngine<L>>
767 where
768 L: Clone + Layout,
769 {
770 AsCopyTarget {
771 engine: RangeEngine::new(self.layout(), 0),
772 inner: self.inner.get_mut(),
773 }
774 }
775}
776
777impl<L> ImageRef<'_, L> {
778 pub fn as_source(&self) -> AsCopySource<'_, RangeEngine<L>>
782 where
783 L: Clone + Layout,
784 {
785 AsCopySource {
786 inner: self.inner.get(),
787 engine: RangeEngine::new(self.layout(), 0),
788 }
789 }
790}
791
792impl Storable for CellBuffer {
793 #[track_caller]
794 fn store_to_buf(&self, buffer: &mut buf, what: Range<usize>, into: usize) {
795 <&'_ cell_buf>::store_to_buf(&&**self, buffer, what, into)
796 }
797
798 #[track_caller]
799 fn store_to_cell(&self, buffer: &cell_buf, what: Range<usize>, into: usize) {
800 <&'_ cell_buf>::store_to_cell(&&**self, buffer, what, into)
801 }
802
803 #[track_caller]
804 fn store_to_atomic(&self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
805 <&'_ cell_buf>::store_to_atomic(&&**self, buffer, what, into)
806 }
807}
808
809impl Loadable for CellBuffer {
810 #[track_caller]
811 fn load_from_buf(&mut self, buffer: &buf, what: Range<usize>, into: usize) {
812 <&'_ cell_buf>::load_from_buf(&mut &**self, buffer, what, into)
813 }
814
815 fn load_from_cell(&mut self, buffer: &cell_buf, what: Range<usize>, into: usize) {
816 <&'_ cell_buf>::load_from_cell(&mut &**self, buffer, what, into)
817 }
818
819 fn load_from_atomic(&mut self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
820 <&'_ cell_buf>::load_from_atomic(&mut &**self, buffer, what, into)
821 }
822}
823
824impl<L> CellImage<L> {
825 pub fn assign<E>(&mut self, mut data: AsCopySource<'_, E>) -> Result<(), BufferReuseError>
835 where
836 E: LayoutEngine<Layout = L>,
837 L: Layout,
838 {
839 let layout = data.engine.consume_layout();
840 self.try_set_layout(layout)?;
841 data.engine_to_buf_at(self.as_capacity_cell_buf());
842 Ok(())
843 }
844
845 pub fn as_source(&self) -> AsCopySource<'_, RangeEngine<L>>
849 where
850 L: Clone + Layout,
851 {
852 AsCopySource {
853 inner: self.inner.get(),
854 engine: RangeEngine::new(self.layout(), 0),
855 }
856 }
857
858 pub fn as_target(&mut self) -> AsCopyTarget<'_, RangeEngine<L>>
862 where
863 L: Clone + Layout,
864 {
865 AsCopyTarget {
866 engine: RangeEngine::new(self.layout(), 0),
867 inner: self.inner.get_mut(),
868 }
869 }
870}
871
872impl Storable for &'_ cell_buf {
873 #[track_caller]
874 fn store_to_buf(&self, buffer: &mut buf, what: Range<usize>, into: usize) {
875 let inner = self.as_texels(texels::U8).as_slice_of_cells();
876 <&'_ [Cell<u8>]>::store_to_buf(&inner, buffer, what, into)
877 }
878
879 #[track_caller]
880 fn store_to_cell(&self, buffer: &cell_buf, what: Range<usize>, into: usize) {
881 let inner = self.as_texels(texels::U8).as_slice_of_cells();
882 <&'_ [Cell<u8>]>::store_to_cell(&inner, buffer, what, into)
883 }
884
885 #[track_caller]
886 fn store_to_atomic(&self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
887 let inner = self.as_texels(texels::U8).as_slice_of_cells();
888 <&'_ [Cell<u8>]>::store_to_atomic(&inner, buffer, what, into)
889 }
890}
891
892impl Loadable for &'_ cell_buf {
893 #[track_caller]
894 fn load_from_buf(&mut self, buffer: &buf, what: Range<usize>, into: usize) {
895 let mut inner = self.as_texels(texels::U8).as_slice_of_cells();
896 <&'_ [Cell<u8>]>::load_from_buf(&mut inner, buffer, what, into)
897 }
898
899 fn load_from_cell(&mut self, buffer: &cell_buf, what: Range<usize>, into: usize) {
900 let mut inner = self.as_texels(texels::U8).as_slice_of_cells();
901 <&'_ [Cell<u8>]>::load_from_cell(&mut inner, buffer, what, into)
902 }
903
904 fn load_from_atomic(&mut self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
905 let mut inner = self.as_texels(texels::U8).as_slice_of_cells();
906 <&'_ [Cell<u8>]>::load_from_atomic(&mut inner, buffer, what, into)
907 }
908}
909
910impl<L> CellImageRef<'_, L> {
911 pub fn assign<E>(&mut self, mut data: AsCopySource<'_, E>) -> Result<(), BufferReuseError>
919 where
920 E: LayoutEngine<Layout = L>,
921 L: Layout,
922 {
923 let layout = data.engine.consume_layout();
924 self.try_set_layout(layout)?;
925 data.engine_to_buf_at(self.as_capacity_cell_buf());
926 Ok(())
927 }
928
929 pub fn as_source(&self) -> AsCopySource<'_, RangeEngine<L>>
933 where
934 L: Clone + Layout,
935 {
936 AsCopySource {
937 inner: self.inner.get(),
938 engine: RangeEngine::new(self.layout(), 0),
939 }
940 }
941
942 pub fn as_target(&mut self) -> AsCopyTarget<'_, RangeEngine<L>>
946 where
947 L: Clone + Layout,
948 {
949 AsCopyTarget {
950 engine: RangeEngine::new(self.layout(), 0),
951 inner: self.inner.get_mut(),
952 }
953 }
954}
955
956impl Storable for AtomicBuffer {
957 #[track_caller]
958 fn store_to_buf(&self, buffer: &mut buf, what: Range<usize>, into: usize) {
959 <&'_ atomic_buf>::store_to_buf(&&**self, buffer, what, into)
960 }
961
962 #[track_caller]
963 fn store_to_cell(&self, buffer: &cell_buf, what: Range<usize>, into: usize) {
964 <&'_ atomic_buf>::store_to_cell(&&**self, buffer, what, into)
965 }
966
967 #[track_caller]
968 fn store_to_atomic(&self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
969 <&'_ atomic_buf>::store_to_atomic(&&**self, buffer, what, into)
970 }
971}
972
973impl Loadable for AtomicBuffer {
974 #[track_caller]
975 fn load_from_buf(&mut self, buffer: &buf, what: Range<usize>, into: usize) {
976 <&'_ atomic_buf>::load_from_buf(&mut &**self, buffer, what, into)
977 }
978
979 fn load_from_cell(&mut self, buffer: &cell_buf, what: Range<usize>, into: usize) {
980 <&'_ atomic_buf>::load_from_cell(&mut &**self, buffer, what, into)
981 }
982
983 fn load_from_atomic(&mut self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
984 <&'_ atomic_buf>::load_from_atomic(&mut &**self, buffer, what, into)
985 }
986}
987
988impl<L> AtomicImage<L> {
989 pub fn assign<E>(&mut self, mut data: AsCopySource<'_, E>) -> Result<(), BufferReuseError>
999 where
1000 E: LayoutEngine<Layout = L>,
1001 L: Layout,
1002 {
1003 let layout = data.engine.consume_layout();
1004 self.try_set_layout(layout)?;
1005 data.engine_to_buf_at(self.as_capacity_atomic_buf());
1006 Ok(())
1007 }
1008
1009 pub fn as_source(&self) -> AsCopySource<'_, RangeEngine<L>>
1013 where
1014 L: Clone + Layout,
1015 {
1016 AsCopySource {
1017 inner: self.inner.get(),
1018 engine: RangeEngine::new(self.layout(), 0),
1019 }
1020 }
1021
1022 pub fn as_target(&mut self) -> AsCopyTarget<'_, RangeEngine<L>>
1026 where
1027 L: Clone + Layout,
1028 {
1029 AsCopyTarget {
1030 engine: RangeEngine::new(self.layout(), 0),
1031 inner: self.inner.get_mut(),
1032 }
1033 }
1034}
1035
1036impl Storable for &'_ atomic_buf {
1037 #[track_caller]
1038 fn store_to_buf(&self, buffer: &mut buf, what: Range<usize>, into: usize) {
1039 let len = what.len();
1040 let target = &mut buffer.as_bytes_mut()[into..][..len];
1041 let source = self.index(texels::U8.to_range(what).unwrap());
1042 texels::U8.load_atomic_slice(source, target);
1043 }
1044
1045 #[track_caller]
1046 fn store_to_cell(&self, buffer: &cell_buf, what: Range<usize>, into: usize) {
1047 let len = what.len();
1048 let target = &buffer.as_texels(texels::U8).as_slice_of_cells()[into..][..len];
1049 let source = self.index(texels::U8.to_range(what).unwrap());
1050 texels::U8.load_atomic_to_cells(source, target);
1051 }
1052
1053 #[track_caller]
1054 fn store_to_atomic(&self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
1055 let len = what.len();
1056 let target = buffer.index(texels::U8.to_range(into..into + len).unwrap());
1057 let source = self.index(texels::U8.to_range(what).unwrap());
1058 texels::U8.atomic_memory_move(source, target);
1059 }
1060}
1061
1062impl Loadable for &'_ atomic_buf {
1063 #[track_caller]
1064 fn load_from_buf(&mut self, buffer: &buf, what: Range<usize>, into: usize) {
1065 let len = what.len();
1066 let source = &buffer.as_bytes()[into..][..len];
1067 let target = self.index(texels::U8.to_range(what).unwrap());
1068 texels::U8.store_atomic_slice(target, source);
1069 }
1070
1071 fn load_from_cell(&mut self, buffer: &cell_buf, what: Range<usize>, into: usize) {
1072 let len = what.len();
1073 let source = &buffer.as_texels(texels::U8).as_slice_of_cells()[into..][..len];
1074 let target = self.index(texels::U8.to_range(what).unwrap());
1075 texels::U8.store_atomic_from_cells(target, source);
1076 }
1077
1078 fn load_from_atomic(&mut self, buffer: &atomic_buf, what: Range<usize>, into: usize) {
1079 let len = what.len();
1080 let source = buffer.index(texels::U8.to_range(into..into + len).unwrap());
1081 let target = self.index(texels::U8.to_range(what).unwrap());
1082 texels::U8.atomic_memory_move(source, target);
1083 }
1084}
1085
1086impl<L> AtomicImageRef<'_, L> {
1087 pub fn assign<E>(&mut self, mut data: AsCopySource<'_, E>) -> Result<(), BufferReuseError>
1095 where
1096 E: LayoutEngine<Layout = L>,
1097 L: Layout,
1098 {
1099 let layout = data.engine.consume_layout();
1100 self.try_set_layout(layout)?;
1101 data.engine_to_buf_at(self.as_capacity_atomic_buf());
1102 Ok(())
1103 }
1104
1105 pub fn as_source(&self) -> AsCopySource<'_, RangeEngine<L>>
1109 where
1110 L: Clone + Layout,
1111 {
1112 AsCopySource {
1113 inner: self.inner.get(),
1114 engine: RangeEngine::new(self.layout(), 0),
1115 }
1116 }
1117
1118 pub fn as_target(&mut self) -> AsCopyTarget<'_, RangeEngine<L>>
1122 where
1123 L: Clone + Layout,
1124 {
1125 AsCopyTarget {
1126 engine: RangeEngine::new(self.layout(), 0),
1127 inner: self.inner.get_mut(),
1128 }
1129 }
1130}
1131
1132impl<E: LayoutEngine> AsCopyTarget<'_, E> {
1133 fn engine_from_buf_at(&mut self, buffer: impl sealed::LoadSource) {
1134 #[inline(never)]
1138 fn ranges_from_buf_at(
1139 ranges: impl Iterator<Item = Range<usize>>,
1140 store: &mut dyn Loadable,
1141 mut buffer: impl sealed::LoadSource,
1142 offset: usize,
1143 ) {
1144 for range in ranges {
1145 buffer.load(store, range, offset)
1146 }
1147 }
1148
1149 ranges_from_buf_at(
1150 self.engine.buffer_ranges(),
1151 self.inner,
1152 buffer,
1153 self.engine.image_offset(),
1154 );
1155 }
1156
1157 pub fn read_from_ref(&mut self, buffer: ImageRef<'_, Bytes>) {
1162 self.engine_from_buf_at(buffer.as_buf());
1163 }
1164
1165 pub fn read_from_cell_ref(&mut self, buffer: CellImageRef<'_, Bytes>) {
1170 self.engine_from_buf_at(buffer.as_cell_buf());
1171 }
1172
1173 pub fn read_from_atomic_ref(&mut self, buffer: CellImageRef<'_, Bytes>) {
1178 self.engine_from_buf_at(buffer.as_cell_buf());
1179 }
1180}
1181
1182pub struct RangeEngine<L> {
1188 inner: Option<L>,
1189 bytes: [Range<usize>; 1],
1190}
1191
1192pub struct RelocateEngine<Inner: sealed::LayoutEngineCore> {
1194 inner: Inner,
1195 offset: AlignedOffset,
1196}
1197
1198impl<L: Layout> LayoutEngine for RangeEngine<L> {}
1199
1200impl<L: Layout> RangeEngine<L> {
1201 fn new(layout: &L, offset: usize) -> Self
1202 where
1203 L: Clone,
1204 {
1205 let byte_len = layout.byte_len();
1206 let bytes = [offset..offset + byte_len];
1207
1208 RangeEngine {
1209 inner: Some(layout.clone()),
1210 bytes,
1211 }
1212 }
1213}
1214
1215impl<L: Layout> sealed::LayoutEngineCore for RangeEngine<L> {
1216 type Layout = L;
1217
1218 fn consume_layout(&mut self) -> L {
1219 self.inner
1220 .take()
1221 .expect("Protocol error, layout polled twice")
1222 }
1223
1224 #[allow(refining_impl_trait)]
1228 fn buffer_ranges(&self) -> core::iter::Cloned<core::slice::Iter<'_, Range<usize>>> {
1229 (&self.bytes[..]).iter().cloned()
1230 }
1231
1232 fn image_offset(&self) -> usize {
1233 0
1234 }
1235}
1236
1237impl<I: sealed::LayoutEngineCore> LayoutEngine for RelocateEngine<I> {}
1238
1239impl<I: sealed::LayoutEngineCore> sealed::LayoutEngineCore for RelocateEngine<I> {
1240 type Layout = Relocated<I::Layout>;
1241
1242 fn consume_layout(&mut self) -> Self::Layout {
1243 Relocated {
1244 inner: self.inner.consume_layout(),
1245 offset: self.offset,
1246 }
1247 }
1248
1249 fn buffer_ranges(&self) -> impl Iterator<Item = Range<usize>> {
1250 self.inner.buffer_ranges()
1251 }
1252
1253 fn image_offset(&self) -> usize {
1254 self.inner.image_offset() + self.offset.get()
1255 }
1256}