diff --git a/src/main.rs b/src/main.rs index 52d865c8..779ddc0f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,6 @@ #![allow(unused_mut)] - extern crate cgmath; extern crate image; extern crate nalgebra as na; @@ -35,6 +34,7 @@ use winit::dpi::LogicalSize; use winit::event_loop::EventLoop; use winit::event::{Event, WindowEvent, DeviceEvent, VirtualKeyCode, ElementState}; use winit::platform::unix::WindowBuilderExtUnix; +use crate::vkprocessor::VkProcessor; pub mod util; @@ -43,157 +43,163 @@ 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 mut processor = vkprocessor::VkProcessor::new(instance.clone()); + let _callback = DebugCallback::errors_and_warnings(&instance, |msg| { + println!("Debug callback: {:?}", msg.description); + }).ok(); - { - let g = hprof::enter("vulkan preload"); - processor.create_swapchain(); + let mut events_loop = EventLoop::new(); - processor.preload_kernels(); - processor.preload_shaders(); - processor.preload_textures(); - processor.preload_fonts(); - } + 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.clone(), &events_loop, instance.clone()).unwrap(); + + let mut processor = VkProcessor::new(&instance, surface.clone()); - let q2 = hprof::enter("Game Objects"); + { + let g = hprof::enter("vulkan preload"); + processor.create_swapchain(surface.clone()); - let mut timer = Timer::new(); - let mut frame_future: Box = - Box::new(sync::now(processor.device.clone())) as Box; + processor.preload_kernels(); + processor.preload_shaders(); + processor.preload_textures(); + processor.preload_fonts(); + } - 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 q2 = hprof::enter("Game Objects"); - 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 mut timer = Timer::new(); + let mut frame_future: Box = + Box::new(sync::now(processor.device.clone())) as Box; - let compute_buffer: Arc = - processor.new_compute_buffer(image_data.0, image_data.1, 4); + 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_kernel: Arc = - processor.get_kernel_handle(String::from("simple-edge.compute")) - .expect("Can't find that kernel"); + 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)); - // 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_buffer: Arc = + processor.new_compute_buffer(image_data.0, image_data.1, 4); - 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 compute_kernel: Arc = + processor.get_kernel_handle(String::from("simple-edge.compute")) + .expect("Can't find that kernel"); + // 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 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 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); - drop(q2); - drop(q1); - let l = hprof::enter("Loop"); + //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 mut exit = false; + drop(q2); + drop(q1); - let mut count = 0; + let l = hprof::enter("Loop"); - while let true = processor.is_open() { + let mut exit = false; - // 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; - } + let mut count = 0; - while (accumulator_time - step_size) >= step_size { - accumulator_time -= step_size; + 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; + } - // 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; + while (accumulator_time - step_size) >= step_size { + accumulator_time -= step_size; + } + + // Events loop is borrowed from the surface + events_loop.run(move |event, _, control_flow| { + match event { + Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => + { + exit = true; } - 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::WindowEvent { event: WindowEvent::Resized(_), .. } => { + processor.swapchain_recreate_needed = true; + } + 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; + _ => () } + }); - let mut canvas_frame = CanvasFrame::default(); - canvas_frame.draw(&funky_sprite); - canvas_frame.draw(&text_sprite); + if exit { + break; + } + + 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(canvas_frame, - compu_frame); - } + { + let g = hprof::enter("Run"); + processor.run(&surface.clone(), + 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 938716f8..1995cfe7 100644 --- a/src/vkprocessor.rs +++ b/src/vkprocessor.rs @@ -32,7 +32,6 @@ use winit::event_loop::EventLoop; /// and the compute and canvas states pub struct VkProcessor<'a> { // Vulkan state fields - pub instance: Arc, pub physical: PhysicalDevice<'a>, pub device: Arc, pub queues: QueuesIter, @@ -43,9 +42,6 @@ pub struct VkProcessor<'a> { pub swapchain_recreate_needed: bool, - pub surface: Arc>, - pub event_loop: Arc>, - /// State holding textures, images, and their related vertex buffers canvas_state: CanvasState, /// State holding @@ -59,42 +55,29 @@ 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: 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 mut surface = WindowBuilder::new() - .with_inner_size(LogicalSize::new(800, 800)); + pub fn new(instance: &'a Arc, surface: Arc>) -> VkProcessor<'a> { - // 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 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. + q.supports_graphics() && + surface.is_supported(q).unwrap_or(false) && + q.supports_compute() + }).unwrap(); - let queue_family = physical.queue_families().find(|&q| { - // We take the first queue that supports drawing to our window. - q.supports_graphics() && - surface.is_supported(q).unwrap_or(false) && - q.supports_compute() - }).unwrap(); + let device_ext = DeviceExtensions { khr_swapchain: true, ..DeviceExtensions::none() }; - let device_ext = DeviceExtensions { khr_swapchain: true, ..DeviceExtensions::none() }; + let (device, mut queues) = Device::new(physical, + physical.supported_features(), + &device_ext, + [(queue_family, 0.5)].iter().cloned()).unwrap(); + let queue = queues.next().unwrap(); - let (device, mut queues) = Device::new(physical, - physical.supported_features(), - &device_ext, - [(queue_family, 0.5)].iter().cloned()).unwrap(); - let queue = queues.next().unwrap(); + let capabilities = surface.capabilities(physical).unwrap(); - let capabilities = surface.capabilities(physical).unwrap(); VkProcessor { - instance: instance.clone(), physical: physical.clone(), device: device.clone(), queue: queue.clone(), @@ -105,8 +88,6 @@ 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, } } @@ -116,24 +97,19 @@ impl<'a> VkProcessor<'a> { 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) { - + pub fn create_swapchain(&mut self, surface: Arc>) { let (mut swapchain, images) = { - let capabilities = self.surface.capabilities(self.physical).unwrap(); + let capabilities = 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 dimensions = self.surface.window().inner_size() { + let initial_dimensions = if let dimensions = surface.window().inner_size() { // convert to physical pixels - let dimensions: (u32, u32) = dimensions.to_logical::(self.surface.window().scale_factor()).into(); + let dimensions: (u32, u32) = dimensions.to_logical::(surface.window().scale_factor()).into(); [dimensions.0, dimensions.1] } else { // The window no longer exists so exit the application. @@ -141,7 +117,7 @@ impl<'a> VkProcessor<'a> { }; Swapchain::new(self.device.clone(), - self.surface.clone(), + surface.clone(), capabilities.min_image_count, // number of attachment images format, initial_dimensions, @@ -160,9 +136,9 @@ impl<'a> VkProcessor<'a> { } /// On screen resizes, the swapchain and images must be recreated - 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(); + pub fn recreate_swapchain(&mut self, surface: &'a Arc>) { + let dimensions = if let dimensions = surface.window().inner_size() { + let dimensions: (u32, u32) = dimensions.to_logical::(surface.window().scale_factor()).into(); [dimensions.0, dimensions.1] } else { return; @@ -254,6 +230,7 @@ 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, ) { @@ -269,7 +246,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(); + self.recreate_swapchain(surface); framebuffers = self.canvas_state.window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone()); self.swapchain_recreate_needed = false;