diff options
Diffstat (limited to 'src/graphics_window_dressing.rs')
| -rw-r--r-- | src/graphics_window_dressing.rs | 117 |
1 files changed, 92 insertions, 25 deletions
diff --git a/src/graphics_window_dressing.rs b/src/graphics_window_dressing.rs index e35332f..63fc693 100644 --- a/src/graphics_window_dressing.rs +++ b/src/graphics_window_dressing.rs @@ -1,6 +1,8 @@ #![deny(unsafe_code)] use crate::error::*; -use crate::graphics_permanent::{ PermanentGraphicsState, QueueFamilyIndices }; +use crate::graphics_permanent::{ + PermanentGraphicsState, GraphicsStateForReinit, QueueFamilyIndices +}; use std::collections::BTreeSet; use vulkanalia::{ Device, Instance }; @@ -73,14 +75,15 @@ pub struct Concurrency { impl WindowDressing { pub fn new(permanent: &PermanentGraphicsState, - physical_device: vk::PhysicalDevice, - indices: QueueFamilyIndices) + for_reinit: &GraphicsStateForReinit) -> Result<Self> { let window = &permanent.window; let instance = &permanent.instance; let surface = &permanent.surface; let device = &permanent.device; + let physical_device = &for_reinit.physical_device; + let indices = &for_reinit.indices; let swapchain = init_swapchain( window, instance, surface, &physical_device, device, &indices)?; @@ -93,9 +96,10 @@ impl WindowDressing { let framebuffers = init_framebuffers( device, &swapchain.extent, &swapchain.image_views, &render_pass)?; - let (command_pool, command_buffers) - = init_commands(device, &swapchain.extent, &framebuffers, - &render_pass, &pipeline, &indices)?; + let command_pool = init_command_pool(device, indices)?; + let command_buffers = init_commands(device, &swapchain.extent, + &framebuffers, &render_pass, + &pipeline, &command_pool)?; let concurrency = init_concurrency(device, &swapchain.images)?; @@ -111,9 +115,58 @@ impl WindowDressing { }) } + #[allow(unsafe_code)] - pub fn destroy(self, permanent: &PermanentGraphicsState) { + pub fn reinit(&mut self, permanent: &PermanentGraphicsState, + for_reinit: &GraphicsStateForReinit) + -> Result<()> + { + let window = &permanent.window; + let instance = &permanent.instance; + let surface = &permanent.surface; let device = &permanent.device; + let physical_device = &for_reinit.physical_device; + let indices = &for_reinit.indices; + + unsafe { device.device_wait_idle() }.unwrap(); + + self.destroy_replaceable(device); + + let swapchain = init_swapchain( + window, instance, surface, &physical_device, device, &indices)?; + + let render_pass = init_render_pass(device, &swapchain.format)?; + + let (pipeline_layout, pipeline) + = init_pipeline(device, &swapchain.extent, &render_pass)?; + + let framebuffers = init_framebuffers( + device, &swapchain.extent, &swapchain.image_views, &render_pass)?; + + // Notice that we reused the command pool. + let command_buffers = init_commands( + device, &swapchain.extent, &framebuffers, &render_pass, + &pipeline, &self.command_pool)?; + + self.concurrency.image_fences.resize(swapchain.images.len(), + vk::Fence::null()); + + self.swapchain = swapchain; + self.render_pass = render_pass; + self.pipeline = pipeline; + self.pipeline_layout = pipeline_layout; + self.framebuffers = framebuffers; + self.command_buffers = command_buffers; + + Ok(()) + } + + + // This relies on its caller to have already waited for the device to be + // idle. + #[allow(unsafe_code)] + pub fn destroy(mut self, device: &Device) { + self.destroy_replaceable(device); for semaphore in self.concurrency.image_available_semaphores { unsafe { device.destroy_semaphore(semaphore, None) }; @@ -127,18 +180,28 @@ impl WindowDressing { unsafe { device.destroy_fence(fence, None) }; } + // Notice that destroy_replaceable freed the pool, but did not destroy it. unsafe { device.destroy_command_pool(self.command_pool, None) }; + } - for framebuffer in self.framebuffers { - unsafe { device.destroy_framebuffer(framebuffer, None) }; + + #[allow(unsafe_code)] + fn destroy_replaceable(&mut self, device: &Device) { + for framebuffer in &self.framebuffers { + unsafe { device.destroy_framebuffer(*framebuffer, None) }; } + // Notice that we free the pool, but do not destroy it. + unsafe { + device.free_command_buffers(self.command_pool, &self.command_buffers) + }; + unsafe { device.destroy_pipeline(self.pipeline, None) }; - unsafe { device.destroy_render_pass(self.render_pass, None) }; unsafe { device.destroy_pipeline_layout(self.pipeline_layout, None) }; + unsafe { device.destroy_render_pass(self.render_pass, None) }; - for view in self.swapchain.image_views { - unsafe { device.destroy_image_view(view, None) }; + for view in &self.swapchain.image_views { + unsafe { device.destroy_image_view(*view, None) }; } unsafe { device.destroy_swapchain_khr(self.swapchain.swapchain, None) }; @@ -446,27 +509,31 @@ fn init_framebuffers(device: &Device, extent: &vk::Extent2D, #[allow(unsafe_code)] -fn init_commands(device: &Device, - extent: &vk::Extent2D, - framebuffers: &Vec<vk::Framebuffer>, - render_pass: &vk::RenderPass, - pipeline: &vk::Pipeline, - indices: &QueueFamilyIndices) - -> Result<(vk::CommandPool, Vec<vk::CommandBuffer>)> +fn init_command_pool(device: &Device, indices: &QueueFamilyIndices) + -> Result<vk::CommandPool> { - // We call this one last time. It's kind of a problem. - let command_pool_info = vk::CommandPoolCreateInfo::builder() .flags(vk::CommandPoolCreateFlags::empty()) .queue_family_index(indices.graphics); - let command_pool = unsafe { + Ok(unsafe { device.create_command_pool(&command_pool_info, None) - }?; + }?) +} + +#[allow(unsafe_code)] +fn init_commands(device: &Device, + extent: &vk::Extent2D, + framebuffers: &Vec<vk::Framebuffer>, + render_pass: &vk::RenderPass, + pipeline: &vk::Pipeline, + command_pool: &vk::CommandPool) + -> Result<Vec<vk::CommandBuffer>> +{ let command_buffer_allocation_info = vk::CommandBufferAllocateInfo::builder() - .command_pool(command_pool) + .command_pool(*command_pool) .level(vk::CommandBufferLevel::PRIMARY) .command_buffer_count(framebuffers.len() as u32); let command_buffers = unsafe { @@ -523,7 +590,7 @@ fn init_commands(device: &Device, unsafe { device.end_command_buffer(command_buffer) }?; } - Ok((command_pool, command_buffers)) + Ok(command_buffers) } |