fix(renderer): handle u32::MAX swapchain extent
Fixed a crash where the renderer would attempt to create a swapchain with u32::MAX dimensions when the OS didn't provide a preferred extent. Updated Renderer::new to accept window dimensions and use them as a fallback. Also renamed InstanceCreateFailed to VulkanError for better generality.
This commit is contained in:
parent
76450da41f
commit
636c44b29f
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1054,6 +1054,7 @@ name = "renderer"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ash",
|
||||
"ash-window",
|
||||
"raw-window-handle",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
|
|
|
|||
|
|
@ -31,8 +31,15 @@ impl ApplicationHandler for App {
|
|||
let required_extensions = ash_window::enumerate_required_extensions(display_handle)
|
||||
.expect("Failed to enumerate required extensions");
|
||||
|
||||
let renderer = renderer::Renderer::new(display_handle, window_handle, required_extensions)
|
||||
.expect("Failed to initialize Vulkan renderer");
|
||||
let size = self.window.as_ref().unwrap().inner_size();
|
||||
let renderer = renderer::Renderer::new(
|
||||
display_handle,
|
||||
window_handle,
|
||||
size.width,
|
||||
size.height,
|
||||
required_extensions,
|
||||
)
|
||||
.expect("Failed to initialize Vulkan renderer");
|
||||
|
||||
self.renderer = Some(renderer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use thiserror::Error;
|
|||
pub enum RendererError {
|
||||
#[error("Failed to load Vulkan library")]
|
||||
LoadFailed(#[from] ash::LoadingError),
|
||||
#[error("Failed to create Vulkan instance")]
|
||||
InstanceCreateFailed(#[from] ash::vk::Result),
|
||||
#[error("Vulkan error")]
|
||||
VulkanError(#[from] ash::vk::Result),
|
||||
#[error("No suitable GPU found")]
|
||||
NoSuitableGpu,
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
pub mod error;
|
||||
|
||||
use std::ffi::{CStr, c_char};
|
||||
use ash::{Device, Entry, Instance, ext, khr, vk::{self, SurfaceKHR}};
|
||||
use ash::{Device, Entry, Instance, ext, khr, vk};
|
||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
|
|
@ -52,6 +52,8 @@ impl Renderer {
|
|||
pub fn new(
|
||||
display_handle: RawDisplayHandle,
|
||||
window_handle: RawWindowHandle,
|
||||
width: u32,
|
||||
height: u32,
|
||||
required_extensions: &[*const c_char],
|
||||
) -> Result<Self, RendererError> {
|
||||
let entry = unsafe { Entry::load() }?;
|
||||
|
|
@ -117,7 +119,9 @@ impl Renderer {
|
|||
// Create the logical device
|
||||
let (device, graphics_queue) = Self::create_logical_device(&instance, physical_device, graphics_queue_index)?;
|
||||
|
||||
let (swapchain_loader, swapchain, swapchain_images, swapchain_format, swapchain_extent) = Self::create_swapchain(&instance, physical_device, &device, &surface_loader, surface)?;
|
||||
// Create the swapchain
|
||||
let (swapchain_loader, swapchain, swapchain_images, swapchain_format, swapchain_extent) =
|
||||
Self::create_swapchain(&instance, physical_device, &device, &surface_loader, surface, width, height)?;
|
||||
|
||||
Ok(Self {
|
||||
_entry: entry,
|
||||
|
|
@ -242,6 +246,8 @@ impl Renderer {
|
|||
device: &Device,
|
||||
surface_loader: &khr::surface::Instance,
|
||||
surface: vk::SurfaceKHR,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> Result<
|
||||
(khr::swapchain::Device, vk::SwapchainKHR, Vec<vk::Image>, vk::Format, vk::Extent2D),
|
||||
RendererError,
|
||||
|
|
@ -262,7 +268,16 @@ impl Renderer {
|
|||
.find(|&m| m == vk::PresentModeKHR::MAILBOX)
|
||||
.unwrap_or(vk::PresentModeKHR::FIFO);
|
||||
|
||||
let extent = surface_capabilities.current_extent;
|
||||
// 3. Match the window resolution
|
||||
// If the surface says u32::MAX, it means we can pick any size within bounds.
|
||||
let extent = if surface_capabilities.current_extent.width != u32::MAX {
|
||||
surface_capabilities.current_extent
|
||||
} else {
|
||||
vk::Extent2D {
|
||||
width: width.clamp(surface_capabilities.min_image_extent.width, surface_capabilities.max_image_extent.width),
|
||||
height: height.clamp(surface_capabilities.min_image_extent.height, surface_capabilities.max_image_extent.height),
|
||||
}
|
||||
};
|
||||
|
||||
let mut image_count = surface_capabilities.min_image_count + 1;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue