diff options
author | JSDurand <mmemmew@gmail.com> | 2025-06-22 12:24:53 +0800 |
---|---|---|
committer | JSDurand <mmemmew@gmail.com> | 2025-06-22 12:24:53 +0800 |
commit | a33d65e60592e962fe8e5099c4058be8395a2323 (patch) | |
tree | fadd0f1d25652f447273b56d875c7edba5eb5f85 /src/renderer | |
parent | 5cd56fc48463de4c084b7aa9b8edeb501a7ac9fd (diff) |
temp state in debugging
I am still in the process of debugging.
Diffstat (limited to 'src/renderer')
-rw-r--r-- | src/renderer/vulkan.rs | 118 |
1 files changed, 110 insertions, 8 deletions
diff --git a/src/renderer/vulkan.rs b/src/renderer/vulkan.rs index 325ad5e..6e2c806 100644 --- a/src/renderer/vulkan.rs +++ b/src/renderer/vulkan.rs @@ -6,6 +6,8 @@ use winit::{ error as werror, event::{DeviceEvent, DeviceId, Event, WindowEvent}, event_loop::{ActiveEventLoop, ControlFlow, EventLoop}, + raw_window_handle::HasDisplayHandle, + raw_window_handle::HasWindowHandle, window::{Window, WindowId}, }; @@ -71,33 +73,91 @@ impl VulkanRenderer { } unsafe fn recreate_swapchain(&mut self) -> Result<(), MainError> { + dbg!("start recreating"); + unsafe { if let Some(device) = &self.device { device.device_wait_idle()?; } + dbg!("before destroy swapchain"); + self.destroy_swapchain(); + dbg!("after destroy swapchain"); + + // --- Destroy and recreate the Vulkan surface --- + if let (Some(instance), Some(window)) = (&self.instance, &self.window) { + dbg!( + "Creating new surface (macOS workaround - skipping old surface destruction)..." + ); + // IMPORTANT: We are intentionally skipping + // `instance.destroy_surface_khr(self.data.surface, + // None);` and the `is_null()` check for the old + // surface here. + // + // On macOS, the existing surface handle often becomes + // invalid after a resize event even if its value is + // not null, causing a crash upon explicit + // destruction. + // + // A new surface will be created, and the old, + // implicitly invalidated one will be cleaned up when + // the VkInstance is destroyed at application exit. + + // dbg!("Creating new surface..."); + + let window_handle = window.window_handle().unwrap(); + let display_handle = window.display_handle().unwrap(); + + dbg!(&display_handle); + dbg!(&window_handle); + + // Use vulkanalia::window::create_surface with the current window handles + self.data.surface = vw::create_surface(instance, &display_handle, &window_handle)?; + dbg!("New surface created."); + } else { + // This case should ideally not be reached if the application is properly initialized. + panic!("Instance or Window is None during surface recreation"); + } + // -- END -- + if let (Some(device), Some(instance), Some(window)) = (&self.device, &self.instance, &self.window) { + dbg!("before create_swapchain"); create_swapchain(window, instance, device, &mut self.data)?; + dbg!("after create_swapchain"); + dbg!("before create_swapchain_image_views"); create_swapchain_image_views(device, &mut self.data)?; + dbg!("after create_swapchain_image_views"); + dbg!("before create_render_pass"); create_render_pass(instance, device, &mut self.data)?; + dbg!("after create_render_pass"); + dbg!("before create_pipeline"); create_pipeline(device, &mut self.data)?; + dbg!("after create_pipeline"); + dbg!("before create_framebuffers"); create_framebuffers(device, &mut self.data)?; + dbg!("after create_framebuffers"); + dbg!("before create_command_buffers"); create_command_buffers(device, &mut self.data)?; + dbg!("after create_command_buffers"); } + dbg!("after create groups"); + self.data .images_in_flight .resize(self.data.swapchain_images.len(), vk::Fence::null()); + dbg!("end recreating"); + Ok(()) } } @@ -142,23 +202,32 @@ impl VulkanRenderer { vk::Fence::null(), ); + dbg!("Acquired next image"); + let image_index = match acquire_image_result { Ok((image_index, _)) => image_index, Err(vk::ErrorCode::OUT_OF_DATE_KHR) => return self.recreate_swapchain(), Err(code) => return Err(code.into()), }; + dbg!("Image index obtained", image_index); + if !self.data.images_in_flight[image_index as usize].is_null() { + dbg!("Image in flight is not null"); device.wait_for_fences( &[self.data.images_in_flight[image_index as usize]], true, u64::MAX, )?; + + dbg!("Waited for image in flight fence"); } self.data.images_in_flight[image_index as usize] = self.data.in_flight_fences[self.frame]; + dbg!("Updated images_in_flight"); + let waiting_sps = [self.data.image_available_sp[self.frame]]; let waiting_stages = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT]; @@ -172,6 +241,7 @@ impl VulkanRenderer { .command_buffers(&command_buffer) .signal_semaphores(&render_sps); + dbg!("Submitting queue"); device.reset_fences(&[self.data.in_flight_fences[self.frame]])?; device.queue_submit( @@ -179,6 +249,7 @@ impl VulkanRenderer { &[submit_info], self.data.in_flight_fences[self.frame], )?; + dbg!("Queue submitted"); let swapchains = [self.data.swapchain]; @@ -189,7 +260,9 @@ impl VulkanRenderer { .swapchains(&swapchains) .image_indices(&image_indices); + dbg!("Presenting queue"); let present_result = device.queue_present_khr(self.data.pqueue, &presentation_info); + dbg!("Queue presented"); if self.resized || matches!( @@ -197,14 +270,18 @@ impl VulkanRenderer { Ok(vk::SuccessCode::SUBOPTIMAL_KHR) | Err(vk::ErrorCode::OUT_OF_DATE_KHR) ) { + dbg!("Recreating swapchain due to resize/suboptimal"); self.resized = false; self.recreate_swapchain()?; } else if let Err(e) = present_result { + dbg!("Present result error", &e); return Err(e.into()); } self.frame = (self.frame + 1).rem_euclid(MAX_FRAMES_IN_FLIGHT); + + dbg!("Render function finished successfully"); } Ok(()) @@ -246,7 +323,7 @@ impl VulkanRenderer { unsafe fn handle_resize(&mut self, new_size: PhysicalSize<u32>) { // recreate swapchain and framebuffers unsafe { - // self.recreate_swapchain().unwrap(); + self.recreate_swapchain().unwrap(); } println!("Window resized to {:?}", new_size); @@ -316,6 +393,8 @@ impl ApplicationHandler for VulkanRenderer { self.data = data; } + + dbg!(); } fn window_event( @@ -337,15 +416,20 @@ impl ApplicationHandler for VulkanRenderer { // self.present(); unsafe { + dbg!(); self.render().unwrap(); } self.window.as_ref().unwrap().request_redraw(); } WindowEvent::Resized(new_size) => unsafe { + dbg!("before handle resize"); self.handle_resize(new_size); + dbg!("after handle resize"); self.window.as_ref().unwrap().request_redraw(); + + dbg!("after request redraw"); }, _ => (), } @@ -653,16 +737,28 @@ unsafe fn create_swapchain( let image_count = (min_image_count + 1).clamp(min_image_count, max_image_count); - let mut queue_family_indices = Vec::new(); - - let image_sharing_mode = if indices.graphics != indices.presentation { - queue_family_indices.extend([indices.graphics, indices.presentation]); - - vk::SharingMode::CONCURRENT + // let mut queue_family_indices = Vec::new(); + + let (image_sharing_mode, queue_family_indices) = if indices.graphics != indices.presentation + { + // If graphics and presentation queues are different, + // use CONCURRENT mode and provide both queue family + // indices. + ( + vk::SharingMode::CONCURRENT, + vec![indices.graphics, indices.presentation], + ) } else { - vk::SharingMode::EXCLUSIVE + // If graphics and presentation queues are the same, + // use EXCLUSIVE mode. + // + // For EXCLUSIVE mode, `queue_family_index_count` MUST + // be 0. + (vk::SharingMode::EXCLUSIVE, vec![]) }; + dbg!("before info"); + let info = vk::SwapchainCreateInfoKHR::builder() .surface(data.surface) .min_image_count(image_count) @@ -679,13 +775,19 @@ unsafe fn create_swapchain( .clipped(true) .old_swapchain(vk::SwapchainKHR::null()); + dbg!("before create khr"); + data.swapchain = device.create_swapchain_khr(&info, None)?; + dbg!("before get image khr"); + data.swapchain_images = device.get_swapchain_images_khr(data.swapchain)?; data.swapchain_format = format.format; data.swapchain_extent = extent; + dbg!("end of create_swapchain"); + Ok(()) } } |