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 | 0353181306702c40ad0fe482b5c2b159b46794a4 (patch) | |
tree | 33acc6a9e8ea4705884cf93b78cf869008f71832 /stockton-render/src/buffers | |
parent | 664f0b0777ba96298b29f0c753d52a81cbb233f1 (diff) |
refactor(all): rename some crates
Diffstat (limited to 'stockton-render/src/buffers')
-rw-r--r-- | stockton-render/src/buffers/dedicated_image.rs | 134 | ||||
-rw-r--r-- | stockton-render/src/buffers/draw_buffers.rs | 43 | ||||
-rw-r--r-- | stockton-render/src/buffers/mod.rs | 63 | ||||
-rw-r--r-- | stockton-render/src/buffers/staged.rs | 142 |
4 files changed, 0 insertions, 382 deletions
diff --git a/stockton-render/src/buffers/dedicated_image.rs b/stockton-render/src/buffers/dedicated_image.rs deleted file mode 100644 index bf49a38..0000000 --- a/stockton-render/src/buffers/dedicated_image.rs +++ /dev/null @@ -1,134 +0,0 @@ -//! A dedicated image. Used for depth buffers. - -use crate::texture::PIXEL_SIZE; -use crate::types::*; - -use std::mem::ManuallyDrop; - -use anyhow::{Context, Result}; -use hal::{ - format::{Format, Swizzle}, - image::{SubresourceRange, Usage, Usage as ImgUsage, ViewKind}, - memory, - memory::Properties, - MemoryTypeId, -}; -use thiserror::Error; - -/// Holds an image that's loaded into GPU memory dedicated only to that image, bypassing the memory allocator. -pub struct DedicatedLoadedImage { - /// The GPU Image handle - image: ManuallyDrop<ImageT>, - - /// The full view of the image - pub image_view: ManuallyDrop<ImageViewT>, - - /// The memory backing the image - memory: ManuallyDrop<MemoryT>, -} - -#[derive(Debug, Error)] -pub enum ImageLoadError { - #[error("No suitable memory type for image memory")] - NoMemoryTypes, -} - -impl DedicatedLoadedImage { - pub fn new( - device: &mut DeviceT, - adapter: &Adapter, - format: Format, - usage: Usage, - resources: SubresourceRange, - width: usize, - height: usize, - ) -> Result<DedicatedLoadedImage> { - let (memory, image_ref) = { - // Round up the size to align properly - let initial_row_size = PIXEL_SIZE * width; - let limits = adapter.physical_device.properties().limits; - let row_alignment_mask = limits.optimal_buffer_copy_pitch_alignment as u32 - 1; - - let row_size = - ((initial_row_size as u32 + row_alignment_mask) & !row_alignment_mask) as usize; - debug_assert!(row_size as usize >= initial_row_size); - - // Make the image - let mut image_ref = unsafe { - use hal::image::{Kind, Tiling, ViewCapabilities}; - - device.create_image( - Kind::D2(width as u32, height as u32, 1, 1), - 1, - format, - Tiling::Optimal, - usage, - memory::SparseFlags::empty(), - ViewCapabilities::empty(), - ) - } - .context("Error creating image")?; - - // Allocate memory - let memory = unsafe { - let requirements = device.get_image_requirements(&image_ref); - - let memory_type_id = adapter - .physical_device - .memory_properties() - .memory_types - .iter() - .enumerate() - .find(|&(id, memory_type)| { - requirements.type_mask & (1 << id) != 0 - && memory_type.properties.contains(Properties::DEVICE_LOCAL) - }) - .map(|(id, _)| MemoryTypeId(id)) - .ok_or(ImageLoadError::NoMemoryTypes)?; - - let memory = device - .allocate_memory(memory_type_id, requirements.size) - .context("Error allocating memory for image")?; - - device - .bind_image_memory(&memory, 0, &mut image_ref) - .context("Error binding memory to image")?; - - memory - }; - - (memory, image_ref) - }; - - // Create ImageView and sampler - let image_view = unsafe { - device.create_image_view( - &image_ref, - ViewKind::D2, - format, - Swizzle::NO, - ImgUsage::DEPTH_STENCIL_ATTACHMENT, - resources, - ) - } - .context("Error creating image view")?; - - Ok(DedicatedLoadedImage { - image: ManuallyDrop::new(image_ref), - image_view: ManuallyDrop::new(image_view), - memory: ManuallyDrop::new(memory), - }) - } - - /// Properly frees/destroys all the objects in this struct - /// Dropping without doing this is a bad idea - pub fn deactivate(self, device: &mut DeviceT) { - unsafe { - use core::ptr::read; - - device.destroy_image_view(ManuallyDrop::into_inner(read(&self.image_view))); - device.destroy_image(ManuallyDrop::into_inner(read(&self.image))); - device.free_memory(ManuallyDrop::into_inner(read(&self.memory))); - } - } -} diff --git a/stockton-render/src/buffers/draw_buffers.rs b/stockton-render/src/buffers/draw_buffers.rs deleted file mode 100644 index 5baec92..0000000 --- a/stockton-render/src/buffers/draw_buffers.rs +++ /dev/null @@ -1,43 +0,0 @@ -//! A vertex and index buffer set for drawing - -use super::StagedBuffer; -use crate::types::*; - -use anyhow::{Context, Result}; -use hal::buffer::Usage; -use std::mem::ManuallyDrop; - -/// Initial size of vertex buffer. TODO: Way of overriding this -pub const INITIAL_VERT_SIZE: u64 = 3 * 3000; - -/// Initial size of index buffer. TODO: Way of overriding this -pub const INITIAL_INDEX_SIZE: u64 = 3000; - -/// The buffers used for drawing, ie index and vertex buffer -pub struct DrawBuffers<'a, T: Sized> { - pub vertex_buffer: ManuallyDrop<StagedBuffer<'a, T>>, - pub index_buffer: ManuallyDrop<StagedBuffer<'a, (u16, u16, u16)>>, -} - -impl<'a, T> DrawBuffers<'a, T> { - pub fn new(device: &mut DeviceT, adapter: &Adapter) -> Result<DrawBuffers<'a, T>> { - let vert = StagedBuffer::new(device, adapter, Usage::VERTEX, INITIAL_VERT_SIZE) - .context("Error creating vertex buffer")?; - let index = StagedBuffer::new(device, adapter, Usage::INDEX, INITIAL_INDEX_SIZE) - .context("Error creating index buffer")?; - - Ok(DrawBuffers { - vertex_buffer: ManuallyDrop::new(vert), - index_buffer: ManuallyDrop::new(index), - }) - } - - pub fn deactivate(self, device: &mut DeviceT) { - unsafe { - use core::ptr::read; - - ManuallyDrop::into_inner(read(&self.vertex_buffer)).deactivate(device); - ManuallyDrop::into_inner(read(&self.index_buffer)).deactivate(device); - } - } -} diff --git a/stockton-render/src/buffers/mod.rs b/stockton-render/src/buffers/mod.rs deleted file mode 100644 index 74c5aab..0000000 --- a/stockton-render/src/buffers/mod.rs +++ /dev/null @@ -1,63 +0,0 @@ -//! All sorts of buffers - -use std::ops::IndexMut; - -use crate::{error::EnvironmentError, types::*}; - -use anyhow::{Context, Result}; -use hal::{ - buffer::Usage, - memory::{Properties, SparseFlags}, - MemoryTypeId, -}; - -mod dedicated_image; -mod draw_buffers; -mod staged; - -pub use dedicated_image::*; -pub use draw_buffers::*; -pub use staged::*; - -/// Create a buffer of the given specifications, allocating more device memory. -// TODO: Use a different memory allocator? -pub(crate) fn create_buffer( - device: &mut DeviceT, - adapter: &Adapter, - usage: Usage, - properties: Properties, - size: u64, -) -> Result<(BufferT, MemoryT)> { - let mut buffer = unsafe { device.create_buffer(size, usage, SparseFlags::empty()) } - .context("Error creating buffer")?; - - let requirements = unsafe { device.get_buffer_requirements(&buffer) }; - let memory_type_id = adapter - .physical_device - .memory_properties() - .memory_types - .iter() - .enumerate() - .find(|&(id, memory_type)| { - requirements.type_mask & (1 << id) != 0 && memory_type.properties.contains(properties) - }) - .map(|(id, _)| MemoryTypeId(id)) - .ok_or(EnvironmentError::NoMemoryTypes)?; - - let memory = unsafe { device.allocate_memory(memory_type_id, requirements.size) } - .context("Error allocating memory")?; - - unsafe { device.bind_buffer_memory(&memory, 0, &mut buffer) } - .context("Error binding memory to buffer")?; - - Ok((buffer, memory)) -} - -/// A buffer that can be modified by the CPU -pub trait ModifiableBuffer: IndexMut<usize> { - /// Get a handle to the underlying GPU buffer - fn get_buffer(&mut self) -> &BufferT; - - /// Record the command(s) required to commit changes to this buffer to the given command buffer. - fn record_commit_cmds(&mut self, cmd_buffer: &mut CommandBufferT) -> Result<()>; -} diff --git a/stockton-render/src/buffers/staged.rs b/stockton-render/src/buffers/staged.rs deleted file mode 100644 index 71b5204..0000000 --- a/stockton-render/src/buffers/staged.rs +++ /dev/null @@ -1,142 +0,0 @@ -//! A buffer that can be written to by the CPU using staging memory - -use super::{create_buffer, ModifiableBuffer}; -use crate::types::*; - -use core::mem::{size_of, ManuallyDrop}; -use std::{ - convert::TryInto, - ops::{Index, IndexMut}, -}; - -use anyhow::{Context, Result}; -use hal::{ - buffer::Usage, - command::BufferCopy, - memory::{Properties, Segment}, -}; - -/// A GPU buffer that is written to using a staging buffer -pub struct StagedBuffer<'a, T: Sized> { - /// CPU-visible buffer - staged_buffer: ManuallyDrop<BufferT>, - - /// CPU-visible memory - staged_memory: ManuallyDrop<MemoryT>, - - /// GPU Buffer - buffer: ManuallyDrop<BufferT>, - - /// GPU Memory - memory: ManuallyDrop<MemoryT>, - - /// Where staged buffer is mapped in CPU memory - staged_mapped_memory: &'a mut [T], - - /// The highest index in the buffer that's been written to. - pub highest_used: usize, -} - -impl<'a, T: Sized> StagedBuffer<'a, T> { - /// size is the size in T - pub fn new(device: &mut DeviceT, adapter: &Adapter, usage: Usage, size: u64) -> Result<Self> { - // Convert size to bytes - let size_bytes = size * size_of::<T>() as u64; - - // Get CPU-visible buffer - let (staged_buffer, mut staged_memory) = create_buffer( - device, - adapter, - Usage::TRANSFER_SRC, - Properties::CPU_VISIBLE, - size_bytes, - ) - .context("Error creating staging buffer")?; - - // Get GPU Buffer - let (buffer, memory) = create_buffer( - device, - adapter, - Usage::TRANSFER_DST | usage, - Properties::DEVICE_LOCAL | Properties::COHERENT, - size_bytes, - ) - .context("Error creating GPU buffer")?; - - // Map it somewhere and get a slice to that memory - let staged_mapped_memory = unsafe { - let ptr = device - .map_memory( - &mut staged_memory, - Segment { - offset: 0, - size: Some(size_bytes), - }, - ) - .context("Error mapping staged memory")?; - - std::slice::from_raw_parts_mut(ptr as *mut T, size.try_into()?) - }; - - Ok(StagedBuffer { - staged_buffer: ManuallyDrop::new(staged_buffer), - staged_memory: ManuallyDrop::new(staged_memory), - buffer: ManuallyDrop::new(buffer), - memory: ManuallyDrop::new(memory), - staged_mapped_memory, - highest_used: 0, - }) - } - - /// Call this before dropping - pub(crate) fn deactivate(mut self, device: &mut DeviceT) { - unsafe { - device.unmap_memory(&mut self.staged_memory); - - device.free_memory(ManuallyDrop::take(&mut self.staged_memory)); - device.destroy_buffer(ManuallyDrop::take(&mut self.staged_buffer)); - - device.free_memory(ManuallyDrop::take(&mut self.memory)); - device.destroy_buffer(ManuallyDrop::take(&mut self.buffer)); - }; - } -} - -impl<'a, T: Sized> ModifiableBuffer for StagedBuffer<'a, T> { - fn get_buffer(&mut self) -> &BufferT { - &self.buffer - } - - fn record_commit_cmds(&mut self, buf: &mut CommandBufferT) -> Result<()> { - unsafe { - buf.copy_buffer( - &self.staged_buffer, - &self.buffer, - std::iter::once(BufferCopy { - src: 0, - dst: 0, - size: ((self.highest_used + 1) * size_of::<T>()) as u64, - }), - ); - } - - Ok(()) - } -} - -impl<'a, T: Sized> Index<usize> for StagedBuffer<'a, T> { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self.staged_mapped_memory[index] - } -} - -impl<'a, T: Sized> IndexMut<usize> for StagedBuffer<'a, T> { - fn index_mut(&mut self, index: usize) -> &mut Self::Output { - if index > self.highest_used { - self.highest_used = index; - } - &mut self.staged_mapped_memory[index] - } -} |