From 08d74437634ed396c92fe5336db6f8f7e197575e Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sun, 26 Jan 2020 20:59:55 +0100 Subject: [PATCH] do not recreate vertex/index buffers --- engine/src/main.rs | 6 +-- engine/src/render/mod.rs | 2 +- engine/src/render/renderable.rs | 80 ++++++++++++++++++++++++++++----- engine/src/render/vulkan/mod.rs | 22 ++------- 4 files changed, 78 insertions(+), 32 deletions(-) diff --git a/engine/src/main.rs b/engine/src/main.rs index 4326502..3402166 100644 --- a/engine/src/main.rs +++ b/engine/src/main.rs @@ -1,6 +1,6 @@ use log; use env_logger; -use std::sync::Arc; +use std::rc::Rc; use cgmath as cgm; @@ -16,13 +16,13 @@ fn main() { let elapsed = 0.0; let transform = cgm::Matrix4::from_angle_z(cgm::Rad::from(cgm::Deg(elapsed as f32 * 0.180))); - let vertices = Arc::new(vec![ + let vertices = Rc::new(vec![ data::Vertex::new([-0.5, -0.5, 0.0], [1.0, 0.0, 0.0]), data::Vertex::new([0.5, -0.5, 0.0], [0.0, 1.0, 0.0]), data::Vertex::new([0.5, 0.5, 0.0], [0.0, 0.0, 1.0]), data::Vertex::new([-0.5, 0.5, 0.0], [1.0, 1.0, 1.0]) ]); - let indices = Arc::new(vec![ + let indices = Rc::new(vec![ 0, 1, 2, 2, 3, 0, ]); let demo = render::renderable::Mesh { diff --git a/engine/src/render/mod.rs b/engine/src/render/mod.rs index 7e7bf31..0e758fc 100644 --- a/engine/src/render/mod.rs +++ b/engine/src/render/mod.rs @@ -53,7 +53,7 @@ impl Renderer { } fn draw_frame(&mut self) { - self.instance.flip(self.render_data.clone()); + self.instance.flip(&mut self.render_data); } pub fn main_loop(&mut self) { diff --git a/engine/src/render/renderable.rs b/engine/src/render/renderable.rs index 80957b5..a9fdd6e 100644 --- a/engine/src/render/renderable.rs +++ b/engine/src/render/renderable.rs @@ -1,6 +1,10 @@ use std::sync::Arc; +use std::rc::Rc; use cgmath as cgm; +use vulkano::device as vd; +use vulkano::buffer as vb; +use vulkano::sync::{FenceSignalFuture, GpuFuture}; use crate::render::vulkan::data; @@ -12,23 +16,79 @@ pub trait Renderable { #[derive(Clone)] pub struct Data { - pub vertices: Arc>, - pub indices: Arc>, - pub transform: cgm::Matrix4, + vertices: Rc>, + indices: Rc>, + transform: cgm::Matrix4, + + vbuffer: Option>>, + ibuffer: Option>>, +} + +impl Data { + pub fn new( + vertices: Rc>, + indices: Rc>, + transform: cgm::Matrix4, + ) -> Data { + Data { + vertices, indices, transform, + vbuffer: None, + ibuffer: None, + } + } + + pub fn vulkan_buffers( + &mut self, + graphics_queue: Arc, + ) -> ( + Arc>, + Arc>, + ) { + + let vbuffer = match &mut self.vbuffer { + Some(v) => v.clone(), + None => { + let (vbuffer, future) = vb::immutable::ImmutableBuffer::from_iter( + self.vertices.iter().cloned(), + vb::BufferUsage::vertex_buffer(), + graphics_queue.clone(), + ).unwrap(); + future.flush().unwrap(); + self.vbuffer = Some(vbuffer.clone()); + vbuffer.clone() + }, + }; + + let ibuffer = match &mut self.ibuffer { + Some(v) => v.clone(), + None => { + let (ibuffer, future) = vb::immutable::ImmutableBuffer::from_iter( + self.indices.iter().cloned(), + vb::BufferUsage::index_buffer(), + graphics_queue.clone(), + ).unwrap(); + future.flush().unwrap(); + self.ibuffer = Some(ibuffer.clone()); + ibuffer.clone() + }, + }; + + (vbuffer, ibuffer) + } + + pub fn get_transform(&self) -> cgm::Matrix4 { + self.transform.clone() + } } pub struct Mesh { - pub vertices: Arc>, - pub indices: Arc>, + pub vertices: Rc>, + pub indices: Rc>, pub transform: cgm::Matrix4, } impl Renderable for Mesh { fn data(&self) -> Option { - Some(Data { - vertices: self.vertices.clone(), - indices: self.indices.clone(), - transform: self.transform.clone(), - }) + Some(Data::new(self.vertices.clone(), self.indices.clone(), self.transform.clone())) } } diff --git a/engine/src/render/vulkan/mod.rs b/engine/src/render/vulkan/mod.rs index 79ec8af..e0b619d 100644 --- a/engine/src/render/vulkan/mod.rs +++ b/engine/src/render/vulkan/mod.rs @@ -108,7 +108,7 @@ impl Instance { // (╯°□°)╯︵ ┻━┻ pub fn flip( &mut self, - render_data: Vec, + render_data: &mut Vec, ) { match &self.previous_frame_end { None => (), @@ -167,7 +167,7 @@ impl Instance { fn make_command_buffer( &mut self, framebuffer: Arc, - render_data: Vec, + render_data: &mut Vec, ) -> Arc { let device = self.surface_binding().device.clone(); let qf = self.surface_binding().graphics_queue.family(); @@ -190,23 +190,9 @@ impl Instance { ); for d in render_data { - let (vbuffer, future) = vb::immutable::ImmutableBuffer::from_iter( - d.vertices.iter().cloned(), - vb::BufferUsage::vertex_buffer(), - self.surface_binding().graphics_queue.clone(), - ).unwrap(); - future.flush().unwrap(); - - let (ibuffer, future) = vb::immutable::ImmutableBuffer::from_iter( - d.indices.iter().cloned(), - vb::BufferUsage::index_buffer(), - self.surface_binding().graphics_queue.clone(), - ).unwrap(); - future.flush().unwrap(); - - + let (vbuffer, ibuffer) = d.vulkan_buffers(self.surface_binding().graphics_queue.clone()); let ubo = data::UniformBufferObject { - model: d.transform.clone(), + model: d.get_transform(), view: view.clone(), proj: proj.clone(), };