Refactoring: Use more Result instead of panic

This commit is contained in:
Stephen Seo 2024-03-12 16:45:33 +09:00
parent 425a0ae501
commit 6b3c83d913

View file

@ -219,18 +219,18 @@ impl VulkanApp {
panic!("Validation layers requested, but not available!"); panic!("Validation layers requested, but not available!");
} }
self.create_instance(); self.create_instance().unwrap();
self.setup_debug_messenger(); self.setup_debug_messenger().unwrap();
self.create_surface(); self.create_surface().unwrap();
self.pick_physical_device(); self.pick_physical_device().unwrap();
self.create_logical_device(); self.create_logical_device().unwrap();
self.create_swap_chain(); self.create_swap_chain().unwrap();
self.create_image_views(); self.create_image_views().unwrap();
self.create_graphics_pipeline() self.create_graphics_pipeline()
.expect("Should be able to set up graphics pipeline"); .expect("Should be able to set up graphics pipeline");
} }
fn create_instance(&mut self) { fn create_instance(&mut self) -> Result<(), String> {
let app_name = CString::new("Vulkan Triangle").unwrap(); let app_name = CString::new("Vulkan Triangle").unwrap();
let engine_name = CString::new("No Engine").unwrap(); let engine_name = CString::new("No Engine").unwrap();
let app_info = ffi::VkApplicationInfo { let app_info = ffi::VkApplicationInfo {
@ -303,17 +303,23 @@ impl VulkanApp {
}; };
if vk_result != ffi::VkResult_VK_SUCCESS { if vk_result != ffi::VkResult_VK_SUCCESS {
panic!("ERROR: Failed to create vk instance!"); return Err(String::from("Failed to create Vulkan instance"));
} }
Ok(())
} }
fn setup_debug_messenger(&mut self) { fn setup_debug_messenger(&mut self) -> Result<(), String> {
if !ENABLE_VALIDATION_LAYERS { if !ENABLE_VALIDATION_LAYERS {
return; return Err(String::from(
"Cannot setup debug messenger if validation layers is not enabled!",
));
} }
if self.vk_instance.is_null() { if self.vk_instance.is_null() {
panic!("ERROR: Cannot set up debug messenger if vk_instance is not initialized!"); return Err(String::from(
"Cannot set up debug messenger if vk_instance is not initialized!",
));
} }
let create_info = create_debug_messenger_create_info(); let create_info = create_debug_messenger_create_info();
@ -325,11 +331,13 @@ impl VulkanApp {
std::ptr::addr_of_mut!(self.debug_messenger), std::ptr::addr_of_mut!(self.debug_messenger),
); );
if result != ffi::VkResult_VK_SUCCESS { if result != ffi::VkResult_VK_SUCCESS {
panic!("Failed to set up debug messenger!"); return Err(String::from("Failed to set up debug messenger!"));
} }
Ok(())
} }
fn pick_physical_device(&mut self) { fn pick_physical_device(&mut self) -> Result<(), String> {
let mut dev_count: u32 = 0; let mut dev_count: u32 = 0;
unsafe { unsafe {
ffi::vkEnumeratePhysicalDevices( ffi::vkEnumeratePhysicalDevices(
@ -340,7 +348,7 @@ impl VulkanApp {
} }
if dev_count == 0 { if dev_count == 0 {
panic!("Failed to find GPUs with Vulkan support!"); return Err(String::from("Failed to find GPUs with Vulkan support!"));
} }
let mut phys_dev_handles_vec: Vec<ffi::VkPhysicalDevice> = let mut phys_dev_handles_vec: Vec<ffi::VkPhysicalDevice> =
@ -355,20 +363,24 @@ impl VulkanApp {
} }
for phys_dev in phys_dev_handles_vec { for phys_dev in phys_dev_handles_vec {
if self.is_device_suitable(phys_dev) { if self.is_device_suitable(phys_dev)? {
self.physical_device = phys_dev; self.physical_device = phys_dev;
break; break;
} }
} }
if self.physical_device.is_null() { if self.physical_device.is_null() {
panic!("Failed to find a suitable GPU!"); return Err(String::from("Failed to find a suitable GPU!"));
} }
Ok(())
} }
fn create_logical_device(&mut self) { fn create_logical_device(&mut self) -> Result<(), String> {
if self.physical_device.is_null() { if self.physical_device.is_null() {
panic!("\"physical_device\" must be set before calling \"create_logical_device\"!"); return Err(String::from(
"\"physical_device\" must be set before calling \"create_logical_device\"!",
));
} }
let indices = self.find_queue_families(self.physical_device); let indices = self.find_queue_families(self.physical_device);
@ -418,7 +430,7 @@ impl VulkanApp {
) )
}; };
if result != ffi::VkResult_VK_SUCCESS { if result != ffi::VkResult_VK_SUCCESS {
panic!("Failed to create logical device!"); return Err(String::from("Failed to create logical device!"));
} }
unsafe { unsafe {
@ -435,9 +447,11 @@ impl VulkanApp {
std::ptr::addr_of_mut!(self.present_queue), std::ptr::addr_of_mut!(self.present_queue),
); );
} }
Ok(())
} }
fn create_surface(&mut self) { fn create_surface(&mut self) -> Result<(), String> {
let result = unsafe { let result = unsafe {
ffi::glfwCreateWindowSurface( ffi::glfwCreateWindowSurface(
self.vk_instance, self.vk_instance,
@ -447,8 +461,10 @@ impl VulkanApp {
) )
}; };
if result != ffi::VkResult_VK_SUCCESS { if result != ffi::VkResult_VK_SUCCESS {
panic!("Failed to create window surface!"); return Err(String::from("Failed to create window surface!"));
} }
Ok(())
} }
fn main_loop(&mut self) { fn main_loop(&mut self) {
@ -521,7 +537,7 @@ impl VulkanApp {
queue_fam queue_fam
} }
fn is_device_suitable(&self, dev: ffi::VkPhysicalDevice) -> bool { fn is_device_suitable(&self, dev: ffi::VkPhysicalDevice) -> Result<bool, String> {
let mut dev_props: ffi::VkPhysicalDeviceProperties = unsafe { std::mem::zeroed() }; let mut dev_props: ffi::VkPhysicalDeviceProperties = unsafe { std::mem::zeroed() };
unsafe { unsafe {
ffi::vkGetPhysicalDeviceProperties(dev, std::ptr::addr_of_mut!(dev_props)); ffi::vkGetPhysicalDeviceProperties(dev, std::ptr::addr_of_mut!(dev_props));
@ -540,12 +556,14 @@ impl VulkanApp {
let mut swap_chain_adequate = false; let mut swap_chain_adequate = false;
if extensions_supported { if extensions_supported {
let swap_chain_support = self.query_swap_chain_support(dev); let swap_chain_support = self.query_swap_chain_support(dev)?;
swap_chain_adequate = !swap_chain_support.formats.is_empty() swap_chain_adequate = !swap_chain_support.formats.is_empty()
&& !swap_chain_support.present_modes.is_empty(); && !swap_chain_support.present_modes.is_empty();
} }
self.find_queue_families(dev).is_complete() && extensions_supported && swap_chain_adequate Ok(self.find_queue_families(dev).is_complete()
&& extensions_supported
&& swap_chain_adequate)
} }
fn check_device_extensions_support(&self, dev: ffi::VkPhysicalDevice) -> bool { fn check_device_extensions_support(&self, dev: ffi::VkPhysicalDevice) -> bool {
@ -586,9 +604,14 @@ impl VulkanApp {
req_extensions.is_empty() req_extensions.is_empty()
} }
fn query_swap_chain_support(&self, device: ffi::VkPhysicalDevice) -> SwapChainSupportDetails { fn query_swap_chain_support(
&self,
device: ffi::VkPhysicalDevice,
) -> Result<SwapChainSupportDetails, String> {
if self.surface.is_null() { if self.surface.is_null() {
panic!("surface must be initialized before calling query_swap_chain_support!"); return Err(String::from(
"surface must be initialized before calling query_swap_chain_support!",
));
} }
let mut swap_chain_support_details = SwapChainSupportDetails::default(); let mut swap_chain_support_details = SwapChainSupportDetails::default();
@ -647,7 +670,7 @@ impl VulkanApp {
} }
} }
swap_chain_support_details Ok(swap_chain_support_details)
} }
fn choose_swap_surface_format( fn choose_swap_surface_format(
@ -714,8 +737,8 @@ impl VulkanApp {
actual_extent actual_extent
} }
fn create_swap_chain(&mut self) { fn create_swap_chain(&mut self) -> Result<(), String> {
let swap_chain_support = self.query_swap_chain_support(self.physical_device); let swap_chain_support = self.query_swap_chain_support(self.physical_device)?;
let surface_format_idx = self let surface_format_idx = self
.choose_swap_surface_format(&swap_chain_support.formats) .choose_swap_surface_format(&swap_chain_support.formats)
@ -776,7 +799,7 @@ impl VulkanApp {
) )
}; };
if result != ffi::VkResult_VK_SUCCESS { if result != ffi::VkResult_VK_SUCCESS {
panic!("Failed to create swap chain!"); return Err(String::from("Failed to create swap chain!"));
} }
unsafe { unsafe {
@ -798,9 +821,11 @@ impl VulkanApp {
self.swap_chain_image_format = swap_chain_support.formats[surface_format_idx].format; self.swap_chain_image_format = swap_chain_support.formats[surface_format_idx].format;
self.swap_chain_extent = extent; self.swap_chain_extent = extent;
Ok(())
} }
fn create_image_views(&mut self) { fn create_image_views(&mut self) -> Result<(), String> {
self.swap_chain_image_views self.swap_chain_image_views
.resize(self.swap_chain_images.len(), std::ptr::null_mut()); .resize(self.swap_chain_images.len(), std::ptr::null_mut());
@ -833,9 +858,11 @@ impl VulkanApp {
) )
}; };
if result != ffi::VkResult_VK_SUCCESS { if result != ffi::VkResult_VK_SUCCESS {
panic!("Failed to create image view {}!", idx); return Err(format!("Failed to create image view {}!", idx));
} }
} }
Ok(())
} }
fn create_graphics_pipeline(&mut self) -> Result<(), String> { fn create_graphics_pipeline(&mut self) -> Result<(), String> {
@ -908,7 +935,7 @@ impl VulkanApp {
) )
}; };
if result != ffi::VkResult_VK_SUCCESS { if result != ffi::VkResult_VK_SUCCESS {
panic!("Failed to create pipeline layout!"); return Err(String::from("Failed to create pipeline layout!"));
} }
// TODO: Use the *_shader_stage_info structs before vert/frag_shader_module is cleaned up. // TODO: Use the *_shader_stage_info structs before vert/frag_shader_module is cleaned up.