blade: encapsulate BladeAtlasStorage for indexing

This commit is contained in:
Dzmitry Malyshau
2024-02-04 13:03:16 -08:00
parent 26ca798707
commit 0a5ebee9e5
+64 -50
View File
@@ -8,7 +8,7 @@ use blade_graphics as gpu;
use collections::FxHashMap; use collections::FxHashMap;
use etagere::BucketedAtlasAllocator; use etagere::BucketedAtlasAllocator;
use parking_lot::Mutex; use parking_lot::Mutex;
use std::{borrow::Cow, sync::Arc}; use std::{borrow::Cow, ops, sync::Arc};
pub(crate) const PATH_TEXTURE_FORMAT: gpu::TextureFormat = gpu::TextureFormat::R16Float; pub(crate) const PATH_TEXTURE_FORMAT: gpu::TextureFormat = gpu::TextureFormat::R16Float;
@@ -23,9 +23,7 @@ struct PendingUpload {
struct BladeAtlasState { struct BladeAtlasState {
gpu: Arc<gpu::Context>, gpu: Arc<gpu::Context>,
upload_belt: BladeBelt, upload_belt: BladeBelt,
monochrome_textures: Vec<BladeAtlasTexture>, storage: BladeAtlasStorage,
polychrome_textures: Vec<BladeAtlasTexture>,
path_textures: Vec<BladeAtlasTexture>,
tiles_by_key: FxHashMap<AtlasKey, AtlasTile>, tiles_by_key: FxHashMap<AtlasKey, AtlasTile>,
initializations: Vec<AtlasTextureId>, initializations: Vec<AtlasTextureId>,
uploads: Vec<PendingUpload>, uploads: Vec<PendingUpload>,
@@ -33,15 +31,7 @@ struct BladeAtlasState {
impl BladeAtlasState { impl BladeAtlasState {
fn destroy(&mut self) { fn destroy(&mut self) {
for mut texture in self.monochrome_textures.drain(..) { self.storage.destroy(&self.gpu);
texture.destroy(&self.gpu);
}
for mut texture in self.polychrome_textures.drain(..) {
texture.destroy(&self.gpu);
}
for mut texture in self.path_textures.drain(..) {
texture.destroy(&self.gpu);
}
self.upload_belt.destroy(&self.gpu); self.upload_belt.destroy(&self.gpu);
} }
} }
@@ -60,9 +50,7 @@ impl BladeAtlas {
min_chunk_size: 0x10000, min_chunk_size: 0x10000,
alignment: 64, // Vulkan `optimalBufferCopyOffsetAlignment` on Intel XE alignment: 64, // Vulkan `optimalBufferCopyOffsetAlignment` on Intel XE
}), }),
monochrome_textures: Default::default(), storage: BladeAtlasStorage::default(),
polychrome_textures: Default::default(),
path_textures: Default::default(),
tiles_by_key: Default::default(), tiles_by_key: Default::default(),
initializations: Vec::new(), initializations: Vec::new(),
uploads: Vec::new(), uploads: Vec::new(),
@@ -75,11 +63,7 @@ impl BladeAtlas {
pub(crate) fn clear_textures(&self, texture_kind: AtlasTextureKind) { pub(crate) fn clear_textures(&self, texture_kind: AtlasTextureKind) {
let mut lock = self.0.lock(); let mut lock = self.0.lock();
let textures = match texture_kind { let textures = &mut lock.storage[texture_kind];
AtlasTextureKind::Monochrome => &mut lock.monochrome_textures,
AtlasTextureKind::Polychrome => &mut lock.polychrome_textures,
AtlasTextureKind::Path => &mut lock.path_textures,
};
for texture in textures { for texture in textures {
texture.clear(); texture.clear();
} }
@@ -102,12 +86,7 @@ impl BladeAtlas {
pub fn get_texture_info(&self, id: AtlasTextureId) -> BladeTextureInfo { pub fn get_texture_info(&self, id: AtlasTextureId) -> BladeTextureInfo {
let lock = self.0.lock(); let lock = self.0.lock();
let textures = match id.kind { let texture = &lock.storage[id];
crate::AtlasTextureKind::Monochrome => &lock.monochrome_textures,
crate::AtlasTextureKind::Polychrome => &lock.polychrome_textures,
crate::AtlasTextureKind::Path => &lock.path_textures,
};
let texture = &textures[id.index as usize];
let size = texture.allocator.size(); let size = texture.allocator.size();
BladeTextureInfo { BladeTextureInfo {
size: gpu::Extent { size: gpu::Extent {
@@ -141,11 +120,7 @@ impl PlatformAtlas for BladeAtlas {
impl BladeAtlasState { impl BladeAtlasState {
fn allocate(&mut self, size: Size<DevicePixels>, texture_kind: AtlasTextureKind) -> AtlasTile { fn allocate(&mut self, size: Size<DevicePixels>, texture_kind: AtlasTextureKind) -> AtlasTile {
let textures = match texture_kind { let textures = &mut self.storage[texture_kind];
AtlasTextureKind::Monochrome => &mut self.monochrome_textures,
AtlasTextureKind::Polychrome => &mut self.polychrome_textures,
AtlasTextureKind::Path => &mut self.path_textures,
};
textures textures
.iter_mut() .iter_mut()
.rev() .rev()
@@ -207,11 +182,7 @@ impl BladeAtlasState {
subresources: &Default::default(), subresources: &Default::default(),
}); });
let textures = match kind { let textures = &mut self.storage[kind];
AtlasTextureKind::Monochrome => &mut self.monochrome_textures,
AtlasTextureKind::Polychrome => &mut self.polychrome_textures,
AtlasTextureKind::Path => &mut self.path_textures,
};
let atlas_texture = BladeAtlasTexture { let atlas_texture = BladeAtlasTexture {
id: AtlasTextureId { id: AtlasTextureId {
index: textures.len() as u32, index: textures.len() as u32,
@@ -235,24 +206,13 @@ impl BladeAtlasState {
fn flush(&mut self, encoder: &mut gpu::CommandEncoder) { fn flush(&mut self, encoder: &mut gpu::CommandEncoder) {
for id in self.initializations.drain(..) { for id in self.initializations.drain(..) {
let textures = match id.kind { let texture = &self.storage[id];
crate::AtlasTextureKind::Monochrome => &self.monochrome_textures,
crate::AtlasTextureKind::Polychrome => &self.polychrome_textures,
crate::AtlasTextureKind::Path => &self.path_textures,
};
let texture = &textures[id.index as usize];
encoder.init_texture(texture.raw); encoder.init_texture(texture.raw);
} }
let mut transfers = encoder.transfer(); let mut transfers = encoder.transfer();
for upload in self.uploads.drain(..) { for upload in self.uploads.drain(..) {
let textures = match upload.id.kind { let texture = &self.storage[upload.id];
crate::AtlasTextureKind::Monochrome => &self.monochrome_textures,
crate::AtlasTextureKind::Polychrome => &self.polychrome_textures,
crate::AtlasTextureKind::Path => &self.path_textures,
};
let texture = &textures[upload.id.index as usize];
transfers.copy_buffer_to_texture( transfers.copy_buffer_to_texture(
upload.data, upload.data,
upload.bounds.size.width.to_bytes(texture.bytes_per_pixel()), upload.bounds.size.width.to_bytes(texture.bytes_per_pixel()),
@@ -276,6 +236,60 @@ impl BladeAtlasState {
} }
} }
#[derive(Default)]
struct BladeAtlasStorage {
monochrome_textures: Vec<BladeAtlasTexture>,
polychrome_textures: Vec<BladeAtlasTexture>,
path_textures: Vec<BladeAtlasTexture>,
}
impl ops::Index<AtlasTextureKind> for BladeAtlasStorage {
type Output = Vec<BladeAtlasTexture>;
fn index(&self, kind: AtlasTextureKind) -> &Self::Output {
match kind {
crate::AtlasTextureKind::Monochrome => &self.monochrome_textures,
crate::AtlasTextureKind::Polychrome => &self.polychrome_textures,
crate::AtlasTextureKind::Path => &self.path_textures,
}
}
}
impl ops::IndexMut<AtlasTextureKind> for BladeAtlasStorage {
fn index_mut(&mut self, kind: AtlasTextureKind) -> &mut Self::Output {
match kind {
crate::AtlasTextureKind::Monochrome => &mut self.monochrome_textures,
crate::AtlasTextureKind::Polychrome => &mut self.polychrome_textures,
crate::AtlasTextureKind::Path => &mut self.path_textures,
}
}
}
impl ops::Index<AtlasTextureId> for BladeAtlasStorage {
type Output = BladeAtlasTexture;
fn index(&self, id: AtlasTextureId) -> &Self::Output {
let textures = match id.kind {
crate::AtlasTextureKind::Monochrome => &self.monochrome_textures,
crate::AtlasTextureKind::Polychrome => &self.polychrome_textures,
crate::AtlasTextureKind::Path => &self.path_textures,
};
&textures[id.index as usize]
}
}
impl BladeAtlasStorage {
fn destroy(&mut self, gpu: &gpu::Context) {
for mut texture in self.monochrome_textures.drain(..) {
texture.destroy(gpu);
}
for mut texture in self.polychrome_textures.drain(..) {
texture.destroy(gpu);
}
for mut texture in self.path_textures.drain(..) {
texture.destroy(gpu);
}
}
}
struct BladeAtlasTexture { struct BladeAtlasTexture {
id: AtlasTextureId, id: AtlasTextureId,
allocator: BucketedAtlasAllocator, allocator: BucketedAtlasAllocator,