diff --git a/Cargo.lock b/Cargo.lock index 7297667..40e668d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -613,7 +613,6 @@ version = "0.1.0" dependencies = [ "ash", "ash-window", - "parking_lot", "thiserror 2.0.12", "tracing", "winit", @@ -1308,7 +1307,6 @@ dependencies = [ "gfx_hal", "glam", "gpu-allocator", - "parking_lot", "resource_manager", "shaderc", "thiserror 2.0.12", @@ -1324,7 +1322,6 @@ dependencies = [ "ash", "gfx_hal", "gpu-allocator", - "parking_lot", "thiserror 2.0.12", "tracing", ] diff --git a/Cargo.toml b/Cargo.toml index ed32bcf..454df20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,6 @@ egui = "0.31" bytemuck = { version = "1.21.0", features = ["derive"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["json"] } -parking_lot = "0.12.3" thiserror = "2.0.12" diff --git a/crates/gfx_hal/Cargo.toml b/crates/gfx_hal/Cargo.toml index caa74b1..acd0197 100644 --- a/crates/gfx_hal/Cargo.toml +++ b/crates/gfx_hal/Cargo.toml @@ -9,4 +9,3 @@ ash-window.workspace = true thiserror.workspace = true tracing.workspace = true winit.workspace = true -parking_lot.workspace = true diff --git a/crates/gfx_hal/src/device.rs b/crates/gfx_hal/src/device.rs index a26e36b..0d0c619 100644 --- a/crates/gfx_hal/src/device.rs +++ b/crates/gfx_hal/src/device.rs @@ -1,9 +1,10 @@ use ash::vk; -use parking_lot::Mutex; use std::collections::HashSet; use std::ffi::CStr; -use std::sync::Weak; -use std::{collections::HashMap, sync::Arc}; +use std::{ + collections::HashMap, + sync::{Arc, Mutex}, +}; use crate::error::{GfxHalError, Result}; use crate::instance::Instance; @@ -146,7 +147,7 @@ impl Device { // Lock the mutex and insert the created queues into the map within the Arc { // Scope for the mutex guard - let mut queues_map_guard = device_arc.queues.lock(); + let mut queues_map_guard = device_arc.queues.lock()?; *queues_map_guard = queues_to_insert; // Replace the empty map with the populated one tracing::debug!( "Device Arc populated with {} queues (Stage 2).", @@ -185,15 +186,21 @@ impl Device { /// Gets a wrapped queue handle. /// Currently only supports queue index 0 for each family. - pub fn get_queue(&self, family_index: u32, queue_index: u32) -> Option> { + pub fn get_queue(&self, family_index: u32, queue_index: u32) -> Result> { if queue_index != 0 { tracing::warn!("get_queue currently only supports queue_index 0"); - return None; + return Err(GfxHalError::MissingQueueFamily( + "get_queue only supports queue_index 0".to_string(), + )); } + self.queues - .lock() + .lock()? .get(&(family_index, queue_index)) .cloned() + .ok_or(GfxHalError::MissingQueueFamily( + "could not get queue family".to_string(), + )) } /// Gets the primary graphics queue (family index from `graphics_queue_family_index`, queue index 0). diff --git a/crates/gfx_hal/src/error.rs b/crates/gfx_hal/src/error.rs index 0e3e8d6..1dec5bc 100644 --- a/crates/gfx_hal/src/error.rs +++ b/crates/gfx_hal/src/error.rs @@ -56,9 +56,19 @@ pub enum GfxHalError { #[error("Error loading the ash entry.")] AshEntryError(#[from] ash::LoadingError), + /// Poisoned Mutex + #[error("Error from poisoned mutex: {0}")] + MutexPoisoned(String), + /// Placeholder for other specific errors. #[error("An unexpected error occurred: {0}")] Other(String), } pub type Result = std::result::Result; + +impl From> for GfxHalError { + fn from(e: std::sync::PoisonError) -> Self { + Self::MutexPoisoned(e.to_string()) + } +} diff --git a/crates/gfx_hal/src/queue.rs b/crates/gfx_hal/src/queue.rs index 8aa4513..7cbe40d 100644 --- a/crates/gfx_hal/src/queue.rs +++ b/crates/gfx_hal/src/queue.rs @@ -1,7 +1,6 @@ -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use ash::{vk, Device as AshDevice}; -use parking_lot::Mutex; use crate::device::Device; use crate::error::Result; diff --git a/crates/renderer/Cargo.toml b/crates/renderer/Cargo.toml index 6f4bbee..fb324c5 100644 --- a/crates/renderer/Cargo.toml +++ b/crates/renderer/Cargo.toml @@ -13,7 +13,6 @@ gpu-allocator.workspace = true egui.workspace = true egui-ash-renderer.workspace = true winit.workspace = true -parking_lot.workspace = true gfx_hal = { path = "../gfx_hal" } resource_manager = { path = "../resource_manager" } diff --git a/crates/renderer/src/lib.rs b/crates/renderer/src/lib.rs index 279df1b..8e32ab0 100644 --- a/crates/renderer/src/lib.rs +++ b/crates/renderer/src/lib.rs @@ -1,12 +1,15 @@ -use std::{ffi::CStr, sync::Arc}; +use std::{ + ffi::CStr, + sync::{Arc, Mutex}, +}; use ash::vk; +use egui_ash_renderer::{DynamicRendering, Options, Renderer as EguiRenderer}; use gfx_hal::{ device::Device, error::GfxHalError, queue::Queue, surface::Surface, swapchain::Swapchain, swapchain::SwapchainConfig, sync::Fence, sync::Semaphore, }; use gpu_allocator::{vulkan::Allocator, MemoryLocation}; -use parking_lot::Mutex; use resource_manager::{ImageHandle, ResourceManager, ResourceManagerError}; use thiserror::Error; use tracing::{debug, error, info, warn}; @@ -79,6 +82,8 @@ pub struct Renderer { swapchain_format: vk::SurfaceFormatKHR, swapchain_extent: vk::Extent2D, + egui_renderer: EguiRenderer, + depth_image_handle: ImageHandle, depth_image_view: vk::ImageView, // Store the view directly depth_format: vk::Format, @@ -128,10 +133,21 @@ impl Renderer { info!("Renderer initialized successfully."); + let egui_renderer = EguiRenderer::with_gpu_allocator( + resource_manager.allocator(), + device.raw().clone(), + DynamicRendering { + color_attachment_format: swapchain.format().format, + depth_attachment_format: Some(depth_format), + }, + Options::default(), + )?; + Ok(Self { device, graphics_queue, resource_manager, + egui_renderer, allocator, // Store the allocator Arc surface, swapchain: Some(swapchain), @@ -465,6 +481,10 @@ impl Renderer { self.depth_image_handle = new_depth_handle; self.depth_image_view = new_depth_view; + // 4. Update Egui Renderer (if necessary, depends on its implementation) + // It might need the new extent or recreate internal resources. + // Assuming it handles extent changes via update_screen_descriptor called earlier. + info!( "Swapchain recreated successfully ({}x{}).", new_extent.width, new_extent.height diff --git a/crates/resource_manager/Cargo.toml b/crates/resource_manager/Cargo.toml index 73c615a..f71fc5d 100644 --- a/crates/resource_manager/Cargo.toml +++ b/crates/resource_manager/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" ash.workspace = true gpu-allocator.workspace = true thiserror.workspace = true -parking_lot.workspace = true tracing.workspace = true gfx_hal = { path = "../gfx_hal" } diff --git a/crates/resource_manager/src/lib.rs b/crates/resource_manager/src/lib.rs index bec4110..add8a42 100644 --- a/crates/resource_manager/src/lib.rs +++ b/crates/resource_manager/src/lib.rs @@ -5,7 +5,7 @@ use std::{ hash::Hash, sync::{ atomic::{AtomicU64, Ordering}, - Arc, + Arc, Mutex, }, }; @@ -18,7 +18,6 @@ use gpu_allocator::{ vulkan::{Allocation, AllocationCreateDesc, Allocator, AllocatorCreateDesc}, MemoryLocation, }; -use parking_lot::Mutex; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct BufferHandle(u64); @@ -63,7 +62,7 @@ impl Drop for InternalBufferInfo { fn drop(&mut self) { trace!("Dropping InternalBufferInfo for handle: {:?}", self.handle); if let Some(allocation) = self.allocation.take() { - let mut allc = self.allocator.lock(); + let mut allc = self.allocator.lock().expect("to acquire mutex lock"); if let Err(e) = allc.free(allocation) { error!( "Failed to free allocation for buffer handle {:?}, {}", @@ -102,7 +101,7 @@ impl Drop for InternalImageInfo { } // Then free memory if let Some(allocation) = self.allocation.take() { - let mut allocator = self.allocator.lock(); + let mut allocator = self.allocator.lock().expect("to acquire mutex lock"); if let Err(e) = allocator.free(allocation) { error!( "Failed to free allocation for image handle {:?}: {}", @@ -171,7 +170,7 @@ impl ResourceManager { /// Gets or initializes the TransferSetup resources. fn get_transfer_setup(&self) -> Result { - let mut setup_guard = self.transfer_setup.lock(); + let mut setup_guard = self.transfer_setup.lock()?; if let Some(setup) = setup_guard.as_ref() { // Simple check: Reset fence before reusing @@ -192,10 +191,7 @@ impl ResourceManager { .or(self.device.compute_queue_family_index()) // Try compute as fallback .unwrap_or(self.device.graphics_queue_family_index()); // Graphics as last resort - let queue = self - .device - .get_queue(queue_family_index, 0) - .ok_or(ResourceManagerError::NoTransferQueue)?; + let queue = self.device.get_queue(queue_family_index, 0)?; // Create command pool for transfer commands let pool_info = vk::CommandPoolCreateInfo::default() @@ -306,7 +302,7 @@ impl ResourceManager { let requirements = unsafe { self.device.raw().get_buffer_memory_requirements(buffer) }; - let allocation = self.allocator.lock().allocate(&AllocationCreateDesc { + let allocation = self.allocator.lock()?.allocate(&AllocationCreateDesc { name: &format!("buffer_usage_{:?}_loc_{:?}", usage, location), requirements, location, @@ -342,7 +338,7 @@ impl ResourceManager { handle, }; - self.buffers.lock().insert(id, internal_info); + self.buffers.lock()?.insert(id, internal_info); debug!("Buffer created successfully: handle={:?}", handle); Ok(handle) } @@ -441,7 +437,7 @@ impl ResourceManager { let requirements = unsafe { self.device.raw().get_image_memory_requirements(image) }; - let allocation = self.allocator.lock().allocate(&AllocationCreateDesc { + let allocation = self.allocator.lock()?.allocate(&AllocationCreateDesc { name: &format!( "image_fmt_{:?}_usage_{:?}", create_info.format, create_info.usage @@ -491,7 +487,7 @@ impl ResourceManager { handle, }; - self.images.lock().insert(id, internal_info); + self.images.lock()?.insert(id, internal_info); debug!("Image created successfully: handle={:?}", handle); Ok(handle) } @@ -501,7 +497,7 @@ impl ResourceManager { /// Destroys a buffer and frees its memory. pub fn destroy_buffer(&self, handle: BufferHandle) -> Result<()> { debug!("Requesting destroy for buffer handle {:?}", handle); - let mut buffers_map = self.buffers.lock(); + let mut buffers_map = self.buffers.lock()?; // Remove the entry. The Drop impl of InternalBufferInfo handles the cleanup. if buffers_map.remove(&handle.0).is_some() { debug!("Buffer handle {:?} removed for destruction.", handle); @@ -518,7 +514,7 @@ impl ResourceManager { /// Destroys an image, its view, and frees its memory. pub fn destroy_image(&self, handle: ImageHandle) -> Result<()> { debug!("Requesting destroy for image handle {:?}", handle); - let mut images_map = self.images.lock(); + let mut images_map = self.images.lock()?; // Remove the entry. The Drop impl of InternalImageInfo handles the cleanup. if images_map.remove(&handle.0).is_some() { debug!("Image handle {:?} removed for destruction.", handle); @@ -534,7 +530,7 @@ impl ResourceManager { /// Gets non-owning information about a buffer. pub fn get_buffer_info(&self, handle: BufferHandle) -> Result { - let buffers_map = self.buffers.lock(); + let buffers_map = self.buffers.lock()?; buffers_map .get(&handle.0) .map(|internal| BufferInfo { @@ -549,7 +545,7 @@ impl ResourceManager { /// Gets non-owning information about an image. pub fn get_image_info(&self, handle: ImageHandle) -> Result { - let images_map = self.images.lock(); + let images_map = self.images.lock()?; images_map .get(&handle.0) .map(|internal| ImageInfo { @@ -586,15 +582,18 @@ impl Drop for ResourceManager { // Clear resource maps. This triggers the Drop impl for each Internal*Info, // which frees allocations and destroys Vulkan objects. - let mut buffers_map = self.buffers.lock(); + let mut buffers_map = self.buffers.lock().expect("mutex to not be poisoned"); debug!("Clearing {} buffer entries...", buffers_map.len()); buffers_map.clear(); - let mut images_map = self.images.lock(); + let mut images_map = self.images.lock().expect("mutex to not be poisoned"); debug!("Clearing {} image entries...", images_map.len()); images_map.clear(); // Destroy transfer setup resources - let mut setup_guard = self.transfer_setup.lock(); + let mut setup_guard = self + .transfer_setup + .lock() + .expect("mutex to not be poisoned"); if let Some(setup) = setup_guard.take() { // take() removes it from the Option debug!("Destroying TransferSetup resources...");