diff options
author | tcmal <me@aria.rip> | 2024-08-25 17:44:23 +0100 |
---|---|---|
committer | tcmal <me@aria.rip> | 2024-08-25 17:44:23 +0100 |
commit | c9fb3ae28fe491bc55243fb80d8c6be93f37ad99 (patch) | |
tree | c8d6519479d3b17f5bd657495c4d7fe2d2830a1a /stockton-render/src/draw/texture | |
parent | c52a05e6d3977efce6bd4479aa312dc90e0452e5 (diff) |
feat(render): ui working
Diffstat (limited to 'stockton-render/src/draw/texture')
-rw-r--r-- | stockton-render/src/draw/texture/load.rs | 21 | ||||
-rw-r--r-- | stockton-render/src/draw/texture/loader.rs | 48 | ||||
-rw-r--r-- | stockton-render/src/draw/texture/mod.rs | 1 | ||||
-rw-r--r-- | stockton-render/src/draw/texture/repo.rs | 16 | ||||
-rw-r--r-- | stockton-render/src/draw/texture/resolver.rs | 36 |
5 files changed, 57 insertions, 65 deletions
diff --git a/stockton-render/src/draw/texture/load.rs b/stockton-render/src/draw/texture/load.rs index eea820a..e278fa2 100644 --- a/stockton-render/src/draw/texture/load.rs +++ b/stockton-render/src/draw/texture/load.rs @@ -1,9 +1,8 @@ use super::{ - block::LoadedImage, block::TexturesBlock, loader::TextureLoader, repo::BLOCK_SIZE, - resolver::TextureResolver, staging_buffer::StagingBuffer, LoadableImage, PIXEL_SIZE, + block::LoadedImage, block::TexturesBlock, repo::BLOCK_SIZE, resolver::TextureResolver, + staging_buffer::StagingBuffer, LoadableImage, PIXEL_SIZE, }; use crate::types::*; -use stockton_levels::prelude::*; use anyhow::{Context, Result}; use arrayvec::ArrayVec; @@ -24,9 +23,6 @@ use thiserror::Error; pub enum TextureLoadError { #[error("No available resources")] NoResources, - - #[error("Texture could not be resolved")] - ResolveFailed(usize), } pub const FORMAT: Format = Format::Rgba8Srgb; @@ -43,6 +39,12 @@ pub const LAYERS: SubresourceLayers = SubresourceLayers { layers: 0..1, }; +pub struct TextureLoadConfig<R: TextureResolver> { + pub resolver: R, + pub filter: Filter, + pub wrap_mode: WrapMode, +} + pub struct QueuedLoad<B: Block<back::Backend>> { pub fence: FenceT, pub buf: CommandBufferT, @@ -62,8 +64,6 @@ impl<B: Block<back::Backend>> QueuedLoad<B> { } } -impl<'a, T: HasTextures, R: TextureResolver<I>, I: LoadableImage> TextureLoader<T, R, I> {} - pub fn tex_size_info<T: LoadableImage>(img: &T, obcpa: hal::buffer::Offset) -> (usize, usize) { let initial_row_size = PIXEL_SIZE * img.width() as usize; let row_alignment_mask = obcpa as u32 - 1; @@ -119,13 +119,14 @@ where Ok((block, image_ref)) } -pub unsafe fn load_image<I: LoadableImage>( +pub unsafe fn load_image<I: LoadableImage, R: TextureResolver>( device: &mut DeviceT, staging_allocator: &mut DynamicAllocator, tex_allocator: &mut DynamicAllocator, staging_memory_type: MemoryTypeId, obcpa: u64, img_data: I, + config: &TextureLoadConfig<R>, ) -> Result<(StagingBuffer, LoadedImage<DynamicBlock>)> { // Calculate buffer size let (row_size, total_size) = tex_size_info(&img_data, obcpa); @@ -172,7 +173,7 @@ pub unsafe fn load_image<I: LoadableImage>( // Create sampler let sampler = device - .create_sampler(&SamplerDesc::new(Filter::Nearest, WrapMode::Tile)) + .create_sampler(&SamplerDesc::new(config.filter, config.wrap_mode)) .context("Error creating sampler")?; Ok(( diff --git a/stockton-render/src/draw/texture/loader.rs b/stockton-render/src/draw/texture/loader.rs index 3d7d32e..96b1646 100644 --- a/stockton-render/src/draw/texture/loader.rs +++ b/stockton-render/src/draw/texture/loader.rs @@ -2,10 +2,10 @@ use super::{ block::{LoadedImage, TexturesBlock}, - load::{load_image, QueuedLoad, TextureLoadError, LAYERS, RESOURCES}, + load::{load_image, QueuedLoad, TextureLoadConfig, TextureLoadError, LAYERS, RESOURCES}, repo::BLOCK_SIZE, resolver::TextureResolver, - LoadableImage, PIXEL_SIZE, + PIXEL_SIZE, }; use crate::{draw::utils::find_memory_type_id, error::LockPoisoned, types::*}; @@ -13,7 +13,6 @@ use std::{ array::IntoIter, collections::VecDeque, iter::{empty, once}, - marker::PhantomData, mem::{drop, ManuallyDrop}, sync::{ mpsc::{Receiver, Sender}, @@ -38,7 +37,6 @@ use image::{Rgba, RgbaImage}; use log::*; use rendy_descriptor::{DescriptorRanges, DescriptorSetLayoutBinding, DescriptorType}; use rendy_memory::DynamicConfig; -use stockton_levels::prelude::HasTextures; use thiserror::Error; /// The number of command buffers to have in flight simultaneously. @@ -49,7 +47,7 @@ pub type BlockRef = usize; /// Manages the loading/unloading of textures /// This is expected to load the textures, then send the loaded blocks back -pub struct TextureLoader<T, R, I> { +pub struct TextureLoader<R: TextureResolver> { /// Blocks for which commands have been queued and are done loading once the fence is triggered. commands_queued: ArrayVec<[QueuedLoad<DynamicBlock>; NUM_SIMULTANEOUS_CMDS]>, @@ -82,11 +80,8 @@ pub struct TextureLoader<T, R, I> { /// From adapter, used for determining alignment optimal_buffer_copy_pitch_alignment: hal::buffer::Offset, - /// The textures lump to get info from - textures: Arc<RwLock<T>>, - - /// The resolver which gets image data for a given texture. - resolver: R, + /// Configuration for how to find and load textures + config: TextureLoadConfig<R>, /// The channel requests come in. /// Requests should reference a texture **block**, for example textures 8..16 is block 1. @@ -97,8 +92,6 @@ pub struct TextureLoader<T, R, I> { /// A filler image for descriptors that aren't needed but still need to be written to blank_image: ManuallyDrop<LoadedImage<DynamicBlock>>, - - _li: PhantomData<I>, } #[derive(Error, Debug)] @@ -107,7 +100,7 @@ pub enum TextureLoaderError { NoMemoryTypes, } -impl<T: HasTextures, R: TextureResolver<I>, I: LoadableImage> TextureLoader<T, R, I> { +impl<R: TextureResolver> TextureLoader<R> { pub fn loop_until_exit(mut self) -> Result<TextureLoaderRemains> { debug!("TextureLoader starting main loop"); let mut res = Ok(false); @@ -196,8 +189,7 @@ impl<T: HasTextures, R: TextureResolver<I>, I: LoadableImage> TextureLoader<T, R ds_layout: Arc<RwLock<DescriptorSetLayoutT>>, request_channel: Receiver<LoaderRequest>, return_channel: Sender<TexturesBlock<DynamicBlock>>, - texs: Arc<RwLock<T>>, - resolver: R, + config: TextureLoadConfig<R>, ) -> Result<Self> { let mut device = device_lock .write() @@ -310,6 +302,7 @@ impl<T: HasTextures, R: TextureResolver<I>, I: LoadableImage> TextureLoader<T, R &mut tex_allocator, staging_memory_type, optimal_buffer_copy_pitch_alignment, + &config, ) } .context("Error creating blank image")?; @@ -333,10 +326,8 @@ impl<T: HasTextures, R: TextureResolver<I>, I: LoadableImage> TextureLoader<T, R request_channel, return_channel, - textures: texs, - resolver, + config, blank_image: ManuallyDrop::new(blank_image), - _li: PhantomData::default(), }) } @@ -347,12 +338,6 @@ impl<T: HasTextures, R: TextureResolver<I>, I: LoadableImage> TextureLoader<T, R .map_err(|_| LockPoisoned::Device) .context("Error getting device lock")?; - let textures = self - .textures - .read() - .map_err(|_| LockPoisoned::Map) - .context("Error getting map lock")?; - // Get assets to use let (mut fence, mut buf) = self .buffers @@ -407,9 +392,9 @@ impl<T: HasTextures, R: TextureResolver<I>, I: LoadableImage> TextureLoader<T, R // For each texture in block for tex_idx in (block_ref * BLOCK_SIZE)..(block_ref + 1) * BLOCK_SIZE { - // Get texture and Resolve image - let tex = textures.get_texture(tex_idx as u32); - if tex.is_none() { + // Resolve texture + let img_data = self.config.resolver.resolve(tex_idx as u32); + if img_data.is_none() { // Write a blank descriptor device.write_descriptor_set(DescriptorSetWrite { set: descriptor_set.raw_mut(), @@ -430,12 +415,8 @@ impl<T: HasTextures, R: TextureResolver<I>, I: LoadableImage> TextureLoader<T, R continue; } - let tex = tex.unwrap(); + let img_data = img_data.unwrap(); - let img_data = self - .resolver - .resolve(tex) - .ok_or(TextureLoadError::ResolveFailed(tex_idx))?; let array_offset = tex_idx % BLOCK_SIZE; let (staging_buffer, img) = load_image( @@ -445,6 +426,7 @@ impl<T: HasTextures, R: TextureResolver<I>, I: LoadableImage> TextureLoader<T, R self.staging_memory_type, self.optimal_buffer_copy_pitch_alignment, img_data, + &self.config, )?; // Write to descriptor set @@ -555,6 +537,7 @@ impl<T: HasTextures, R: TextureResolver<I>, I: LoadableImage> TextureLoader<T, R tex_allocator: &mut DynamicAllocator, staging_memory_type: MemoryTypeId, obcpa: u64, + config: &TextureLoadConfig<R>, ) -> Result<LoadedImage<DynamicBlock>> { let img_data = RgbaImage::from_pixel(1, 1, Rgba([0, 0, 0, 0])); @@ -572,6 +555,7 @@ impl<T: HasTextures, R: TextureResolver<I>, I: LoadableImage> TextureLoader<T, R staging_memory_type, obcpa, img_data, + &config, )?; buf.begin_primary(CommandBufferFlags::ONE_TIME_SUBMIT); diff --git a/stockton-render/src/draw/texture/mod.rs b/stockton-render/src/draw/texture/mod.rs index 43c89d5..62b28c5 100644 --- a/stockton-render/src/draw/texture/mod.rs +++ b/stockton-render/src/draw/texture/mod.rs @@ -10,6 +10,7 @@ mod staging_buffer; pub use self::block::TexturesBlock; pub use self::image::LoadableImage; +pub use self::load::TextureLoadConfig; pub use self::loader::BlockRef; pub use self::repo::TextureRepo; diff --git a/stockton-render/src/draw/texture/repo.rs b/stockton-render/src/draw/texture/repo.rs index 8191f7b..ef35610 100644 --- a/stockton-render/src/draw/texture/repo.rs +++ b/stockton-render/src/draw/texture/repo.rs @@ -1,10 +1,8 @@ -use stockton_levels::prelude::HasTextures; - use super::{ block::TexturesBlock, + load::TextureLoadConfig, loader::{BlockRef, LoaderRequest, TextureLoader, TextureLoaderRemains, NUM_SIMULTANEOUS_CMDS}, resolver::TextureResolver, - LoadableImage, }; use crate::error::LockPoisoned; use crate::types::*; @@ -49,17 +47,12 @@ impl<'a> TextureRepo<'a> { family.queue_type().supports_transfer() && family.max_queues() >= NUM_SIMULTANEOUS_CMDS } - pub fn new< - T: 'static + HasTextures + Send + Sync, - R: 'static + TextureResolver<I> + Send + Sync, - I: 'static + LoadableImage + Send, - >( + pub fn new<R: 'static + TextureResolver + Send + Sync>( device_lock: Arc<RwLock<DeviceT>>, family: QueueFamilyId, queue: Arc<RwLock<QueueT>>, adapter: &Adapter, - texs_lock: Arc<RwLock<T>>, - resolver: R, + config: TextureLoadConfig<R>, ) -> Result<Self> { // Create Channels let (req_send, req_recv) = channel(); @@ -112,8 +105,7 @@ impl<'a> TextureRepo<'a> { ds_lock.clone(), req_recv, resp_send, - texs_lock, - resolver, + config, )?; std::thread::spawn(move || loader.loop_until_exit()) diff --git a/stockton-render/src/draw/texture/resolver.rs b/stockton-render/src/draw/texture/resolver.rs index 20efa00..1ecb7a0 100644 --- a/stockton-render/src/draw/texture/resolver.rs +++ b/stockton-render/src/draw/texture/resolver.rs @@ -1,33 +1,47 @@ //! Resolves a texture in a BSP File to an image use crate::draw::texture::image::LoadableImage; -use stockton_levels::traits::textures::Texture; +use stockton_levels::prelude::HasTextures; -use std::path::Path; +use std::{ + mem::drop, + path::Path, + sync::{Arc, RwLock}, +}; use image::{io::Reader, RgbaImage}; /// An object that can be used to resolve a texture from a BSP File -pub trait TextureResolver<T: LoadableImage> { +pub trait TextureResolver { + type Image: LoadableImage; + /// Get the given texture, or None if it's corrupt/not there. - fn resolve(&mut self, texture: &Texture) -> Option<T>; + fn resolve(&mut self, texture_id: u32) -> Option<Self::Image>; } -/// A basic filesystem resolver which expects no file extension and guesses the image format -pub struct BasicFsResolver<'a> { +/// A basic filesystem resolver which gets the texture name from any HasTextures Object. +pub struct FsResolver<'a, T: HasTextures> { path: &'a Path, + map_lock: Arc<RwLock<T>>, } -impl<'a> BasicFsResolver<'a> { - pub fn new(path: &'a Path) -> BasicFsResolver<'a> { - BasicFsResolver { path } +impl<'a, T: HasTextures> FsResolver<'a, T> { + pub fn new(path: &'a Path, map_lock: Arc<RwLock<T>>) -> Self { + FsResolver { path, map_lock } } } -impl<'a> TextureResolver<RgbaImage> for BasicFsResolver<'a> { - fn resolve(&mut self, tex: &Texture) -> Option<RgbaImage> { +impl<'a, T: HasTextures> TextureResolver for FsResolver<'a, T> { + type Image = RgbaImage; + + fn resolve(&mut self, tex: u32) -> Option<Self::Image> { + let map = self.map_lock.read().unwrap(); + let tex = map.get_texture(tex)?; let path = self.path.join(&tex.name); + drop(tex); + drop(map); + if let Ok(file) = Reader::open(path) { if let Ok(guessed) = file.with_guessed_format() { if let Ok(decoded) = guessed.decode() { |