From 90d308143e8fb0ee0d1ab96d38d53dae7095860a Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Mon, 20 Jan 2020 04:01:36 +0100 Subject: [PATCH] refactoring --- engine/src/render/vulkan/binding.rs | 4 +- engine/src/render/vulkan/mod.rs | 88 +++++++------------------- engine/src/render/vulkan/swapchains.rs | 70 ++++++++++++++++---- 3 files changed, 85 insertions(+), 77 deletions(-) diff --git a/engine/src/render/vulkan/binding.rs b/engine/src/render/vulkan/binding.rs index eeb88a6..e464553 100644 --- a/engine/src/render/vulkan/binding.rs +++ b/engine/src/render/vulkan/binding.rs @@ -6,7 +6,7 @@ use vulkano::device as vd; use vulkano::swapchain as vs; // A Binding to a surface, resulting in concrete device information. -pub struct Binding { +pub struct SurfaceBinding { instance: Arc, physical_device_ix: usize, pub device: Arc, @@ -15,7 +15,7 @@ pub struct Binding { pub present_queue: Arc, } -impl Binding { +impl SurfaceBinding { pub fn physical_device(&self) -> vi::PhysicalDevice { vi::PhysicalDevice::from_index(&self.instance, self.physical_device_ix).unwrap() } diff --git a/engine/src/render/vulkan/mod.rs b/engine/src/render/vulkan/mod.rs index 6feef40..5a1f992 100644 --- a/engine/src/render/vulkan/mod.rs +++ b/engine/src/render/vulkan/mod.rs @@ -6,7 +6,6 @@ use vulkano::command_buffer as vc; use vulkano::buffer as vb; use vulkano::instance as vi; use vulkano::swapchain as vs; -use vulkano::framebuffer as vf; use vulkano::pipeline as vp; use vulkano::sync::{FenceSignalFuture, GpuFuture}; @@ -28,11 +27,8 @@ pub struct Instance { debug_callback: vi::debug::DebugCallback, vulkan: Arc, - surface: Option>>, - binding: Option>, - swapchains: Option>, - render_pass: Option>, - framebuffers: Vec>, + surface_binding: Option>, + swapchain_binding: Option>, command_buffers: Vec>, armed: bool, @@ -62,11 +58,8 @@ impl Instance { debug_callback, vulkan, - surface: None, - binding: None, - swapchains: None, - render_pass: None, - framebuffers: vec![], + surface_binding: None, + swapchain_binding: None, command_buffers: vec![], previous_frame_end: None, @@ -79,35 +72,34 @@ impl Instance { self.vulkan.clone() } - pub fn get_swapchain(&self) -> Arc> { - self.swapchains.as_ref().unwrap().chain.clone() + fn swapchain_binding(&self) -> &swapchains::SwapchainBinding { + self.swapchain_binding.as_ref().unwrap() + } + + fn surface_binding(&self) -> &binding::SurfaceBinding { + self.surface_binding.as_ref().unwrap() } pub fn use_surface(&mut self, surface: &Arc>) { - self.surface = Some(surface.clone()); - - self.binding = Some(binding::Binding::new(&self.vulkan, self.surface.as_ref().unwrap().clone())); - log::info!("Bound to Vulkan Device: {}", self.binding.as_ref().unwrap().physical_device().name()); + self.surface_binding = Some(binding::SurfaceBinding::new(&self.vulkan, surface.clone())); + log::info!("Bound to Vulkan Device: {}", self.surface_binding().physical_device().name()); self.arm(); } fn arm(&mut self) { - self.swapchains = Some(swapchains::Swapchains::new(self.binding.as_ref().unwrap(), self.swapchains.as_ref())); + self.swapchain_binding = Some(swapchains::SwapchainBinding::new(self.surface_binding(), self.swapchain_binding.as_ref())); - let device = self.binding.as_ref().unwrap().device.clone(); - let chain = self.get_swapchain(); + let device = self.surface_binding().device.clone(); + let chain = self.swapchain_binding().chain.clone(); - self.create_render_pass(chain.format()); - self.create_framebuffers(); - - let render_pass = self.render_pass.as_ref().unwrap().clone(); + let render_pass = self.swapchain_binding().render_pass.clone(); let pipeline = shaders::pipeline_forward(device.clone(), chain.dimensions(), render_pass); let (buffer, future) = vb::immutable::ImmutableBuffer::from_iter( data::vertices().iter().cloned(), vb::BufferUsage::vertex_buffer(), - self.binding.as_ref().unwrap().graphics_queue.clone(), + self.surface_binding().graphics_queue.clone(), ).unwrap(); future.flush().unwrap(); @@ -129,7 +121,7 @@ impl Instance { self.arm(); } - let chain = self.get_swapchain(); + let chain = self.swapchain_binding().chain.clone(); let (image_index, acquire_future) = match vs::acquire_next_image(chain.clone(), None) { Ok(r) => r, Err(vs::AcquireError::OutOfDate) => { @@ -141,13 +133,13 @@ impl Instance { }; let command_buffer = self.command_buffers[image_index].clone(); - let gq = self.binding.as_ref().unwrap().graphics_queue.clone(); - let pq = self.binding.as_ref().unwrap().present_queue.clone(); + let gq = self.surface_binding().graphics_queue.clone(); + let pq = self.surface_binding().present_queue.clone(); let future = acquire_future .then_execute(gq, command_buffer) .unwrap() - .then_swapchain_present(pq, chain, image_index) + .then_swapchain_present(pq, chain.clone(), image_index) .then_signal_fence_and_flush(); match future { @@ -167,46 +159,14 @@ impl Instance { } } - fn create_render_pass(&mut self, color_format: vulkano::format::Format) { - let device = self.binding.as_ref().unwrap().device.clone(); - - self.render_pass = Some(Arc::new(vulkano::single_pass_renderpass!(device.clone(), - attachments: { - color: { - load: Clear, - store: Store, - format: color_format, - samples: 1, - } - }, - pass: { - color: [color], - depth_stencil: {} - } - ).unwrap())) - } - - fn create_framebuffers(&mut self) { - let render_pass = self.render_pass.as_ref().unwrap().clone(); - - self.framebuffers = self.swapchains.as_ref().unwrap().images.iter() - .map(|image| { - let fba: Arc = Arc::new(vf::Framebuffer::start(render_pass.clone()) - .add(image.clone()).unwrap() - .build().unwrap()); - fba - }) - .collect::>(); - } - fn create_command_buffers( &mut self, pipeline: Arc, vertex_buffer: Arc, ) { - let device = self.binding.as_ref().unwrap().device.clone(); - let qf = self.binding.as_ref().unwrap().graphics_queue.family(); - self.command_buffers = self.framebuffers.iter() + let device = self.surface_binding().device.clone(); + let qf = self.surface_binding().graphics_queue.family(); + self.command_buffers = self.swapchain_binding().framebuffers.iter() .map(|framebuffer| { Arc::new(vc::AutoCommandBufferBuilder::primary_simultaneous_use(device.clone(), qf) .unwrap() diff --git a/engine/src/render/vulkan/swapchains.rs b/engine/src/render/vulkan/swapchains.rs index c71b87c..ef9a32b 100644 --- a/engine/src/render/vulkan/swapchains.rs +++ b/engine/src/render/vulkan/swapchains.rs @@ -3,17 +3,23 @@ use std::sync::Arc; use vulkano::swapchain as vs; use vulkano::image as vm; use vulkano::format as vf; +use vulkano::framebuffer as vfb; use vulkano::sync as vy; -pub struct Swapchains { +pub struct SwapchainBinding { pub chain: Arc>, pub images: Vec>>, + pub render_pass: Arc, + pub framebuffers: Vec>, } -impl Swapchains { - pub fn new(binding: &super::binding::Binding, previous: Option<&Swapchains>) -> Self { - let physical_device = binding.physical_device(); - let capabilities = binding.surface.capabilities(physical_device).expect("could not get capabilities"); +impl SwapchainBinding { + pub fn new( + surface_binding: &super::binding::SurfaceBinding, + previous: Option<&SwapchainBinding> + ) -> Self { + let physical_device = surface_binding.physical_device(); + let capabilities = surface_binding.surface.capabilities(physical_device).expect("could not get capabilities"); let surface_format = Self::choose_swap_surface_format(&capabilities.supported_formats); let present_mode = Self::choose_swap_present_mode(capabilities.present_modes); @@ -31,11 +37,11 @@ impl Swapchains { .. vm::ImageUsage::none() }; - let indices = super::qfi::QueueFamilyIndices::find(&binding.surface, &physical_device).unwrap(); + let indices = super::qfi::QueueFamilyIndices::find(&surface_binding.surface, &physical_device).unwrap(); let sharing: vy::SharingMode = if indices.graphics_family != indices.present_family { - vec![&binding.graphics_queue, &binding.present_queue].as_slice().into() + vec![&surface_binding.graphics_queue, &surface_binding.present_queue].as_slice().into() } else { - (&binding.graphics_queue).into() + (&surface_binding.graphics_queue).into() }; let prev = match previous { @@ -44,8 +50,8 @@ impl Swapchains { }; let (chain, images) = vs::Swapchain::new( - binding.device.clone(), - binding.surface.clone(), + surface_binding.device.clone(), + surface_binding.surface.clone(), image_count, surface_format.0, extent, @@ -59,11 +65,53 @@ impl Swapchains { prev.as_ref(), ).expect("could not create swap chain"); + let render_pass = Self::create_render_pass(surface_binding, chain.format()); + let framebuffers = Self::create_framebuffers(render_pass.clone(), images.clone()); + Self { - chain, images + chain, + images, + render_pass, + framebuffers, } } + fn create_render_pass( + surface_binding: &super::binding::SurfaceBinding, + color_format: vulkano::format::Format, + ) -> Arc { + let device = surface_binding.device.clone(); + + Arc::new(vulkano::single_pass_renderpass!(device, + attachments: { + color: { + load: Clear, + store: Store, + format: color_format, + samples: 1, + } + }, + pass: { + color: [color], + depth_stencil: {} + } + ).unwrap()) + } + + fn create_framebuffers( + render_pass: Arc, + images: Vec>>, + ) -> Vec> { + images.iter() + .map(|image| { + let fba: Arc = Arc::new(vfb::Framebuffer::start(render_pass.clone()) + .add(image.clone()).unwrap() + .build().unwrap()); + fba + }) + .collect::>() + } + fn choose_swap_surface_format(available_formats: &[(vf::Format, vs::ColorSpace)]) -> (vf::Format, vs::ColorSpace) { *available_formats.iter() .find(|(format, color_space)|