More code reorganization
This commit is contained in:
parent
e61e15770e
commit
da64696c8f
110
src/app.rs
110
src/app.rs
@ -6,7 +6,6 @@ use structs::*;
|
||||
|
||||
use ::anyhow::{anyhow, Result};
|
||||
use ::nalgebra_glm as glm;
|
||||
use ::std::collections::HashSet;
|
||||
use ::std::mem::size_of;
|
||||
use ::std::ptr::copy_nonoverlapping as memcpy;
|
||||
use ::std::time::Instant;
|
||||
@ -206,112 +205,3 @@ impl App {
|
||||
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)?)
|
||||
}
|
||||
|
229
src/app/data.rs
229
src/app/data.rs
@ -95,11 +95,10 @@ pub(crate) struct AppData {
|
||||
pub(super) images_in_flight: Vec<vk::Fence>,
|
||||
}
|
||||
|
||||
impl AppData {
|
||||
//================================================
|
||||
// Create / Destroy Data
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
pub(super) unsafe fn create(
|
||||
&mut self,
|
||||
window: &Window,
|
||||
@ -134,6 +133,43 @@ impl AppData {
|
||||
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> {
|
||||
// Application Info
|
||||
let application_info = vk::ApplicationInfo::builder()
|
||||
@ -241,48 +277,12 @@ impl AppData {
|
||||
.for_each(|v| device.destroy_image_view(*v, None));
|
||||
device.destroy_swapchain_khr(self.swapchain, None);
|
||||
}
|
||||
|
||||
/// Destroys our Vulkan app, in reverse order of creation
|
||||
///
|
||||
/// # Safety
|
||||
/// Here be Dragons
|
||||
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
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn pick_physical_device(&mut self, instance: &Instance) -> Result<()> {
|
||||
for physical_device in instance.enumerate_physical_devices()? {
|
||||
let properties = instance.get_physical_device_properties(physical_device);
|
||||
@ -322,11 +322,31 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
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."
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Logical Device
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_logical_device(&mut self, instance: &Instance) -> Result<Device> {
|
||||
// Queue Create Infos
|
||||
let indices = QueueFamilyIndices::get(instance, self, self.physical_device)?;
|
||||
@ -385,11 +405,12 @@ impl AppData {
|
||||
|
||||
Ok(device)
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Swapchain
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_swapchain(
|
||||
&mut self,
|
||||
window: &Window,
|
||||
@ -488,11 +509,59 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Pipeline
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_render_pass(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||
let color_attachment = vk::AttachmentDescription::builder()
|
||||
.format(self.swapchain_format)
|
||||
@ -687,11 +756,29 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
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)?)
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Framebuffers
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_framebuffers(&mut self, device: &Device) -> Result<()> {
|
||||
self.framebuffers = self
|
||||
.swapchain_image_views
|
||||
@ -711,11 +798,12 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Command Pool
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_command_pool(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||
let indices = QueueFamilyIndices::get(instance, self, self.physical_device)?;
|
||||
|
||||
@ -727,11 +815,12 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Depth Objects
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_depth_objects(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||
let format = self.get_depth_format(instance)?;
|
||||
|
||||
@ -798,11 +887,12 @@ impl AppData {
|
||||
})
|
||||
.ok_or_else(|| anyhow!("Failed to find supported depth image format."))
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Texture
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
fn create_texture_image(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||
// Load the image
|
||||
let image = File::open("resources/viking_room.png")?;
|
||||
@ -908,11 +998,12 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Model
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn load_model(&mut self) -> Result<()> {
|
||||
let mut reader = BufReader::new(File::open("resources/viking_room.obj")?);
|
||||
|
||||
@ -958,11 +1049,12 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Buffers
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_vertex_buffer(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||
// Create staging buffer
|
||||
let size = (size_of::<Vertex>() * self.vertices.len()) as u64;
|
||||
@ -1058,11 +1150,11 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
//================================================
|
||||
// Descriptors
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_descriptor_pool(&mut self, device: &Device) -> Result<()> {
|
||||
let ubo_size = vk::DescriptorPoolSize::builder()
|
||||
.type_(vk::DescriptorType::UNIFORM_BUFFER)
|
||||
@ -1125,11 +1217,12 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Command Buffers
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_command_buffers(&mut self, device: &Device) -> Result<()> {
|
||||
// Create the buffers
|
||||
let allocate_info = vk::CommandBufferAllocateInfo::builder()
|
||||
@ -1202,11 +1295,12 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Sync Objects
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_sync_objects(&mut self, device: &Device) -> Result<()> {
|
||||
let semaphore_info = vk::SemaphoreCreateInfo::builder();
|
||||
let fence_info = vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED);
|
||||
@ -1229,11 +1323,12 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Shared (Buffers)
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_buffer(
|
||||
&self,
|
||||
instance: &Instance,
|
||||
@ -1278,11 +1373,12 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Shared (Images)
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn create_image(
|
||||
&self,
|
||||
instance: &Instance,
|
||||
@ -1427,11 +1523,34 @@ impl AppData {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
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)?)
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Shared (Other)
|
||||
//================================================
|
||||
|
||||
impl AppData {
|
||||
unsafe fn get_memory_type_index(
|
||||
&self,
|
||||
instance: &Instance,
|
||||
|
Loading…
Reference in New Issue
Block a user