diff options
Diffstat (limited to '')
| -rw-r--r-- | wgpu/src/texture/atlas.rs | 52 | ||||
| -rw-r--r-- | wgpu/src/texture/atlas/allocator.rs | 61 | 
2 files changed, 78 insertions, 35 deletions
diff --git a/wgpu/src/texture/atlas.rs b/wgpu/src/texture/atlas.rs index bf528dc9..3d4e81c1 100644 --- a/wgpu/src/texture/atlas.rs +++ b/wgpu/src/texture/atlas.rs @@ -10,7 +10,7 @@ pub use layer::Layer;  use allocator::Allocator; -pub const SIZE: u32 = 4096; +pub const SIZE: u32 = 2048;  #[derive(Debug)]  pub struct Atlas { @@ -78,24 +78,33 @@ impl Atlas {              entry          }; +        log::info!("Allocated atlas entry: {:?}", entry); +          let buffer = device              .create_buffer_mapped(data.len(), wgpu::BufferUsage::COPY_SRC)              .fill_from_slice(data);          match &entry {              Entry::Contiguous(allocation) => { -                self.upload_texture(&buffer, 0, &allocation, encoder); +                self.upload_allocation( +                    &buffer, +                    width, +                    height, +                    0, +                    &allocation, +                    encoder, +                );              }              Entry::Fragmented { fragments, .. } => {                  for fragment in fragments { -                    let (x, y) = fragment.allocation.position(); - -                    let offset = -                        (y * height + x) as usize * std::mem::size_of::<C>(); +                    let (x, y) = fragment.position; +                    let offset = (y * width + x) as usize * 4; -                    self.upload_texture( +                    self.upload_allocation(                          &buffer, -                        offset as u64, +                        width, +                        height, +                        offset,                          &fragment.allocation,                          encoder,                      ); @@ -103,6 +112,8 @@ impl Atlas {              }          } +        log::info!("Current atlas: {:?}", &self); +          Some(entry)      } @@ -204,10 +215,12 @@ impl Atlas {          None      } -    fn upload_texture( +    fn upload_allocation(          &mut self,          buffer: &wgpu::Buffer, -        offset: u64, +        image_width: u32, +        image_height: u32, +        offset: usize,          allocation: &Allocation,          encoder: &mut wgpu::CommandEncoder,      ) { @@ -224,9 +237,9 @@ impl Atlas {          encoder.copy_buffer_to_texture(              wgpu::BufferCopyView {                  buffer, -                offset, -                row_pitch: 4 * width, -                image_height: height, +                offset: offset as u64, +                row_pitch: 4 * image_width, +                image_height,              },              wgpu::TextureCopyView {                  texture: &self.texture, @@ -258,7 +271,7 @@ impl Atlas {                  height: SIZE,                  depth: 1,              }, -            array_layer_count: (self.layers.len() + amount) as u32, +            array_layer_count: self.layers.len() as u32,              mip_level_count: 1,              sample_count: 1,              dimension: wgpu::TextureDimension::D2, @@ -268,7 +281,11 @@ impl Atlas {                  | wgpu::TextureUsage::SAMPLED,          }); -        for (i, layer) in self.layers.iter_mut().enumerate() { +        let amount_to_copy = self.layers.len() - amount; + +        for (i, layer) in +            self.layers.iter_mut().take(amount_to_copy).enumerate() +        {              if layer.is_empty() {                  continue;              } @@ -302,10 +319,7 @@ impl Atlas {              );          } -        for _ in 0..amount { -            self.layers.push(Layer::Empty); -        } -          self.texture = new_texture; +        self.texture_view = self.texture.create_default_view();      }  } diff --git a/wgpu/src/texture/atlas/allocator.rs b/wgpu/src/texture/atlas/allocator.rs index cd710522..ad111212 100644 --- a/wgpu/src/texture/atlas/allocator.rs +++ b/wgpu/src/texture/atlas/allocator.rs @@ -2,41 +2,70 @@ use guillotiere::{AtlasAllocator, Size};  pub struct Allocator {      raw: AtlasAllocator, +    size: u32,  }  impl Allocator { +    const PADDING: u32 = 1; +      pub fn new(size: u32) -> Allocator {          let raw = AtlasAllocator::new(Size::new(size as i32, size as i32)); -        Allocator { raw } +        Allocator { raw, size }      }      pub fn allocate(&mut self, width: u32, height: u32) -> Option<Region> { -        let allocation = self -            .raw -            .allocate(Size::new(width as i32 + 2, height as i32 + 2))?; +        let padding = ( +            if width + Self::PADDING * 2 < self.size { +                Self::PADDING +            } else { +                0 +            }, +            if height + Self::PADDING * 2 < self.size { +                Self::PADDING +            } else { +                0 +            }, +        ); + +        let allocation = self.raw.allocate(Size::new( +            (width + padding.0 * 2) as i32, +            (height + padding.1 * 2) as i32, +        ))?; -        Some(Region(allocation)) +        Some(Region { +            allocation, +            padding, +        })      }      pub fn deallocate(&mut self, region: Region) { -        self.raw.deallocate(region.0.id); +        self.raw.deallocate(region.allocation.id);      }  } -pub struct Region(guillotiere::Allocation); +pub struct Region { +    allocation: guillotiere::Allocation, +    padding: (u32, u32), +}  impl Region {      pub fn position(&self) -> (u32, u32) { -        let rectangle = &self.0.rectangle; +        let rectangle = &self.allocation.rectangle; -        (rectangle.min.x as u32 + 1, rectangle.min.y as u32 + 1) +        ( +            rectangle.min.x as u32 + self.padding.0, +            rectangle.min.y as u32 + self.padding.1, +        )      }      pub fn size(&self) -> (u32, u32) { -        let size = self.0.rectangle.size(); +        let size = self.allocation.rectangle.size(); -        (size.width as u32 - 2, size.height as u32 - 2) +        ( +            size.width as u32 - self.padding.0 * 2, +            size.height as u32 - self.padding.1 * 2, +        )      }  } @@ -48,10 +77,10 @@ impl std::fmt::Debug for Allocator {  impl std::fmt::Debug for Region {      fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { -        write!( -            f, -            "Region {{ id: {:?}, rectangle: {:?} }}", -            self.0.id, self.0.rectangle -        ) +        f.debug_struct("Region") +            .field("id", &self.allocation.id) +            .field("rectangle", &self.allocation.rectangle) +            .field("padding", &self.padding) +            .finish()      }  }  | 
