1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
use std::mem::size_of; use crate::internal::align_offset; use crate::std140::{AsStd140, Std140}; /** Type that computes the buffer size needed by a series of `std140` types laid out. This type works well well when paired with `Writer`, precomputing a buffer's size to alleviate the need to dynamically re-allocate buffers. ## Example ```glsl struct Frob { vec3 size; float frobiness; } buffer FROBS { uint len; Frob[] frobs; } frobs; ``` ``` use crevice::std140::{self, AsStd140}; #[derive(AsStd140)] struct Frob { size: mint::Vector3<f32>, frobiness: f32, } // Many APIs require that buffers contain at least enough space for all // fixed-size bindiongs to a buffer as well as one element of any arrays, if // there are any. let mut sizer = std140::Sizer::new(); sizer.add::<u32>(); sizer.add::<Frob>(); # fn create_buffer_with_size(size: usize) {} let buffer = create_buffer_with_size(sizer.len()); # assert_eq!(sizer.len(), 32); ``` */ pub struct Sizer { offset: usize, } impl Sizer { /// Create a new `Sizer`. pub fn new() -> Self { Self { offset: 0 } } /// Add a type's necessary padding and size to the `Sizer`. Returns the /// offset into the buffer where that type would be written. pub fn add<T>(&mut self) -> usize where T: AsStd140, { let size = size_of::<<T as AsStd140>::Std140Type>(); let alignment = <T as AsStd140>::Std140Type::ALIGNMENT; let padding = align_offset(self.offset, alignment); self.offset += padding; let write_here = self.offset; self.offset += size; write_here } /// Returns the number of bytes required to contain all the types added to /// the `Sizer`. pub fn len(&self) -> usize { self.offset } }