diff --git a/Cargo.toml b/Cargo.toml index 23accfcc..be6b03e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,22 +5,28 @@ authors = ["MitchellHansen "] edition = "2018" [dependencies] -cgmath = "0.17.0" -simple-stopwatch="0.1.4" -nalgebra = "0.18.0" -image = "0.21.2" -rand = "0.6.5" + #vulkano = "0.13.0" vulkano = {path = "../vulkano/vulkano"} + #vulkano-shaders = "0.14.0" vulkano-shaders = {path = "../vulkano/vulkano-shaders"} + #vulkano-win = "0.14.0" vulkano-win= {path = "../vulkano/vulkano-win"} -time = "0.1.38" -shaderc = "0.6.1" + #shade_runner = {version = "0.1.1", git = "https://github.com/MitchellHansen/shade_runner"} shade_runner = {path = "../shade_runner"} -winit = "0.19.1" + +cgmath = "0.17.0" +simple-stopwatch="0.1.4" +nalgebra = "0.18.0" +image = "0.21.2" +rand = "0.6.5" +time = "0.1.38" +shaderc = "0.6.1" +winit = "0.22.0" #criterion = "0.3.0" hprof = "0.1.3" rusttype = { version = "0.7.0", features = ["gpu_cache"] } +vulkano_text = "0.12.0" \ No newline at end of file diff --git a/notes/PossiblePathfinderPort.txt b/notes/PossiblePathfinderPort.txt index 1f67f1f9..9c356a62 100644 --- a/notes/PossiblePathfinderPort.txt +++ b/notes/PossiblePathfinderPort.txt @@ -9,6 +9,68 @@ So I'm just going to use this space to talk about hooking up vulkano to this bac All in all, this seems somewhat simple. This backend expects you to define a dozen or so types which are then passed around and manipulated using this interface. + +==== Where I am at currently ==== + +So I need to figure out how pathfinder is creating and storing the framebuffers. + + + + + + + + + +RuntimeVertexDef { + buffers: buffers, + vertex_buffer_ids: vertex_buffer_ids, + num_vertices: num_vertices, + attributes: attributes, +} + +buffers [ + (position, size, InputRate::Vertex) + (position, size, InputRate::Vertex) + (position, size, InputRate::Vertex) +] + +vertex_buffer_ids [ + start and end addresses of buffers? +] + +num_vertices : usize + +attributes [ + ("attribute_name1", position, Format::R32G32Sfloat) + ("attribute_name2", position, Format::R32G32Sfloat) + ("attribute_name3", position, Format::R32G32Sfloat) +] + + +vertex shader input + +attrib loc, buffer id + +0,0 rgb +1,1 rgb +2,0 rgba +3,2 rg +4,0 rg +5,0 rgba +6,0 rgba +7,0 rgba + +layout(location = 0) in vec3 i_position; +layout(location = 1) in vec3 i_normal; +layout(location = 2) in vec4 i_tangent; +layout(location = 3) in vec2 i_texcoord_0; +layout(location = 4) in vec2 i_texcoord_1; +layout(location = 5) in vec4 i_color_0; +layout(location = 6) in vec4 i_joints_0; +layout(location = 7) in vec4 i_weights_0; + + pub struct RenderState<'a, D> where D: Device pub target: &'a RenderTarget<'a, D>, pub program: &'a D::Program, @@ -77,24 +139,29 @@ pub struct RenderState<'a, D> where D: Device **This one I'm a little shakey on. Where do I get these attributes?** [ ] fn get_vertex_attr(&self, program: &Self::Program, name: &str) -> Option; + **This first bind_vertex_array()'s ** + **Then it appears to set the instancing using the descriptor and divisor?** + **Then it configures the vertex attributes for the state. it's push pop it seems in gl** + fn configure_vertex_attr(&self, + vertex_array: &Self::VertexArray, + attr: &Self::VertexAttr, + descriptor: &VertexAttrDescriptor); + **This function just looks up the uniform using the name** [ ] fn get_uniform(&self, program: &Self::Program, name: &str) -> Self::Uniform; **Probably just allocating a buffer with data. Target is just usage** **See that it passes in a borrow for Buffer, I assume we should do an** **uninitialized_buffer type of deal** - [>] fn bind_buffer(&self, + + **Revising this : In GL all it is doing is assigning the buffer to an index in an array** + **Probably should do like metal and emulate it (Ended up taking metal impl!)** + [*] fn bind_buffer(&self, vertex_array: &Self::VertexArray, buffer: &Self::Buffer, target: BufferTarget); - **This first bind_vertex_array()'s ** - **Then it appears to set the instancing using the descriptor and divisor?** - **Then it configures the vertex attributes for the state. it's push pop it seems in gl** - fn configure_vertex_attr(&self, - vertex_array: &Self::VertexArray, - attr: &Self::VertexAttr, - descriptor: &VertexAttrDescriptor); + **This creates the framebuffer using render_pass** **Since it's single-frame. We don't use the swapchain** diff --git a/notes/vulkan b/notes/vulkan index 98e47484..82b14d6a 100644 --- a/notes/vulkan +++ b/notes/vulkan @@ -1 +1 @@ -7VtZc5swEP41fnQGcfh4jO2kzbSZydTpkUcFZKOMQIwQsd1fX2GEgapOcGbixXWezK60ID6+PXS450yj9SeBk/CWB4T1bCtY95xZz7bRCA3UT67ZlJoxKjRLQQOtqxRz+ptopaW1GQ1I2ugoOWeSJk2lz+OY+LKhw0LwVbPbgrPmUxO8JIZi7mNman/SQIaFduRZlf4zocuwfDKydEuEy85akYY44KuayrnqOVPBuSyuovWUsBy9EpfC7npP625ggsSyjcGQjQl5+vLo3WaDyff+w81osOgjRw9Obso3JoECQItcyJAveYzZVaWdCJ7FAclvaymp6vOV80QpkVI+ESk3+mviTHKlCmXEdCtZU/krN7/wtPRQa5mt9Z23wqYUYik2NaNcfKi3VWZbqbILLnMeKDGgOOJxcB/SuGi4poxV3fRwUS4WqORQ7EVbq1KeCZ+8BLFmLRZLIl/oN9xxQnkT4RFRb6HsBGFY0ufmOLBm9XLXr/rw6kJ/+wN44LiQPEA1FlgXQ68lERo0qFixhwip+gKy/o1bMAN1ghkeJDPcEWiEaDCjJTHQuRBjAEkMfd9nzDL9pG0NQP1Uae9oQhiNicGdJjNWIZVknuAtGitl3mSBfgIRkqxfBtUEQRuU2VfXH64WV1UuR2WXsJbHB9Z7BVrvw52O7U72KcRZ23Cnnj1gariTR3WxzC9uoiiT+JGRSbZYEFG2q8ftuuxsRKn5UXiPbZVGwA7peE2PHIF75AHA30T5dKEV7vdkLTNBugs8ggbefR34SymxH0bqDQ9AXnftCu59NGgC71jQyHuvI1+EjbztX5CDJ/WOxZCBAehczfa7SD7wAmi3HHKWBZDPcJpS/4jFz7Bl8TOCLH6Ghv98U4jk/mPdKcDA3eivWQQCDzgjM+CscOKHWBXW0GAZMQceLmTWGjW8rG3F0AGWeV0rFMrl+y4sC3ZnVfCd14u9lhG7IDXY8s8YNI83dg6sltRo7hyg/5caoHsJLuheAnSF13FmwMYMc+J5LXBEOjJTt7uWfp3hR/o9tiftThm85kkOpCc5sNn3LGNsa2bsiTJH2kcw9+VmJPUFTSTP59NzNXT4QNuxpWgHGZgctZi133AO5vT9qW3NYoNWsx1ar7TbJuHDjkidMDVAQ60LGzXeVJ6dDTP2paAjUeP0zlWeUT4B3etwQSd1teOVbz9ze3orZ+0TCuwhIHOBZMqjCMdBrzPnGdxxs3jvD6Grd9vcDZttYhxRP5/vSCzhjyEah2/ecUtMidW/CrZttT9nOFd/AA== \ No newline at end of file +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 \ No newline at end of file diff --git a/src/canvas/canvas_state.rs b/src/canvas/canvas_state.rs index e1b8eafd..df687fe7 100644 --- a/src/canvas/canvas_state.rs +++ b/src/canvas/canvas_state.rs @@ -15,7 +15,6 @@ use std::path::PathBuf; use image::GenericImageView; use std::iter::FromIterator; use vulkano::swapchain::Capabilities; -use winit::Window; use vulkano::pipeline::viewport::Viewport; use vulkano::descriptor::descriptor::DescriptorDescTy::TexelBuffer; use crate::canvas::canvas_frame::CanvasFrame; @@ -35,6 +34,7 @@ use crate::canvas::managed::shader::generic_shader::GenericShader; use crate::VertexTypes; use crate::util::vertex::{TextVertex3D, TextureVertex3D, ImageVertex3D, ColorVertex3D, CanvasFrameAllocation}; use shade_runner::Input; +use winit::window::Window; /// Canvas state is used for storage of texture and image buffers in addition to vertex buffers @@ -380,7 +380,7 @@ impl CanvasState { fn get_solid_color_descriptor_set(&self, kernel: Arc) -> Box { let o: Box = Box::new( PersistentDescriptorSet::start( - kernel.clone().get_pipeline().clone(), 0, + kernel.clone().get_pipeline().clone().descriptor_set_layout(0).unwrap().clone(), ).build().unwrap()); o } @@ -458,10 +458,10 @@ impl CanvasState { /// Pushes the draw commands to the command buffer. Requires the framebuffers and /// image number to be passed in as they are taken care of by the vkprocessor pub fn draw_commands(&mut self, - mut command_buffer: AutoCommandBufferBuilder, + mut command_buffer: &mut AutoCommandBufferBuilder, framebuffers: Vec>, image_num: usize, - allocated_buffers: CanvasFrameAllocation) -> AutoCommandBufferBuilder { + allocated_buffers: CanvasFrameAllocation) { // Specify the color to clear the framebuffer with i.e. blue let clear_values = vec!( @@ -478,7 +478,7 @@ impl CanvasState { reference: None, }; - let mut command_buffer = command_buffer.begin_render_pass( + command_buffer = command_buffer.begin_render_pass( framebuffers[image_num].clone(), false, clear_values.clone(), ).unwrap(); @@ -547,10 +547,10 @@ impl CanvasState { // Text - let mut shader = self.shader_buffers.get( - self.get_shader_handle(String::from("simple_text")) - .unwrap().clone().get_handle() as usize - ).unwrap(); + // let mut shader = self.shader_buffers.get( + // self.get_shader_handle(String::from("simple_text")) + // .unwrap().clone().get_handle() as usize + // ).unwrap(); // // self.dynamic_state = DynamicState { // line_width: None, @@ -597,18 +597,18 @@ impl CanvasState { // }), // }; - if !allocated_buffers.text_vertex_buffer.is_empty() { - command_buffer = command_buffer.draw( - shader.get_pipeline().clone(), - &self.dynamic_state.clone(), - allocated_buffers.text_vertex_buffer.clone(), - (), (), - ).unwrap(); - } + // if !allocated_buffers.text_vertex_buffer.is_empty() { + // command_buffer = command_buffer.draw( + // shader.get_pipeline().clone(), + // &self.dynamic_state.clone(), + // allocated_buffers.text_vertex_buffer.clone(), + // (), (), + // ).unwrap(); + // } command_buffer .end_render_pass() - .unwrap() + .unwrap(); } } diff --git a/src/canvas/managed/gpu_buffers.rs b/src/canvas/managed/gpu_buffers.rs index a8f8e773..6a2c2a38 100644 --- a/src/canvas/managed/gpu_buffers.rs +++ b/src/canvas/managed/gpu_buffers.rs @@ -2,7 +2,7 @@ use vulkano::image::{ImmutableImage, AttachmentImage}; use std::sync::Arc; use vulkano::format::{Format, R8Unorm}; use vulkano::sampler::Sampler; -use vulkano::descriptor::DescriptorSet; +use vulkano::descriptor::{DescriptorSet, PipelineLayoutAbstract}; use vulkano::descriptor::descriptor_set::PersistentDescriptorSet; use vulkano::buffer::{CpuAccessibleBuffer, BufferAccess}; use vulkano::pipeline::GraphicsPipelineAbstract; @@ -25,7 +25,7 @@ impl CanvasTexture { sampler: Arc) -> Box { let o: Box = Box::new( PersistentDescriptorSet::start( - pipeline.clone(), 0, + pipeline.clone().descriptor_set_layout(0).unwrap().clone(), ) .add_sampled_image(self.buffer.clone(), sampler.clone()).unwrap() .build().unwrap()); @@ -46,7 +46,7 @@ impl CanvasImage { -> Box { let o: Box = Box::new( PersistentDescriptorSet::start( - pipeline.clone(), 0, + pipeline.clone().descriptor_set_layout(0).unwrap().clone() ) .add_image(self.buffer.clone()).unwrap() .build().unwrap()); @@ -65,12 +65,13 @@ pub struct CanvasFont { } impl CanvasFont { - pub fn get_descriptor_set(pipeline: Arc) + pub fn get_descriptor_set(&self, pipeline: Arc) -> Box { let o: Box = Box::new( PersistentDescriptorSet::start( - pipeline.clone(), 0, + pipeline.clone().descriptor_set_layout(0).unwrap().clone() ) + .add_buffer(self.buffer.clone()).unwrap() .build().unwrap()); o } diff --git a/src/compute/compu_state.rs b/src/compute/compu_state.rs index dcc471d1..08ac9733 100644 --- a/src/compute/compu_state.rs +++ b/src/compute/compu_state.rs @@ -93,9 +93,8 @@ impl CompuState { pub fn compute_commands(&mut self, compute_frame: CompuFrame, - mut command_buffer: AutoCommandBufferBuilder, - canvas: &CanvasState) - -> AutoCommandBufferBuilder { + mut command_buffer: &mut AutoCommandBufferBuilder, + canvas: &CanvasState) { // i = (Buffer, Kernel) for i in compute_frame.pure_compute { @@ -167,7 +166,6 @@ impl CompuState { output_buffer.get_input_buffer()).unwrap(); } - command_buffer } } diff --git a/src/compute/managed/compu_buffer.rs b/src/compute/managed/compu_buffer.rs index 62852f27..5f4c0667 100644 --- a/src/compute/managed/compu_buffer.rs +++ b/src/compute/managed/compu_buffer.rs @@ -8,6 +8,7 @@ use image::ImageBuffer; use image::Rgba; use shade_runner::Layout; use crate::compute::managed::handles::CompuBufferHandle; +use vulkano::descriptor::PipelineLayoutAbstract; #[derive(Clone)] @@ -30,13 +31,13 @@ impl CompuBuffers { let input_buffer = { let mut buff = data.iter(); let data_iter = (0..data_length).map(|n| *(buff.next().unwrap())); - CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap() + CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), false, data_iter).unwrap() }; let output_buffer = { let mut buff = data.iter(); let data_iter = (0..data_length).map(|n| *(buff.next().unwrap())); - CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap() + CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), false, data_iter).unwrap() }; // Settings buffer which holds i32's @@ -48,7 +49,7 @@ impl CompuBuffers { (0..2).map(|n| *(buff.next().unwrap())); CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), - data_iter).unwrap() + false, data_iter).unwrap() }; CompuBuffers { @@ -66,12 +67,12 @@ impl CompuBuffers { } pub fn get_descriptor_set(&self, compute_pipeline: std::sync::Arc>>) - -> Arc>>, ((((), + -> Arc>>), PersistentDescriptorSetBuf>>), PersistentDescriptorSetBuf>>)>> { - Arc::new(PersistentDescriptorSet::start(compute_pipeline.clone(), 0) + Arc::new(PersistentDescriptorSet::start(compute_pipeline.clone().descriptor_set_layout(0).unwrap().clone()) .add_buffer(self.io_buffers.get(0).unwrap().clone()).unwrap() .add_buffer(self.io_buffers.get(1).unwrap().clone()).unwrap() .add_buffer(self.settings_buffer.clone()).unwrap() diff --git a/src/compute/managed/compu_kernel.rs b/src/compute/managed/compu_kernel.rs index b597632b..230a7edb 100644 --- a/src/compute/managed/compu_kernel.rs +++ b/src/compute/managed/compu_kernel.rs @@ -50,7 +50,8 @@ impl CompuKernel { let mut options = CompileOptions::new().ok_or(CompileError::CreateCompiler).unwrap(); - let shader = sr::load_compute_with_options(compute_path.clone(), options) + + let shader = sr::load_compute(compute_path.clone(), Some(options)) .expect("Failed to compile"); let entry = sr::parse_compute(&shader) @@ -106,7 +107,7 @@ impl CompuKernel { self.compute_kernel_path = CompuKernel::get_path(filename); self.shader = - sr::load_compute_with_options(self.compute_kernel_path.clone(), options) + sr::load_compute(self.compute_kernel_path.clone(), Some(options)) .expect("Failed to compile"); self.entry = diff --git a/src/main.rs b/src/main.rs index 00f197d5..52d865c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,8 +15,6 @@ use vulkano::sync; use crate::util::timer::Timer; use vulkano::instance::Instance; use vulkano::sync::GpuFuture; -use winit::{EventsLoop, WindowBuilder, WindowEvent, Event, DeviceEvent, VirtualKeyCode, ElementState}; -use winit::dpi::LogicalSize; use vulkano_win::VkSurfaceBuild; use crate::util::load_raw; @@ -32,6 +30,12 @@ use crate::drawables::sprite::Sprite; use crate::drawables::rect::Rect; use crate::drawables::compu_sprite::CompuSprite; use crate::drawables::text::Text; +use winit::window::{WindowBuilder}; +use winit::dpi::LogicalSize; +use winit::event_loop::EventLoop; +use winit::event::{Event, WindowEvent, DeviceEvent, VirtualKeyCode, ElementState}; +use winit::platform::unix::WindowBuilderExtUnix; + pub mod util; pub mod vkprocessor; @@ -39,162 +43,157 @@ pub mod drawables; pub mod canvas; pub mod compute; + pub fn main() { hprof::start_frame(); let q1 = hprof::enter("setup"); + let instance = { let extensions = vulkano_win::required_extensions(); Instance::new(None, &extensions, None).unwrap() }; - let _callback = DebugCallback::errors_and_warnings(&instance, |msg| { - println!("Debug callback: {:?}", msg.description); - }).ok(); - - let mut events_loop = EventsLoop::new(); - let mut surface = WindowBuilder::new() - .with_dimensions(LogicalSize::from((800, 800))) - .build_vk_surface(&events_loop, instance.clone()).unwrap(); - let mut window = surface.window(); - - let mut processor = vkprocessor::VkProcessor::new(&instance, &surface); - { - let g = hprof::enter("vulkan preload"); - processor.create_swapchain(&surface); + let mut processor = vkprocessor::VkProcessor::new(instance.clone()); - processor.preload_kernels(); - processor.preload_shaders(); - processor.preload_textures(); - processor.preload_fonts(); - } + { + let g = hprof::enter("vulkan preload"); + processor.create_swapchain(); - let q2 = hprof::enter("Game Objects"); + processor.preload_kernels(); + processor.preload_shaders(); + processor.preload_textures(); + processor.preload_fonts(); + } - let mut timer = Timer::new(); - let mut frame_future : Box = - Box::new(sync::now(processor.device.clone())) as Box; + let q2 = hprof::enter("Game Objects"); - let step_size: f32 = 0.005; - let mut elapsed_time: f32; - let mut delta_time: f32; - let mut accumulator_time: f32 = 0.0; - let mut current_time: f32 = timer.elap_time(); + let mut timer = Timer::new(); + let mut frame_future: Box = + Box::new(sync::now(processor.device.clone())) as Box; - let image_data = load_raw(String::from("funky-bird.jpg")); - let image_dimensions_f : (f32, f32) = ((image_data.1).0 as f32, (image_data.1).1 as f32); - let image_dimensions_u : (u32, u32) = image_data.1; - let compu_sprite1 : CompuSprite = - CompuSprite::new((0.0, -0.5), (0.4, 0.4), 0, image_dimensions_f, - // Swap image to render the result to. Must match dimensions - processor.new_swap_image(image_dimensions_u)); + let step_size: f32 = 0.005; + let mut elapsed_time: f32; + let mut delta_time: f32; + let mut accumulator_time: f32 = 0.0; + let mut current_time: f32 = timer.elap_time(); - let compute_buffer : Arc = - processor.new_compute_buffer(image_data.0, image_data.1, 4); + let image_data = load_raw(String::from("funky-bird.jpg")); + let image_dimensions_f: (f32, f32) = ((image_data.1).0 as f32, (image_data.1).1 as f32); + let image_dimensions_u: (u32, u32) = image_data.1; + let compu_sprite1: CompuSprite = + CompuSprite::new((0.0, -0.5), (0.4, 0.4), 0, image_dimensions_f, + // Swap image to render the result to. Must match dimensions + processor.new_swap_image(image_dimensions_u)); - let compute_kernel : Arc = - processor.get_kernel_handle(String::from("simple-edge.compute")) - .expect("Can't find that kernel"); + let compute_buffer: Arc = + processor.new_compute_buffer(image_data.0, image_data.1, 4); - // Get the handles for the assets - let funky_handle : Arc = - processor.get_texture_handle(String::from("funky-bird.jpg")).unwrap(); - let sfml_handle : Arc = - processor.get_texture_handle(String::from("sfml.png")).unwrap(); - let font_handle : Arc = - processor.get_font_handle(String::from("sansation.ttf")).unwrap(); + let compute_kernel: Arc = + processor.get_kernel_handle(String::from("simple-edge.compute")) + .expect("Can't find that kernel"); - let funky_sprite = Sprite::new((0.0, 0.5), (0.5, 0.5), 0, funky_handle.clone()); - let sfml_sprite = Sprite::new((0.0, -0.5), (0.5, 0.5), 1, sfml_handle.clone()); - let rect = Rect::new((-0.5, -0.5), (0.5, 0.5), 1); + // Get the handles for the assets + let funky_handle: Arc = + processor.get_texture_handle(String::from("funky-bird.jpg")).unwrap(); + let sfml_handle: Arc = + processor.get_texture_handle(String::from("sfml.png")).unwrap(); + //let font_handle : Arc = + // processor.get_font_handle(String::from("sansation.ttf")).unwrap(); + let funky_sprite = Sprite::new((0.0, 0.5), (0.5, 0.5), 0, funky_handle.clone()); + let sfml_sprite = Sprite::new((0.0, -0.5), (0.5, 0.5), 1, sfml_handle.clone()); + let rect = Rect::new((-0.5, -0.5), (0.5, 0.5), 1); - //let sfml_sprite = Sprite::new((0.0, -0.5), (0.5, 0.5), 1, sfml_handle.clone()); - let text_sprite = Text::new((-0.1,-0.1), (10.0, 10.0), 1); - //let test_polygon = Poly::new_with_color((-0.5, -0.5), (0.5, 0.5), 1, (1.0,0.0,0.0,0.0)); - drop(q2); - drop(q1); + //let sfml_sprite = Sprite::new((0.0, -0.5), (0.5, 0.5), 1, sfml_handle.clone()); + let text_sprite = Text::new((-0.1, -0.1), (10.0, 10.0), 1); + //let test_polygon = Poly::new_with_color((-0.5, -0.5), (0.5, 0.5), 1, (1.0,0.0,0.0,0.0)); - let l = hprof::enter("Loop"); + drop(q2); + drop(q1); - let mut exit = false; + let l = hprof::enter("Loop"); - let mut count = 0; + let mut exit = false; - while let true = processor.is_open() { + let mut count = 0; - // Take care of our timing - { - elapsed_time = timer.elap_time(); - delta_time = elapsed_time - current_time; - current_time = elapsed_time; - if delta_time > 0.02 { - delta_time = 0.02; + while let true = processor.is_open() { + + // Take care of our timing + { + elapsed_time = timer.elap_time(); + delta_time = elapsed_time - current_time; + current_time = elapsed_time; + if delta_time > 0.02 { + delta_time = 0.02; + } + accumulator_time += delta_time; } - accumulator_time += delta_time; - } - while (accumulator_time - step_size) >= step_size { - accumulator_time -= step_size; - } + while (accumulator_time - step_size) >= step_size { + accumulator_time -= step_size; + } - // Events loop is borrowed from the surface - events_loop.poll_events(|event| { - match event { - Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => - { - exit = true; + // Events loop is borrowed from the surface + processor.event_loop().clone().run(move |event, _, control_flow| { + match event { + Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => + { + exit = true; + } + Event::WindowEvent { event: WindowEvent::Resized(_), .. } => { + processor.swapchain_recreate_needed = true; } - Event::WindowEvent { event: WindowEvent::Resized(_), .. } => { - processor.recreate_swapchain(&surface); - } - Event::DeviceEvent { event: DeviceEvent::Key(keyboard_input), .. } => { - match keyboard_input.virtual_keycode.unwrap() { - VirtualKeyCode::A => { - if keyboard_input.state == ElementState::Pressed { - // processor.save_edges_image(); + Event::DeviceEvent { event: DeviceEvent::Key(keyboard_input), .. } => { + match keyboard_input.virtual_keycode.unwrap() { + VirtualKeyCode::A => { + if keyboard_input.state == ElementState::Pressed { + // processor.save_edges_image(); + } } + _ => () } - _ => () } - } // Event::DeviceEvent { event: DeviceEvent::Button(mouse_input), .. } => { // mouse_xy.x // }, - _ => () - } - }); + _ => () + } + }); - if exit { - break; - } + if exit { + break; + } - let mut canvas_frame = CanvasFrame::default(); - canvas_frame.draw(&funky_sprite); - canvas_frame.draw(&text_sprite); + let mut canvas_frame = CanvasFrame::default(); + canvas_frame.draw(&funky_sprite); + canvas_frame.draw(&text_sprite); // canvas_frame.draw(&rect); - let mut compu_frame = CompuFrame::new(); - //compu_frame.add(compute_buffer.clone(), compute_kernel.clone()); - compu_frame.add_with_image_swap(compute_buffer.clone(), compute_kernel.clone(), &compu_sprite1); + let mut compu_frame = CompuFrame::new(); + //compu_frame.add(compute_buffer.clone(), compute_kernel.clone()); + compu_frame.add_with_image_swap(compute_buffer.clone(), compute_kernel.clone(), &compu_sprite1); - { - let g = hprof::enter("Run"); - processor.run(&surface, - canvas_frame, - compu_frame); + { + let g = hprof::enter("Run"); + processor.run(canvas_frame, + compu_frame); + } } - } - drop(l); + drop(l); + + hprof::end_frame(); + hprof::profiler().print_timing(); - hprof::end_frame(); - hprof::profiler().print_timing(); + drop(processor); + } } diff --git a/src/vkprocessor.rs b/src/vkprocessor.rs index 5a68d0bf..938716f8 100644 --- a/src/vkprocessor.rs +++ b/src/vkprocessor.rs @@ -5,9 +5,8 @@ use vulkano::sync::{GpuFuture, FlushError, NowFuture}; use vulkano::sync::now; use vulkano::sync; use std::sync::Arc; -use vulkano::swapchain::{Swapchain, PresentMode, SurfaceTransform, Surface, SwapchainCreationError, AcquireError, Capabilities}; +use vulkano::swapchain::{Swapchain, PresentMode, SurfaceTransform, Surface, SwapchainCreationError, AcquireError, Capabilities, FullscreenExclusive, ColorSpace}; use vulkano::image::swapchain::SwapchainImage; -use winit::Window; use crate::compute::compu_state::CompuState; use vulkano::image::ImageUsage; use crate::compute::compu_frame::CompuFrame; @@ -21,6 +20,12 @@ use crate::canvas::managed::shader::text_shader::TextShader; use crate::canvas::managed::handles::{CanvasTextureHandle, CompiledShaderHandle, CanvasFontHandle, CanvasImageHandle}; use crate::compute::managed::handles::{CompuKernelHandle, CompuBufferHandle}; use crate::util::vertex::{VertexTypes, ColorVertex3D, TextVertex3D, TextureVertex3D, ImageVertex3D}; +use vulkano_text::DrawText; +use winit::window::{Window, WindowBuilder}; +use vulkano::instance::debug::DebugCallback; +use winit::dpi::LogicalSize; +use vulkano_win::VkSurfaceBuild; +use winit::event_loop::EventLoop; /// VKProcessor holds the vulkan instance information, the swapchain, @@ -36,7 +41,10 @@ pub struct VkProcessor<'a> { pub swapchain: Option>>, pub swapchain_images: Option>>>, - swapchain_recreate_needed: bool, + pub swapchain_recreate_needed: bool, + + pub surface: Arc>, + pub event_loop: Arc>, /// State holding textures, images, and their related vertex buffers canvas_state: CanvasState, @@ -49,12 +57,24 @@ pub struct VkProcessor<'a> { impl<'a> VkProcessor<'a> { - /// Creates a new VkProcessor from an instance and surface /// This includes the physical device, queues, compute and canvas state - pub fn new(instance: &'a Arc, surface: &'a Arc>) -> VkProcessor<'a> { + //pub fn new(instance: &'a Arc, surface: &'a Arc>) -> VkProcessor<'a> { + pub fn new(instance: Arc) -> VkProcessor<'a> { + + let _callback = DebugCallback::errors_and_warnings(&instance, |msg| { + println!("Debug callback: {:?}", msg.description); + }).ok(); + + let mut events_loop = Arc::new(EventLoop::new()); - let physical = PhysicalDevice::enumerate(instance).next().unwrap(); + let mut surface = WindowBuilder::new() + .with_inner_size(LogicalSize::new(800, 800)); + + // Some weird namespacing issue here + let mut surface = VkSurfaceBuild::build_vk_surface(surface, &events_loop, instance.clone()).unwrap(); + + let physical = PhysicalDevice::enumerate(&instance).next().unwrap(); let queue_family = physical.queue_families().find(|&q| { // We take the first queue that supports drawing to our window. @@ -85,28 +105,35 @@ impl<'a> VkProcessor<'a> { compute_state: CompuState::new(), capabilities: capabilities.clone(), canvas_state: CanvasState::new(queue, device, physical, capabilities), + surface: surface, + event_loop: events_loop, } } /// VKProcessor controls the window. So it will let the main loop know when it is done pub fn is_open(&mut self) -> bool { - // self.surface + // self.surface true } + pub fn event_loop(&mut self) -> Arc> { + self.event_loop() + } + /// Using the surface, we calculate the surface capabilities and create the swapchain and swapchain images - pub fn create_swapchain(&mut self, surface: &'a Arc>) { + pub fn create_swapchain(&mut self) { + let (mut swapchain, images) = { - let capabilities = surface.capabilities(self.physical).unwrap(); + let capabilities = self.surface.capabilities(self.physical).unwrap(); let usage = capabilities.supported_usage_flags; let alpha = capabilities.supported_composite_alpha.iter().next().unwrap(); // Choosing the internal format that the images will have. let format = capabilities.supported_formats[0].0; // Set the swapchains window dimensions - let initial_dimensions = if let Some(dimensions) = surface.window().get_inner_size() { + let initial_dimensions = if let dimensions = self.surface.window().inner_size() { // convert to physical pixels - let dimensions: (u32, u32) = dimensions.to_physical(surface.window().get_hidpi_factor()).into(); + let dimensions: (u32, u32) = dimensions.to_logical::(self.surface.window().scale_factor()).into(); [dimensions.0, dimensions.1] } else { // The window no longer exists so exit the application. @@ -114,7 +141,7 @@ impl<'a> VkProcessor<'a> { }; Swapchain::new(self.device.clone(), - surface.clone(), + self.surface.clone(), capabilities.min_image_count, // number of attachment images format, initial_dimensions, @@ -123,7 +150,9 @@ impl<'a> VkProcessor<'a> { &self.queue, SurfaceTransform::Identity, alpha, - PresentMode::Immediate, true, None).unwrap() + PresentMode::Immediate, + FullscreenExclusive::Default, true, + ColorSpace::PassThrough).unwrap() }; self.swapchain = Some(swapchain); @@ -131,15 +160,16 @@ impl<'a> VkProcessor<'a> { } /// On screen resizes, the swapchain and images must be recreated - pub fn recreate_swapchain(&mut self, surface: &'a Arc>) { - let dimensions = if let Some(dimensions) = surface.window().get_inner_size() { - let dimensions: (u32, u32) = dimensions.to_physical(surface.window().get_hidpi_factor()).into(); + pub fn recreate_swapchain(&mut self) { + let dimensions = if let dimensions = self.surface.window().inner_size() { + let dimensions: (u32, u32) = dimensions.to_logical::(self.surface.window().scale_factor()).into(); [dimensions.0, dimensions.1] } else { return; }; - let (new_swapchain, new_images) = match self.swapchain.clone().unwrap().clone().recreate_with_dimension(dimensions) { + let (new_swapchain, new_images) = match self.swapchain.clone().unwrap().clone() + .recreate_with_dimensions(dimensions) { Ok(r) => r, // This error tends to happen when the user is manually resizing the window. // Simply restarting the loop is the easiest way to fix this issue. @@ -176,7 +206,7 @@ impl<'a> VkProcessor<'a> { /// A hardcoded list of shaders which can be proloaded from this function pub fn preload_fonts(&mut self) { - self.canvas_state.load_font(String::from("sansation.ttf")); + //self.canvas_state.load_font(String::from("sansation.ttf")); } /// O(n) Lookup for the matching texture string @@ -224,11 +254,9 @@ impl<'a> VkProcessor<'a> { /// Run the VKprocessor for a single frame, consuming the Canvas/Compu Frames pub fn run(&mut self, - surface: &'a Arc>, canvas_frame: CanvasFrame, compute_frame: CompuFrame, ) { - { let g = hprof::enter("Waiting at queue"); self.queue.wait(); @@ -241,7 +269,7 @@ impl<'a> VkProcessor<'a> { // Whenever the window resizes we need to recreate everything dependent on the window size. // In this example that includes the swapchain, the framebuffers and the dynamic state viewport. if self.swapchain_recreate_needed { - self.recreate_swapchain(surface); + self.recreate_swapchain(); framebuffers = self.canvas_state.window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone()); self.swapchain_recreate_needed = false; @@ -249,7 +277,7 @@ impl<'a> VkProcessor<'a> { // This function can block if no image is available. The parameter is an optional timeout // after which the function call will return an error. - let (image_num, acquire_future) = + let (image_num, suboptimal, acquire_future) = match vulkano::swapchain::acquire_next_image( self.swapchain.clone().unwrap().clone(), None, @@ -262,6 +290,10 @@ impl<'a> VkProcessor<'a> { Err(err) => panic!("{:?}", err) }; + if suboptimal { + self.swapchain_recreate_needed = true; + } + drop(g); let allocated_buffers = { @@ -271,20 +303,21 @@ impl<'a> VkProcessor<'a> { self.canvas_state.allocate(canvas_frame) }; + // let mut draw_text = DrawText::new(self.device.clone(), self.queue.clone(), self.swapchain.unwrap().clone(), &self.swapchain_images.images); + let mut command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(self.device.clone(), self.queue.family()).unwrap(); let g = hprof::enter("Push compute commands to command buffer"); // Add the compute commands - let mut command_buffer = self.compute_state.compute_commands(compute_frame, command_buffer, &self.canvas_state); + self.compute_state.compute_commands(compute_frame, &mut command_buffer, &self.canvas_state); drop(g); let g = hprof::enter("Push draw commands to command buffer"); - + // Add the draw commands //let mut command_buffer = self.canvas_state.draw_commands(command_buffer, framebuffers, image_num); - let mut command_buffer = - self.canvas_state.draw_commands(command_buffer, framebuffers, image_num, allocated_buffers); + self.canvas_state.draw_commands(&mut command_buffer, framebuffers, image_num, allocated_buffers); // And build let command_buffer = command_buffer.build().unwrap(); @@ -292,7 +325,6 @@ impl<'a> VkProcessor<'a> { // Wait on the previous frame, then execute the command buffer and present the image { - let g = hprof::enter("Joining on the framebuffer"); let mut future = sync::now(self.device.clone()) .join(acquire_future);