refactoring

ecs
q3k 2020-01-20 04:01:36 +01:00
parent fde3c4f94c
commit 90d308143e
3 changed files with 85 additions and 77 deletions

View File

@ -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<WT> {
pub struct SurfaceBinding<WT> {
instance: Arc<vi::Instance>,
physical_device_ix: usize,
pub device: Arc<vd::Device>,
@ -15,7 +15,7 @@ pub struct Binding<WT> {
pub present_queue: Arc<vd::Queue>,
}
impl <WT> Binding<WT> {
impl <WT> SurfaceBinding<WT> {
pub fn physical_device(&self) -> vi::PhysicalDevice {
vi::PhysicalDevice::from_index(&self.instance, self.physical_device_ix).unwrap()
}

View File

@ -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<WT> {
debug_callback: vi::debug::DebugCallback,
vulkan: Arc<vi::Instance>,
surface: Option<Arc<vs::Surface<WT>>>,
binding: Option<binding::Binding<WT>>,
swapchains: Option<swapchains::Swapchains<WT>>,
render_pass: Option<Arc<dyn vf::RenderPassAbstract + Send + Sync>>,
framebuffers: Vec<Arc<dyn vf::FramebufferAbstract + Send + Sync>>,
surface_binding: Option<binding::SurfaceBinding<WT>>,
swapchain_binding: Option<swapchains::SwapchainBinding<WT>>,
command_buffers: Vec<Arc<vc::AutoCommandBuffer>>,
armed: bool,
@ -62,11 +58,8 @@ impl<WT: 'static + Send + Sync> Instance<WT> {
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<WT: 'static + Send + Sync> Instance<WT> {
self.vulkan.clone()
}
pub fn get_swapchain(&self) -> Arc<vs::Swapchain<WT>> {
self.swapchains.as_ref().unwrap().chain.clone()
fn swapchain_binding(&self) -> &swapchains::SwapchainBinding<WT> {
self.swapchain_binding.as_ref().unwrap()
}
fn surface_binding(&self) -> &binding::SurfaceBinding<WT> {
self.surface_binding.as_ref().unwrap()
}
pub fn use_surface(&mut self, surface: &Arc<vs::Surface<WT>>) {
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<WT: 'static + Send + Sync> Instance<WT> {
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<WT: 'static + Send + Sync> Instance<WT> {
};
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<WT: 'static + Send + Sync> Instance<WT> {
}
}
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<dyn vf::FramebufferAbstract + Send + Sync> = Arc::new(vf::Framebuffer::start(render_pass.clone())
.add(image.clone()).unwrap()
.build().unwrap());
fba
})
.collect::<Vec<_>>();
}
fn create_command_buffers(
&mut self,
pipeline: Arc<dyn vp::GraphicsPipelineAbstract + Send + Sync>,
vertex_buffer: Arc<dyn vb::BufferAccess + Send + Sync>,
) {
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()

View File

@ -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<WT> {
pub struct SwapchainBinding<WT> {
pub chain: Arc<vs::Swapchain<WT>>,
pub images: Vec<Arc<vm::SwapchainImage<WT>>>,
pub render_pass: Arc<dyn vfb::RenderPassAbstract + Send + Sync>,
pub framebuffers: Vec<Arc<dyn vfb::FramebufferAbstract + Send + Sync>>,
}
impl<WT> Swapchains<WT> {
pub fn new(binding: &super::binding::Binding<WT>, previous: Option<&Swapchains<WT>>) -> Self {
let physical_device = binding.physical_device();
let capabilities = binding.surface.capabilities(physical_device).expect("could not get capabilities");
impl<WT: 'static + Send + Sync> SwapchainBinding<WT> {
pub fn new(
surface_binding: &super::binding::SurfaceBinding<WT>,
previous: Option<&SwapchainBinding<WT>>
) -> 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<WT> Swapchains<WT> {
.. 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<WT> Swapchains<WT> {
};
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<WT> Swapchains<WT> {
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<WT>,
color_format: vulkano::format::Format,
) -> Arc<dyn vfb::RenderPassAbstract + Send + Sync> {
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<dyn vfb::RenderPassAbstract + Send + Sync>,
images: Vec<Arc<vm::SwapchainImage<WT>>>,
) -> Vec<Arc<dyn vfb::FramebufferAbstract + Send + Sync>> {
images.iter()
.map(|image| {
let fba: Arc<dyn vfb::FramebufferAbstract + Send + Sync> = Arc::new(vfb::Framebuffer::start(render_pass.clone())
.add(image.clone()).unwrap()
.build().unwrap());
fba
})
.collect::<Vec<_>>()
}
fn choose_swap_surface_format(available_formats: &[(vf::Format, vs::ColorSpace)]) -> (vf::Format, vs::ColorSpace) {
*available_formats.iter()
.find(|(format, color_space)|