Skip to content

Commit

Permalink
Fix Core::upload_image_raw for multi-layer uploads; Implement basic i…
Browse files Browse the repository at this point in the history
…mage array loading in resource manager
  • Loading branch information
manpat committed Sep 29, 2024
1 parent 8efed69 commit 64b14de
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 2 deletions.
2 changes: 1 addition & 1 deletion toybox-gfx/src/core/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ impl super::Core {

let ImageRange {offset, size} = range.into().unwrap_or(ImageRange::from_size(image_info.size));

let expected_size = format.texel_byte_size() * (size.x * size.y) as usize;
let expected_size = format.texel_byte_size() * (size.x * size.y * size.z) as usize;
assert_eq!(data_size, expected_size, "Core::upload_image_raw not passed expected amount of data");

// TODO(pat.m): assert that size + offset < image_info.size
Expand Down
7 changes: 7 additions & 0 deletions toybox-gfx/src/resource_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub struct ResourceManager {
pub shaders: ResourceStorage<ShaderResource>,

load_image_requests: ResourceRequestMap<LoadImageRequest>,
load_image_array_requests: ResourceRequestMap<LoadImageArrayRequest>,
create_image_requests: ResourceRequestMap<CreateImageRequest>,
pub images: ResourceStorage<ImageResource>,

Expand Down Expand Up @@ -135,6 +136,7 @@ impl ResourceManager {
shaders,

load_image_requests: ResourceRequestMap::new(),
load_image_array_requests: ResourceRequestMap::new(),
create_image_requests: ResourceRequestMap::new(),
images: ResourceStorage::new(),

Expand Down Expand Up @@ -210,6 +212,11 @@ impl ResourceManager {
.with_context(|| format!("Loading image '{}'", def.path.display()))
})?;

self.load_image_array_requests.process_requests(&mut self.images, |def| {
ImageResource::array_from_vfs(core, vfs, &def.paths, def.label.clone())
.with_context(|| format!("Loading image array '{}'", def.label))
})?;

self.create_image_requests.process_requests(&mut self.images, |def| {
Ok(ImageResource::from_create_request(core, def))
})?;
Expand Down
46 changes: 45 additions & 1 deletion toybox-gfx/src/resource_manager/image.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::prelude::*;
use std::path::Path;
use std::path::{Path, PathBuf};

use crate::core::*;

Expand Down Expand Up @@ -84,6 +84,50 @@ impl ImageResource {
})
}

pub fn array_from_vfs(core: &mut Core, vfs: &vfs::Vfs, virtual_paths: &[PathBuf], label: String) -> anyhow::Result<ImageResource> {
if virtual_paths.is_empty() {
anyhow::bail!("Trying to create empty image array")
}

let mut image_data = Vec::new();

let mut common_size = None;

for virtual_path in virtual_paths {
// TODO(pat.m): use a BufReader instead so that image can read only what it needs
let file_data = vfs.load_resource_data(virtual_path)?;

let image = ::image::load_from_memory(&file_data)?.flipv().into_rgba8();
let size = image.dimensions();

if *common_size.get_or_insert(size) != size {
let (w, h) = common_size.unwrap();
let (w2, h2) = size;
let path = virtual_path.display();
anyhow::bail!("Size mismatch while loading image array '{label}'. Expected {w}x{h}, but {path} was {w2}x{h2}");
}

image_data.extend(image.into_vec());
}

let (width, height) = common_size.unwrap();
let num_layers = virtual_paths.len() as u32;
let size = Vec2i::new(width as i32, height as i32);

// TODO(pat.m): allow diff texel formats
let name = core.create_image_2d_array(ImageFormat::Srgba8, size, num_layers);
core.upload_image(name, None, ImageFormat::Srgba8, &image_data);
core.set_debug_label(name, &label);

Ok(ImageResource {
name,
image_info: core.get_image_info(name).unwrap(),
resize_policy: ImageResizePolicy::Fixed,
clear_policy: ImageClearPolicy::Never,
label,
})
}

pub fn from_create_request(core: &mut Core, req: &CreateImageRequest) -> ImageResource {
let mut image_info = req.image_info.clone();

Expand Down
27 changes: 27 additions & 0 deletions toybox-gfx/src/resource_manager/image/load_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,31 @@ impl ResourceRequest for LoadImageRequest {
fn register(self, rm: &mut ResourceManager) -> ImageHandle {
rm.load_image_requests.request_handle(&mut rm.images, self)
}
}



#[derive(Hash, Clone, Debug, Eq, PartialEq)]
pub struct LoadImageArrayRequest {
pub paths: Vec<PathBuf>,
pub label: String,
}


impl LoadImageArrayRequest {
pub fn from<P: Into<PathBuf>>(label: impl Into<String>, paths: impl IntoIterator<Item=P>) -> LoadImageArrayRequest {
LoadImageArrayRequest {
label: label.into(),
paths: paths.into_iter().map(Into::into).collect()
}
}
}


impl ResourceRequest for LoadImageArrayRequest {
type Resource = ImageResource;

fn register(self, rm: &mut ResourceManager) -> ImageHandle {
rm.load_image_array_requests.request_handle(&mut rm.images, self)
}
}

0 comments on commit 64b14de

Please sign in to comment.