diff --git a/crates/renderer/src/renderer.rs b/crates/renderer/src/renderer.rs index 764ac21..985d7e6 100644 --- a/crates/renderer/src/renderer.rs +++ b/crates/renderer/src/renderer.rs @@ -1,30 +1,57 @@ -use ash::{Device, Instance, khr, vk}; use crate::error::RendererError; use crate::sync::SyncPrimitives; +use ash::{Device, Instance, khr, vk}; +use gpu_allocator::vulkan::Allocator; -pub const MAX_FRAMES_IN_FLIGHT: usize = 2; +pub const MAX_FRAMES_IN_FLIGHT: usize = 3; /// The core renderer structure holding the Vulkan resources. pub struct Renderer { + /// Entry point to the Vulkan library. pub(crate) _entry: ash::Entry, + /// The Vulkan instance. pub(crate) instance: Instance, + /// Optional debug utility loader for validation layers. pub(crate) debug_utils: Option, + /// The debug messenger for validation layer output. pub(crate) debug_messenger: vk::DebugUtilsMessengerEXT, + /// Handle to the selected physical device (GPU). pub(crate) physical_device: vk::PhysicalDevice, + /// The logical Vulkan device. pub(crate) device: Device, + /// The queue used for graphics operations. pub(crate) graphics_queue: vk::Queue, + /// Index of the graphics queue family. pub(crate) graphics_queue_index: u32, + /// Surface extension loader. pub(crate) surface_loader: khr::surface::Instance, + /// The presentation surface. pub(crate) surface: vk::SurfaceKHR, + /// Swapchain extension loader. pub(crate) swapchain_loader: khr::swapchain::Device, + /// The swapchain for presenting images. pub(crate) swapchain: vk::SwapchainKHR, + /// Images acquired from the swapchain. pub(crate) swapchain_images: Vec, + /// The pixel format of the swapchain images. pub(crate) swapchain_format: vk::Format, + /// The dimensions of the swapchain images. pub(crate) swapchain_extent: vk::Extent2D, + /// Image views for each swapchain image. pub(crate) swapchain_image_views: Vec, + /// The command pool used for allocating command buffers. pub(crate) command_pool: vk::CommandPool, + /// Pre-allocated command buffers for each frame in flight. pub(crate) command_buffers: Vec, + /// The layout of the graphics pipeline. + pub(crate) pipeline_layout: vk::PipelineLayout, + /// The compiled graphics pipeline state. + pub(crate) graphics_pipeline: vk::Pipeline, + /// Memory manager for GPU allocations. + pub(crate) allocator: Allocator, + /// Synchronization primitives for frame-by-frame execution. pub(crate) sync: SyncPrimitives, + /// Index of the current frame being processed (0 to MAX_FRAMES_IN_FLIGHT - 1). pub(crate) current_frame: usize, } @@ -37,7 +64,8 @@ impl Renderer { // 1. Wait for the current frame's GPU work to finish unsafe { - self.device.wait_for_fences(&[in_flight_fence], true, u64::MAX)?; + self.device + .wait_for_fences(&[in_flight_fence], true, u64::MAX)?; self.device.reset_fences(&[in_flight_fence])?; } @@ -56,7 +84,8 @@ impl Renderer { // 3. Reset and begin recording the command buffer unsafe { - self.device.reset_command_buffer(cmd, vk::CommandBufferResetFlags::empty())?; + self.device + .reset_command_buffer(cmd, vk::CommandBufferResetFlags::empty())?; let begin_info = vk::CommandBufferBeginInfo::default() .flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT); self.device.begin_command_buffer(cmd, &begin_info)?; @@ -142,7 +171,8 @@ impl Renderer { .signal_semaphores(std::slice::from_ref(&render_finished_semaphore)); unsafe { - self.device.queue_submit(self.graphics_queue, &[submit_info], in_flight_fence)?; + self.device + .queue_submit(self.graphics_queue, &[submit_info], in_flight_fence)?; } // 8. Present the result to the screen @@ -152,7 +182,8 @@ impl Renderer { .image_indices(std::slice::from_ref(&image_index)); unsafe { - self.swapchain_loader.queue_present(self.graphics_queue, &present_info)?; + self.swapchain_loader + .queue_present(self.graphics_queue, &present_info)?; } // Advance the frame index for the next call @@ -167,6 +198,10 @@ impl Drop for Renderer { unsafe { let _ = self.device.device_wait_idle(); + self.device.destroy_pipeline(self.graphics_pipeline, None); + self.device + .destroy_pipeline_layout(self.pipeline_layout, None); + self.device.destroy_command_pool(self.command_pool, None); // Use the safe cleanup function from sync module @@ -174,7 +209,8 @@ impl Drop for Renderer { crate::sync::destroy_sync_primitives(&self.device, sync); // Destroy the swapchain - self.swapchain_loader.destroy_swapchain(self.swapchain, None); + self.swapchain_loader + .destroy_swapchain(self.swapchain, None); // Destroy image views for &view in &self.swapchain_image_views { @@ -194,6 +230,6 @@ impl Drop for Renderer { // Destroy the instance self.instance.destroy_instance(None); - } + } } } diff --git a/crates/renderer/src/sync.rs b/crates/renderer/src/sync.rs index 1f43362..00f050b 100644 --- a/crates/renderer/src/sync.rs +++ b/crates/renderer/src/sync.rs @@ -3,8 +3,11 @@ use crate::error::RendererError; /// Groups all synchronization primitives for the renderer. pub struct SyncPrimitives { + /// Semaphores signaled when an image has been acquired from the swapchain and is ready for rendering. pub image_available: Vec, + /// Semaphores signaled when rendering to a swapchain image is complete. pub render_finished: Vec, + /// Fences used to synchronize CPU execution with GPU frame completion. pub in_flight: Vec, }