More code reorganization

This commit is contained in:
Timothy Warren 2023-04-20 11:28:43 -04:00
parent e61e15770e
commit da64696c8f
2 changed files with 221 additions and 212 deletions

View File

@ -6,7 +6,6 @@ use structs::*;
use ::anyhow::{anyhow, Result}; use ::anyhow::{anyhow, Result};
use ::nalgebra_glm as glm; use ::nalgebra_glm as glm;
use ::std::collections::HashSet;
use ::std::mem::size_of; use ::std::mem::size_of;
use ::std::ptr::copy_nonoverlapping as memcpy; use ::std::ptr::copy_nonoverlapping as memcpy;
use ::std::time::Instant; use ::std::time::Instant;
@ -206,112 +205,3 @@ impl App {
Ok(()) Ok(())
} }
} }
//================================================
// Functions
//================================================
pub(crate) unsafe fn check_physical_device_extensions(
instance: &Instance,
physical_device: vk::PhysicalDevice,
) -> Result<()> {
let extensions = instance
.enumerate_device_extension_properties(physical_device, None)?
.iter()
.map(|e| e.extension_name)
.collect::<HashSet<_>>();
if DEVICE_EXTENSIONS.iter().all(|e| extensions.contains(e)) {
Ok(())
} else {
Err(anyhow!(SuitabilityError(
"Missing required device extensions."
)))
}
}
pub(crate) fn get_swapchain_surface_format(
formats: &[vk::SurfaceFormatKHR],
) -> vk::SurfaceFormatKHR {
formats
.iter()
.cloned()
.find(|f| {
f.format == vk::Format::B8G8R8A8_SRGB
&& f.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR
})
.unwrap_or_else(|| formats[0])
}
pub(crate) fn get_swapchain_present_mode(
present_modes: &[vk::PresentModeKHR],
) -> vk::PresentModeKHR {
present_modes
.iter()
.cloned()
.find(|m| *m == vk::PresentModeKHR::MAILBOX)
.unwrap_or(vk::PresentModeKHR::FIFO)
}
pub(crate) fn get_swapchain_extent(
window: &Window,
capabilities: vk::SurfaceCapabilitiesKHR,
) -> vk::Extent2D {
if capabilities.current_extent.width != u32::MAX {
capabilities.current_extent
} else {
let size = window.inner_size();
let clamp = |min: u32, max: u32, v: u32| min.max(max.min(v));
vk::Extent2D::builder()
.width(clamp(
capabilities.min_image_extent.width,
capabilities.max_image_extent.width,
size.width,
))
.height(clamp(
capabilities.min_image_extent.height,
capabilities.max_image_extent.height,
size.height,
))
.build()
}
}
pub(crate) unsafe fn create_shader_module(
device: &Device,
bytecode: &[u8],
) -> Result<vk::ShaderModule> {
let bytecode = Vec::<u8>::from(bytecode);
let (prefix, code, suffix) = bytecode.align_to::<u32>();
if !prefix.is_empty() || !suffix.is_empty() {
return Err(anyhow!("Shader bytecode is not properly aligned."));
}
let info = vk::ShaderModuleCreateInfo::builder()
.code_size(bytecode.len())
.code(code);
Ok(device.create_shader_module(&info, None)?)
}
pub(crate) unsafe fn create_image_view(
device: &Device,
image: vk::Image,
format: vk::Format,
aspects: vk::ImageAspectFlags,
) -> Result<vk::ImageView> {
let subresource_range = vk::ImageSubresourceRange::builder()
.aspect_mask(aspects)
.base_mip_level(0)
.level_count(1)
.base_array_layer(0)
.layer_count(1);
let info = vk::ImageViewCreateInfo::builder()
.image(image)
.view_type(vk::ImageViewType::_2D)
.format(format)
.subresource_range(subresource_range);
Ok(device.create_image_view(&info, None)?)
}

View File

@ -95,11 +95,10 @@ pub(crate) struct AppData {
pub(super) images_in_flight: Vec<vk::Fence>, pub(super) images_in_flight: Vec<vk::Fence>,
} }
//================================================
// Create / Destroy Data
//================================================
impl AppData { impl AppData {
//================================================
// Create / Destroy Data
//================================================
pub(super) unsafe fn create( pub(super) unsafe fn create(
&mut self, &mut self,
window: &Window, window: &Window,
@ -134,6 +133,43 @@ impl AppData {
Ok((instance, device)) Ok((instance, device))
} }
/// Destroys our Vulkan app, in reverse order of creation
///
/// # Safety
/// Here be Dragons
pub(super) unsafe fn destroy(&mut self, instance: &Instance, device: &Device) {
self.destroy_swapchain(device);
device.destroy_sampler(self.texture_sampler, None);
device.destroy_image_view(self.texture_image_view, None);
device.destroy_image(self.texture_image, None);
device.free_memory(self.texture_image_memory, None);
device.destroy_descriptor_set_layout(self.descriptor_set_layout, None);
device.destroy_buffer(self.index_buffer, None);
device.free_memory(self.index_buffer_memory, None);
device.destroy_buffer(self.vertex_buffer, None);
device.free_memory(self.vertex_buffer_memory, None);
self.in_flight_fences
.iter()
.for_each(|f| device.destroy_fence(*f, None));
self.render_finished_semaphores
.iter()
.for_each(|s| device.destroy_semaphore(*s, None));
self.image_available_semaphores
.iter()
.for_each(|s| device.destroy_semaphore(*s, None));
device.destroy_command_pool(self.command_pool, None);
device.destroy_device(None);
instance.destroy_surface_khr(self.surface, None);
if VALIDATION_ENABLED {
instance.destroy_debug_utils_messenger_ext(self.messenger, None);
}
instance.destroy_instance(None);
}
unsafe fn create_instance(&mut self, window: &Window, entry: &Entry) -> Result<Instance> { unsafe fn create_instance(&mut self, window: &Window, entry: &Entry) -> Result<Instance> {
// Application Info // Application Info
let application_info = vk::ApplicationInfo::builder() let application_info = vk::ApplicationInfo::builder()
@ -241,48 +277,12 @@ impl AppData {
.for_each(|v| device.destroy_image_view(*v, None)); .for_each(|v| device.destroy_image_view(*v, None));
device.destroy_swapchain_khr(self.swapchain, None); device.destroy_swapchain_khr(self.swapchain, None);
} }
}
/// Destroys our Vulkan app, in reverse order of creation //================================================
/// // Physical Device
/// # Safety //================================================
/// Here be Dragons impl AppData {
pub unsafe fn destroy(&mut self, instance: &Instance, device: &Device) {
self.destroy_swapchain(device);
device.destroy_sampler(self.texture_sampler, None);
device.destroy_image_view(self.texture_image_view, None);
device.destroy_image(self.texture_image, None);
device.free_memory(self.texture_image_memory, None);
device.destroy_descriptor_set_layout(self.descriptor_set_layout, None);
device.destroy_buffer(self.index_buffer, None);
device.free_memory(self.index_buffer_memory, None);
device.destroy_buffer(self.vertex_buffer, None);
device.free_memory(self.vertex_buffer_memory, None);
self.in_flight_fences
.iter()
.for_each(|f| device.destroy_fence(*f, None));
self.render_finished_semaphores
.iter()
.for_each(|s| device.destroy_semaphore(*s, None));
self.image_available_semaphores
.iter()
.for_each(|s| device.destroy_semaphore(*s, None));
device.destroy_command_pool(self.command_pool, None);
device.destroy_device(None);
instance.destroy_surface_khr(self.surface, None);
if VALIDATION_ENABLED {
instance.destroy_debug_utils_messenger_ext(self.messenger, None);
}
instance.destroy_instance(None);
}
//================================================
// Physical Device
//================================================
unsafe fn pick_physical_device(&mut self, instance: &Instance) -> Result<()> { unsafe fn pick_physical_device(&mut self, instance: &Instance) -> Result<()> {
for physical_device in instance.enumerate_physical_devices()? { for physical_device in instance.enumerate_physical_devices()? {
let properties = instance.get_physical_device_properties(physical_device); let properties = instance.get_physical_device_properties(physical_device);
@ -322,11 +322,31 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ pub(crate) unsafe fn check_physical_device_extensions(
// Logical Device instance: &Instance,
//================================================ physical_device: vk::PhysicalDevice,
) -> Result<()> {
let extensions = instance
.enumerate_device_extension_properties(physical_device, None)?
.iter()
.map(|e| e.extension_name)
.collect::<HashSet<_>>();
if DEVICE_EXTENSIONS.iter().all(|e| extensions.contains(e)) {
Ok(())
} else {
Err(anyhow!(SuitabilityError(
"Missing required device extensions."
)))
}
}
//================================================
// Logical Device
//================================================
impl AppData {
unsafe fn create_logical_device(&mut self, instance: &Instance) -> Result<Device> { unsafe fn create_logical_device(&mut self, instance: &Instance) -> Result<Device> {
// Queue Create Infos // Queue Create Infos
let indices = QueueFamilyIndices::get(instance, self, self.physical_device)?; let indices = QueueFamilyIndices::get(instance, self, self.physical_device)?;
@ -385,11 +405,12 @@ impl AppData {
Ok(device) Ok(device)
} }
}
//================================================ //================================================
// Swapchain // Swapchain
//================================================ //================================================
impl AppData {
unsafe fn create_swapchain( unsafe fn create_swapchain(
&mut self, &mut self,
window: &Window, window: &Window,
@ -488,11 +509,59 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ pub(crate) fn get_swapchain_surface_format(
// Pipeline formats: &[vk::SurfaceFormatKHR],
//================================================ ) -> vk::SurfaceFormatKHR {
formats
.iter()
.cloned()
.find(|f| {
f.format == vk::Format::B8G8R8A8_SRGB
&& f.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR
})
.unwrap_or_else(|| formats[0])
}
pub(crate) fn get_swapchain_present_mode(
present_modes: &[vk::PresentModeKHR],
) -> vk::PresentModeKHR {
present_modes
.iter()
.cloned()
.find(|m| *m == vk::PresentModeKHR::MAILBOX)
.unwrap_or(vk::PresentModeKHR::FIFO)
}
pub(crate) fn get_swapchain_extent(
window: &Window,
capabilities: vk::SurfaceCapabilitiesKHR,
) -> vk::Extent2D {
if capabilities.current_extent.width != u32::MAX {
capabilities.current_extent
} else {
let size = window.inner_size();
let clamp = |min: u32, max: u32, v: u32| min.max(max.min(v));
vk::Extent2D::builder()
.width(clamp(
capabilities.min_image_extent.width,
capabilities.max_image_extent.width,
size.width,
))
.height(clamp(
capabilities.min_image_extent.height,
capabilities.max_image_extent.height,
size.height,
))
.build()
}
}
//================================================
// Pipeline
//================================================
impl AppData {
unsafe fn create_render_pass(&mut self, instance: &Instance, device: &Device) -> Result<()> { unsafe fn create_render_pass(&mut self, instance: &Instance, device: &Device) -> Result<()> {
let color_attachment = vk::AttachmentDescription::builder() let color_attachment = vk::AttachmentDescription::builder()
.format(self.swapchain_format) .format(self.swapchain_format)
@ -687,11 +756,29 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ pub(crate) unsafe fn create_shader_module(
// Framebuffers device: &Device,
//================================================ bytecode: &[u8],
) -> Result<vk::ShaderModule> {
let bytecode = Vec::<u8>::from(bytecode);
let (prefix, code, suffix) = bytecode.align_to::<u32>();
if !prefix.is_empty() || !suffix.is_empty() {
return Err(anyhow!("Shader bytecode is not properly aligned."));
}
let info = vk::ShaderModuleCreateInfo::builder()
.code_size(bytecode.len())
.code(code);
Ok(device.create_shader_module(&info, None)?)
}
//================================================
// Framebuffers
//================================================
impl AppData {
unsafe fn create_framebuffers(&mut self, device: &Device) -> Result<()> { unsafe fn create_framebuffers(&mut self, device: &Device) -> Result<()> {
self.framebuffers = self self.framebuffers = self
.swapchain_image_views .swapchain_image_views
@ -711,11 +798,12 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ //================================================
// Command Pool // Command Pool
//================================================ //================================================
impl AppData {
unsafe fn create_command_pool(&mut self, instance: &Instance, device: &Device) -> Result<()> { unsafe fn create_command_pool(&mut self, instance: &Instance, device: &Device) -> Result<()> {
let indices = QueueFamilyIndices::get(instance, self, self.physical_device)?; let indices = QueueFamilyIndices::get(instance, self, self.physical_device)?;
@ -727,11 +815,12 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ //================================================
// Depth Objects // Depth Objects
//================================================ //================================================
impl AppData {
unsafe fn create_depth_objects(&mut self, instance: &Instance, device: &Device) -> Result<()> { unsafe fn create_depth_objects(&mut self, instance: &Instance, device: &Device) -> Result<()> {
let format = self.get_depth_format(instance)?; let format = self.get_depth_format(instance)?;
@ -798,11 +887,12 @@ impl AppData {
}) })
.ok_or_else(|| anyhow!("Failed to find supported depth image format.")) .ok_or_else(|| anyhow!("Failed to find supported depth image format."))
} }
}
//================================================ //================================================
// Texture // Texture
//================================================ //================================================
impl AppData {
fn create_texture_image(&mut self, instance: &Instance, device: &Device) -> Result<()> { fn create_texture_image(&mut self, instance: &Instance, device: &Device) -> Result<()> {
// Load the image // Load the image
let image = File::open("resources/viking_room.png")?; let image = File::open("resources/viking_room.png")?;
@ -908,11 +998,12 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ //================================================
// Model // Model
//================================================ //================================================
impl AppData {
unsafe fn load_model(&mut self) -> Result<()> { unsafe fn load_model(&mut self) -> Result<()> {
let mut reader = BufReader::new(File::open("resources/viking_room.obj")?); let mut reader = BufReader::new(File::open("resources/viking_room.obj")?);
@ -958,11 +1049,12 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ //================================================
// Buffers // Buffers
//================================================ //================================================
impl AppData {
unsafe fn create_vertex_buffer(&mut self, instance: &Instance, device: &Device) -> Result<()> { unsafe fn create_vertex_buffer(&mut self, instance: &Instance, device: &Device) -> Result<()> {
// Create staging buffer // Create staging buffer
let size = (size_of::<Vertex>() * self.vertices.len()) as u64; let size = (size_of::<Vertex>() * self.vertices.len()) as u64;
@ -1058,11 +1150,11 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ //================================================
// Descriptors // Descriptors
//================================================ //================================================
impl AppData {
unsafe fn create_descriptor_pool(&mut self, device: &Device) -> Result<()> { unsafe fn create_descriptor_pool(&mut self, device: &Device) -> Result<()> {
let ubo_size = vk::DescriptorPoolSize::builder() let ubo_size = vk::DescriptorPoolSize::builder()
.type_(vk::DescriptorType::UNIFORM_BUFFER) .type_(vk::DescriptorType::UNIFORM_BUFFER)
@ -1125,11 +1217,12 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ //================================================
// Command Buffers // Command Buffers
//================================================ //================================================
impl AppData {
unsafe fn create_command_buffers(&mut self, device: &Device) -> Result<()> { unsafe fn create_command_buffers(&mut self, device: &Device) -> Result<()> {
// Create the buffers // Create the buffers
let allocate_info = vk::CommandBufferAllocateInfo::builder() let allocate_info = vk::CommandBufferAllocateInfo::builder()
@ -1202,11 +1295,12 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ //================================================
// Sync Objects // Sync Objects
//================================================ //================================================
impl AppData {
unsafe fn create_sync_objects(&mut self, device: &Device) -> Result<()> { unsafe fn create_sync_objects(&mut self, device: &Device) -> Result<()> {
let semaphore_info = vk::SemaphoreCreateInfo::builder(); let semaphore_info = vk::SemaphoreCreateInfo::builder();
let fence_info = vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED); let fence_info = vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED);
@ -1229,11 +1323,12 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ //================================================
// Shared (Buffers) // Shared (Buffers)
//================================================ //================================================
impl AppData {
unsafe fn create_buffer( unsafe fn create_buffer(
&self, &self,
instance: &Instance, instance: &Instance,
@ -1278,11 +1373,12 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ //================================================
// Shared (Images) // Shared (Images)
//================================================ //================================================
impl AppData {
unsafe fn create_image( unsafe fn create_image(
&self, &self,
instance: &Instance, instance: &Instance,
@ -1427,11 +1523,34 @@ impl AppData {
Ok(()) Ok(())
} }
}
//================================================ pub(crate) unsafe fn create_image_view(
// Shared (Other) device: &Device,
//================================================ image: vk::Image,
format: vk::Format,
aspects: vk::ImageAspectFlags,
) -> Result<vk::ImageView> {
let subresource_range = vk::ImageSubresourceRange::builder()
.aspect_mask(aspects)
.base_mip_level(0)
.level_count(1)
.base_array_layer(0)
.layer_count(1);
let info = vk::ImageViewCreateInfo::builder()
.image(image)
.view_type(vk::ImageViewType::_2D)
.format(format)
.subresource_range(subresource_range);
Ok(device.create_image_view(&info, None)?)
}
//================================================
// Shared (Other)
//================================================
impl AppData {
unsafe fn get_memory_type_index( unsafe fn get_memory_type_index(
&self, &self,
instance: &Instance, instance: &Instance,