From 5bd6ac348b17d76bfc06c31c69d35e211b10d28f Mon Sep 17 00:00:00 2001 From: buckn Date: Tue, 13 Feb 2024 17:23:37 -0500 Subject: [PATCH] errors fixed --- diffs | 602 ----------- src/entities.rs | 77 +- src/main.rs | 12 +- src/render.rs | 1723 +++++++++++++++++++++++------ src/rnd.rs | 979 ----------------- src/shaders/tri.comp | 7 +- src/shaders/tri.frag | 9 +- src/shaders/tri.vert | 17 +- src/utility.rs | 2 +- src/utility/constants.rs | 10 +- src/utility/debug.rs | 2 +- src/utility/share.rs | 2139 ------------------------------------- src/utility/structures.rs | 97 +- 13 files changed, 1565 insertions(+), 4111 deletions(-) delete mode 100644 diffs delete mode 100644 src/rnd.rs delete mode 100644 src/utility/share.rs diff --git a/diffs b/diffs deleted file mode 100644 index 40da610..0000000 --- a/diffs +++ /dev/null @@ -1,602 +0,0 @@ -diff --git a/src/render.rs b/src/render.rs -index c8f2dc6..b094570 100644 ---- a/src/render.rs -+++ b/src/render.rs -@@ -14,6 +14,22 @@ use std::ptr; - // Constants - const WINDOW_TITLE: &'static str = "Template"; - -+const IS_PAINT_FPS_COUNTER: bool = true; -+ -+pub fn init_window( -+ event_loop: &EventLoop<()>, -+ title: &str, -+ width: u32, -+ height: u32, -+) -> winit::window::Window { -+ winit::window::WindowBuilder::new() -+ .with_title(title) -+ .with_inner_size(winit::dpi::LogicalSize::new(width, height)) -+ .build(event_loop) -+ .expect("Failed to create window.") -+} -+ -+ - pub struct VulkanApp { - window: winit::window::Window, - -@@ -31,7 +47,10 @@ pub struct VulkanApp { - queue_family: QueueFamilyIndices, - graphics_queue: vk::Queue, - present_queue: vk::Queue, -+ //new from C++ -+ compute_queue: vk::Queue, - -+ //not in C++ - swapchain_loader: ash::extensions::khr::Swapchain, - swapchain: vk::SwapchainKHR, - swapchain_images: Vec, -@@ -41,14 +60,31 @@ pub struct VulkanApp { - swapchain_framebuffers: Vec, - - render_pass: vk::RenderPass, -- pipeline_layout: vk::PipelineLayout, -+ -+ graphics_pipeline_layout: vk::PipelineLayout, - graphics_pipeline: vk::Pipeline, -+ -+ //new from C++ -+ compute_descriptor_set_layout: vk::DescriptorSetLayout, -+ compute_pipeline_layout: vk::PipelineLayout, -+ compute_pipeline: vk::Pipeline, -+ -+ //vertex buffer for the triangle verticies -+ //i think this is the same as shaderStorageBuffers in C++ version -+ shader_storage_buffers: Vec, -+ shader_storage_buffers_memory: Vec, -+ -+ uniform_buffers: Vec, -+ uniform_buffers_memory: Vec, -+ uniform_buffers_mapped: Vec<*mut c_void>, -+ - -- vertex_buffer: vk::Buffer, -- vertex_buffer_memory: vk::DeviceMemory, -+ descriptor_pool: vk::DescriptorPool, -+ compute_descriptor_sets: Vec, - - command_pool: vk::CommandPool, - command_buffers: Vec, -+ compute_command_buffers: Vec, - - image_available_semaphores: Vec, - render_finished_semaphores: Vec, -@@ -59,9 +95,33 @@ pub struct VulkanApp { - } - - impl VulkanApp { -+ //C++ code:: -+ /* -+ ### cleanup(); -+ createInstance(); DONE -+ setupDebugMessenger(); DONE -+ createSurface(); SurfaceStuff::new DONE -+ pickPhysicalDevice(); DONE -+ createLogicalDevice(); -+ createSwapChain(); -+ createImageViews(); -+ createRenderPass(); -+ createComputeDescriptorSetLayout(); -+ createGraphicsPipeline(); -+ createComputePipeline(); -+ createFramebuffers(); DONE -+ createCommandPool(); DONE -+ createShaderStorageBuffers(); DONE -+ createUniformBuffers(); DONE -+ createDescriptorPool(); DONE -+ createComputeDescriptorSets(); DONE -+ createCommandBuffers(); DONE -+ createComputeCommandBuffers(); DONE -+ createSyncObjects(); DONE -+ */ - pub fn new(event_loop: &winit::event_loop::EventLoop<()>) -> VulkanApp { - let window = -- utility::window::init_window(event_loop, WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT); -+ init_window(event_loop, WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT); - - // init vulkan stuff - let entry = unsafe { Entry::load().unwrap() }; -@@ -72,7 +132,7 @@ impl VulkanApp { - &VALIDATION.required_validation_layers.to_vec(), - ); - let surface_stuff = -- share::create_surface(&entry, &instance, &window, WINDOW_WIDTH, WINDOW_HEIGHT); -+ SurfaceStuff::new(&entry, &instance, &window, WINDOW_WIDTH, WINDOW_HEIGHT); - let (debug_utils_loader, debug_merssager) = - setup_debug_utils(VALIDATION.is_enable, &entry, &instance); - let physical_device = -@@ -88,7 +148,9 @@ impl VulkanApp { - unsafe { device.get_device_queue(queue_family.graphics_family.unwrap(), 0) }; - let present_queue = - unsafe { device.get_device_queue(queue_family.present_family.unwrap(), 0) }; -- let swapchain_stuff = share::create_swapchain( -+ let compute_queue = -+ unsafe { device.get_device_queue(queue_family.compute_family.unwrap(), 0) }; -+ let swapchain_stuff = SwapChainStuff::new( - &instance, - &device, - physical_device, -@@ -102,11 +164,19 @@ impl VulkanApp { - &swapchain_stuff.swapchain_images, - ); - let render_pass = share::create_render_pass(&device, swapchain_stuff.swapchain_format); -- let (graphics_pipeline, pipeline_layout) = VulkanApp::create_graphics_pipeline( -+ let (graphics_pipeline, graphics_pipeline_layout) = VulkanApp::create_graphics_pipeline( -+ &device, -+ render_pass, -+ swapchain_stuff.swapchain_extent, -+ ); -+ let (compute_pipelines, compute_pipeline_layout) = VulkanApp::create_compute_pipelines( - &device, - render_pass, - swapchain_stuff.swapchain_extent, - ); -+ -+ let compute_pipeline = compute_pipelines[0]; -+ - let swapchain_framebuffers = share::create_framebuffers( - &device, - render_pass, -@@ -125,7 +195,7 @@ impl VulkanApp { - swapchain_stuff.swapchain_extent, - vertex_buffer, - ); -- let sync_ojbects = share::create_sync_objects(&device, MAX_FRAMES_IN_FLIGHT); -+ let sync_ojbects = SyncObjects::new(&device, MAX_FRAMES_IN_FLIGHT); - - // cleanup(); the 'drop' function will take care of it. - VulkanApp { -@@ -146,6 +216,7 @@ impl VulkanApp { - queue_family, - graphics_queue, - present_queue, -+ compute_queue, - - swapchain_loader: swapchain_stuff.swapchain_loader, - swapchain: swapchain_stuff.swapchain, -@@ -155,10 +226,15 @@ impl VulkanApp { - swapchain_imageviews, - swapchain_framebuffers, - -- pipeline_layout, -+ graphics_pipeline_layout, - render_pass, - graphics_pipeline, - -+ -+ compute_descriptor_sets, -+ compute_pipeline_layout, -+ compute_pipeline, -+ - vertex_buffer, - vertex_buffer_memory, - -@@ -174,6 +250,56 @@ impl VulkanApp { - } - } - -+ pub fn main_loop(self) { -+ let mut tick_counter = super::fps_limiter::FPSLimiter::new(); -+ -+ self.event_loop -+ .run(move |event, _, control_flow| match event { -+ Event::WindowEvent { event, .. } => match event { -+ WindowEvent::CloseRequested => { -+ vulkan_app.wait_device_idle(); -+ *control_flow = ControlFlow::Exit -+ } -+ WindowEvent::KeyboardInput { input, .. } => match input { -+ KeyboardInput { -+ virtual_keycode, -+ state, -+ .. -+ } => match (virtual_keycode, state) { -+ (Some(VirtualKeyCode::Escape), ElementState::Pressed) => { -+ vulkan_app.wait_device_idle(); -+ *control_flow = ControlFlow::Exit -+ } -+ _ => {} -+ }, -+ }, -+ WindowEvent::Resized(_new_size) => { -+ vulkan_app.wait_device_idle(); -+ vulkan_app.resize_framebuffer(); -+ } -+ _ => {} -+ }, -+ Event::MainEventsCleared => { -+ vulkan_app.window_ref().request_redraw(); -+ } -+ Event::RedrawRequested(_window_id) => { -+ let delta_time = tick_counter.delta_time(); -+ vulkan_app.draw_frame(delta_time); -+ -+ if IS_PAINT_FPS_COUNTER { -+ print!("FPS: {}\r", tick_counter.fps()); -+ } -+ -+ tick_counter.tick_frame(); -+ } -+ Event::LoopDestroyed => { -+ vulkan_app.wait_device_idle(); -+ } -+ _ => (), -+ }) -+ -+ } -+ - fn create_vertex_buffer( - instance: &ash::Instance, - device: &ash::Device, -@@ -263,10 +389,111 @@ impl VulkanApp { - } - - panic!("Failed to find suitable memory type!") -+ share::pick_physical_device(&instance, &surface_stuff, &DEVICE_EXTENSIONS); - } -+ /* -+ * IDEK WHERE THIS CAME FROM I FUCKED UP THIS FILE, SHITS WHACK -+ * let (device, queue_family) = share::create_logical_device( -+ &instance, -+ physical_device, -+ &VALIDATION, -+ &DEVICE_EXTENSIONS, -+ &surface_stuff, -+ ); -+ let graphics_queue = -+ unsafe { device.get_device_queue(queue_family.graphics_family.unwrap(), 0) }; -+ let present_queue = -+ unsafe { device.get_device_queue(queue_family.present_family.unwrap(), 0) }; -+ let compute_queue = -+ unsafe { device.get_device_queue(queue_family.compute_family.unwrap(), 0) }; -+ let swapchain_stuff = SwapChainStuff::new( -+ &instance, -+ &device, -+ physical_device, -+ &window, -+ &surface_stuff, -+ &queue_family, -+ ); -+ let swapchain_imageviews = share::create_image_views( -+ &device, -+ swapchain_stuff.swapchain_format, -+ &swapchain_stuff.swapchain_images, -+ ); -+ let render_pass = share::create_render_pass(&device, swapchain_stuff.swapchain_format); -+ let (graphics_pipeline, graphics_pipeline_layout) = VulkanApp::create_graphics_pipeline( -+ &device, -+ render_pass, -+ swapchain_stuff.swapchain_extent, -+ ); -+ let (compute_pipelines, compute_pipeline_layout) = VulkanApp::create_compute_pipelines( -+ &device, -+ render_pass, -+ swapchain_stuff.swapchain_extent, -+ ); - -- fn create_command_buffers( -- device: &ash::Device, -+ let compute_pipeline = compute_pipelines[0]; -+ -+ let swapchain_framebuffers = share::create_framebuffers( -+ &device, -+ render_pass, -+ &swapchain_imageviews, -+ swapchain_stuff.swapchain_extent, -+ ); -+ let command_pool = share::create_command_pool(&device, &queue_family); -+ let (vertex_buffer, vertex_buffer_memory) = -+ VulkanApp::create_vertex_buffer(&instance, &device, physical_device); -+ let command_buffers = VulkanApp::create_command_buffers( -+ &device, -+ command_pool, -+ graphics_pipeline, -+ &swapchain_framebuffers, -+ render_pass, -+ swapchain_stuff.swapchain_extent, -+ vertex_buffer, -+ ); -+ let sync_ojbects = SyncObjects::new(&device, MAX_FRAMES_IN_FLIGHT); -+ -+ // cleanup(); the 'drop' function will take care of it. -+ VulkanApp { -+ // winit stuff -+ window, -+ -+ // vulkan stuff -+ _entry: entry, -+ instance, -+ surface: surface_stuff.surface, -+ surface_loader: surface_stuff.surface_loader, -+ debug_utils_loader, -+ debug_merssager, -+ -+ physical_device, -+ device, -+ -+ queue_family, -+ graphics_queue, -+ present_queue, -+ compute_queue, -+ -+ swapchain_loader: swapchain_stuff.swapchain_loader, -+ swapchain: swapchain_stuff.swapchain, -+ swapchain_format: swapchain_stuff.swapchain_format, -+ swapchain_images: swapchain_stuff.swapchain_images, -+ swapchain_extent: swapchain_stuff.swapchain_extent, -+ swapchain_imageviews, -+ swapchain_framebuffers, -+ -+ graphics_pipeline_layout, -+ render_pass, -+ graphics_pipeline, -+ -+ -+ compute_descriptor_set, -+ compute_pipeline_layout, -+ compute_pipeline,*/ -+ -+ -+/* FUCKED UP GRAPHICS PIPELINE CREATION FUNCTION WITH INTEGRATED COMPUTE PIPELINE CCREATION, THIS -+ * IS SUPER FUCKED - command_pool: vk::CommandPool, - graphics_pipeline: vk::Pipeline, - framebuffers: &Vec, -@@ -346,31 +573,42 @@ impl VulkanApp { - .end_command_buffer(command_buffer) - .expect("Failed to record Command Buffer at Ending!"); - } -- } -- -- command_buffers -- } --} -- --// Fix content ------------------------------------------------------------------------------- --impl VulkanApp { -- fn create_graphics_pipeline( -- device: &ash::Device, -- render_pass: vk::RenderPass, -- swapchain_extent: vk::Extent2D, -- ) -> (vk::Pipeline, vk::PipelineLayout) { -- let mut shader_modules: Vec = vec![]; -- let main_function = CString::new("main").unwrap(); -- for (shader, stage_i) in shaders() { -- shader_modules.push(vk::PipelineShaderStageCreateInfo { -- s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, -- p_next: ptr::null(), -- flags: vk::PipelineShaderStageCreateFlags::empty(), -- module: share::create_shader_module(device, shader), -- p_name: main_function.as_ptr(), -- stage: stage_i, -- p_specialization_info: ptr::null(), -- }) -+ shader_modules.push(vk::PipelineShaderStageCreateInfo { -+ s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, -+ p_next: ptr::null(), -+ flags: vk::PipelineShaderStageCreateFlags::empty(), -+ module: share::create_shader_module(device, shader), -+ p_name: main_function.as_ptr(), -+ stage: stage_flag, -+ p_specialization_info: ptr::null(), -+ }); -+ } else if stage_flag == vk::ShaderStageFlags::FRAGMENT { -+ shader_modules.push( -+ vk::PipelineShaderStageCreateInfo { -+ s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, -+ p_next: ptr::null(), -+ flags: vk::PipelineShaderStageCreateFlags::empty(), -+ module: share::create_shader_module(device, shader), -+ p_name: main_function.as_ptr(), -+ stage: stage_flag, -+ p_specialization_info: ptr::null(), -+ -+ } -+ ) -+ } else if stage_flag == vk::ShaderStageFlags::VERTEX { -+ shader_modules.push( -+ vk::PipelineShaderStageCreateInfo { -+ s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, -+ p_next: ptr::null(), -+ flags: vk::PipelineShaderStageCreateFlags::empty(), -+ module: share::create_shader_module(device, shader), -+ p_name: main_function.as_ptr(), -+ stage: stage_flag, -+ p_specialization_info: ptr::null(), -+ -+ } -+ ) -+ } - } - - let binding_description = Vertex::get_binding_description(); -@@ -417,6 +655,12 @@ impl VulkanApp { - p_viewports: viewports.as_ptr(), - }; - -+ let rasterization_statue_create_info = vk::PipelineRasterizationStateCreateInfo { -+ s_type: vk::StructureType::PIPELINE_RASTERIZATION_STATE_CREATE_INFO, -+ p_next: ptr::null(), -+ p_viewports: viewports.as_ptr(), -+ }; -+ - let rasterization_statue_create_info = vk::PipelineRasterizationStateCreateInfo { - s_type: vk::StructureType::PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - p_next: ptr::null(), -@@ -492,21 +736,7 @@ impl VulkanApp { - blend_constants: [0.0, 0.0, 0.0, 0.0], - }; - -- let pipeline_layout_create_info = vk::PipelineLayoutCreateInfo { -- s_type: vk::StructureType::PIPELINE_LAYOUT_CREATE_INFO, -- p_next: ptr::null(), -- flags: vk::PipelineLayoutCreateFlags::empty(), -- set_layout_count: 0, -- p_set_layouts: ptr::null(), -- push_constant_range_count: 0, -- p_push_constant_ranges: ptr::null(), -- }; -- -- let pipeline_layout = unsafe { -- device -- .create_pipeline_layout(&pipeline_layout_create_info, None) -- .expect("Failed to create pipeline layout!") -- }; -+ println!("shader module count: {}", shader_modules.len()); - - let graphic_pipeline_create_infos = [vk::GraphicsPipelineCreateInfo { - s_type: vk::StructureType::GRAPHICS_PIPELINE_CREATE_INFO, -@@ -520,34 +750,26 @@ impl VulkanApp { - p_viewport_state: &viewport_state_create_info, - p_rasterization_state: &rasterization_statue_create_info, - p_multisample_state: &multisample_state_create_info, -- p_depth_stencil_state: &depth_state_create_info, -- p_color_blend_state: &color_blend_state, -- p_dynamic_state: ptr::null(), -- layout: pipeline_layout, -- render_pass, -- subpass: 0, -- base_pipeline_handle: vk::Pipeline::null(), -- base_pipeline_index: -1, -- }]; -+ s_type: vk::StructureType::COMPUTE_PIPELINE_CREATE_INFO, -+ p_next: ptr::null(), -+ layout: pipeline_layout, -+ flags: vk::PipelineCreateFlags::empty(), -+ ..Default::default() -+ } -+ ); - -- let graphics_pipelines = unsafe { -+ } -+ let compute_pipelines = unsafe { - device -- .create_graphics_pipelines( -+ .create_compute_pipelines( - vk::PipelineCache::null(), -- &graphic_pipeline_create_infos, -+ &compute_infos, - None, - ) -- .expect("Failed to create Graphics Pipeline!.") -- }; -- -- unsafe { -- for shader in shader_modules { -- device.destroy_shader_module(shader.module, None) -- } -- } -+ }.unwrap(); - -- (graphics_pipelines[0], pipeline_layout) -- } -+ (compute_pipelines, pipeline_layout) -+ }*/ - - fn draw_frame(&mut self) { - let wait_fences = [self.in_flight_fences[self.current_frame]]; -@@ -657,7 +879,7 @@ impl VulkanApp { - }; - self.cleanup_swapchain(); - -- let swapchain_stuff = share::create_swapchain( -+ let swapchain_stuff = SwapChainStuff::new( - &self.instance, - &self.device, - self.physical_device, -@@ -680,7 +902,7 @@ impl VulkanApp { - swapchain_stuff.swapchain_extent, - ); - self.graphics_pipeline = graphics_pipeline; -- self.pipeline_layout = pipeline_layout; -+ self.graphics_pipeline_layout = pipeline_layout; - - self.swapchain_framebuffers = share::create_framebuffers( - &self.device, -@@ -708,7 +930,7 @@ impl VulkanApp { - } - self.device.destroy_pipeline(self.graphics_pipeline, None); - self.device -- .destroy_pipeline_layout(self.pipeline_layout, None); -+ .destroy_pipeline_layout(self.graphics_pipeline_layout, None); - self.device.destroy_render_pass(self.render_pass, None); - for &image_view in self.swapchain_imageviews.iter() { - self.device.destroy_image_view(image_view, None); -@@ -719,7 +941,10 @@ impl VulkanApp { - } - } - -+ -+ - impl Drop for VulkanApp { -+ //cleanup in C++ - fn drop(&mut self) { - unsafe { - for i in 0..MAX_FRAMES_IN_FLIGHT { -@@ -732,6 +957,9 @@ impl Drop for VulkanApp { - - self.cleanup_swapchain(); - -+ self.device -+ .destory -+ - self.device.destroy_buffer(self.vertex_buffer, None); - self.device.free_memory(self.vertex_buffer_memory, None); - -@@ -749,46 +977,3 @@ impl Drop for VulkanApp { - } - } - --impl VulkanApp { -- pub fn main_loop(mut self, event_loop: EventLoop<()>) { -- let mut tick_counter = utility::fps_limiter::FPSLimiter::new(); -- -- event_loop.run(move |event, _, control_flow| match event { -- Event::WindowEvent { event, .. } => match event { -- WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, -- WindowEvent::KeyboardInput { input, .. } => match input { -- KeyboardInput { -- virtual_keycode, -- state, -- .. -- } => match (virtual_keycode, state) { -- (Some(VirtualKeyCode::Escape), ElementState::Pressed) => { -- *control_flow = ControlFlow::Exit -- } -- _ => {} -- }, -- }, -- _ => {} -- }, -- Event::MainEventsCleared => { -- self.window.request_redraw(); -- } -- Event::RedrawRequested(_window_id) => { -- self.draw_frame(); -- -- tick_counter.tick_frame(); -- if true { -- print!("FPS: {}\r", tick_counter.fps()); -- } -- } -- Event::LoopDestroyed => { -- unsafe { -- self.device -- .device_wait_idle() -- .expect("Failed to wait device idle!") -- }; -- } -- _ => (), -- }) -- } --} diff --git a/src/entities.rs b/src/entities.rs index 7c4dd78..8670ff8 100644 --- a/src/entities.rs +++ b/src/entities.rs @@ -9,14 +9,28 @@ use rand::{ use crate::utility::constants::*; use std::f32::consts::PI; -pub const PARTICLE_COUNT: i32 = 1000; +pub const PARTICLE_COUNT: u64 = 1; #[repr(C)] #[derive(Clone, Debug, Copy)] pub struct Particle { - pos: Vector2, - vel: Vector2, - color: Vector4, + pos: (f32, f32), + vel: (f32, f32), + color: (f32, f32, f32, f32), +} + +fn normalize(vec2: (f32, f32)) -> (f32, f32) { + let magnitude = (vec2.0.powi(2) + vec2.1.powi(2)).sqrt(); + + if magnitude != 0.0 { + (vec2.0 / magnitude, vec2.1 / magnitude) + } else { + vec2 + } +} + +fn vec2_scalar_mul(vec2: (f32, f32), scalar: f32) -> (f32, f32) { + (vec2.0 * scalar, vec2.1 * scalar) } impl Particle { @@ -27,14 +41,16 @@ impl Particle { let mut rng = thread_rng(); for _i in 0..PARTICLE_COUNT { - let r = (between.sample(&mut rng) as f32).sqrt(); + let r = 0.25 * (between.sample(&mut rng) as f32).sqrt(); let theta = between.sample(&mut rng) * 2.0 * PI; - let x = r * theta.cos() * WINDOW_HEIGHT as f32 * WINDOW_WIDTH as f32; + println!("THETA {}", theta); + let x = r * theta.cos() * WINDOW_HEIGHT as f32 / WINDOW_WIDTH as f32; let y = r * theta.sin(); + let (x, y) = (10.0, 0.0); res.push(Particle { - pos: Vector2::new(x, y), - vel: Vector2::new(x, y).normalize() * 0.00025, - color: Vector4::new( + pos: (x, y), + vel: vec2_scalar_mul(normalize((x, y)), 0.00025), + color: ( between.sample(&mut rng), between.sample(&mut rng), between.sample(&mut rng), @@ -42,6 +58,7 @@ impl Particle { ), }) } + println!("gen: {:?}", res); res } @@ -79,45 +96,3 @@ pub struct Vertex { pos: [f32; 2], color: [f32; 3], } - -impl Vertex { - pub fn get_binding_description() -> [vk::VertexInputBindingDescription; 1] { - [vk::VertexInputBindingDescription { - binding: 0, - stride: std::mem::size_of::() as u32, - input_rate: vk::VertexInputRate::VERTEX, - }] - } - - pub fn get_attribute_descriptions() -> [vk::VertexInputAttributeDescription; 2] { - [ - vk::VertexInputAttributeDescription { - binding: 0, - location: 0, - format: vk::Format::R32G32_SFLOAT, - offset: offset_of!(Vertex, pos) as u32, - }, - vk::VertexInputAttributeDescription { - binding: 0, - location: 1, - format: vk::Format::R32G32B32_SFLOAT, - offset: offset_of!(Vertex, color) as u32, - }, - ] - } -} - -pub const TRI_VERT_DATA: [Vertex; 3] = [ - Vertex { - pos: [0.0, -0.5], - color: [1.0, 1.0, 1.0], - }, - Vertex { - pos: [0.5, 0.5], - color: [0.0, 1.0, 0.0], - }, - Vertex { - pos: [-0.5, 0.5], - color: [0.0, 0.0, 1.0], - }, -]; diff --git a/src/main.rs b/src/main.rs index e9975fa..924b699 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,19 @@ +#![feature(slice_ptr_get)] +#![allow(warnings)] pub mod entities; pub mod render; pub mod shaders; pub mod utility; -use render::VulkanApp; +use render::{ App, ProgramProc }; use winit::event_loop::EventLoop; fn main() { - let event_loop = EventLoop::new(); + let program = ProgramProc { + event_loop: EventLoop::new() + }; - let vulkan_app = VulkanApp::new(&event_loop); - vulkan_app.main_loop(event_loop); + let app = App::new(); + program.main_loop(app); } // ------------------------------------------------------------------------------------------- diff --git a/src/render.rs b/src/render.rs index c3d9c99..cc1cd24 100644 --- a/src/render.rs +++ b/src/render.rs @@ -1,57 +1,173 @@ use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; +use ash::vk; +use image; +use image::GenericImageView; + +use crate::utility; +use crate::utility::constants::*; +use crate::utility::debug::*; +use crate::utility::structures::*; +use crate::utility::fps_limiter::*; +use crate::utility::{debug, platforms}; +use crate::utility::tools::*; +use crate::entities::*; +use crate::shaders::shaders; + use std::ffi::CString; use std::ptr; +use std::mem::size_of; +use std::default; +use std::os::raw::{ c_void, c_char }; + // Constants const WINDOW_TITLE: &'static str = "Template"; const IS_PAINT_FPS_COUNTER: bool = true; -/* Non share.rs functions to check - * - * debug fns covered by setup_debug_utils + - * Particle related functions get_binding, get_attribute + - * create_swapchain relocated to structures.rs + - * - * check_validation_layer_support - * - * - * - * - */ - -/* LIST USED share.rs functions here - * - * create_swapchain - * create_shader_module + - * pick_physical_device + - * create_instance + - * create_logical_device + - * create_image_views + - * create_render_pass + - * create_framebuffers + - * create_command_pool - * choose_swap_surface_format + - * choose_swap_present_mode + - * choose_swap_extent + - * query_swapchain_support + - * is_physical_device_suitable + - * check_device_extension_support + - * find_queue_family + - * required_extension_names + - * create_command_buffers - * record_command_buffer + - */ - -/* - * TODO fix create_command_buffers so it matches C++ code - * TODO create initVulkan equivalent - * TODO cleanup_swapchain and cleanup functions - * TODO create_command_buffer, record_command_buffer - * */ +pub struct ProgramProc { + pub event_loop: EventLoop<()>, +} + +impl ProgramProc { + + pub fn new() -> ProgramProc { + // init window stuff + let event_loop = EventLoop::new(); + + ProgramProc { event_loop } + } + + pub fn main_loop(self, mut vulkan_app: App) { + + let mut tick_counter = utility::fps_limiter::FPSLimiter::new(); + + self.event_loop.run(move |event, _, control_flow| { + + match event { + | Event::WindowEvent { event, .. } => { + match event { + | WindowEvent::CloseRequested => { + vulkan_app.wait_device_idle(); + *control_flow = ControlFlow::Exit + }, + | WindowEvent::KeyboardInput { input, .. } => { + match input { + | KeyboardInput { virtual_keycode, state, .. } => { + match (virtual_keycode, state) { + | (Some(VirtualKeyCode::Escape), ElementState::Pressed) => { + vulkan_app.wait_device_idle(); + *control_flow = ControlFlow::Exit + }, + | _ => {}, + } + }, + } + }, + | WindowEvent::Resized(_new_size) => { + vulkan_app.wait_device_idle(); + vulkan_app.is_framebuffer_resized = true; + }, + | _ => {}, + } + }, + | Event::MainEventsCleared => { + &vulkan_app.window.request_redraw(); + }, + | Event::RedrawRequested(_window_id) => { + let delta_time = tick_counter.delta_time(); + vulkan_app.draw_frame(); + + if IS_PAINT_FPS_COUNTER { + print!("FPS: {}\r", tick_counter.fps()); + } + + tick_counter.tick_frame(); + }, + | Event::LoopDestroyed => { + vulkan_app.wait_device_idle(); + }, + _ => (), + } + + }) + } + +} + +pub fn create_instance( + entry: &ash::Entry, + window_title: &str, + is_enable_debug: bool, + required_validation_layers: &Vec<&str>, +) -> ash::Instance { + if is_enable_debug + && debug::check_validation_layer_support(entry, required_validation_layers) == false + { + panic!("Validation layers requested, but not available!"); + } + let app_name = CString::new(window_title).unwrap(); + let engine_name = CString::new("Vulkan Engine").unwrap(); + let app_info = vk::ApplicationInfo { + p_application_name: app_name.as_ptr(), + s_type: vk::StructureType::APPLICATION_INFO, + p_next: ptr::null(), + application_version: APPLICATION_VERSION, + p_engine_name: engine_name.as_ptr(), + engine_version: ENGINE_VERSION, + api_version: API_VERSION, + }; + + // This create info used to debug issues in vk::createInstance and vk::destroyInstance. + let debug_utils_create_info = debug::populate_debug_messenger_create_info(); + + // VK_EXT debug report has been requested here. + let extension_names = platforms::required_extension_names(); + + let requred_validation_layer_raw_names: Vec = required_validation_layers + .iter() + .map(|layer_name| CString::new(*layer_name).unwrap()) + .collect(); + let layer_names: Vec<*const i8> = requred_validation_layer_raw_names + .iter() + .map(|layer_name| layer_name.as_ptr()) + .collect(); + + let create_info = vk::InstanceCreateInfo { + s_type: vk::StructureType::INSTANCE_CREATE_INFO, + p_next: if VALIDATION.is_enabled { + &debug_utils_create_info as *const vk::DebugUtilsMessengerCreateInfoEXT + as *const c_void + } else { + ptr::null() + }, + flags: vk::InstanceCreateFlags::empty(), + p_application_info: &app_info, + pp_enabled_layer_names: if is_enable_debug { + layer_names.as_ptr() + } else { + ptr::null() + }, + enabled_layer_count: if is_enable_debug { + layer_names.len() + } else { + 0 + } as u32, + pp_enabled_extension_names: extension_names.as_ptr(), + enabled_extension_count: extension_names.len() as u32, + }; + + let instance: ash::Instance = unsafe { + entry + .create_instance(&create_info, None) + .expect("Failed to create instance!") + }; + + instance +} pub fn init_window( event_loop: &EventLoop<()>, @@ -66,28 +182,87 @@ pub fn init_window( .expect("Failed to create window.") } +pub fn choose_swapchain_format( + available_formats: &Vec, +) -> vk::SurfaceFormatKHR { + for available_format in available_formats { + if available_format.format == vk::Format::B8G8R8A8_SRGB + && available_format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR + { + return available_format.clone(); + } + } + + return available_formats.first().unwrap().clone(); +} + +pub fn choose_swapchain_present_mode( + available_present_modes: &Vec, +) -> vk::PresentModeKHR { + for &available_present_mode in available_present_modes.iter() { + if available_present_mode == vk::PresentModeKHR::MAILBOX { + return available_present_mode; + } + } + + vk::PresentModeKHR::FIFO +} + +pub fn create_shader_module(device: &ash::Device, code: Vec) -> vk::ShaderModule { + let shader_module_create_info = vk::ShaderModuleCreateInfo { + s_type: vk::StructureType::SHADER_MODULE_CREATE_INFO, + p_next: ptr::null(), + flags: vk::ShaderModuleCreateFlags::empty(), + code_size: code.len(), + p_code: code.as_ptr() as *const u32, + }; + + unsafe { + device + .create_shader_module(&shader_module_create_info, None) + .expect("Failed to create Shader Module!") + } +} + + +pub fn find_memory_type( + type_filter: u32, + required_properties: vk::MemoryPropertyFlags, + mem_properties: &vk::PhysicalDeviceMemoryProperties, +) -> u32 { + for (i, memory_type) in mem_properties.memory_types.iter().enumerate() { + if (type_filter & (1 << i)) > 0 && memory_type.property_flags.contains(required_properties) + { + return i as u32; + } + } + + panic!("Failed to find suitable memory type!") +} pub struct App { - window: winit::window::Window, + pub window: winit::window::Window, + pub event_loop: winit::event_loop::EventLoop<()>, // vulkan stuff - _entry: ash::Entry, - instance: ash::Instance, - surface_loader: ash::extensions::khr::Surface, - surface: vk::SurfaceKHR, - debug_utils_loader: ash::extensions::ext::DebugUtils, - debug_merssager: vk::DebugUtilsMessengerEXT, - - physical_device: vk::PhysicalDevice, - device: ash::Device, - - queue_family: QueueFamilyIndices, - graphics_queue: vk::Queue, - present_queue: vk::Queue, + pub entry: ash::Entry, + pub instance: ash::Instance, + pub surface_stuff: SurfaceStuff, + //surface_loader: ash::extensions::khr::Surface, + //surface: vk::SurfaceKHR, + pub debug_utils_loader: ash::extensions::ext::DebugUtils, + pub debug_messenger: vk::DebugUtilsMessengerEXT, + + pub physical_device: vk::PhysicalDevice, + pub device: ash::Device, + + pub queue_family: QueueFamilyIndices, + pub graphics_queue: vk::Queue, + pub present_queue: vk::Queue, //new from C++ - compute_queue: vk::Queue, + pub compute_queue: vk::Queue, - swapchain_stuff: SwapChainStuff, + pub swapchain_stuff: SwapChainStuff, //not in C++ //swapchain_loader: ash::extensions::khr::Swapchain, //swapchain: vk::SwapchainKHR, @@ -97,79 +272,93 @@ pub struct App { //swapchain_imageviews: Vec, //swapchain_framebuffers: Vec, - render_pass: vk::RenderPass, + pub render_pass: vk::RenderPass, - graphics_pipeline_layout: vk::PipelineLayout, - graphics_pipeline: vk::Pipeline, + pub graphics_pipeline_layout: vk::PipelineLayout, + pub graphics_pipeline: vk::Pipeline, //new from C++ - compute_descriptor_set_layout: vk::DescriptorSetLayout, - compute_pipeline_layout: vk::PipelineLayout, - compute_pipeline: vk::Pipeline, + pub compute_descriptor_set_layout: vk::DescriptorSetLayout, + pub compute_pipeline_layout: vk::PipelineLayout, + pub compute_pipeline: vk::Pipeline, //vertex buffer for the triangle verticies //i think this is the same as shaderStorageBuffers in C++ version - shader_storage_buffers: Vec, - shader_storage_buffers_memory: Vec, + pub shader_storage_buffers: Vec, + pub shader_storage_buffers_memory: Vec, - uniform_buffers: Vec, - uniform_buffers_memory: Vec, - uniform_buffers_mapped: Vec<*mut c_void>, + pub uniform_buffers: Vec, + pub uniform_buffers_memory: Vec, + pub uniform_buffers_mapped: Vec<*mut c_void>, - descriptor_pool: vk::DescriptorPool, - compute_descriptor_sets: Vec, + pub descriptor_pool: vk::DescriptorPool, + pub compute_descriptor_sets: Vec, - command_pool: vk::CommandPool, - command_buffers: Vec, - compute_command_buffers: Vec, + pub command_pool: vk::CommandPool, + pub command_buffers: Vec, + pub compute_command_buffers: Vec, - sync_objects: SyncObjects, + pub sync_objects: SyncObjects, //image_available_semaphores: Vec, //render_finished_semaphores: Vec, - //in_flight_fences: Vec, - //compute_in_flight_fences: Vec, - current_frame: usize, + //inflight_fences: Vec, + //.compute_inflight_fences: Vec, + pub current_frame: usize, + + pub last_frame_time: f32, - last_frame_time: float, + pub is_framebuffer_resized: bool, - is_framebuffer_resized: bool, + pub last_time: f64, + + pub physical_device_memory_properties: vk::PhysicalDeviceMemoryProperties, } impl App { - ///initVulkan in C++ - pub fn new(event_loop: &winit::event_loop::EventLoop<()>) -> App { - let window = - init_window(event_loop, WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT); - - // init vulkan stuff - let entry = unsafe { Entry::load().unwrap() }; - let instance = share::create_instance( + + pub fn new() -> Self { + let event_loop = winit::event_loop::EventLoop::new(); + let window = init_window(&event_loop, WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT); + + let entry = unsafe { ash::Entry::load().unwrap() }; + + let instance = create_instance( + &entry, + WINDOW_TITLE, + VALIDATION.is_enabled, + &VALIDATION.required_validation_layers.to_vec(), + ); + + let (debug_utils_loader, debug_messenger) = setup_debug_utils(VALIDATION.is_enabled, &entry, &instance); + + let surface_stuff = SurfaceStuff::new( &entry, - WINDOW_TITLE, - VALIDATION.is_enable, - &VALIDATION.required_validation_layers.to_vec(), + &instance, + &window, + WINDOW_WIDTH, + WINDOW_HEIGHT ); - let surface_stuff = - SurfaceStuff::new(&entry, &instance, &window, WINDOW_WIDTH, WINDOW_HEIGHT); - let (debug_utils_loader, debug_merssager) = - setup_debug_utils(VALIDATION.is_enable, &entry, &instance); - let physical_device = - share::pick_physical_device(&instance, &surface_stuff, &DEVICE_EXTENSIONS); - let (device, queue_family) = share::create_logical_device( + + let physical_device = Self::pick_physical_device(&instance, &surface_stuff, &DEVICE_EXTENSIONS); + + let physical_device_memory_properties = unsafe { + instance.get_physical_device_memory_properties(physical_device) + }; + let (device, queue_family, graphics_queue, compute_queue, present_queue) = Self::create_logical_device( &instance, physical_device, &VALIDATION, &DEVICE_EXTENSIONS, &surface_stuff, ); - let graphics_queue = - unsafe { device.get_device_queue(queue_family.graphics_family.unwrap(), 0) }; + + /*let graphics_queue = + unsafe { device.get_device_queue(queue_family.graphics_and_compute_family.unwrap(), 0) }; let present_queue = - unsafe { device.get_device_queue(queue_family.present_family.unwrap(), 0) }; - let compute_queue = - unsafe { device.get_device_queue(queue_family.compute_family.unwrap(), 0) }; - let swapchain_stuff = SwapChainStuff::new( + unsafe { device.get_device_queue(queue_family.present_family.unwrap(), 0) };*/ + + let mut swapchain_stuff = SwapChainStuff::new( &instance, &device, physical_device, @@ -177,58 +366,48 @@ impl App { &surface_stuff, &queue_family, ); - let swapchain_imageviews = share::create_image_views( - &device, - swapchain_stuff.swapchain_format, - &swapchain_stuff.swapchain_images, - ); - let render_pass = share::create_render_pass(&device, swapchain_stuff.swapchain_format); - let (graphics_pipeline, graphics_pipeline_layout) = App::create_graphics_pipeline( - &device, - render_pass, - swapchain_stuff.swapchain_extent, - ); - let (compute_pipelines, compute_pipeline_layout) = App::create_compute_pipelines( - &device, - render_pass, - swapchain_stuff.swapchain_extent, - ); - let compute_pipeline = compute_pipelines[0]; + swapchain_stuff.swapchain_imageviews = Self::create_image_views(&device, &swapchain_stuff.swapchain_format, &swapchain_stuff.swapchain_images); - let swapchain_framebuffers = share::create_framebuffers( - &device, - render_pass, - &swapchain_imageviews, - swapchain_stuff.swapchain_extent, - ); - let command_pool = share::create_command_pool(&device, &queue_family); - let (vertex_buffer, vertex_buffer_memory) = - App::create_vertex_buffer(&instance, &device, physical_device); - let command_buffers = App::create_command_buffers( - &device, - command_pool, - graphics_pipeline, - &swapchain_framebuffers, - render_pass, - swapchain_stuff.swapchain_extent, - vertex_buffer, - ); - let sync_ojbects = SyncObjects::new(&device, MAX_FRAMES_IN_FLIGHT); + let render_pass = Self::create_render_pass(&device, &swapchain_stuff.swapchain_format); + + let compute_descriptor_set_layout = Self::create_compute_descriptor_set_layout(&device); + + let (graphics_pipeline, graphics_pipeline_layout) = Self::create_graphics_pipeline(&device, render_pass, &swapchain_stuff); + + let (compute_pipeline, compute_pipeline_layout) = Self::create_compute_pipeline(&device, compute_descriptor_set_layout); + + let swapchain_framebuffers = Self::create_framebuffers(&device, render_pass, &swapchain_stuff.swapchain_imageviews, &swapchain_stuff.swapchain_extent); + + swapchain_stuff.swapchain_framebuffers = swapchain_framebuffers; + + let command_pool = Self::create_command_pool(&device, &queue_family); + + let (shader_storage_buffers, shader_storage_buffers_memory) = Self::create_shader_storage_buffers(&device, physical_device_memory_properties, command_pool, graphics_queue); + + let (uniform_buffers, uniform_buffers_memory, uniform_buffers_mapped) = Self::create_uniform_buffers(&device, physical_device_memory_properties); + + let descriptor_pool = Self::create_descriptor_pool(&device, MAX_FRAMES_IN_FLIGHT); + + let compute_descriptor_sets = Self::create_compute_descriptor_sets(&device, compute_descriptor_set_layout, descriptor_pool, &uniform_buffers, &shader_storage_buffers); + + let command_buffers = Self::create_command_buffers(&device, command_pool); + + let compute_command_buffers = Self::create_command_buffers(&device, command_pool); + + let sync_objects = SyncObjects::new(&device, MAX_FRAMES_IN_FLIGHT); - // cleanup(); the 'drop' function will take care of it. - App { - // winit stuff + + Self { window, + event_loop, - // vulkan stuff - _entry: entry, + entry, instance, - surface: surface_stuff.surface, - surface_loader: surface_stuff.surface_loader, + surface_stuff, debug_utils_loader, - debug_merssager, - + debug_messenger, + physical_device, device, @@ -237,88 +416,46 @@ impl App { present_queue, compute_queue, - swapchain_loader: swapchain_stuff.swapchain_loader, - swapchain: swapchain_stuff.swapchain, - swapchain_format: swapchain_stuff.swapchain_format, - swapchain_images: swapchain_stuff.swapchain_images, - swapchain_extent: swapchain_stuff.swapchain_extent, - swapchain_imageviews, - swapchain_framebuffers, + swapchain_stuff, - graphics_pipeline_layout, render_pass, - graphics_pipeline, + graphics_pipeline_layout, + graphics_pipeline, - compute_descriptor_sets, + compute_descriptor_set_layout, compute_pipeline_layout, compute_pipeline, - vertex_buffer, - vertex_buffer_memory, + shader_storage_buffers, + shader_storage_buffers_memory, + + uniform_buffers, + uniform_buffers_memory, + uniform_buffers_mapped, + + descriptor_pool, + compute_descriptor_sets, command_pool, command_buffers, + compute_command_buffers, - image_available_semaphores: sync_ojbects.image_available_semaphores, - render_finished_semaphores: sync_ojbects.render_finished_semaphores, - in_flight_fences: sync_ojbects.inflight_fences, + sync_objects, current_frame: 0, - is_framebuffer_resized: false, - } - } + last_frame_time: 0.0, - pub fn main_loop(self) { - let mut tick_counter = super::fps_limiter::FPSLimiter::new(); + is_framebuffer_resized: false, - self.event_loop - .run(move |event, _, control_flow| match event { - Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => { - vulkan_app.wait_device_idle(); - *control_flow = ControlFlow::Exit - } - WindowEvent::KeyboardInput { input, .. } => match input { - KeyboardInput { - virtual_keycode, - state, - .. - } => match (virtual_keycode, state) { - (Some(VirtualKeyCode::Escape), ElementState::Pressed) => { - vulkan_app.wait_device_idle(); - *control_flow = ControlFlow::Exit - } - _ => {} - }, - }, - WindowEvent::Resized(_new_size) => { - vulkan_app.wait_device_idle(); - vulkan_app.resize_framebuffer(); - } - _ => {} - }, - Event::MainEventsCleared => { - vulkan_app.window_ref().request_redraw(); - } - Event::RedrawRequested(_window_id) => { - let delta_time = tick_counter.delta_time(); - vulkan_app.draw_frame(delta_time); + last_time: 0.0, - if IS_PAINT_FPS_COUNTER { - print!("FPS: {}\r", tick_counter.fps()); - } + physical_device_memory_properties, + } - tick_counter.tick_frame(); - } - Event::LoopDestroyed => { - vulkan_app.wait_device_idle(); - } - _ => (), - }) } - fn create_vertex_buffer( + /*fn create_vertex_buffer( instance: &ash::Instance, device: &ash::Device, physical_device: vk::PhysicalDevice, @@ -347,7 +484,7 @@ impl App { unsafe { instance.get_physical_device_memory_properties(physical_device) }; let required_memory_flags: vk::MemoryPropertyFlags = vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT; - let memory_type = VulkanApp::find_memory_type( + let memory_type = App::find_memory_type( mem_requirements.memory_type_bits, required_memory_flags, mem_properties, @@ -386,7 +523,7 @@ impl App { } (vertex_buffer, vertex_buffer_memory) - } + }*/ fn find_memory_type( type_filter: u32, @@ -399,27 +536,25 @@ impl App { } } - panic!("Failed to find suitable memory type!") - share::pick_physical_device(&instance, &surface_stuff, &DEVICE_EXTENSIONS); + panic!("Failed to find suitable memory type!"); } fn create_graphics_pipeline( - self, device: &ash::Device, render_pass: vk::RenderPass, - swapchain_extent: vk::Extent2D, + swapchain_stuff: &SwapChainStuff, ) -> (vk::Pipeline, vk::PipelineLayout) { let mut shader_modules: Vec = vec![]; let main_function = CString::new("main").unwrap(); for (shader, stage_i) in shaders() { //check if graphics shader - if stage_i.contains(ShaderStageFlags::ALL_GRAPHICS) { + if stage_i == vk::ShaderStageFlags::VERTEX || stage_i == vk::ShaderStageFlags::FRAGMENT { shader_modules.push( vk::PipelineShaderStageCreateInfo { s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, p_next: ptr::null(), flags: vk::PipelineShaderStageCreateFlags::empty(), - module: share::create_shader_module(device, shader), + module: create_shader_module(device, shader), p_name: main_function.as_ptr(), stage: stage_i, p_specialization_info: ptr::null(), @@ -434,7 +569,7 @@ impl App { //612-621 let binding_description = Particle::get_binding_description(); - let attribute_description = Particle::get_attribute_description(); + let attribute_description = Particle::get_attribute_descriptions(); let vertex_input_info = vk::PipelineVertexInputStateCreateInfo { s_type: vk::StructureType::PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, @@ -443,32 +578,31 @@ impl App { vertex_attribute_description_count: attribute_description.len() as u32, p_vertex_attribute_descriptions: attribute_description.as_ptr(), vertex_binding_description_count: binding_description.len() as u32, - p_ver - } + p_vertex_binding_descriptions: binding_description.as_ptr(), + }; //623-626 let input_assembly = vk::PipelineInputAssemblyStateCreateInfo { s_type: vk::StructureType::PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - flags: vk::PipelineInputAssemblyStateCreateFlags::empty(), - p_next: ptr::null(), topology: vk::PrimitiveTopology::POINT_LIST, primitive_restart_enable: vk::FALSE, + ..Default::default() }; //628-631, more verbose and explicit than C++ let viewports = [vk::Viewport { x: 0.0, y: 0.0, - width: self.swapchain_stuff.swapchain_extent.width as f32, - height: self.swapchain_stuff.swapchain_extent.height as f32, + width: swapchain_stuff.swapchain_extent.width as f32, + height: swapchain_stuff.swapchain_extent.height as f32, min_depth: 0.0, max_depth: 1.0, }]; let scissors = [vk::Rect2D { offset: vk::Offset2D { x: 0, y: 0 }, - extent: self.swapchain_stuff.swapchain_extent, + extent: swapchain_stuff.swapchain_extent, }]; let viewport_state = vk::PipelineViewportStateCreateInfo { @@ -493,7 +627,6 @@ impl App { rasterizer_discard_enable: vk::FALSE, depth_clamp_enable: vk::FALSE, depth_bias_clamp: 0.0, - device.destroy_shader_module(); depth_bias_constant_factor: 0.0, depth_bias_enable: vk::FALSE, depth_bias_slope_factor: 0.0, @@ -531,41 +664,42 @@ impl App { flags: vk::PipelineColorBlendStateCreateFlags::empty(), logic_op_enable: vk::FALSE, logic_op: vk::LogicOp::COPY, - attachment_count: color_blend_attachment_states.len() as u32, - p_attachments: color_blend_attachment_states.as_ptr(), + attachment_count: 1, + p_attachments: &color_blend_attachment as *const vk::PipelineColorBlendAttachmentState, blend_constants: [0.0, 0.0, 0.0, 0.0], }; //669-676 - let dynamic_states = vk::DynamicState { + let dynamic_states = vec![ vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR, - }; + ]; let dynamic_state = vk::PipelineDynamicStateCreateInfo { s_type: vk::StructureType::PIPELINE_DYNAMIC_STATE_CREATE_INFO, dynamic_state_count: dynamic_states.len() as u32, p_dynamic_states: dynamic_states.as_ptr(), - ..default::Default() + ..Default::default() }; //678-685 let pipeline_layout_info = vk::PipelineLayoutCreateInfo { s_type: vk::StructureType::PIPELINE_LAYOUT_CREATE_INFO, set_layout_count: 0, - p_sets_layout: ptr::null(), + p_set_layouts: ptr::null(), + ..Default::default() }; - unsafe { + let pipeline_layout = unsafe { device - .create_pipeline_layout(&pipeline_layout_info, ptr::null(), self.graphics_pipeline_layout) - .expect("failed to create graphics pipeline layout"); - } + .create_pipeline_layout(&pipeline_layout_info, None) + .expect("failed to create graphics pipeline layout") + }; let pipeline_info = vk::GraphicsPipelineCreateInfo { - s_type: vk::StructureType::GRAPHICS_PIPELINE_CREATE_INFO + s_type: vk::StructureType::GRAPHICS_PIPELINE_CREATE_INFO, stage_count: 2, - p_stages: shader_modules, + p_stages: shader_modules.as_ptr(), p_vertex_input_state: &vertex_input_info, p_input_assembly_state: &input_assembly, p_viewport_state: &viewport_state, @@ -573,42 +707,45 @@ impl App { p_multisample_state: &multisampling, p_color_blend_state: &color_blending, p_dynamic_state: &dynamic_state, - layout: self.graphics_pipeline_layout, - render_pass: self.render_pass, + layout: pipeline_layout, + render_pass: render_pass, subpass: 0, base_pipeline_handle: vk::Pipeline::null(), - ..default::Default() + ..Default::default() }; - //703-708 - unsafe { + let pipelines = unsafe { device - .create_graphics_pipeline(vk::PipelineCache::null, pipeline_info, None) - .expect("failed to create graphics pipeline"); + .create_graphics_pipelines(vk::PipelineCache::null(), &[pipeline_info], None) + .expect("failed to create graphics pipeline") + }; + //703-708 + unsafe { for shader in shader_modules { - device.destroy_shader_module(shader); + device.destroy_shader_module(shader.module, None); } } + + (pipelines[0], pipeline_layout) } fn create_compute_pipeline( - self - device: &ash::Device - ) { + device: &ash::Device, + compute_descriptor_set_layout: vk::DescriptorSetLayout, + ) -> (vk::Pipeline, vk::PipelineLayout) { //712-720 let mut shader_modules: Vec = vec![]; let main_function = CString::new("main").unwrap(); for (shader, stage_i) in shaders() { //check if graphics shader - if stage_i.contains(ShaderStageFlags::COMPUTE) { - share::create_shader_module(device, ) + if stage_i == vk::ShaderStageFlags::COMPUTE { shader_modules.push( vk::PipelineShaderStageCreateInfo { s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, p_next: ptr::null(), flags: vk::PipelineShaderStageCreateFlags::empty(), - module: share::create_shader_module(device, shader), + module: create_shader_module(device, shader), p_name: main_function.as_ptr(), stage: stage_i, p_specialization_info: ptr::null(), @@ -621,30 +758,33 @@ impl App { let comp_shader = shader_modules[0]; let pipeline_layout_info = vk::PipelineLayoutCreateInfo { - s_type: vk::StructureType::LAYOUT_CREATE_INFO, + s_type: vk::StructureType::PIPELINE_LAYOUT_CREATE_INFO, set_layout_count: 1, - p_set_layouts: &self.compute_descriptor_set_layout, + p_set_layouts: &compute_descriptor_set_layout, + ..Default::default() }; - self.compute_pipeline_layout = unsafe { + let compute_pipeline_layout = unsafe { device .create_pipeline_layout(&pipeline_layout_info, None) .expect("couldnt create compute pipeline layout") }; - pipeline_info = vk::ComputePipelineCreateInfo { + let pipeline_info = vk::ComputePipelineCreateInfo { s_type: vk::StructureType::COMPUTE_PIPELINE_CREATE_INFO, - layout: self.compute_pipeline_layout, - stage: compute_shader, + layout: compute_pipeline_layout, + stage: comp_shader, + ..Default::default() }; - self.compute__pipeline = unsafe { + let compute_pipeline = unsafe { device .create_compute_pipelines( vk::PipelineCache::null(), - &pipeline_info, + &[pipeline_info], None, ) + .expect("failed to create compute pipeline")[0] }; unsafe { @@ -653,16 +793,18 @@ impl App { None, ); } + + (compute_pipeline, compute_pipeline_layout) } - fn update_uniform_buffer(&mut self, current_image: u32) { - ubo = UniformBufferObject { + fn update_uniform_buffer(&mut self, current_image: usize) { + let mut ubo = UniformBufferObject { delta_time: self.last_frame_time, - } + }; unsafe { ptr::copy_nonoverlapping( - ubo, - self.uniform_buffers_mapped, + &mut ubo as *mut UniformBufferObject, + self.uniform_buffers_mapped[current_image] as *mut UniformBufferObject, size_of::() ); } @@ -670,7 +812,7 @@ impl App { fn record_compute_command_buffer( - self, + &self, device: &ash::Device, command_buffer: vk::CommandBuffer ) { @@ -694,14 +836,14 @@ impl App { vk::PipelineBindPoint::COMPUTE, self.compute_pipeline_layout, 0, - &self.compute_descriptor_sets[self.current_frame], + &[self.compute_descriptor_sets[self.current_frame]], &[], ); device .cmd_dispatch( command_buffer, - PARTICLE_COUNT / 256, + (PARTICLE_COUNT / 256) as u32, 1, 1, ); @@ -711,30 +853,30 @@ impl App { } } - fn draw_frame(&mut self, device: &ash::Device) { + fn draw_frame(&mut self) { //compute submission - let submit_infos; + let mut submit_infos; unsafe { - device + self.device .wait_for_fences( - &self.sync_objects.compute_in_flight_fences[self.current_frame], + &[self.sync_objects.compute_inflight_fences[self.current_frame]], true, - u32::MAX, + u64::MAX, ); } - update_uniform_buffer(&mut self, current_frame); + self.update_uniform_buffer(self.current_frame); unsafe { - device - .reset_fences(&self.sync_objects.compute_in_flight_fences[self.current_frame]); + self.device + .reset_fences(&[self.sync_objects.compute_inflight_fences[self.current_frame]]); - device + self.device .reset_command_buffer(self.compute_command_buffers[self.current_frame], vk::CommandBufferResetFlags::empty()); } - record_compute_command_buffer(self.compute_command_buffers[self.current_frame]); + self.record_compute_command_buffer(&self.device, self.compute_command_buffers[self.current_frame]); submit_infos = [vk::SubmitInfo { s_type: vk::StructureType::SUBMIT_INFO, @@ -743,27 +885,27 @@ impl App { p_command_buffers: &self.compute_command_buffers[self.current_frame], signal_semaphore_count: 1, p_signal_semaphores: &self.sync_objects.compute_finished_semaphores[self.current_frame], - ..default::Default() + ..Default::default() }]; unsafe { - device + self.device .queue_submit( self.compute_queue, &submit_infos, - self.sync_objects.compute_in_flight_fences[self.current_frame] + self.sync_objects.compute_inflight_fences[self.current_frame] ); } //graphics submission unsafe { - device + self.device .wait_for_fences( - &self.sync_objects.in_flight_fences[self.current_frame], + &[self.sync_objects.inflight_fences[self.current_frame]], true, - u32::MAX, + u64::MAX, ); } @@ -778,7 +920,7 @@ impl App { Ok(image_index) => image_index, Err(vk_result) => match vk_result { vk::Result::ERROR_OUT_OF_DATE_KHR => { - self.recreate_swapchain(); + SwapChainStuff::recreate_swapchain(self); return; } _ => panic!("Failed to acquire Swap Chain Image!"), @@ -787,16 +929,16 @@ impl App { }; unsafe { - device - .reset_fences(self.sync_objects.in_flight_fences[self.current_frame]); - device + self.device + .reset_fences(&[self.sync_objects.inflight_fences[self.current_frame]]); + self.device .reset_command_buffer( self.command_buffers[self.current_frame], - CommandBufferResetFlags::empty, + vk::CommandBufferResetFlags::empty(), ); } - share::record_command_buffer(self.command_buffers[current_frame]); + self.record_command_buffer(self.command_buffers[self.current_frame], image_index as usize); let wait_semaphores = [ @@ -811,22 +953,22 @@ impl App { submit_infos = [vk::SubmitInfo { s_type: vk::StructureType::SUBMIT_INFO, wait_semaphore_count: 2, - p_wait_semaphores: wait_semaphores, - p_wait_dst_stage_mask: wait_stages, + p_wait_semaphores: wait_semaphores.as_ptr(), + p_wait_dst_stage_mask: wait_stages.as_ptr(), p_next: ptr::null(), command_buffer_count: 1, p_command_buffers: &self.command_buffers[self.current_frame], signal_semaphore_count: 1, - p_signal_semaphores: &self.sync_objects.render_finished_semaphores[current_frame], - ..default::Default() + p_signal_semaphores: &self.sync_objects.render_finished_semaphores[self.current_frame], + ..Default::default() }]; unsafe { - device + self.device .queue_submit( self.graphics_queue, &submit_infos, - self.sync_objects.in_flight_fences[self.current_frame], + self.sync_objects.inflight_fences[self.current_frame], ) .expect("failed to submit draw command buffer"); } @@ -837,7 +979,7 @@ impl App { s_type: vk::StructureType::PRESENT_INFO_KHR, p_next: ptr::null(), wait_semaphore_count: 1, - p_wait_semaphores: &self.sync_objects.render_finished_semaphores, + p_wait_semaphores: &self.sync_objects.render_finished_semaphores[self.current_frame], swapchain_count: 1, p_swapchains: swapchains.as_ptr(), p_image_indices: &image_index, @@ -857,11 +999,990 @@ impl App { }; if is_resized { self.is_framebuffer_resized = false; - self.recreate_swapchain(); + SwapChainStuff::recreate_swapchain(self); } self.current_frame = (self.current_frame + 1) % MAX_FRAMES_IN_FLIGHT; } + pub fn create_shader_storage_buffers( + device: &ash::Device, + physical_device_memory_properties: vk::PhysicalDeviceMemoryProperties, + command_pool: vk::CommandPool, + graphics_queue: vk::Queue, + ) -> (Vec, Vec) { + let mut particles = Particle::gen(); + + let buffer_size: u64 = std::mem::size_of::() as u64 * PARTICLE_COUNT as u64; + + + let (staging_buffer, staging_buffer_memory) = Self::create_buffer( + device, + buffer_size, + vk::BufferUsageFlags::TRANSFER_SRC, + vk::MemoryPropertyFlags::HOST_VISIBLE | + vk::MemoryPropertyFlags::HOST_COHERENT, + physical_device_memory_properties, + ); + + let mut shader_storage_buffers = vec![]; + let mut shader_storage_buffers_memory = vec![]; + + unsafe { + let data = device + .map_memory( + staging_buffer_memory, + 0, + buffer_size, + vk::MemoryMapFlags::empty(), + ) + .expect("failed to map shader storage buffer memory"); + ptr::copy_nonoverlapping( + data, + particles.as_mut_ptr() as *mut c_void, + buffer_size as usize, + ); + device + .unmap_memory(staging_buffer_memory); + + for i in 0..MAX_FRAMES_IN_FLIGHT { + let (current_shader_storage_buffer, current_shader_storage_buffer_memory) = Self::create_buffer( + device, + buffer_size, + vk::BufferUsageFlags::STORAGE_BUFFER | + vk::BufferUsageFlags::VERTEX_BUFFER | + vk::BufferUsageFlags::TRANSFER_DST, + vk::MemoryPropertyFlags::DEVICE_LOCAL, + physical_device_memory_properties, + ); + + shader_storage_buffers.push(current_shader_storage_buffer); + shader_storage_buffers_memory.push(current_shader_storage_buffer_memory); + + Self::copy_buffer( + device, + staging_buffer, + shader_storage_buffers[i], + buffer_size, + command_pool, + graphics_queue, + ); + + } + + device + .destroy_buffer(staging_buffer, None); + + device + .free_memory(staging_buffer_memory, None); + } + + (shader_storage_buffers, shader_storage_buffers_memory) + } + + pub fn copy_buffer( + device: &ash::Device, + src_buffer: vk::Buffer, + dst_buffer: vk::Buffer, + size: vk::DeviceSize, + command_pool: vk::CommandPool, + graphics_queue: vk::Queue, + ) { + let command_buffer_allocate_info = vk::CommandBufferAllocateInfo { + s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO, + p_next: ptr::null(), + command_buffer_count: 1, + command_pool: command_pool, + level: vk::CommandBufferLevel::PRIMARY, + }; + + let alloced_command_buffer = unsafe { + device + .allocate_command_buffers( + &command_buffer_allocate_info + ) + .expect("could not allocate command buffer when copying command buffer") + [0] + + }; + + let begin_info = vk::CommandBufferBeginInfo { + s_type: vk::StructureType::COMMAND_BUFFER_BEGIN_INFO, + flags: vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT, + ..Default::default() + }; + + unsafe { + device + .begin_command_buffer(alloced_command_buffer, &begin_info); + } + + let copy_region = vk::BufferCopy { + size: size, + ..Default::default() + }; + + unsafe { + device + .cmd_copy_buffer( + alloced_command_buffer, + src_buffer, + dst_buffer, + &[copy_region], + ); + + device.end_command_buffer(alloced_command_buffer); + } + + let submit_info = vk::SubmitInfo { + s_type: vk::StructureType::SUBMIT_INFO, + command_buffer_count: 1, + p_command_buffers: &alloced_command_buffer as *const vk::CommandBuffer, + ..Default::default() + }; + + unsafe { + device + .queue_submit( + graphics_queue, + &[submit_info], + vk::Fence::null(), + ); + + device + .queue_wait_idle( + graphics_queue + ); + + device + .free_command_buffers(command_pool, &[alloced_command_buffer]); + } + } + + pub fn create_buffer( + device: &ash::Device, + size: vk::DeviceSize, + usage: vk::BufferUsageFlags, + required_memory_properties: vk::MemoryPropertyFlags, + physical_device_memory_properties: vk::PhysicalDeviceMemoryProperties, + ) -> (vk::Buffer, vk::DeviceMemory) { + let buffer_create_info = vk::BufferCreateInfo { + s_type: vk::StructureType::BUFFER_CREATE_INFO, + p_next: ptr::null(), + flags: vk::BufferCreateFlags::empty(), + size, + usage, + sharing_mode: vk::SharingMode::EXCLUSIVE, + queue_family_index_count: 0, + p_queue_family_indices: ptr::null(), + }; + + let buffer = unsafe { + device + .create_buffer(&buffer_create_info, None) + .expect("Failed to create Vertex Buffer") + }; + + let mem_requirements = unsafe { device.get_buffer_memory_requirements(buffer) }; + + let allocate_info = vk::MemoryAllocateInfo { + s_type: vk::StructureType::MEMORY_ALLOCATE_INFO, + p_next: ptr::null(), + allocation_size: mem_requirements.size, + memory_type_index: find_memory_type( + mem_requirements.memory_type_bits, + required_memory_properties, + &physical_device_memory_properties, + ), + }; + + let buffer_memory = unsafe { + device + .allocate_memory(&allocate_info, None) + .expect("Failed to allocate vertex buffer memory!") + }; + + unsafe { + device + .bind_buffer_memory(buffer, buffer_memory, 0) + .expect("Failed to bind Buffer"); + } + + (buffer, buffer_memory) + } + + pub fn create_uniform_buffers( + device: &ash::Device, + physical_device_memory_properties: vk::PhysicalDeviceMemoryProperties, + ) -> (Vec, Vec, Vec<*mut c_void>) { + let buffer_size = ::std::mem::size_of::(); + + let mut uniform_buffers = vec![]; + let mut uniform_buffers_memory = vec![]; + let mut uniform_buffers_mapped = vec![]; + + for i in 0..MAX_FRAMES_IN_FLIGHT { + let (uniform_buffer, uniform_buffer_memory) = Self::create_buffer( + device, + buffer_size as u64, + vk::BufferUsageFlags::UNIFORM_BUFFER, + vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT, + physical_device_memory_properties + ); + uniform_buffers.push(uniform_buffer); + uniform_buffers_memory.push(uniform_buffer_memory); + uniform_buffers_mapped.push( + unsafe { + device + .map_memory( + uniform_buffers_memory[i], + 0, + buffer_size as u64, + vk::MemoryMapFlags::empty(), + ) + .unwrap() + } + ); + } + + (uniform_buffers, uniform_buffers_memory, uniform_buffers_mapped) + } + + pub fn create_logical_device( + instance: &ash::Instance, + physical_device: vk::PhysicalDevice, + validation: &debug::ValidationInfo, + device_extensions: &DeviceExtension, + surface_stuff: &SurfaceStuff, + ) -> (ash::Device, QueueFamilyIndices, vk::Queue, vk::Queue, vk::Queue) { + let indices = App::find_queue_family(&instance, physical_device, &surface_stuff); + + use std::collections::HashSet; + let mut unique_queue_families = HashSet::new(); + unique_queue_families.insert(indices.graphics_and_compute_family.unwrap()); + unique_queue_families.insert(indices.present_family.unwrap()); + + let queue_priorities = [1.0_f32]; + let mut queue_create_infos = vec![]; + + for &queue_family in unique_queue_families.iter() { + queue_create_infos.push(vk::DeviceQueueCreateInfo { + s_type: vk::StructureType::DEVICE_QUEUE_CREATE_INFO, + p_next: ptr::null(), + flags: vk::DeviceQueueCreateFlags::empty(), + queue_family_index: queue_family, + p_queue_priorities: queue_priorities.as_ptr(), + queue_count: queue_priorities.len() as u32, + }); + } + + let physical_device_features = vk::PhysicalDeviceFeatures { + sampler_anisotropy: vk::TRUE, // enable anisotropy device feature from Chapter-24. + ..Default::default() + }; + + let requred_validation_layer_raw_names: Vec = validation + .required_validation_layers + .iter() + .map(|layer_name| CString::new(*layer_name).unwrap()) + .collect(); + let _enable_layer_names: Vec<*const c_char> = requred_validation_layer_raw_names + .iter() + .map(|layer_name| layer_name.as_ptr()) + .collect(); + + let enable_extension_names = device_extensions.get_extensions_raw_names(); + + let device_create_info = vk::DeviceCreateInfo { + s_type: vk::StructureType::DEVICE_CREATE_INFO, + p_next: ptr::null(), + flags: vk::DeviceCreateFlags::empty(), + queue_create_info_count: queue_create_infos.len() as u32, + p_queue_create_infos: queue_create_infos.as_ptr(), + enabled_extension_count: enable_extension_names.len() as u32, + pp_enabled_extension_names: enable_extension_names.as_ptr(), + p_enabled_features: &physical_device_features, + ..Default::default() + }; + + let device: ash::Device = unsafe { + instance + .create_device(physical_device, &device_create_info, None) + .expect("Failed to create logical Device!") + }; + + let graphics_queue = + unsafe { device.get_device_queue(indices.graphics_and_compute_family.unwrap(), 0) }; + let present_queue = + unsafe { device.get_device_queue(indices.present_family.unwrap(), 0) }; + let compute_queue = + unsafe { device.get_device_queue(indices.graphics_and_compute_family.unwrap(), 0) }; + + (device, indices, graphics_queue, compute_queue, present_queue) + } + + pub fn record_command_buffer( + &self, + //device: &ash::Device, + command_buffer: vk::CommandBuffer, + image_index: usize, + //render_pass: vk::RenderPass, + //swapchain_extent: vk::Extent2D, + //shader_storage_buffers: Vec, + //shader_storage_buffers_memory: Vec, + //current_frame: usize, + //graphics_pipeline: vk::Pipeline, + + + ) { + let command_buffer_begin_info = vk::CommandBufferBeginInfo { + s_type: vk::StructureType::COMMAND_BUFFER_BEGIN_INFO, + p_next: ptr::null(), + p_inheritance_info: ptr::null(), + flags: vk::CommandBufferUsageFlags::SIMULTANEOUS_USE, + }; + + unsafe { + self.device + .begin_command_buffer(command_buffer, &command_buffer_begin_info) + .expect("failed to start recording command buffer") + } + let clear_color = [vk::ClearValue { + color: vk::ClearColorValue { + float32: [1.0, 1.0, 1.0, 1.0], + }, + }]; + + let render_pass_begin_info = vk::RenderPassBeginInfo { + s_type: vk::StructureType::RENDER_PASS_BEGIN_INFO, + render_pass: self.render_pass, + p_next: ptr::null(), + framebuffer: self.swapchain_stuff.swapchain_framebuffers[image_index], + render_area: vk::Rect2D { + offset: vk::Offset2D { x: 0, y: 0 }, + extent: self.swapchain_stuff.swapchain_extent, + }, + clear_value_count: clear_color.len() as u32, + p_clear_values: clear_color.as_ptr(), + }; + + unsafe { + self.device + .cmd_begin_render_pass( + command_buffer, + &render_pass_begin_info, + vk::SubpassContents::INLINE, + ); + + self.device + .cmd_bind_pipeline( + command_buffer, + vk::PipelineBindPoint::GRAPHICS, + self.graphics_pipeline, + ); + } + + let viewport = vec![vk::Viewport { + x: 0.0, + y: 0.0, + width: self.swapchain_stuff.swapchain_extent.width as f32, + height: self.swapchain_stuff.swapchain_extent.height as f32, + min_depth: 0.0, + max_depth: 1.0, + }]; + + unsafe { + self.device + .cmd_set_viewport( + command_buffer, + 0, + &viewport, + ); + } + + let scissor = vec![vk::Rect2D { + offset: vk::Offset2D { x: 0, y: 0 }, + extent: self.swapchain_stuff.swapchain_extent, + }]; + + unsafe { + self.device + .cmd_set_scissor( + command_buffer, + 0, + &scissor + ); + } + + let offsets = &[0 as vk::DeviceSize]; + + unsafe { + self.device + .cmd_bind_vertex_buffers( + command_buffer, + 0, + &[self.shader_storage_buffers[self.current_frame]], + offsets, + ); + self.device + .cmd_draw( + command_buffer, + PARTICLE_COUNT as u32, + 1, + 0, + 0, + ); + self.device + .cmd_end_render_pass( + command_buffer + ); + self.device + .end_command_buffer(command_buffer) + .expect("failed to end command buffer"); + } + } + + + pub fn create_framebuffers( + device: &ash::Device, + render_pass: vk::RenderPass, + image_views: &Vec, + swapchain_extent: &vk::Extent2D, + ) -> Vec { + let mut framebuffers = vec![]; + + for &image_view in image_views.iter() { + let attachments = [image_view]; + + let framebuffer_create_info = vk::FramebufferCreateInfo { + s_type: vk::StructureType::FRAMEBUFFER_CREATE_INFO, + p_next: ptr::null(), + flags: vk::FramebufferCreateFlags::empty(), + render_pass: render_pass, + attachment_count: attachments.len() as u32, + p_attachments: attachments.as_ptr(), + width: swapchain_extent.width, + height: swapchain_extent.height, + layers: 1, + }; + + let framebuffer = unsafe { + device + .create_framebuffer(&framebuffer_create_info, None) + .expect("Failed to create Framebuffer!") + }; + + framebuffers.push(framebuffer); + } + + framebuffers + } + + pub fn create_image_views( + device: &ash::Device, + surface_format: &vk::Format, + images: &Vec, + ) -> Vec { + let swapchain_imageviews: Vec = images + .iter() + .map(|&image| { + App::create_image_view( + device, + image, + surface_format, + vk::ImageAspectFlags::COLOR, + 1, + ) + }) + .collect(); + + swapchain_imageviews + } + + pub fn create_image_view( + device: &ash::Device, + image: vk::Image, + format: &vk::Format, + aspect_flags: vk::ImageAspectFlags, + mip_levels: u32, + ) -> vk::ImageView { + let imageview_create_info = vk::ImageViewCreateInfo { + s_type: vk::StructureType::IMAGE_VIEW_CREATE_INFO, + p_next: ptr::null(), + flags: vk::ImageViewCreateFlags::empty(), + view_type: vk::ImageViewType::TYPE_2D, + format: format.clone(), + components: vk::ComponentMapping { + r: vk::ComponentSwizzle::IDENTITY, + g: vk::ComponentSwizzle::IDENTITY, + b: vk::ComponentSwizzle::IDENTITY, + a: vk::ComponentSwizzle::IDENTITY, + }, + subresource_range: vk::ImageSubresourceRange { + aspect_mask: aspect_flags, + base_mip_level: 0, + level_count: mip_levels, + base_array_layer: 0, + layer_count: 1, + }, + image, + }; + + unsafe { + device + .create_image_view(&imageview_create_info, None) + .expect("Failed to create Image View!") + } + } + + pub fn choose_swapchain_extent( + &self, + capabilities: &vk::SurfaceCapabilitiesKHR, + ) -> vk::Extent2D { + if capabilities.current_extent.width != u32::max_value() { + capabilities.current_extent + } else { + use num::clamp; + + let window_size = self.window.inner_size(); + println!( + "\t\tInner Window Size: ({}, {})", + window_size.width, window_size.height + ); + + vk::Extent2D { + width: clamp( + window_size.width as u32, + capabilities.min_image_extent.width, + capabilities.max_image_extent.width, + ), + height: clamp( + window_size.height as u32, + capabilities.min_image_extent.height, + capabilities.max_image_extent.height, + ), + } + } + } + + pub fn query_swapchain_support( + physical_device: vk::PhysicalDevice, + surface_stuff: &SurfaceStuff, + ) -> SwapChainSupportDetails { + unsafe { + let capabilities = surface_stuff + .surface_loader + .get_physical_device_surface_capabilities(physical_device, surface_stuff.surface) + .expect("Failed to query for surface capabilities."); + let formats = surface_stuff + .surface_loader + .get_physical_device_surface_formats(physical_device, surface_stuff.surface) + .expect("Failed to query for surface formats."); + let present_modes = surface_stuff + .surface_loader + .get_physical_device_surface_present_modes(physical_device, surface_stuff.surface) + .expect("Failed to query for surface present mode."); + + SwapChainSupportDetails { + capabilities, + formats, + present_modes, + } + } + } + + pub fn find_queue_family( + instance: &ash::Instance, + physical_device: vk::PhysicalDevice, + surface_stuff: &SurfaceStuff, + ) -> QueueFamilyIndices { + let queue_families = + unsafe { instance.get_physical_device_queue_family_properties(physical_device) }; + + let mut queue_family_indices = QueueFamilyIndices::new(); + + for (i, queue_family) in queue_families.iter().enumerate() { + if queue_family.queue_count > 0 + && ( + queue_family.queue_flags.contains(vk::QueueFlags::GRAPHICS) && + queue_family.queue_flags.contains(vk::QueueFlags::COMPUTE) + ) + { + queue_family_indices.graphics_and_compute_family = Some(i as u32); + } + + let is_present_support = unsafe { + surface_stuff + .surface_loader + .get_physical_device_surface_support( + physical_device, + i as u32, + surface_stuff.surface, + ) + .unwrap() + }; + if queue_family.queue_count > 0 && is_present_support { + queue_family_indices.present_family = Some(i as u32); + } + + if queue_family_indices.is_complete() { + break; + } + } + + queue_family_indices + } + + pub fn pick_physical_device( + instance: &ash::Instance, + surface_stuff: &SurfaceStuff, + required_device_extensions: &DeviceExtension, + ) -> vk::PhysicalDevice { + let physical_devices = unsafe { + instance + .enumerate_physical_devices() + .expect("Failed to enumerate Physical Devices!") + }; + + let result = physical_devices.iter().find(|physical_device| { + let is_suitable = Self::is_physical_device_suitable( + &instance, + **physical_device, + &surface_stuff, + required_device_extensions, + ); + + is_suitable + }); + + match result { + Some(p_physical_device) => *p_physical_device, + None => panic!("Failed to find a suitable GPU!"), + } + } + + pub fn is_physical_device_suitable( + instance: &ash::Instance, + physical_device: vk::PhysicalDevice, + surface_stuff: &SurfaceStuff, + required_device_extensions: &DeviceExtension, + ) -> bool { + let device_features = unsafe { instance.get_physical_device_features(physical_device) }; + + let indices = Self::find_queue_family(&instance, physical_device, &surface_stuff); + + let is_queue_family_supported = indices.is_complete(); + let is_device_extension_supported = + Self::check_device_extension_support(&instance, physical_device, required_device_extensions); + let is_swapchain_supported = if is_device_extension_supported { + let swapchain_support = Self::query_swapchain_support(physical_device, &surface_stuff); + !swapchain_support.formats.is_empty() && !swapchain_support.present_modes.is_empty() + } else { + false + }; + let is_support_sampler_anisotropy = device_features.sampler_anisotropy == 1; + + return is_queue_family_supported + && is_device_extension_supported + && is_swapchain_supported + && is_support_sampler_anisotropy; + } + pub fn check_device_extension_support( + instance: &ash::Instance, + physical_device: vk::PhysicalDevice, + device_extensions: &DeviceExtension, + ) -> bool { + let available_extensions = unsafe { + instance + .enumerate_device_extension_properties(physical_device) + .expect("Failed to get device extension properties.") + }; + + let mut available_extension_names = vec![]; + + for extension in available_extensions.iter() { + let extension_name = vk_to_string(&extension.extension_name); + + available_extension_names.push(extension_name); + } + + use std::collections::HashSet; + let mut required_extensions = HashSet::new(); + for extension in device_extensions.names.iter() { + required_extensions.insert(extension.to_string()); + } + + for extension_name in available_extension_names.iter() { + required_extensions.remove(extension_name); + } + + return required_extensions.is_empty(); + } + + pub fn create_render_pass(device: &ash::Device, surface_format: &vk::Format) -> vk::RenderPass { + let color_attachment = vk::AttachmentDescription { + format: surface_format.clone(), + flags: vk::AttachmentDescriptionFlags::empty(), + samples: vk::SampleCountFlags::TYPE_1, + load_op: vk::AttachmentLoadOp::CLEAR, + store_op: vk::AttachmentStoreOp::STORE, + stencil_load_op: vk::AttachmentLoadOp::DONT_CARE, + stencil_store_op: vk::AttachmentStoreOp::DONT_CARE, + initial_layout: vk::ImageLayout::UNDEFINED, + final_layout: vk::ImageLayout::PRESENT_SRC_KHR, + }; + + let color_attachment_ref = vk::AttachmentReference { + attachment: 0, + layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, + }; + + let subpasses = [vk::SubpassDescription { + color_attachment_count: 1, + p_color_attachments: &color_attachment_ref, + p_depth_stencil_attachment: ptr::null(), + flags: vk::SubpassDescriptionFlags::empty(), + pipeline_bind_point: vk::PipelineBindPoint::GRAPHICS, + input_attachment_count: 0, + p_input_attachments: ptr::null(), + p_resolve_attachments: ptr::null(), + preserve_attachment_count: 0, + p_preserve_attachments: ptr::null(), + }]; + + let render_pass_attachments = [color_attachment]; + + let subpass_dependencies = [vk::SubpassDependency { + src_subpass: vk::SUBPASS_EXTERNAL, + dst_subpass: 0, + src_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, + dst_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, + src_access_mask: vk::AccessFlags::empty(), + dst_access_mask: vk::AccessFlags::COLOR_ATTACHMENT_WRITE, + dependency_flags: vk::DependencyFlags::empty(), + }]; + + let renderpass_create_info = vk::RenderPassCreateInfo { + s_type: vk::StructureType::RENDER_PASS_CREATE_INFO, + flags: vk::RenderPassCreateFlags::empty(), + p_next: ptr::null(), + attachment_count: render_pass_attachments.len() as u32, + p_attachments: render_pass_attachments.as_ptr(), + subpass_count: subpasses.len() as u32, + p_subpasses: subpasses.as_ptr(), + dependency_count: subpass_dependencies.len() as u32, + p_dependencies: subpass_dependencies.as_ptr(), + }; + + unsafe { + device + .create_render_pass(&renderpass_create_info, None) + .expect("Failed to create render pass!") + } + } + + pub fn create_compute_descriptor_set_layout(device: &ash::Device) -> vk::DescriptorSetLayout { + let ubo_layout_bindings = [ + vk::DescriptorSetLayoutBinding { + binding: 0, + descriptor_type: vk::DescriptorType::UNIFORM_BUFFER, + descriptor_count: 1, + stage_flags: vk::ShaderStageFlags::COMPUTE, + p_immutable_samplers: ptr::null(), + }, + vk::DescriptorSetLayoutBinding { + binding: 1, + descriptor_type: vk::DescriptorType::STORAGE_BUFFER, + descriptor_count: 1, + stage_flags: vk::ShaderStageFlags::COMPUTE, + p_immutable_samplers: ptr::null(), + }, + vk::DescriptorSetLayoutBinding { + binding: 2, + descriptor_type: vk::DescriptorType::STORAGE_BUFFER, + descriptor_count: 1, + stage_flags: vk::ShaderStageFlags::COMPUTE, + p_immutable_samplers: ptr::null(), + }, + ]; + + let ubo_layout_create_info = vk::DescriptorSetLayoutCreateInfo { + s_type: vk::StructureType::DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + p_next: ptr::null(), + flags: vk::DescriptorSetLayoutCreateFlags::empty(), + binding_count: ubo_layout_bindings.len() as u32, + p_bindings: ubo_layout_bindings.as_ptr(), + }; + + unsafe { + device + .create_descriptor_set_layout(&ubo_layout_create_info, None) + .expect("Failed to create Descriptor Set Layout!") + } + } + + pub fn create_compute_descriptor_sets( + device: &ash::Device, + compute_descriptor_set_layout: vk::DescriptorSetLayout, + descriptor_pool: vk::DescriptorPool, + uniform_buffers: &Vec, + shader_storage_buffers: &Vec, + ) -> Vec { + let layouts = vec![compute_descriptor_set_layout; MAX_FRAMES_IN_FLIGHT]; + + let alloc_info = vk::DescriptorSetAllocateInfo { + s_type: vk::StructureType::DESCRIPTOR_SET_ALLOCATE_INFO, + p_next: ptr::null(), + descriptor_pool: descriptor_pool, + descriptor_set_count: MAX_FRAMES_IN_FLIGHT as u32, + p_set_layouts: layouts.as_ptr(), + }; + + let descriptor_sets = unsafe { + device + .allocate_descriptor_sets(&alloc_info) + .expect("failed to allocate descriptor sets") + }; + + for i in 0..MAX_FRAMES_IN_FLIGHT { + let uniform_buffer_info = vk::DescriptorBufferInfo { + buffer: uniform_buffers[i], + offset: 0, + range: size_of::() as u64, + }; + + let storage_buffer_info_last_frame = vk::DescriptorBufferInfo { + buffer: shader_storage_buffers[(i as i32 - 1) as usize % MAX_FRAMES_IN_FLIGHT], + offset: 0, + range: size_of::() as u64 * PARTICLE_COUNT, + }; + + let storage_buffer_info_current_frame = vk::DescriptorBufferInfo { + buffer: shader_storage_buffers[i], + offset: 0, + range: size_of::() as u64 * PARTICLE_COUNT, + }; + + //eprintln!("PARTICLE STRUCT SIZE: {:?}", ::std::mem::size_of::() as u8); + + let descriptor_writes = [ + vk::WriteDescriptorSet { + s_type: vk::StructureType::WRITE_DESCRIPTOR_SET, + dst_set: descriptor_sets[i], + dst_binding: 0, + dst_array_element: 0, + descriptor_type: vk::DescriptorType::UNIFORM_BUFFER, + descriptor_count: 1, + p_buffer_info: &uniform_buffer_info as *const vk::DescriptorBufferInfo, + ..Default::default() + }, + vk::WriteDescriptorSet { + s_type: vk::StructureType::WRITE_DESCRIPTOR_SET, + dst_set: descriptor_sets[i], + dst_binding: 1, + dst_array_element: 0, + descriptor_type: vk::DescriptorType::STORAGE_BUFFER, + descriptor_count: 1, + p_buffer_info: &storage_buffer_info_last_frame as *const vk::DescriptorBufferInfo, + ..Default::default() + }, + vk::WriteDescriptorSet { + s_type: vk::StructureType::WRITE_DESCRIPTOR_SET, + dst_set: descriptor_sets[i], + dst_binding: 2, + dst_array_element: 0, + descriptor_type: vk::DescriptorType::STORAGE_BUFFER, + descriptor_count: 1, + p_buffer_info: &storage_buffer_info_current_frame as *const vk::DescriptorBufferInfo, + ..Default::default() + }, + ]; + + unsafe { + device + .update_descriptor_sets(&descriptor_writes, &[]); + } + } + + descriptor_sets + } + + + + pub fn create_command_pool( + device: &ash::Device, + queue_families: &QueueFamilyIndices, + ) -> vk::CommandPool { + let command_pool_create_info = vk::CommandPoolCreateInfo { + s_type: vk::StructureType::COMMAND_POOL_CREATE_INFO, + p_next: ptr::null(), + flags: vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER, + queue_family_index: queue_families.graphics_and_compute_family.unwrap(), + }; + + unsafe { + device + .create_command_pool(&command_pool_create_info, None) + .expect("Failed to create Command Pool!") + } + } + + pub fn create_descriptor_pool( + device: &ash::Device, + swapchain_images_size: usize, + ) -> vk::DescriptorPool { + let pool_sizes = [ + vk::DescriptorPoolSize { + ty: vk::DescriptorType::UNIFORM_BUFFER, + descriptor_count: swapchain_images_size as u32, + }, + vk::DescriptorPoolSize { + ty: vk::DescriptorType::STORAGE_BUFFER, + descriptor_count: swapchain_images_size as u32 * 2, + } + ]; + + let descriptor_pool_create_info = vk::DescriptorPoolCreateInfo { + s_type: vk::StructureType::DESCRIPTOR_POOL_CREATE_INFO, + p_next: ptr::null(), + flags: vk::DescriptorPoolCreateFlags::empty(), + max_sets: swapchain_images_size as u32, + pool_size_count: pool_sizes.len() as u32, + p_pool_sizes: pool_sizes.as_ptr(), + }; + + unsafe { + device + .create_descriptor_pool(&descriptor_pool_create_info, None) + .expect("Failed to create Descriptor Pool!") + } + } + + pub fn create_command_buffers( + device: &ash::Device, + command_pool: vk::CommandPool, + ) -> Vec { + let command_buffer_allocate_info = vk::CommandBufferAllocateInfo { + s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO, + p_next: ptr::null(), + command_buffer_count: MAX_FRAMES_IN_FLIGHT as u32, + command_pool, + level: vk::CommandBufferLevel::PRIMARY, + }; + + let command_buffers = unsafe { + device + .allocate_command_buffers(&command_buffer_allocate_info) + .expect("Failed to allocate Command Buffers!") + }; + command_buffers + } + fn wait_device_idle(&self) { + unsafe { + self.device + .device_wait_idle() + .expect("Failed to wait device idle!") + }; + } } diff --git a/src/rnd.rs b/src/rnd.rs deleted file mode 100644 index b094570..0000000 --- a/src/rnd.rs +++ /dev/null @@ -1,979 +0,0 @@ -use crate::{ - entities::*, shaders::*, utility, utility::constants::*, utility::debug::*, utility::share, - utility::structures::*, -}; - -use ash::{vk, Entry}; - -use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}; -use winit::event_loop::{ControlFlow, EventLoop}; - -use std::ffi::CString; -use std::ptr; - -// Constants -const WINDOW_TITLE: &'static str = "Template"; - -const IS_PAINT_FPS_COUNTER: bool = true; - -pub fn init_window( - event_loop: &EventLoop<()>, - title: &str, - width: u32, - height: u32, -) -> winit::window::Window { - winit::window::WindowBuilder::new() - .with_title(title) - .with_inner_size(winit::dpi::LogicalSize::new(width, height)) - .build(event_loop) - .expect("Failed to create window.") -} - - -pub struct VulkanApp { - window: winit::window::Window, - - // vulkan stuff - _entry: ash::Entry, - instance: ash::Instance, - surface_loader: ash::extensions::khr::Surface, - surface: vk::SurfaceKHR, - debug_utils_loader: ash::extensions::ext::DebugUtils, - debug_merssager: vk::DebugUtilsMessengerEXT, - - physical_device: vk::PhysicalDevice, - device: ash::Device, - - queue_family: QueueFamilyIndices, - graphics_queue: vk::Queue, - present_queue: vk::Queue, - //new from C++ - compute_queue: vk::Queue, - - //not in C++ - swapchain_loader: ash::extensions::khr::Swapchain, - swapchain: vk::SwapchainKHR, - swapchain_images: Vec, - swapchain_format: vk::Format, - swapchain_extent: vk::Extent2D, - swapchain_imageviews: Vec, - swapchain_framebuffers: Vec, - - render_pass: vk::RenderPass, - - graphics_pipeline_layout: vk::PipelineLayout, - graphics_pipeline: vk::Pipeline, - - //new from C++ - compute_descriptor_set_layout: vk::DescriptorSetLayout, - compute_pipeline_layout: vk::PipelineLayout, - compute_pipeline: vk::Pipeline, - - //vertex buffer for the triangle verticies - //i think this is the same as shaderStorageBuffers in C++ version - shader_storage_buffers: Vec, - shader_storage_buffers_memory: Vec, - - uniform_buffers: Vec, - uniform_buffers_memory: Vec, - uniform_buffers_mapped: Vec<*mut c_void>, - - - descriptor_pool: vk::DescriptorPool, - compute_descriptor_sets: Vec, - - command_pool: vk::CommandPool, - command_buffers: Vec, - compute_command_buffers: Vec, - - image_available_semaphores: Vec, - render_finished_semaphores: Vec, - in_flight_fences: Vec, - current_frame: usize, - - is_framebuffer_resized: bool, -} - -impl VulkanApp { - //C++ code:: - /* - ### cleanup(); - createInstance(); DONE - setupDebugMessenger(); DONE - createSurface(); SurfaceStuff::new DONE - pickPhysicalDevice(); DONE - createLogicalDevice(); - createSwapChain(); - createImageViews(); - createRenderPass(); - createComputeDescriptorSetLayout(); - createGraphicsPipeline(); - createComputePipeline(); - createFramebuffers(); DONE - createCommandPool(); DONE - createShaderStorageBuffers(); DONE - createUniformBuffers(); DONE - createDescriptorPool(); DONE - createComputeDescriptorSets(); DONE - createCommandBuffers(); DONE - createComputeCommandBuffers(); DONE - createSyncObjects(); DONE - */ - pub fn new(event_loop: &winit::event_loop::EventLoop<()>) -> VulkanApp { - let window = - init_window(event_loop, WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT); - - // init vulkan stuff - let entry = unsafe { Entry::load().unwrap() }; - let instance = share::create_instance( - &entry, - WINDOW_TITLE, - VALIDATION.is_enable, - &VALIDATION.required_validation_layers.to_vec(), - ); - let surface_stuff = - SurfaceStuff::new(&entry, &instance, &window, WINDOW_WIDTH, WINDOW_HEIGHT); - let (debug_utils_loader, debug_merssager) = - setup_debug_utils(VALIDATION.is_enable, &entry, &instance); - let physical_device = - share::pick_physical_device(&instance, &surface_stuff, &DEVICE_EXTENSIONS); - let (device, queue_family) = share::create_logical_device( - &instance, - physical_device, - &VALIDATION, - &DEVICE_EXTENSIONS, - &surface_stuff, - ); - let graphics_queue = - unsafe { device.get_device_queue(queue_family.graphics_family.unwrap(), 0) }; - let present_queue = - unsafe { device.get_device_queue(queue_family.present_family.unwrap(), 0) }; - let compute_queue = - unsafe { device.get_device_queue(queue_family.compute_family.unwrap(), 0) }; - let swapchain_stuff = SwapChainStuff::new( - &instance, - &device, - physical_device, - &window, - &surface_stuff, - &queue_family, - ); - let swapchain_imageviews = share::create_image_views( - &device, - swapchain_stuff.swapchain_format, - &swapchain_stuff.swapchain_images, - ); - let render_pass = share::create_render_pass(&device, swapchain_stuff.swapchain_format); - let (graphics_pipeline, graphics_pipeline_layout) = VulkanApp::create_graphics_pipeline( - &device, - render_pass, - swapchain_stuff.swapchain_extent, - ); - let (compute_pipelines, compute_pipeline_layout) = VulkanApp::create_compute_pipelines( - &device, - render_pass, - swapchain_stuff.swapchain_extent, - ); - - let compute_pipeline = compute_pipelines[0]; - - let swapchain_framebuffers = share::create_framebuffers( - &device, - render_pass, - &swapchain_imageviews, - swapchain_stuff.swapchain_extent, - ); - let command_pool = share::create_command_pool(&device, &queue_family); - let (vertex_buffer, vertex_buffer_memory) = - VulkanApp::create_vertex_buffer(&instance, &device, physical_device); - let command_buffers = VulkanApp::create_command_buffers( - &device, - command_pool, - graphics_pipeline, - &swapchain_framebuffers, - render_pass, - swapchain_stuff.swapchain_extent, - vertex_buffer, - ); - let sync_ojbects = SyncObjects::new(&device, MAX_FRAMES_IN_FLIGHT); - - // cleanup(); the 'drop' function will take care of it. - VulkanApp { - // winit stuff - window, - - // vulkan stuff - _entry: entry, - instance, - surface: surface_stuff.surface, - surface_loader: surface_stuff.surface_loader, - debug_utils_loader, - debug_merssager, - - physical_device, - device, - - queue_family, - graphics_queue, - present_queue, - compute_queue, - - swapchain_loader: swapchain_stuff.swapchain_loader, - swapchain: swapchain_stuff.swapchain, - swapchain_format: swapchain_stuff.swapchain_format, - swapchain_images: swapchain_stuff.swapchain_images, - swapchain_extent: swapchain_stuff.swapchain_extent, - swapchain_imageviews, - swapchain_framebuffers, - - graphics_pipeline_layout, - render_pass, - graphics_pipeline, - - - compute_descriptor_sets, - compute_pipeline_layout, - compute_pipeline, - - vertex_buffer, - vertex_buffer_memory, - - command_pool, - command_buffers, - - image_available_semaphores: sync_ojbects.image_available_semaphores, - render_finished_semaphores: sync_ojbects.render_finished_semaphores, - in_flight_fences: sync_ojbects.inflight_fences, - current_frame: 0, - - is_framebuffer_resized: false, - } - } - - pub fn main_loop(self) { - let mut tick_counter = super::fps_limiter::FPSLimiter::new(); - - self.event_loop - .run(move |event, _, control_flow| match event { - Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => { - vulkan_app.wait_device_idle(); - *control_flow = ControlFlow::Exit - } - WindowEvent::KeyboardInput { input, .. } => match input { - KeyboardInput { - virtual_keycode, - state, - .. - } => match (virtual_keycode, state) { - (Some(VirtualKeyCode::Escape), ElementState::Pressed) => { - vulkan_app.wait_device_idle(); - *control_flow = ControlFlow::Exit - } - _ => {} - }, - }, - WindowEvent::Resized(_new_size) => { - vulkan_app.wait_device_idle(); - vulkan_app.resize_framebuffer(); - } - _ => {} - }, - Event::MainEventsCleared => { - vulkan_app.window_ref().request_redraw(); - } - Event::RedrawRequested(_window_id) => { - let delta_time = tick_counter.delta_time(); - vulkan_app.draw_frame(delta_time); - - if IS_PAINT_FPS_COUNTER { - print!("FPS: {}\r", tick_counter.fps()); - } - - tick_counter.tick_frame(); - } - Event::LoopDestroyed => { - vulkan_app.wait_device_idle(); - } - _ => (), - }) - - } - - fn create_vertex_buffer( - instance: &ash::Instance, - device: &ash::Device, - physical_device: vk::PhysicalDevice, - ) -> (vk::Buffer, vk::DeviceMemory) { - let vertex_buffer_create_info = vk::BufferCreateInfo { - s_type: vk::StructureType::BUFFER_CREATE_INFO, - p_next: ptr::null(), - flags: vk::BufferCreateFlags::empty(), - size: std::mem::size_of_val(&TRI_VERT_DATA) as u64, - usage: vk::BufferUsageFlags::VERTEX_BUFFER - | vk::BufferUsageFlags::STORAGE_BUFFER - | vk::BufferUsageFlags::TRANSFER_DST, - sharing_mode: vk::SharingMode::EXCLUSIVE, - queue_family_index_count: 0, - p_queue_family_indices: ptr::null(), - }; - - let vertex_buffer = unsafe { - device - .create_buffer(&vertex_buffer_create_info, None) - .expect("Failed to create Vertex Buffer") - }; - - let mem_requirements = unsafe { device.get_buffer_memory_requirements(vertex_buffer) }; - let mem_properties = - unsafe { instance.get_physical_device_memory_properties(physical_device) }; - let required_memory_flags: vk::MemoryPropertyFlags = - vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT; - let memory_type = VulkanApp::find_memory_type( - mem_requirements.memory_type_bits, - required_memory_flags, - mem_properties, - ); - - let allocate_info = vk::MemoryAllocateInfo { - s_type: vk::StructureType::MEMORY_ALLOCATE_INFO, - p_next: ptr::null(), - allocation_size: mem_requirements.size, - memory_type_index: memory_type, - }; - - let vertex_buffer_memory = unsafe { - device - .allocate_memory(&allocate_info, None) - .expect("Failed to allocate vertex buffer memory!") - }; - - unsafe { - device - .bind_buffer_memory(vertex_buffer, vertex_buffer_memory, 0) - .expect("Failed to bind Buffer"); - - let data_ptr = device - .map_memory( - vertex_buffer_memory, - 0, - vertex_buffer_create_info.size, - vk::MemoryMapFlags::empty(), - ) - .expect("Failed to Map Memory") as *mut Vertex; - - data_ptr.copy_from_nonoverlapping(TRI_VERT_DATA.as_ptr(), TRI_VERT_DATA.len()); - - device.unmap_memory(vertex_buffer_memory); - } - - (vertex_buffer, vertex_buffer_memory) - } - - fn find_memory_type( - type_filter: u32, - required_properties: vk::MemoryPropertyFlags, - mem_properties: vk::PhysicalDeviceMemoryProperties, - ) -> u32 { - for (i, memory_type) in mem_properties.memory_types.iter().enumerate() { - //if (type_filter & (1 << i)) > 0 && (memory_type.property_flags & required_properties) == required_properties { - // return i as u32 - // } - - // same implementation - if (type_filter & (1 << i)) > 0 - && memory_type.property_flags.contains(required_properties) - { - return i as u32; - } - } - - panic!("Failed to find suitable memory type!") - share::pick_physical_device(&instance, &surface_stuff, &DEVICE_EXTENSIONS); - } - /* - * IDEK WHERE THIS CAME FROM I FUCKED UP THIS FILE, SHITS WHACK - * let (device, queue_family) = share::create_logical_device( - &instance, - physical_device, - &VALIDATION, - &DEVICE_EXTENSIONS, - &surface_stuff, - ); - let graphics_queue = - unsafe { device.get_device_queue(queue_family.graphics_family.unwrap(), 0) }; - let present_queue = - unsafe { device.get_device_queue(queue_family.present_family.unwrap(), 0) }; - let compute_queue = - unsafe { device.get_device_queue(queue_family.compute_family.unwrap(), 0) }; - let swapchain_stuff = SwapChainStuff::new( - &instance, - &device, - physical_device, - &window, - &surface_stuff, - &queue_family, - ); - let swapchain_imageviews = share::create_image_views( - &device, - swapchain_stuff.swapchain_format, - &swapchain_stuff.swapchain_images, - ); - let render_pass = share::create_render_pass(&device, swapchain_stuff.swapchain_format); - let (graphics_pipeline, graphics_pipeline_layout) = VulkanApp::create_graphics_pipeline( - &device, - render_pass, - swapchain_stuff.swapchain_extent, - ); - let (compute_pipelines, compute_pipeline_layout) = VulkanApp::create_compute_pipelines( - &device, - render_pass, - swapchain_stuff.swapchain_extent, - ); - - let compute_pipeline = compute_pipelines[0]; - - let swapchain_framebuffers = share::create_framebuffers( - &device, - render_pass, - &swapchain_imageviews, - swapchain_stuff.swapchain_extent, - ); - let command_pool = share::create_command_pool(&device, &queue_family); - let (vertex_buffer, vertex_buffer_memory) = - VulkanApp::create_vertex_buffer(&instance, &device, physical_device); - let command_buffers = VulkanApp::create_command_buffers( - &device, - command_pool, - graphics_pipeline, - &swapchain_framebuffers, - render_pass, - swapchain_stuff.swapchain_extent, - vertex_buffer, - ); - let sync_ojbects = SyncObjects::new(&device, MAX_FRAMES_IN_FLIGHT); - - // cleanup(); the 'drop' function will take care of it. - VulkanApp { - // winit stuff - window, - - // vulkan stuff - _entry: entry, - instance, - surface: surface_stuff.surface, - surface_loader: surface_stuff.surface_loader, - debug_utils_loader, - debug_merssager, - - physical_device, - device, - - queue_family, - graphics_queue, - present_queue, - compute_queue, - - swapchain_loader: swapchain_stuff.swapchain_loader, - swapchain: swapchain_stuff.swapchain, - swapchain_format: swapchain_stuff.swapchain_format, - swapchain_images: swapchain_stuff.swapchain_images, - swapchain_extent: swapchain_stuff.swapchain_extent, - swapchain_imageviews, - swapchain_framebuffers, - - graphics_pipeline_layout, - render_pass, - graphics_pipeline, - - - compute_descriptor_set, - compute_pipeline_layout, - compute_pipeline,*/ - - -/* FUCKED UP GRAPHICS PIPELINE CREATION FUNCTION WITH INTEGRATED COMPUTE PIPELINE CCREATION, THIS - * IS SUPER FUCKED - command_pool: vk::CommandPool, - graphics_pipeline: vk::Pipeline, - framebuffers: &Vec, - render_pass: vk::RenderPass, - surface_extent: vk::Extent2D, - vertex_buffer: vk::Buffer, - ) -> Vec { - let command_buffer_allocate_info = vk::CommandBufferAllocateInfo { - s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO, - p_next: ptr::null(), - command_buffer_count: framebuffers.len() as u32, - command_pool, - level: vk::CommandBufferLevel::PRIMARY, - }; - - let command_buffers = unsafe { - device - .allocate_command_buffers(&command_buffer_allocate_info) - .expect("Failed to allocate Command Buffers!") - }; - - for (i, &command_buffer) in command_buffers.iter().enumerate() { - let command_buffer_begin_info = vk::CommandBufferBeginInfo { - s_type: vk::StructureType::COMMAND_BUFFER_BEGIN_INFO, - p_next: ptr::null(), - flags: vk::CommandBufferUsageFlags::SIMULTANEOUS_USE, - p_inheritance_info: ptr::null(), - }; - - unsafe { - device - .begin_command_buffer(command_buffer, &command_buffer_begin_info) - .expect("Failed to begin recording Command Buffer at beginning!"); - } - - let clear_values = [vk::ClearValue { - color: vk::ClearColorValue { - float32: [0.0, 0.0, 0.0, 1.0], - }, - }]; - - let render_pass_begin_info = vk::RenderPassBeginInfo { - s_type: vk::StructureType::RENDER_PASS_BEGIN_INFO, - p_next: ptr::null(), - framebuffer: framebuffers[i], - render_pass, - clear_value_count: clear_values.len() as u32, - p_clear_values: clear_values.as_ptr(), - render_area: vk::Rect2D { - offset: vk::Offset2D { x: 0, y: 0 }, - extent: surface_extent, - }, - }; - - unsafe { - device.cmd_begin_render_pass( - command_buffer, - &render_pass_begin_info, - vk::SubpassContents::INLINE, - ); - device.cmd_bind_pipeline( - command_buffer, - vk::PipelineBindPoint::GRAPHICS, - graphics_pipeline, - ); - - let vertex_buffers = [vertex_buffer]; - let offsets = [0_u64]; - - device.cmd_bind_vertex_buffers(command_buffer, 0, &vertex_buffers, &offsets); - - device.cmd_draw(command_buffer, TRI_VERT_DATA.len() as u32, 1, 0, 0); - - device.cmd_end_render_pass(command_buffer); - - device - .end_command_buffer(command_buffer) - .expect("Failed to record Command Buffer at Ending!"); - } - shader_modules.push(vk::PipelineShaderStageCreateInfo { - s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::PipelineShaderStageCreateFlags::empty(), - module: share::create_shader_module(device, shader), - p_name: main_function.as_ptr(), - stage: stage_flag, - p_specialization_info: ptr::null(), - }); - } else if stage_flag == vk::ShaderStageFlags::FRAGMENT { - shader_modules.push( - vk::PipelineShaderStageCreateInfo { - s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::PipelineShaderStageCreateFlags::empty(), - module: share::create_shader_module(device, shader), - p_name: main_function.as_ptr(), - stage: stage_flag, - p_specialization_info: ptr::null(), - - } - ) - } else if stage_flag == vk::ShaderStageFlags::VERTEX { - shader_modules.push( - vk::PipelineShaderStageCreateInfo { - s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::PipelineShaderStageCreateFlags::empty(), - module: share::create_shader_module(device, shader), - p_name: main_function.as_ptr(), - stage: stage_flag, - p_specialization_info: ptr::null(), - - } - ) - } - } - - let binding_description = Vertex::get_binding_description(); - let attribute_description = Vertex::get_attribute_descriptions(); - - let vertex_input_state_create_info = vk::PipelineVertexInputStateCreateInfo { - s_type: vk::StructureType::PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::PipelineVertexInputStateCreateFlags::empty(), - vertex_attribute_description_count: attribute_description.len() as u32, - p_vertex_attribute_descriptions: attribute_description.as_ptr(), - vertex_binding_description_count: binding_description.len() as u32, - p_vertex_binding_descriptions: binding_description.as_ptr(), - }; - let vertex_input_assembly_state_info = vk::PipelineInputAssemblyStateCreateInfo { - s_type: vk::StructureType::PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - flags: vk::PipelineInputAssemblyStateCreateFlags::empty(), - p_next: ptr::null(), - topology: vk::PrimitiveTopology::TRIANGLE_LIST, - primitive_restart_enable: vk::FALSE, - }; - - let viewports = [vk::Viewport { - x: 0.0, - y: 0.0, - width: swapchain_extent.width as f32, - height: swapchain_extent.height as f32, - min_depth: 0.0, - max_depth: 1.0, - }]; - - let scissors = [vk::Rect2D { - offset: vk::Offset2D { x: 0, y: 0 }, - extent: swapchain_extent, - }]; - - let viewport_state_create_info = vk::PipelineViewportStateCreateInfo { - s_type: vk::StructureType::PIPELINE_VIEWPORT_STATE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::PipelineViewportStateCreateFlags::empty(), - scissor_count: scissors.len() as u32, - p_scissors: scissors.as_ptr(), - viewport_count: viewports.len() as u32, - p_viewports: viewports.as_ptr(), - }; - - let rasterization_statue_create_info = vk::PipelineRasterizationStateCreateInfo { - s_type: vk::StructureType::PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - p_next: ptr::null(), - p_viewports: viewports.as_ptr(), - }; - - let rasterization_statue_create_info = vk::PipelineRasterizationStateCreateInfo { - s_type: vk::StructureType::PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::PipelineRasterizationStateCreateFlags::empty(), - cull_mode: vk::CullModeFlags::BACK, - front_face: vk::FrontFace::CLOCKWISE, - line_width: 1.0, - polygon_mode: vk::PolygonMode::FILL, - rasterizer_discard_enable: vk::FALSE, - depth_clamp_enable: vk::FALSE, - depth_bias_clamp: 0.0, - depth_bias_constant_factor: 0.0, - depth_bias_enable: vk::FALSE, - depth_bias_slope_factor: 0.0, - }; - - let multisample_state_create_info = vk::PipelineMultisampleStateCreateInfo { - s_type: vk::StructureType::PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - flags: vk::PipelineMultisampleStateCreateFlags::empty(), - p_next: ptr::null(), - rasterization_samples: vk::SampleCountFlags::TYPE_1, - sample_shading_enable: vk::FALSE, - min_sample_shading: 0.0, - p_sample_mask: ptr::null(), - alpha_to_one_enable: vk::FALSE, - alpha_to_coverage_enable: vk::FALSE, - }; - - let stencil_state = vk::StencilOpState { - fail_op: vk::StencilOp::KEEP, - pass_op: vk::StencilOp::KEEP, - depth_fail_op: vk::StencilOp::KEEP, - compare_op: vk::CompareOp::ALWAYS, - compare_mask: 0, - write_mask: 0, - reference: 0, - }; - - let depth_state_create_info = vk::PipelineDepthStencilStateCreateInfo { - s_type: vk::StructureType::PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::PipelineDepthStencilStateCreateFlags::empty(), - depth_test_enable: vk::FALSE, - depth_write_enable: vk::FALSE, - depth_compare_op: vk::CompareOp::LESS_OR_EQUAL, - depth_bounds_test_enable: vk::FALSE, - stencil_test_enable: vk::FALSE, - front: stencil_state, - back: stencil_state, - max_depth_bounds: 1.0, - min_depth_bounds: 0.0, - }; - - let color_blend_attachment_states = [vk::PipelineColorBlendAttachmentState { - blend_enable: vk::FALSE, - color_write_mask: vk::ColorComponentFlags::RGBA, - src_color_blend_factor: vk::BlendFactor::ONE, - dst_color_blend_factor: vk::BlendFactor::ZERO, - color_blend_op: vk::BlendOp::ADD, - src_alpha_blend_factor: vk::BlendFactor::ONE, - dst_alpha_blend_factor: vk::BlendFactor::ZERO, - alpha_blend_op: vk::BlendOp::ADD, - }]; - - let color_blend_state = vk::PipelineColorBlendStateCreateInfo { - s_type: vk::StructureType::PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::PipelineColorBlendStateCreateFlags::empty(), - logic_op_enable: vk::FALSE, - logic_op: vk::LogicOp::COPY, - attachment_count: color_blend_attachment_states.len() as u32, - p_attachments: color_blend_attachment_states.as_ptr(), - blend_constants: [0.0, 0.0, 0.0, 0.0], - }; - - println!("shader module count: {}", shader_modules.len()); - - let graphic_pipeline_create_infos = [vk::GraphicsPipelineCreateInfo { - s_type: vk::StructureType::GRAPHICS_PIPELINE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::PipelineCreateFlags::empty(), - stage_count: shader_modules.len() as u32, - p_stages: shader_modules.as_ptr(), - p_vertex_input_state: &vertex_input_state_create_info, - p_input_assembly_state: &vertex_input_assembly_state_info, - p_tessellation_state: ptr::null(), - p_viewport_state: &viewport_state_create_info, - p_rasterization_state: &rasterization_statue_create_info, - p_multisample_state: &multisample_state_create_info, - s_type: vk::StructureType::COMPUTE_PIPELINE_CREATE_INFO, - p_next: ptr::null(), - layout: pipeline_layout, - flags: vk::PipelineCreateFlags::empty(), - ..Default::default() - } - ); - - } - let compute_pipelines = unsafe { - device - .create_compute_pipelines( - vk::PipelineCache::null(), - &compute_infos, - None, - ) - }.unwrap(); - - (compute_pipelines, pipeline_layout) - }*/ - - fn draw_frame(&mut self) { - let wait_fences = [self.in_flight_fences[self.current_frame]]; - - unsafe { - self.device - .wait_for_fences(&wait_fences, true, std::u64::MAX) - .expect("Failed to wait for Fence!"); - } - - let (image_index, _is_sub_optimal) = unsafe { - let result = self.swapchain_loader.acquire_next_image( - self.swapchain, - std::u64::MAX, - self.image_available_semaphores[self.current_frame], - vk::Fence::null(), - ); - match result { - Ok(image_index) => image_index, - Err(vk_result) => match vk_result { - vk::Result::ERROR_OUT_OF_DATE_KHR => { - self.recreate_swapchain(); - return; - } - _ => panic!("Failed to acquire Swap Chain Image!"), - }, - } - }; - - let wait_semaphores = [self.image_available_semaphores[self.current_frame]]; - let wait_stages = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT]; - let signal_semaphores = [self.render_finished_semaphores[self.current_frame]]; - - let submit_infos = [vk::SubmitInfo { - s_type: vk::StructureType::SUBMIT_INFO, - p_next: ptr::null(), - wait_semaphore_count: wait_semaphores.len() as u32, - p_wait_semaphores: wait_semaphores.as_ptr(), - p_wait_dst_stage_mask: wait_stages.as_ptr(), - command_buffer_count: 1, - p_command_buffers: &self.command_buffers[image_index as usize], - signal_semaphore_count: signal_semaphores.len() as u32, - p_signal_semaphores: signal_semaphores.as_ptr(), - }]; - - unsafe { - self.device - .reset_fences(&wait_fences) - .expect("Failed to reset Fence!"); - - self.device - .queue_submit( - self.graphics_queue, - &submit_infos, - self.in_flight_fences[self.current_frame], - ) - .expect("Failed to execute queue submit."); - } - - let swapchains = [self.swapchain]; - - let present_info = vk::PresentInfoKHR { - s_type: vk::StructureType::PRESENT_INFO_KHR, - p_next: ptr::null(), - wait_semaphore_count: 1, - p_wait_semaphores: signal_semaphores.as_ptr(), - swapchain_count: 1, - p_swapchains: swapchains.as_ptr(), - p_image_indices: &image_index, - p_results: ptr::null_mut(), - }; - - let result = unsafe { - self.swapchain_loader - .queue_present(self.present_queue, &present_info) - }; - - let is_resized = match result { - Ok(_) => self.is_framebuffer_resized, - Err(vk_result) => match vk_result { - vk::Result::ERROR_OUT_OF_DATE_KHR | vk::Result::SUBOPTIMAL_KHR => true, - _ => panic!("Failed to execute queue present."), - }, - }; - if is_resized { - self.is_framebuffer_resized = false; - self.recreate_swapchain(); - } - - self.current_frame = (self.current_frame + 1) % MAX_FRAMES_IN_FLIGHT; - } - - fn recreate_swapchain(&mut self) { - // parameters ------------- - let surface_suff = SurfaceStuff { - surface_loader: self.surface_loader.clone(), - surface: self.surface, - screen_width: WINDOW_WIDTH, - screen_height: WINDOW_HEIGHT, - }; - // ------------------------ - - unsafe { - self.device - .device_wait_idle() - .expect("Failed to wait device idle!") - }; - self.cleanup_swapchain(); - - let swapchain_stuff = SwapChainStuff::new( - &self.instance, - &self.device, - self.physical_device, - &self.window, - &surface_suff, - &self.queue_family, - ); - self.swapchain_loader = swapchain_stuff.swapchain_loader; - self.swapchain = swapchain_stuff.swapchain; - self.swapchain_images = swapchain_stuff.swapchain_images; - self.swapchain_format = swapchain_stuff.swapchain_format; - self.swapchain_extent = swapchain_stuff.swapchain_extent; - - self.swapchain_imageviews = - share::create_image_views(&self.device, self.swapchain_format, &self.swapchain_images); - self.render_pass = share::create_render_pass(&self.device, self.swapchain_format); - let (graphics_pipeline, pipeline_layout) = VulkanApp::create_graphics_pipeline( - &self.device, - self.render_pass, - swapchain_stuff.swapchain_extent, - ); - self.graphics_pipeline = graphics_pipeline; - self.graphics_pipeline_layout = pipeline_layout; - - self.swapchain_framebuffers = share::create_framebuffers( - &self.device, - self.render_pass, - &self.swapchain_imageviews, - self.swapchain_extent, - ); - self.command_buffers = VulkanApp::create_command_buffers( - &self.device, - self.command_pool, - self.graphics_pipeline, - &self.swapchain_framebuffers, - self.render_pass, - self.swapchain_extent, - self.vertex_buffer, - ); - } - - fn cleanup_swapchain(&self) { - unsafe { - self.device - .free_command_buffers(self.command_pool, &self.command_buffers); - for &framebuffer in self.swapchain_framebuffers.iter() { - self.device.destroy_framebuffer(framebuffer, None); - } - self.device.destroy_pipeline(self.graphics_pipeline, None); - self.device - .destroy_pipeline_layout(self.graphics_pipeline_layout, None); - self.device.destroy_render_pass(self.render_pass, None); - for &image_view in self.swapchain_imageviews.iter() { - self.device.destroy_image_view(image_view, None); - } - self.swapchain_loader - .destroy_swapchain(self.swapchain, None); - } - } -} - - - -impl Drop for VulkanApp { - //cleanup in C++ - fn drop(&mut self) { - unsafe { - for i in 0..MAX_FRAMES_IN_FLIGHT { - self.device - .destroy_semaphore(self.image_available_semaphores[i], None); - self.device - .destroy_semaphore(self.render_finished_semaphores[i], None); - self.device.destroy_fence(self.in_flight_fences[i], None); - } - - self.cleanup_swapchain(); - - self.device - .destory - - self.device.destroy_buffer(self.vertex_buffer, None); - self.device.free_memory(self.vertex_buffer_memory, None); - - self.device.destroy_command_pool(self.command_pool, None); - - self.device.destroy_device(None); - self.surface_loader.destroy_surface(self.surface, None); - - if VALIDATION.is_enable { - self.debug_utils_loader - .destroy_debug_utils_messenger(self.debug_merssager, None); - } - self.instance.destroy_instance(None); - } - } -} - diff --git a/src/shaders/tri.comp b/src/shaders/tri.comp index 44a1790..2bff93c 100644 --- a/src/shaders/tri.comp +++ b/src/shaders/tri.comp @@ -3,7 +3,7 @@ struct Particle { vec2 position; vec2 velocity; - vec4 color; + vec4 color; }; layout (binding = 0) uniform ParameterUBO { @@ -26,9 +26,12 @@ void main() Particle particleIn = particlesIn[index]; - particlesOut[index].position = particleIn.position + particleIn.velocity.xy * ubo.deltaTime; + //particlesOut[index].position = particleIn.position + particleIn.velocity.xy * ubo.deltaTime; + particlesOut[index].velocity = particleIn.velocity; + particlesOut[index].position = vec2(5, 5) + // Flip movement at window border if ((particlesOut[index].position.x <= -1.0) || (particlesOut[index].position.x >= 1.0)) { particlesOut[index].velocity.x = -particlesOut[index].velocity.x; diff --git a/src/shaders/tri.frag b/src/shaders/tri.frag index c64de63..94517ec 100644 --- a/src/shaders/tri.frag +++ b/src/shaders/tri.frag @@ -1,12 +1,11 @@ #version 450 -#extension GL_ARB_separate_shader_objects: enable +layout(location = 0) in vec3 fragColor; -layout (location = 0) in vec3 fragColor; - -layout (location = 0) out vec4 outColor; +layout(location = 0) out vec4 outColor; void main() { - outColor = vec4(fragColor, 1.0); + vec2 coord = gl_PointCoord - vec2(0.5); + outColor = vec4(fragColor, 0.5 - length(coord)); } diff --git a/src/shaders/tri.vert b/src/shaders/tri.vert index 78a941a..9730d27 100644 --- a/src/shaders/tri.vert +++ b/src/shaders/tri.vert @@ -1,18 +1,13 @@ #version 450 -#extension GL_ARB_separate_shader_objects: enable +layout(location = 0) in vec2 inPosition; +layout(location = 1) in vec4 inColor; -layout (location = 0) in vec2 inPosition; -layout (location = 1) in vec3 inColor; - -layout (location = 0) out vec3 fragColor; - -out gl_PerVertex { - vec4 gl_Position; -}; +layout(location = 0) out vec3 fragColor; void main() { - gl_Position = vec4(inPosition, 0.0, 1.0); - fragColor = inColor; + gl_PointSize = 14.0; + gl_Position = vec4(inPosition.xy, 1.0, 1.0); + fragColor = inColor.rgb; } diff --git a/src/utility.rs b/src/utility.rs index bac03bb..0c59107 100644 --- a/src/utility.rs +++ b/src/utility.rs @@ -2,6 +2,6 @@ pub mod constants; pub mod debug; pub mod fps_limiter; pub mod platforms; -pub mod share; +//pub mod share; pub mod structures; pub mod tools; diff --git a/src/utility/constants.rs b/src/utility/constants.rs index 2d588e0..fbfcb08 100644 --- a/src/utility/constants.rs +++ b/src/utility/constants.rs @@ -4,20 +4,20 @@ use ash::vk::make_api_version; use std::os::raw::c_char; -pub const APPLICATION_VERSION: u32 = make_api_version(1, 0, 0, 0); +pub const APPLICATION_VERSION: u32 = make_api_version(0, 0, 0, 0); pub const ENGINE_VERSION: u32 = make_api_version(1, 0, 0, 0); pub const API_VERSION: u32 = make_api_version(1, 3, 251, 0); -pub const WINDOW_WIDTH: u32 = 800; -pub const WINDOW_HEIGHT: u32 = 600; +pub const WINDOW_WIDTH: u32 = 3000; +pub const WINDOW_HEIGHT: u32 = 2000; pub const VALIDATION: ValidationInfo = ValidationInfo { - is_enable: true, + is_enabled: true, required_validation_layers: ["VK_LAYER_KHRONOS_validation"], }; pub const DEVICE_EXTENSIONS: DeviceExtension = DeviceExtension { names: ["VK_KHR_swapchain"], }; -pub const MAX_FRAMES_IN_FLIGHT: usize = 4; +pub const MAX_FRAMES_IN_FLIGHT: usize = 2; pub const IS_PAINT_FPS_COUNTER: bool = true; impl DeviceExtension { diff --git a/src/utility/debug.rs b/src/utility/debug.rs index 2720a29..ddd2a63 100644 --- a/src/utility/debug.rs +++ b/src/utility/debug.rs @@ -30,7 +30,7 @@ unsafe extern "system" fn vulkan_debug_utils_callback( } pub struct ValidationInfo { - pub is_enable: bool, + pub is_enabled: bool, pub required_validation_layers: [&'static str; 1], } diff --git a/src/utility/share.rs b/src/utility/share.rs deleted file mode 100644 index 4c4a403..0000000 --- a/src/utility/share.rs +++ /dev/null @@ -1,2139 +0,0 @@ -use ash::vk; -use image; -use image::GenericImageView; - -use crate::utility::constants::*; -use crate::utility::structures::*; -use crate::utility::{debug, platforms}; -use crate::entities::PARTICLE_COUNT; - -use std::cmp::max; -use std::ffi::CString; -use std::os::raw::{c_char, c_void}; -use std::path::Path; -use std::{ptr, mem::size_of}; - -pub fn create_instance( - entry: &ash::Entry, - window_title: &str, - is_enable_debug: bool, - required_validation_layers: &Vec<&str>, -) -> ash::Instance { - if is_enable_debug - && debug::check_validation_layer_support(entry, required_validation_layers) == false - { - panic!("Validation layers requested, but not available!"); - } - - let app_name = CString::new(window_title).unwrap(); - let engine_name = CString::new("Vulkan Engine").unwrap(); - let app_info = vk::ApplicationInfo { - p_application_name: app_name.as_ptr(), - s_type: vk::StructureType::APPLICATION_INFO, - p_next: ptr::null(), - application_version: APPLICATION_VERSION, - p_engine_name: engine_name.as_ptr(), - engine_version: ENGINE_VERSION, - api_version: API_VERSION, - }; - - // This create info used to debug issues in vk::createInstance and vk::destroyInstance. - let debug_utils_create_info = debug::populate_debug_messenger_create_info(); - - // VK_EXT debug report has been requested here. - let extension_names = platforms::required_extension_names(); - - let requred_validation_layer_raw_names: Vec = required_validation_layers - .iter() - .map(|layer_name| CString::new(*layer_name).unwrap()) - .collect(); - let layer_names: Vec<*const i8> = requred_validation_layer_raw_names - .iter() - .map(|layer_name| layer_name.as_ptr()) - .collect(); - - let create_info = vk::InstanceCreateInfo { - s_type: vk::StructureType::INSTANCE_CREATE_INFO, - p_next: if VALIDATION.is_enable { - &debug_utils_create_info as *const vk::DebugUtilsMessengerCreateInfoEXT - as *const c_void - } else { - ptr::null() - }, - flags: vk::InstanceCreateFlags::empty(), - p_application_info: &app_info, - pp_enabled_layer_names: if is_enable_debug { - layer_names.as_ptr() - } else { - ptr::null() - }, - enabled_layer_count: if is_enable_debug { - layer_names.len() - } else { - 0 - } as u32, - pp_enabled_extension_names: extension_names.as_ptr(), - enabled_extension_count: extension_names.len() as u32, - }; - - unsafe { - entry - .create_instance(&create_info, None) - .expect("Failed to create instance!") - } -} - -pub fn create_render_pass(device: &ash::Device, surface_format: vk::Format) -> vk::RenderPass { - let color_attachment = vk::AttachmentDescription { - format: surface_format, - flags: vk::AttachmentDescriptionFlags::empty(), - samples: vk::SampleCountFlags::TYPE_1, - load_op: vk::AttachmentLoadOp::CLEAR, - store_op: vk::AttachmentStoreOp::STORE, - stencil_load_op: vk::AttachmentLoadOp::DONT_CARE, - stencil_store_op: vk::AttachmentStoreOp::DONT_CARE, - initial_layout: vk::ImageLayout::UNDEFINED, - final_layout: vk::ImageLayout::PRESENT_SRC_KHR, - }; - - let color_attachment_ref = vk::AttachmentReference { - attachment: 0, - layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, - }; - - let subpasses = [vk::SubpassDescription { - color_attachment_count: 1, - p_color_attachments: &color_attachment_ref, - p_depth_stencil_attachment: ptr::null(), - flags: vk::SubpassDescriptionFlags::empty(), - pipeline_bind_point: vk::PipelineBindPoint::GRAPHICS, - input_attachment_count: 0, - p_input_attachments: ptr::null(), - p_resolve_attachments: ptr::null(), - preserve_attachment_count: 0, - p_preserve_attachments: ptr::null(), - }]; - - let render_pass_attachments = [color_attachment]; - - let subpass_dependencies = [vk::SubpassDependency { - src_subpass: vk::SUBPASS_EXTERNAL, - dst_subpass: 0, - src_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, - dst_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, - src_access_mask: vk::AccessFlags::empty(), - dst_access_mask: vk::AccessFlags::COLOR_ATTACHMENT_WRITE, - dependency_flags: vk::DependencyFlags::empty(), - }]; - - let renderpass_create_info = vk::RenderPassCreateInfo { - s_type: vk::StructureType::RENDER_PASS_CREATE_INFO, - flags: vk::RenderPassCreateFlags::empty(), - p_next: ptr::null(), - attachment_count: render_pass_attachments.len() as u32, - p_attachments: render_pass_attachments.as_ptr(), - subpass_count: subpasses.len() as u32, - p_subpasses: subpasses.as_ptr(), - dependency_count: subpass_dependencies.len() as u32, - p_dependencies: subpass_dependencies.as_ptr(), - }; - - unsafe { - device - .create_render_pass(&renderpass_create_info, None) - .expect("Failed to create render pass!") - } -} - -pub fn create_framebuffers( - device: &ash::Device, - render_pass: vk::RenderPass, - image_views: &Vec, - swapchain_extent: vk::Extent2D, -) -> Vec { - let mut framebuffers = vec![]; - - for &image_view in image_views.iter() { - let attachments = [image_view]; - - let framebuffer_create_info = vk::FramebufferCreateInfo { - s_type: vk::StructureType::FRAMEBUFFER_CREATE_INFO, - p_next: ptr::null(), - flags: vk::FramebufferCreateFlags::empty(), - render_pass, - attachment_count: attachments.len() as u32, - p_attachments: attachments.as_ptr(), - width: swapchain_extent.width, - height: swapchain_extent.height, - layers: 1, - }; - - let framebuffer = unsafe { - device - .create_framebuffer(&framebuffer_create_info, None) - .expect("Failed to create Framebuffer!") - }; - - framebuffers.push(framebuffer); - } - - framebuffers -} - -pub fn create_command_pool( - device: &ash::Device, - queue_families: &QueueFamilyIndices, -) -> vk::CommandPool { - let command_pool_create_info = vk::CommandPoolCreateInfo { - s_type: vk::StructureType::COMMAND_POOL_CREATE_INFO, - p_next: ptr::null(), - flags: vk::CommandPoolCreateFlags::empty(), - queue_family_index: queue_families.graphics_and_compute_family.unwrap(), - }; - - unsafe { - device - .create_command_pool(&command_pool_create_info, None) - .expect("Failed to create Command Pool!") - } -} - -/* -let (staging_buffer, staging_buffer_memory) = create_buffer( - device, - buffer_size, - vk::BufferUsageFlags::TRANSFER_SRC, - vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT, - &device_memory_properties, - ); - -*/ - -pub fn create_shader_storage_buffers( - device: &ash::Device, - shader_storage_buffers: Vec, - shader_storage_buffers_memory: Vec -) { - let particles = Particle::gen(); - - let buffer_size = std::mem::size_of::() * PARTICLE_COUNT; - - - let (staging_buffer, staging_buffer_memory) = create_buffer( - device, - buffer_size, - BufferUsageFlags::TRANSFER_SRC, - MemoryPropertyFlags::HOST_VISIBLE | - MemoryPropertyFlags::HOST_COHERENT, - staging_buffer, - staging_buffer_memory, - ); - - unsafe { - let data = device - .map_memory( - staging_buffer_memory, - 0, - buffer_size, - 0, - ) - .expect("failed to map shader storage buffer memory"); - ptr::copy_nonoverlapping( - data, - particles.as_mut_ptr(), - buffer_size - ); - device - .unmap_memory(staging_buffer_memory); - - for i in 0..MAX_FRAMES_IN_FLIGHT { - (shader_storage_buffers[i], shader_storage_buffers_memory[i]) = create_buffer( - device, - buffer_size, - BufferUsageFlags::STORAGE_BUFFER | - BufferUsageFlags::VERTEX_BUFFER | - BufferUsageFlags::TRANSFER_DST, - MemoryPropertyFlags::DEVICE_LOCAL, - shader_storage_buffers, - shader_storage_buffers_memory, - ); - - let (buffer_copy, buffer_copy_memory) = - copy_buffer( - staging_buffer, - shader_storage_buffers[i], - buffer_size - ); - - } - - device - .destory_buffer(staging_buffer, ptr::null()) - - device - .free_memory(staging_buffer_memory, ptr::null); - } -} - -///createCommandBuffers in C++ -pub fn create_command_buffers( - device: &ash::Device, - command_pool: vk::CommandPool, - command_buffers: &Vec, - //graphics_pipeline: vk::Pipeline, - //framebuffers: &Vec, - //render_pass: vk::RenderPass, - //surface_extent: vk::Extent2D, -) -> Vec { - let command_buffer_allocate_info = vk::CommandBufferAllocateInfo { - s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO, - p_next: ptr::null(), - command_buffer_count: command_buffers.len() as u32, - command_pool, - level: vk::CommandBufferLevel::PRIMARY, - }; - - let command_buffers = unsafe { - device - .allocate_command_buffers(&command_buffer_allocate_info) - .expect("Failed to allocate Command Buffers!") - }; - - command_buffers -} - -pub fn record_command_buffer( - device: &ash::Device, - command_buffer: vk::CommandBuffer, - image_index: u32, - render_pass: vk::RenderPass, - swapchain_extent: vk::Extent2D, - shader_storage_buffers: Vec, - //shader_storage_buffers_memory: Vec, - current_frame: usize, - graphics_pipeline: vk::GraphicsPipeline, - - -) { - let command_buffer_begin_info = vk::CommandBufferBeginInfo { - s_type: vk::StructureType::COMMAND_BUFFER_BEGIN_INFO, - p_next: ptr::null(), - p_inheritance_info: ptr::null(), - flags: vk::CommandBufferUsageFlags::SIMULTANEOUS_USE, - } - - unsafe { - device - .begin_command_buffer(command_buffer, &command_buffer_begin_info) - .expect("failed to start recording command buffer") - } - let clear_values = [vk::ClearValue { - color: vk::ClearColorValue { - float32: [0.0, 0.0, 0.0, 1.0], - }, - }]; - - let render_pass_begin_info = vk::RenderPassBeginInfo { - s_type: vk::StructureType::RENDER_PASS_BEGIN_INFO, - p_next: ptr::null(), - render_pass, - framebuffer: framebuffers[i], - render_area: vk::Rect2D { - offset: vk::Offset2D { x: 0, y: 0 }, - extent: surface_extent, - }, - clear_value_count: clear_values.len() as u32, - p_clear_values: clear_values.as_ptr(), - }; - - let viewport = vec![vk::Viewport { - x: 0.0, - y: 0.0, - width: swapchain_extent.width as f32, - height: swapchain_extent.height as f32, - min_depth: 0.0, - max_depth: 1.0, - }]; - - let scissor = vec![vk::Rect2D { - offset: vk::Offset2D { x: 0, y: 0 }, - extent: swapchain_extent, - }]; - - let offsets: Vec = vec![0] - - unsafe { - device.cmd_begin_render_pass( - command_buffer, - &render_pass_begin_info, - vk::SubpassContents::INLINE, - .create_framebuffer(&framebuffer_create_info, None) - .expect("Failed to create Framebuffer!") - ); - - - framebuffers.push(framebuffer); - } - - framebuffers -} - -pub fn create_command_pool( - device: &ash::Device, - queue_families: &QueueFamilyIndices, -) -> vk::CommandPool { - let command_pool_create_info = vk::CommandPoolCreateInfo { - s_type: vk::StructureType::COMMAND_POOL_CREATE_INFO, - p_next: ptr::null(), - flags: vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER, - queue_family_index: queue_families.graphics_family.unwrap(), - }; - - unsafe { - device - .create_command_pool(&command_pool_create_info, None) - .expect("Failed to create Command Pool!") - } -} - -///createCommandBuffers in C++ -pub fn create_command_buffers( - device: &ash::Device, - command_pool: vk::CommandPool, - command_buffers: &Vec, - //graphics_pipeline: vk::Pipeline, - //framebuffers: &Vec, - //render_pass: vk::RenderPass, - //surface_extent: vk::Extent2D, -) -> Vec { - let command_buffer_allocate_info = vk::CommandBufferAllocateInfo { - s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO, - p_next: ptr::null(), - command_buffer_count: command_buffers.len() as u32, - command_pool, - level: vk::CommandBufferLevel::PRIMARY, - }; - - let command_buffers = unsafe { - device - .allocate_command_buffers(&command_buffer_allocate_info) - .expect("Failed to allocate Command Buffers!") - }; - - command_buffers -} - -/*pub fn record_command_buffer( - device: &ash::Device, - command_buffer: vk::CommandBuffer, - image_index: u32, - render_pass: vk::RenderPass, - swapchain_extent: vk::Extent2D, - shader_storage_buffers: Vec, - //shader_storage_buffers_memory: Vec, - current_frame: usize, - graphics_pipeline: vk::GraphicsPipeline, - - -) { - let command_buffer_begin_info = vk::CommandBufferBeginInfo { - s_type: vk::StructureType::COMMAND_BUFFER_BEGIN_INFO, - p_next: ptr::null(), - p_inheritance_info: ptr::null(), - flags: vk::CommandBufferUsageFlags::SIMULTANEOUS_USE, - } - - unsafe { - device - .begin_command_buffer(command_buffer, &command_buffer_begin_info) - .expect("failed to start recording command buffer") - } - let clear_values = [vk::ClearValue { - color: vk::ClearColorValue { - float32: [0.0, 0.0, 0.0, 1.0], - }, - }]; - - let render_pass_begin_info = vk::RenderPassBeginInfo { - s_type: vk::StructureType::RENDER_PASS_BEGIN_INFO, - p_next: ptr::null(), - render_pass, - framebuffer: framebuffers[i], - render_area: vk::Rect2D { - offset: vk::Offset2D { x: 0, y: 0 }, - extent: surface_extent, - }, - clear_value_count: clear_values.len() as u32, - p_clear_values: clear_values.as_ptr(), - }; - - let viewport = vec![vk::Viewport { - x: 0.0, - y: 0.0, - width: swapchain_extent.width as f32, - height: swapchain_extent.height as f32, - min_depth: 0.0, - max_depth: 1.0, - }]; - - let scissor = vec![vk::Rect2D { - offset: vk::Offset2D { x: 0, y: 0 }, - extent: swapchain_extent, - }]; - - let offsets: Vec = vec![0] - - unsafe { - device.cmd_begin_render_pass(); - } - - unsafe { - let data_ptr = device - .map_memory( - staging_buffer_memory, - 0, - buffer_size, - vk::MemoryMapFlags::empty(), - ) - .expect("Failed to Map Memory") as *mut T; - - data_ptr.copy_from_nonoverlapping(data.as_ptr(), data.len()); - - device.unmap_memory(staging_buffer_memory); - } - - let (vertex_buffer, vertex_buffer_memory) = create_buffer( - device, - buffer_size, - vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::VERTEX_BUFFER, - vk::MemoryPropertyFlags::DEVICE_LOCAL, - &device_memory_properties, - ); - - copy_buffer( - device, - submit_queue, - command_pool, - staging_buffer, - vertex_buffer, - buffer_size, - ); - - unsafe { - device.destroy_buffer(staging_buffer, None); - device.free_memory(staging_buffer_memory, None); - } - - (vertex_buffer, vertex_buffer_memory) -}*/ - -pub fn create_descriptor_pool( - device: &ash::Device, - swapchain_images_size: usize, -) -> vk::DescriptorPool { - let pool_sizes = [ - vk::DescriptorPoolSize { - ty: vk::DescriptorType::UNIFORM_BUFFER, - descriptor_count: swapchain_images_size as u32, - }, - vk::DescriptorPoolSize { - ty: vk::DescriptorType::STORAGE_BUFFER, - descriptor_count: swapchain_images_size as u32 * 2, - } - ]; - - let descriptor_pool_create_info = vk::DescriptorPoolCreateInfo { - s_type: vk::StructureType::DESCRIPTOR_POOL_CREATE_INFO, - p_next: ptr::null(), - flags: vk::DescriptorPoolCreateFlags::empty(), - max_sets: swapchain_images_size as u32, - pool_size_count: pool_sizes.len() as u32, - p_pool_sizes: pool_sizes.as_ptr(), - }; - - unsafe { - device - .create_descriptor_pool(&descriptor_pool_create_info, None) - .expect("Failed to create Descriptor Pool!") - } -} - -pub fn create_compute_descriptor_sets( - device: &ash::Device, - compute_descriptor_set_layout: vk::DescriptorSetLayout, - descriptor_pool: vk::DescriptorPool, - compute_descriptor_sets: Vec, - uniform_buffers: Vec, - shader_storage_buffers: Vec -) { - let layouts = vec![compute_descriptor_set_layout; MAX_FRAMES_IN_FLIGHT]; - - let alloc_info - vk::DescriptorSetAllocateInfo { - s_type: DESCRIPTOR_SET_ALLOCATE_INFO, - p_next: ptr::null() DONE, - descriptor_pool: descriptor_pool, - descriptor_set_count: MAX_FRAMES_IN_FLIGHT as u32, - p_set_layouts: layouts.as_ptr(), - }; - - unsafe { - device - .allocate_descriptor_sets() - .expect("failed to allocate descriptor sets") - } - - for i in 0..MAX_FRAMES_IN_FLIGHT { - uniform_buffer_info = vk::DescriptorBufferInfo { - buffer: uniform_buffers, - offset: 0, - range: size_of:: as u64, - }; - - storage_buffer_info_last_frame = vk::DescriptorBufferInfo { - buffer: shader_storage_buffers[(i - 1) % MAX_FRAMES_IN_FLIGHT], - offset: 0, - range: size_of:: as u64 * PARTICLE_COUNT, - }; - - storage_buffer_info_current_frame = vk::DescriptorBufferInfo { - buffer: shader_storage_buffers[i], - offset: 0, - range: size_of:: as u64 * PARTICLE_COUNT, - }; - - descriptor_writes = [ - vk::WriteDescriptorSet { - s_type: WRITE_DESCRIPTOR_SET, - dst_set: compute_descriptor_sets[i], - dst_binding: 0, - dst_array_element: 0, - descriptor_type: DescriptorType::UNIFORM_BUFFER, - descriptor_count: 1, - p_buffer_info: uniform_buffer_info, - ..Default::default() - } - vk::WriteDescriptorSet { - s_type: WRITE_DESCRIPTOR_SET, - dst_set: compute_descriptor_sets[i], - dst_binding: 1, - dst_array_element: 0, - descriptor_type: DescriptorType::STORAGE_BUFFER, - descriptor_count: 1, - p_buffer_info: storage_buffer_info_last_frame, - ..Default::default() - } - vk::WriteDescriptorSet { - s_type: WRITE_DESCRIPTOR_SET, - dst_set: compute_descriptor_sets[i], - dst_binding: 2, - dst_array_element: 0, - descriptor_type: DescriptorType::STORAGE_BUFFER, - descriptor_count: 1, - p_buffer_info: storage_buffer_info_current_frame, - ..Default::default() - } - ] - - unsafe { - device - .update_descriptor_sets(descriptor_writes, vec![]) - } - } -} - -/*pub fn create_descriptor_sets( - device: &ash::Device, - descriptor_pool: vk::DescriptorPool, - descriptor_set_layout: vk::DescriptorSetLayout, - uniform_buffers: Option<&Vec>, - compute_buffers: Option<&Vec>, - swapchain_images_size: usize, -) -> Vec { - let mut layouts: Vec = vec![]; - for _ in 0..swapchain_images_size { - layouts.push(descriptor_set_layout); - } - - let descriptor_set_allocate_info = vk::DescriptorSetAllocateInfo { - s_type: vk::StructureType::DESCRIPTOR_SET_ALLOCATE_INFO, - p_next: ptr::null(), - descriptor_pool, - offset: i as u64, - range: size_of:: as u64, - } - ); - } - let mut descriptor_write_sets = vec![]; - - let mut descriptor_count = 0; - - for info in &uniform_descriptor_info { - descriptor_write_sets.push( - vk::WriteDescriptorSet { - s_type: vk::StructureType::WRITE_DESCRIPTOR_SET, - p_next: ptr::null(), - dst_set: descritptor_set, - dst_binding: descriptor_count, - dst_array_element: 0, - descriptor_count: uniform_descriptor_info.len() as u32, - descriptor_type: vk::DescriptorType::UNIFORM_BUFFER, - p_image_info: ptr::null(), - p_buffer_info: uniform_descriptor_info.as_ptr(), - p_texel_buffer_view: ptr::null(), - } - ); - descriptor_count += 1; - } - for info in &compute_descriptor_info { - descriptor_write_sets.push( - vk::WriteDescriptorSet { - s_type: vk::StructureType::WRITE_DESCRIPTOR_SET, - p_next: ptr::null(), - dst_set: descritptor_set, - dst_binding: descriptor_count, - dst_array_element: 0, - descriptor_count: compute_descriptor_info.len() as u32, - descriptor_type: vk::DescriptorType::STORAGE_BUFFER, - p_image_info: ptr::null(), - p_buffer_info: compute_descriptor_info.as_ptr(), - p_texel_buffer_view: ptr::null(), - } - ); - descriptor_count += 1; - } - - unsafe { - device.update_descriptor_sets(&descriptor_write_sets, &[]); - } - } - - descriptor_sets -}*/ - -pub fn create_descriptor_set_layout(device: &ash::Device) -> vk::DescriptorSetLayout { - let ubo_layout_bindings = [ - vk::DescriptorSetLayoutBinding { - binding: 0, - descriptor_type: vk::DescriptorType::UNIFORM_BUFFER, - descriptor_count: 1, - stage_flags: vk::ShaderStageFlags::VERTEX, - p_immutable_samplers: ptr::null(), - }, - vk::DescriptorSetLayoutBinding { - binding: 1, - descriptor_type: vk::DescriptorType::STORAGE_BUFFER, - descriptor_count: 1, - stage_flags: vk::ShaderStageFlags::COMPUTE, - p_immutable_samplers: ptr::null(), - }, - vk::DescriptorSetLayoutBinding { - binding: 2, - descriptor_type: vk::DescriptorType::STORAGE_BUFFER, - descriptor_count: 1, - stage_flags: vk::ShaderStageFlags::COMPUTE, - p_immutable_samplers: ptr::null(), - }, - ]; - - let ubo_layout_create_info = vk::DescriptorSetLayoutCreateInfo { - s_type: vk::StructureType::DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - p_next: ptr::null(), - flags: vk::DescriptorSetLayoutCreateFlags::empty(), - binding_count: ubo_layout_bindings.len() as u32, - p_bindings: ubo_layout_bindings.as_ptr(), - }; - - unsafe { - device - .create_descriptor_set_layout(&ubo_layout_create_info, None) - .expect("Failed to create Descriptor Set Layout!") - } -} - -pub fn create_uniform_buffers( - device: &ash::Device, - device_memory_properties: &vk::PhysicalDeviceMemoryProperties, - swapchain_image_count: usize, -) -> (Vec, Vec) { - let buffer_size = ::std::mem::size_of::(); - - let mut uniform_buffers = vec![]; - let mut uniform_buffers_memory = vec![]; - - for _ in 0..swapchain_image_count { - let (uniform_buffer, uniform_buffer_memory) = create_buffer( - device, - buffer_size as u64, - vk::BufferUsageFlags::UNIFORM_BUFFER, - vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT, - device_memory_properties, - ); - uniform_buffers.push(uniform_buffer); - uniform_buffers_memory.push(uniform_buffer_memory); - } - - (uniform_buffers, uniform_buffers_memory) -} - -pub fn create_image( - device: &ash::Device, - width: u32, - height: u32, - mip_levels: u32, - num_samples: vk::SampleCountFlags, - format: vk::Format, - tiling: vk::ImageTiling, - usage: vk::ImageUsageFlags, - required_memory_properties: vk::MemoryPropertyFlags, - device_memory_properties: &vk::PhysicalDeviceMemoryProperties, -) -> (vk::Image, vk::DeviceMemory) { - let image_create_info = vk::ImageCreateInfo { - s_type: vk::StructureType::IMAGE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::ImageCreateFlags::empty(), - image_type: vk::ImageType::TYPE_2D, - format, - mip_levels, - array_layers: 1, - samples: num_samples, - tiling, - usage, - sharing_mode: vk::SharingMode::EXCLUSIVE, - queue_family_index_count: 0, - p_queue_family_indices: ptr::null(), - initial_layout: vk::ImageLayout::UNDEFINED, - extent: vk::Extent3D { - width, - height, - depth: 1, - }, - }; - - let texture_image = unsafe { - device - .create_image(&image_create_info, None) - .expect("Failed to create Texture Image!") - }; - - let image_memory_requirement = unsafe { device.get_image_memory_requirements(texture_image) }; - let memory_allocate_info = vk::MemoryAllocateInfo { - s_type: vk::StructureType::MEMORY_ALLOCATE_INFO, - p_next: ptr::null(), - allocation_size: image_memory_requirement.size, - memory_type_index: find_memory_type( - image_memory_requirement.memory_type_bits, - required_memory_properties, - device_memory_properties, - ), - }; - - let texture_image_memory = unsafe { - device - .allocate_memory(&memory_allocate_info, None) - .expect("Failed to allocate Texture Image memory!") - }; - - unsafe { - device - .bind_image_memory(texture_image, texture_image_memory, 0) - .expect("Failed to bind Image Memmory!"); - } - - (texture_image, texture_image_memory) -} - -pub fn transition_image_layout( - device: &ash::Device, - command_pool: vk::CommandPool, - submit_queue: vk::Queue, - image: vk::Image, - _format: vk::Format, - old_layout: vk::ImageLayout, - new_layout: vk::ImageLayout, - mip_levels: u32, -) { - let command_buffer = begin_single_time_command(device, command_pool); - - let src_access_mask; - let dst_access_mask; - let source_stage; - let destination_stage; - - if old_layout == vk::ImageLayout::UNDEFINED - && new_layout == vk::ImageLayout::TRANSFER_DST_OPTIMAL - { - src_access_mask = vk::AccessFlags::empty(); - dst_access_mask = vk::AccessFlags::TRANSFER_WRITE; - source_stage = vk::PipelineStageFlags::TOP_OF_PIPE; - destination_stage = vk::PipelineStageFlags::TRANSFER; - } else if old_layout == vk::ImageLayout::TRANSFER_DST_OPTIMAL - && new_layout == vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL - { - src_access_mask = vk::AccessFlags::TRANSFER_WRITE; - dst_access_mask = vk::AccessFlags::SHADER_READ; - source_stage = vk::PipelineStageFlags::TRANSFER; - destination_stage = vk::PipelineStageFlags::FRAGMENT_SHADER; - } else if old_layout == vk::ImageLayout::UNDEFINED - && new_layout == vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL - { - src_access_mask = vk::AccessFlags::empty(); - dst_access_mask = - vk::AccessFlags::COLOR_ATTACHMENT_READ | vk::AccessFlags::COLOR_ATTACHMENT_WRITE; - source_stage = vk::PipelineStageFlags::TOP_OF_PIPE; - destination_stage = vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT; - } else { - panic!("Unsupported layout transition!") - } - - let image_barriers = [vk::ImageMemoryBarrier { - s_type: vk::StructureType::IMAGE_MEMORY_BARRIER, - p_next: ptr::null(), - src_access_mask, - dst_access_mask, - old_layout, - new_layout, - src_queue_family_index: vk::QUEUE_FAMILY_IGNORED, - dst_queue_family_index: vk::QUEUE_FAMILY_IGNORED, - image, - subresource_range: vk::ImageSubresourceRange { - aspect_mask: vk::ImageAspectFlags::COLOR, - base_mip_level: 0, - level_count: mip_levels, - base_array_layer: 0, - layer_count: 1, - }, - }]; - - unsafe { - device.cmd_pipeline_barrier( - command_buffer, - source_stage, - destination_stage, - vk::DependencyFlags::empty(), - &[], - &[], - &image_barriers, - ); - } - - end_single_time_command(device, command_pool, submit_queue, command_buffer); -} - -pub fn create_image_views( - device: &ash::Device, - surface_format: vk::Format, - images: &Vec, -) -> Vec { - let swapchain_imageviews: Vec = images - .iter() - .map(|&image| { - create_image_view( - device, - image, - surface_format, - vk::ImageAspectFlags::COLOR, - 1, - ) - }) - .collect(); - - swapchain_imageviews -} - -pub fn create_image_view( - device: &ash::Device, - image: vk::Image, - format: vk::Format, - aspect_flags: vk::ImageAspectFlags, - mip_levels: u32, -) -> vk::ImageView { - let imageview_create_info = vk::ImageViewCreateInfo { - s_type: vk::StructureType::IMAGE_VIEW_CREATE_INFO, - p_next: ptr::null(), - flags: vk::ImageViewCreateFlags::empty(), - view_type: vk::ImageViewType::TYPE_2D, - format, - components: vk::ComponentMapping { - r: vk::ComponentSwizzle::IDENTITY, - g: vk::ComponentSwizzle::IDENTITY, - b: vk::ComponentSwizzle::IDENTITY, - a: vk::ComponentSwizzle::IDENTITY, - }, - subresource_range: vk::ImageSubresourceRange { - aspect_mask: aspect_flags, - base_mip_level: 0, - level_count: mip_levels, - base_array_layer: 0, - layer_count: 1, - }, - image, - }; - - unsafe { - device - .create_image_view(&imageview_create_info, None) - .expect("Failed to create Image View!") - } -} - -pub fn create_texture_image_view( - device: &ash::Device, - texture_image: vk::Image, - mip_levels: u32, -) -> vk::ImageView { - create_image_view( - device, - texture_image, - vk::Format::R8G8B8A8_SRGB, - vk::ImageAspectFlags::COLOR, - mip_levels, - ) -} - -pub fn create_texture_sampler(device: &ash::Device) -> vk::Sampler { - let sampler_create_info = vk::SamplerCreateInfo { - s_type: vk::StructureType::SAMPLER_CREATE_INFO, - p_next: ptr::null(), - flags: vk::SamplerCreateFlags::empty(), - mag_filter: vk::Filter::LINEAR, - min_filter: vk::Filter::LINEAR, - address_mode_u: vk::SamplerAddressMode::REPEAT, - address_mode_v: vk::SamplerAddressMode::REPEAT, - address_mode_w: vk::SamplerAddressMode::REPEAT, - max_anisotropy: 16.0, - compare_enable: vk::FALSE, - compare_op: vk::CompareOp::ALWAYS, - mipmap_mode: vk::SamplerMipmapMode::LINEAR, - min_lod: 0.0, - max_lod: 0.0, - mip_lod_bias: 0.0, - border_color: vk::BorderColor::INT_OPAQUE_BLACK, - anisotropy_enable: vk::TRUE, - unnormalized_coordinates: vk::FALSE, - }; - - unsafe { - device - .create_sampler(&sampler_create_info, None) - .expect("Failed to create Sampler!") - } -} - -pub fn create_texture_image( - device: &ash::Device, - command_pool: vk::CommandPool, - submit_queue: vk::Queue, - device_memory_properties: &vk::PhysicalDeviceMemoryProperties, - image_path: &Path, -) -> (vk::Image, vk::DeviceMemory) { - let mut image_object = image::open(image_path).unwrap(); // this function is slow in debug mode. - image_object = image_object.flipv(); - let (image_width, image_height) = (image_object.width(), image_object.height()); - let image_data = match &image_object { - image::DynamicImage::ImageBgr8(_) - | image::DynamicImage::ImageLuma8(_) - | image::DynamicImage::ImageRgb8(_) => image_object.to_rgba().into_raw(), - image::DynamicImage::ImageBgra8(_) - | image::DynamicImage::ImageLumaA8(_) - | image::DynamicImage::ImageRgba8(_) => image_object.raw_pixels(), - }; - let image_size = - (::std::mem::size_of::() as u32 * image_width * image_height * 4) as vk::DeviceSize; - - if image_size <= 0 { - panic!("Failed to load texture image!") - } - - let (staging_buffer, staging_buffer_memory) = create_buffer( - device, - image_size, - vk::BufferUsageFlags::TRANSFER_SRC, - vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT, - device_memory_properties, - ); - - unsafe { - let data_ptr = device - .map_memory( - staging_buffer_memory, - 0, - image_size, - vk::MemoryMapFlags::empty(), - ) - .expect("Failed to Map Memory") as *mut u8; - - data_ptr.copy_from_nonoverlapping(image_data.as_ptr(), image_data.len()); - - device.unmap_memory(staging_buffer_memory); - } - - let (texture_image, texture_image_memory) = create_image( - device, - image_width, - image_height, - 1, - vk::SampleCountFlags::TYPE_1, - vk::Format::R8G8B8A8_SRGB, - vk::ImageTiling::OPTIMAL, - vk::ImageUsageFlags::TRANSFER_DST | vk::ImageUsageFlags::SAMPLED, - vk::MemoryPropertyFlags::DEVICE_LOCAL, - device_memory_properties, - ); - - transition_image_layout( - device, - command_pool, - submit_queue, - texture_image, - vk::Format::R8G8B8A8_SRGB, - vk::ImageLayout::UNDEFINED, - vk::ImageLayout::TRANSFER_DST_OPTIMAL, - 1, - ); - - copy_buffer_to_image( - device, - command_pool, - submit_queue, - staging_buffer, - texture_image, - image_width, - image_height, - ); - - transition_image_layout( - device, - command_pool, - submit_queue, - texture_image, - vk::Format::R8G8B8A8_UNORM, - vk::ImageLayout::TRANSFER_DST_OPTIMAL, - vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL, - 1, - ); - - unsafe { - device.destroy_buffer(staging_buffer, None); - device.free_memory(staging_buffer_memory, None); - } - - (texture_image, texture_image_memory) -} - -pub fn create_depth_resources( - instance: &ash::Instance, - device: &ash::Device, - physical_device: vk::PhysicalDevice, - _command_pool: vk::CommandPool, - _submit_queue: vk::Queue, - swapchain_extent: vk::Extent2D, - device_memory_properties: &vk::PhysicalDeviceMemoryProperties, - msaa_samples: vk::SampleCountFlags, -) -> (vk::Image, vk::ImageView, vk::DeviceMemory) { - let depth_format = find_depth_format(instance, physical_device); - let (depth_image, depth_image_memory) = create_image( - device, - swapchain_extent.width, - swapchain_extent.height, - 1, - msaa_samples, - depth_format, - vk::ImageTiling::OPTIMAL, - vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT, - vk::MemoryPropertyFlags::DEVICE_LOCAL, - device_memory_properties, - ); - let depth_image_view = create_image_view( - device, - depth_image, - depth_format, - vk::ImageAspectFlags::DEPTH, - 1, - ); - - (depth_image, depth_image_view, depth_image_memory) -} - -/*pub fn generate_mipmaps( - device: &ash::Device, - command_pool: vk::CommandPool, - submit_queue: vk::Queue, - image: vk::Image, - tex_width: u32, - tex_height: u32, - mip_levels: u32, -) { - let command_buffer = begin_single_time_command(device, command_pool); - - let mut image_barrier = vk::ImageMemoryBarrier { - s_type: vk::StructureType::IMAGE_MEMORY_BARRIER, - p_next: ptr::null(), - src_access_mask: vk::AccessFlags::empty(), - dst_access_mask: vk::AccessFlags::empty(), - old_layout: vk::ImageLayout::UNDEFINED, - new_layout: vk::ImageLayout::UNDEFINED, - src_queue_family_index: vk::QUEUE_FAMILY_IGNORED, - dst_queue_family_index: vk::QUEUE_FAMILY_IGNORED, - image, - subresource_range: vk::ImageSubresourceRange { - aspect_mask: vk::ImageAspectFlags::COLOR, - base_mip_level: 0, - level_count: 1, - base_array_layer: 0, - layer_count: 1, - }, - }; - - let mut mip_width = tex_width as i32; - let mut mip_height = tex_height as i32; - - for i in 1..mip_levels { - image_barrier.subresource_range.base_mip_level = i - 1; - image_barrier.old_layout = vk::ImageLayout::TRANSFER_DST_OPTIMAL; - image_barrier.new_layout = vk::ImageLayout::TRANSFER_SRC_OPTIMAL; - image_barrier.src_access_mask = vk::AccessFlags::TRANSFER_WRITE; - image_barrier.dst_access_mask = vk::AccessFlags::TRANSFER_READ; - - unsafe { - device.cmd_pipeline_barrier( - command_buffer, - vk::PipelineStageFlags::TRANSFER, - vk::PipelineStageFlags::TRANSFER, - vk::DependencyFlags::empty(), - &[], - &[], - &[image_barrier.clone()], - ); - } - - let blits = [vk::ImageBlit { - src_subresource: vk::ImageSubresourceLayers { - .create_framebuffer(&framebuffer_create_info, None) - .expect("Failed to create Framebuffer!") - }]; - - framebuffers.push(framebuffer); - } - - framebuffers -}*/ - -pub fn create_command_pool( - device: &ash::Device, - queue_families: &QueueFamilyIndices, -) -> vk::CommandPool { - let command_pool_create_info = vk::CommandPoolCreateInfo { - s_type: vk::StructureType::COMMAND_POOL_CREATE_INFO, - p_next: ptr::null(), - flags: vk::CommandPoolCreateFlags::empty(), - queue_family_index: queue_families.graphics_family.unwrap(), - }; - - unsafe { - device - .create_command_pool(&command_pool_create_info, None) - .expect("Failed to create Command Pool!") - } -} - -///createCommandBuffers in C++ -pub fn create_command_buffers( - device: &ash::Device, - command_pool: vk::CommandPool, - command_buffers: &Vec, - //graphics_pipeline: vk::Pipeline, - //framebuffers: &Vec, - //render_pass: vk::RenderPass, - //surface_extent: vk::Extent2D, -) -> Vec { - let command_buffer_allocate_info = vk::CommandBufferAllocateInfo { - s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO, - p_next: ptr::null(), - command_buffer_count: command_buffers.len() as u32, - command_pool, - level: vk::CommandBufferLevel::PRIMARY, - }; - - let command_buffers = unsafe { - device - .allocate_command_buffers(&command_buffer_allocate_info) - .expect("Failed to allocate Command Buffers!") - }; - - command_buffers -} - -/*pub fn record_command_buffer( - device: &ash::Device, - command_buffer: vk::CommandBuffer, - image_index: u32, - render_pass: vk::RenderPass, - swapchain_extent: vk::Extent2D, - shader_storage_buffers: Vec, - //shader_storage_buffers_memory: Vec, - current_frame: usize, - graphics_pipeline: vk::GraphicsPipeline, - - -) { - let command_buffer_begin_info = vk::CommandBufferBeginInfo { - s_type: vk::StructureType::COMMAND_BUFFER_BEGIN_INFO, - p_next: ptr::null(), - p_inheritance_info: ptr::null(), - flags: vk::CommandBufferUsageFlags::SIMULTANEOUS_USE, - } - - unsafe { - device - .begin_command_buffer(command_buffer, &command_buffer_begin_info) - .expect("failed to start recording command buffer") - } - let clear_values = [vk::ClearValue { - color: vk::ClearColorValue { - float32: [0.0, 0.0, 0.0, 1.0], - }, - }]; - - let render_pass_begin_info = vk::RenderPassBeginInfo { - s_type: vk::StructureType::RENDER_PASS_BEGIN_INFO, - p_next: ptr::null(), - render_pass, - framebuffer: framebuffers[i], - render_area: vk::Rect2D { - offset: vk::Offset2D { x: 0, y: 0 }, - extent: surface_extent, - }, - clear_value_count: clear_values.len() as u32, - p_clear_values: clear_values.as_ptr(), - }; - - let viewport = vec![vk::Viewport { - x: 0.0, - y: 0.0, - width: swapchain_extent.width as f32, - height: swapchain_extent.height as f32, - min_depth: 0.0, - max_depth: 1.0, - - // This create info used to debug issues in vk::createInstance and vk::destroyInstance. - let debug_utils_create_info = debug::populate_debug_messenger_create_info(); - - // VK_EXT debug report has been requested here. - let extension_names = platforms::required_extension_names(); - - let requred_validation_layer_raw_names: Vec = required_validation_layers - .iter() - .map(|layer_name| CString::new(*layer_name).unwrap()) - .collect(); - let layer_names: Vec<*const i8> = requred_validation_layer_raw_names - .iter() - .map(|layer_name| layer_name.as_ptr()) - .collect(); - - let create_info = vk::InstanceCreateInfo { - s_type: vk::StructureType::INSTANCE_CREATE_INFO, - p_next: if VALIDATION.is_enable { - &debug_utils_create_info as *const vk::DebugUtilsMessengerCreateInfoEXT as *const c_void - } else { - ptr::null() - }, - flags: vk::InstanceCreateFlags::empty(), - p_application_info: &app_info, - pp_enabled_layer_names: if is_enable_debug { - layer_names.as_ptr() - } else { - ptr::null() - }, - enabled_layer_count: if is_enable_debug { - layer_names.len() - } else { - 0 - } as u32, - pp_enabled_extension_names: extension_names.as_ptr(), - enabled_extension_count: extension_names.len() as u32, - }; - - let instance: ash::Instance = unsafe { - entry - .create_instance(&create_info, None) - .expect("Failed to create instance!") - }; - - instance -}*/ - - - - -pub fn pick_physical_device( - instance: &ash::Instance, - surface_stuff: &SurfaceStuff, - required_device_extensions: &DeviceExtension, -) -> vk::PhysicalDevice { - let physical_devices = unsafe { - instance - .enumerate_physical_devices() - .expect("Failed to enumerate Physical Devices!") - }; - - let result = physical_devices.iter().find(|physical_device| { - let is_suitable = is_physical_device_suitable( - instance, - **physical_device, - surface_stuff, - required_device_extensions, - ); - - is_suitable - }); - - match result { - Some(p_physical_device) => *p_physical_device, - None => panic!("Failed to find a suitable GPU!"), - } -} - -pub fn is_physical_device_suitable( - instance: &ash::Instance, - physical_device: vk::PhysicalDevice, - surface_stuff: &SurfaceStuff, - required_device_extensions: &DeviceExtension, -) -> bool { - let device_features = unsafe { instance.get_physical_device_features(physical_device) }; - - let indices = find_queue_family(instance, physical_device, surface_stuff); - - let is_queue_family_supported = indices.is_complete(); - let is_device_extension_supported = - check_device_extension_support(instance, physical_device, required_device_extensions); - let is_swapchain_supported = if is_device_extension_supported { - let swapchain_support = query_swapchain_support(physical_device, surface_stuff); - !swapchain_support.formats.is_empty() && !swapchain_support.present_modes.is_empty() - } else { - false - }; - let is_support_sampler_anisotropy = device_features.sampler_anisotropy == 1; - - return is_queue_family_supported - && is_device_extension_supported - && is_swapchain_supported - && is_support_sampler_anisotropy; -} - -pub fn create_logical_device( - instance: &ash::Instance, - physical_device: vk::PhysicalDevice, - validation: &super::debug::ValidationInfo, - device_extensions: &DeviceExtension, - surface_stuff: &SurfaceStuff, -) -> (ash::Device, QueueFamilyIndices, vk::Queue, vk::Queue, vk::Queue) { - let indices = find_queue_family(instance, physical_device, surface_stuff); - - use std::collections::HashSet; - let mut unique_queue_families = HashSet::new(); - unique_queue_families.insert(indices.graphics_family.unwrap()); - unique_queue_families.insert(indices.present_family.unwrap()); - - let queue_priorities = [1.0_f32]; - let mut queue_create_infos = vec![]; - - for &queue_family in unique_queue_families.iter() { - queue_create_infos.push(vk::DeviceQueueCreateInfo { - s_type: vk::StructureType::DEVICE_QUEUE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::DeviceQueueCreateFlags::empty(), - queue_family_index: queue_family, - p_queue_priorities: queue_priorities.as_ptr(), - queue_count: queue_priorities.len() as u32, - }); - } - - let physical_device_features = vk::PhysicalDeviceFeatures { - sampler_anisotropy: vk::TRUE, // enable anisotropy device feature from Chapter-24. - ..Default::default() - }; - - let requred_validation_layer_raw_names: Vec = validation - .required_validation_layers - .iter() - .map(|layer_name| CString::new(*layer_name).unwrap()) - .collect(); - let _enable_layer_names: Vec<*const c_char> = requred_validation_layer_raw_names - .iter() - .map(|layer_name| layer_name.as_ptr()) - .collect(); - - let enable_extension_names = device_extensions.get_extensions_raw_names(); - - let device_create_info = vk::DeviceCreateInfo { - s_type: vk::StructureType::DEVICE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::DeviceCreateFlags::empty(), - queue_create_info_count: queue_create_infos.len() as u32, - p_queue_create_infos: queue_create_infos.as_ptr(), - enabled_extension_count: enable_extension_names.len() as u32, - pp_enabled_extension_names: enable_extension_names.as_ptr(), - p_enabled_features: &physical_device_features, - ..Default::default() - }; - - let device: ash::Device = unsafe { - instance - .create_device(physical_device, &device_create_info, None) - .expect("Failed to create logical Device!") - }; - - let graphics_queue = - unsafe { device.get_device_queue(queue_family.graphics_family.unwrap(), 0) }; - let present_queue = - unsafe { device.get_device_queue(queue_family.present_family.unwrap(), 0) }; - let compute_queue = - unsafe { device.get_device_queue(queue_family.compute_family.unwrap(), 0) }; - - (device, indices, graphics_queue, compute_queue, present_queue) -} - -//Updated from C++ to support compute -pub fn find_queue_family( - instance: &ash::Instance, - physical_device: vk::PhysicalDevice, - surface_stuff: &SurfaceStuff, -) -> QueueFamilyIndices { - let queue_families = - unsafe { instance.get_physical_device_queue_family_properties(physical_device) }; - - let mut queue_family_indices = QueueFamilyIndices::new(); - - for (i, queue_family) in queue_families.iter().enumerate() { - if queue_family.queue_count > 0 - && ( - queue_family.queue_flags.contains(vk::QueueFlags::GRAPHICS) && - queue_family.queue_flags.contains(vk::QueueFlags::COMPUTE) - ) - { - queue_family_indices.graphics_and_compute_family = Some(i); - } - - let is_present_support = unsafe { - surface_stuff - .surface_loader - .get_physical_device_surface_support( - physical_device, - i as u32, - surface_stuff.surface, - ) - .unwrap() - }; - if queue_family.queue_count > 0 && is_present_support { - queue_family_indices.present_family = Some(i); - } - - if queue_family_indices.is_complete() { - break; - } - } - - queue_family_indices -} - -pub fn check_device_extension_support( - instance: &ash::Instance, - physical_device: vk::PhysicalDevice, - device_extensions: &DeviceExtension, -) -> bool { - let available_extensions = unsafe { - instance - .enumerate_device_extension_properties(physical_device) - .expect("Failed to get device extension properties.") - }; - - let mut available_extension_names = vec![]; - - for extension in available_extensions.iter() { - let extension_name = super::tools::vk_to_string(&extension.extension_name); - - available_extension_names.push(extension_name); - } - - use std::collections::HashSet; - let mut required_extensions = HashSet::new(); - for extension in device_extensions.names.iter() { - required_extensions.insert(extension.to_string()); - } - - for extension_name in available_extension_names.iter() { - required_extensions.remove(extension_name); - } - - return required_extensions.is_empty(); -} - -pub fn query_swapchain_support( - physical_device: vk::PhysicalDevice, - surface_stuff: &SurfaceStuff, -) -> SwapChainSupportDetail { - unsafe { - let capabilities = surface_stuff - .surface_loader - .get_physical_device_surface_capabilities(physical_device, surface_stuff.surface) - .expect("Failed to query for surface capabilities."); - let formats = surface_stuff - .surface_loader - .get_physical_device_surface_formats(physical_device, surface_stuff.surface) - .expect("Failed to query for surface formats."); - let present_modes = surface_stuff - .surface_loader - .get_physical_device_surface_present_modes(physical_device, surface_stuff.surface) - .expect("Failed to query for surface present mode."); - - SwapChainSupportDetail { - capabilities, - formats, - present_modes, - } - } -} - -pub fn choose_swapchain_format( - available_formats: &Vec, -) -> vk::SurfaceFormatKHR { - for available_format in available_formats { - if available_format.format == vk::Format::B8G8R8A8_SRGB - && available_format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR - { - return available_format.clone(); - } - } - - return available_formats.first().unwrap().clone(); -} - -pub fn choose_swapchain_present_mode( - available_present_modes: &Vec, -) -> vk::PresentModeKHR { - for &available_present_mode in available_present_modes.iter() { - if available_present_mode == vk::PresentModeKHR::MAILBOX { - return available_present_mode; - } - } - - vk::PresentModeKHR::FIFO -} - -pub fn choose_swapchain_extent( - capabilities: &vk::SurfaceCapabilitiesKHR, - window: &winit::window::Window, -) -> vk::Extent2D { - if capabilities.current_extent.width != u32::max_value() { - capabilities.current_extent - } else { - use num::clamp; - - let window_size = window.inner_size(); - println!( - "\t\tInner Window Size: ({}, {})", - window_size.width, window_size.height - ); - - vk::Extent2D { - width: clamp( - window_size.width as u32, - capabilities.min_image_extent.width, - capabilities.max_image_extent.width, - ), - height: clamp( - window_size.height as u32, - capabilities.min_image_extent.height, - capabilities.max_image_extent.height, - ), - } - } -} - -pub fn create_shader_module(device: &ash::Device, code: Vec) -> vk::ShaderModule { - let shader_module_create_info = vk::ShaderModuleCreateInfo { - s_type: vk::StructureType::SHADER_MODULE_CREATE_INFO, - p_next: ptr::null(), - flags: vk::ShaderModuleCreateFlags::empty(), - code_size: code.len(), - p_code: code.as_ptr() as *const u32, - }; - - unsafe { - device - .create_shader_module(&shader_module_create_info, None) - .expect("Failed to create Shader Module!") - } -} - -pub fn create_buffer( - device: &ash::Device, - size: vk::DeviceSize, - usage: vk::BufferUsageFlags, - required_memory_properties: vk::MemoryPropertyFlags, - device_memory_properties: &vk::PhysicalDeviceMemoryProperties, -) -> (vk::Buffer, vk::DeviceMemory) { - let buffer_create_info = vk::BufferCreateInfo { - s_type: vk::StructureType::BUFFER_CREATE_INFO, - p_next: ptr::null(), - flags: vk::BufferCreateFlags::empty(), - size, - usage, - sharing_mode: vk::SharingMode::EXCLUSIVE, - queue_family_index_count: 0, - p_queue_family_indices: ptr::null(), - }; - - let buffer = unsafe { - device - .create_buffer(&buffer_create_info, None) - .expect("Failed to create Vertex Buffer") - }; - - let mem_requirements = unsafe { device.get_buffer_memory_requirements(buffer) }; - let memory_type = find_memory_type( - mem_requirements.memory_type_bits, - required_memory_properties, - device_memory_properties, - ); - - let allocate_info = vk::MemoryAllocateInfo { - s_type: vk::StructureType::MEMORY_ALLOCATE_INFO, - p_next: ptr::null(), - allocation_size: mem_requirements.size, - memory_type_index: memory_type, - }; - - let buffer_memory = unsafe { - device - .allocate_memory(&allocate_info, None) - .expect("Failed to allocate vertex buffer memory!") - }; - - unsafe { - device - .bind_buffer_memory(buffer, buffer_memory, 0) - .expect("Failed to bind Buffer"); - } - - (buffer, buffer_memory) -} - -pub fn copy_buffer( - device: &ash::Device, - submit_queue: vk::Queue, - command_pool: vk::CommandPool, - src_buffer: vk::Buffer, - dst_buffer: vk::Buffer, - size: vk::DeviceSize, - graphics_queue: vk::Queue, -) { - let command_buffer_allocate_info = vk::CommandBufferAllocateInfo { - s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO, - p_next: ptr::null(), - command_buffer_count: 1, - command_pool, - level: vk::CommandBufferLevel::PRIMARY, - }; - - unsafe { - let command_buffers = device - .allocate_command_buffers( - command_buffer_allocate_info - ); - } - - let begin_info = vk::CommandBufferBeginInfo { - s_type: StructureType::COMMAND_BUFFER_BEGIN_INFO, - flags: CommandBufferUsageFlags::ONE_TIME_SUBMIT, - ..default::Default() - }; - - unsafe { - device - .begin_command_buffer(command_buffers[0], &begin_info); - } - - let copy_region = vk::BufferCopy { - size: size, - ..default::Default() - }; - - unsafe { - device - .cmd_copy_buffer( - command_buffers[0], - src_buffer, - dst_buffer, - copy_region, - ); - - vk::end_command_buffer(command_buffers[0]); - } - - let submit_info = vk::SubmitInfo { - s_type: StructureType::SUBMIT_INFO, - command_buffer_count: 1, - p_command_buffers: command_buffers[0], - ..default::Default() - }; - - unsafe { - device - .queue_submit( - graphics_queue, - submit_info, - Fence::null(), - ); - - device - .queue_wait_idle( - graphics_queue - ); - - device - .free_command_buffers(command_pool, command_buffers); - } -} - -pub fn begin_single_time_command( - device: &ash::Device, - command_pool: vk::CommandPool, -) -> vk::CommandBuffer { - let command_buffer_allocate_info = vk::CommandBufferAllocateInfo { - s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO, - p_next: ptr::null(), - command_buffer_count: 1, - command_pool, - level: vk::CommandBufferLevel::PRIMARY, - }; - - let command_buffer = unsafe { - device - .allocate_command_buffers(&command_buffer_allocate_info) - .expect("Failed to allocate Command Buffers!") - }[0]; - - let command_buffer_begin_info = vk::CommandBufferBeginInfo { - s_type: vk::StructureType::COMMAND_BUFFER_BEGIN_INFO, - p_next: ptr::null(), - p_inheritance_info: ptr::null(), - flags: vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT, - }; - - unsafe { - device - .begin_command_buffer(command_buffer, &command_buffer_begin_info) - .expect("Failed to begin recording Command Buffer at beginning!"); - } - - command_buffer -} - -pub fn end_single_time_command( - device: &ash::Device, - command_pool: vk::CommandPool, - submit_queue: vk::Queue, - command_buffer: vk::CommandBuffer, -) { - unsafe { - device - .end_command_buffer(command_buffer) - .expect("Failed to record Command Buffer at Ending!"); - } - - let buffers_to_submit = [command_buffer]; - - let sumbit_infos = [vk::SubmitInfo { - s_type: vk::StructureType::SUBMIT_INFO, - p_next: ptr::null(), - wait_semaphore_count: 0, - p_wait_semaphores: ptr::null(), - p_wait_dst_stage_mask: ptr::null(), - command_buffer_count: 1, - p_command_buffers: buffers_to_submit.as_ptr(), - signal_semaphore_count: 0, - p_signal_semaphores: ptr::null(), - }]; - - unsafe { - device - .queue_submit(submit_queue, &sumbit_infos, vk::Fence::null()) - .expect("Failed to Queue Submit!"); - device - .queue_wait_idle(submit_queue) - .expect("Failed to wait Queue idle!"); - device.free_command_buffers(command_pool, &buffers_to_submit); - } -} - -pub fn find_memory_type( - type_filter: u32, - required_properties: vk::MemoryPropertyFlags, - mem_properties: &vk::PhysicalDeviceMemoryProperties, -) -> u32 { - for (i, memory_type) in mem_properties.memory_types.iter().enumerate() { - if (type_filter & (1 << i)) > 0 && memory_type.property_flags.contains(required_properties) - { - return i as u32; - } - } - - panic!("Failed to find suitable memory type!") -} - -pub fn has_stencil_component(format: vk::Format) -> bool { - format == vk::Format::D32_SFLOAT_S8_UINT || format == vk::Format::D24_UNORM_S8_UINT -} - -pub fn copy_buffer_to_image( - device: &ash::Device, - command_pool: vk::CommandPool, - submit_queue: vk::Queue, - buffer: vk::Buffer, - image: vk::Image, - width: u32, - height: u32, -) { - let command_buffer = begin_single_time_command(device, command_pool); - - let buffer_image_regions = [vk::BufferImageCopy { - image_subresource: vk::ImageSubresourceLayers { - aspect_mask: vk::ImageAspectFlags::COLOR, - mip_level: 0, - base_array_layer: 0, - layer_count: 1, - }, - image_extent: vk::Extent3D { - width, - height, - depth: 1, - }, - buffer_offset: 0, - buffer_image_height: 0, - buffer_row_length: 0, - image_offset: vk::Offset3D { x: 0, y: 0, z: 0 }, - }]; - - unsafe { - device.cmd_copy_buffer_to_image( - command_buffer, - buffer, - image, - vk::ImageLayout::TRANSFER_DST_OPTIMAL, - &buffer_image_regions, - ); - } - - end_single_time_command(device, command_pool, submit_queue, command_buffer); -} - -/*pub fn find_depth_format( - instance: &ash::Instance, - physical_device: vk::PhysicalDevice, -) -> vk::Format { - find_supported_format( - instance, - physical_device, - &[ - vk::Format::D32_SFLOAT, - vk::Format::D32_SFLOAT_S8_UINT - ], - .create_framebuffer(&framebuffer_create_info, None) - .expect("Failed to create Framebuffer!") - ); - - framebuffers.push(framebuffer); - } - - framebuffers -} - -pub fn find_supported_format( - instance: &ash::Instance, - physical_device: vk::PhysicalDevice, - candidate_formats: &[vk::Format], - tiling: vk::ImageTiling, - features: vk::FormatFeatureFlags, -) -> vk::Format { - for &format in candidate_formats.iter() { - let format_properties = - unsafe { instance.get_physical_device_format_properties(physical_device, format) }; - if tiling == vk::ImageTiling::LINEAR - && format_properties.linear_tiling_features.contains(features) - { - return format.clone(); - } else if tiling == vk::ImageTiling::OPTIMAL - && format_properties.optimal_tiling_features.contains(features) - { - return format.clone(); - } - } - - panic!("Failed to find supported format!") -}*/ - -pub fn create_command_pool( - device: &ash::Device, - queue_families: &QueueFamilyIndices, -) -> vk::CommandPool { - let command_pool_create_info = vk::CommandPoolCreateInfo { - s_type: vk::StructureType::COMMAND_POOL_CREATE_INFO, - p_next: ptr::null(), - flags: vk::CommandPoolCreateFlags::empty(), - queue_family_index: queue_families.graphics_family.unwrap(), - }; - - unsafe { - device - .create_command_pool(&command_pool_create_info, None) - .expect("Failed to create Command Pool!") - } -} - -///createCommandBuffers in C++ -pub fn create_command_buffers( - device: &ash::Device, - command_pool: vk::CommandPool, - command_buffers: &Vec, - //graphics_pipeline: vk::Pipeline, - //framebuffers: &Vec, - //render_pass: vk::RenderPass, - //surface_extent: vk::Extent2D, -) -> Vec { - let command_buffer_allocate_info = vk::CommandBufferAllocateInfo { - s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO, - p_next: ptr::null(), - command_buffer_count: command_buffers.len() as u32, - command_pool, - level: vk::CommandBufferLevel::PRIMARY, - }; - - let command_buffers = unsafe { - device - .allocate_command_buffers(&command_buffer_allocate_info) - .expect("Failed to allocate Command Buffers!") - }; - - command_buffers -} - -pub fn record_command_buffer( - device: &ash::Device, - command_buffer: vk::CommandBuffer, - image_index: u32, - render_pass: vk::RenderPass, - swapchain_extent: vk::Extent2D, - shader_storage_buffers: Vec, - //shader_storage_buffers_memory: Vec, - current_frame: usize, - graphics_pipeline: vk::GraphicsPipeline, - - -) { - let command_buffer_begin_info = vk::CommandBufferBeginInfo { - s_type: vk::StructureType::COMMAND_BUFFER_BEGIN_INFO, - p_next: ptr::null(), - p_inheritance_info: ptr::null(), - flags: vk::CommandBufferUsageFlags::SIMULTANEOUS_USE, - } - - unsafe { - device - .begin_command_buffer(command_buffer, &command_buffer_begin_info) - .expect("failed to start recording command buffer") - } - let clear_color = [vk::ClearValue { - color: vk::ClearColorValue { - float32: [0.0, 0.0, 0.0, 1.0], - }, - }]; - - let render_pass_begin_info = vk::RenderPassBeginInfo { - s_type: vk::StructureType::RENDER_PASS_BEGIN_INFO, - p_next: ptr::null(), - render_pass, - framebuffer: framebuffers[i], - render_area: vk::Rect2D { - offset: vk::Offset2D { x: 0, y: 0 }, - extent: surface_extent, - }, - clear_value_count: clear_color.len() as u32, - p_clear_values: clear_color.as_ptr(), - }; - - unsafe { - device - .cmd_begin_render_pass( - command_buffer, - &render_pass_begin_info, - vk::SubPassContents::INLINE, - ); - - device - .cmd_bind_pipeline( - command_buffer, - vk::PipelineBindPoint::GRAPHICS, - graphics_pipeline, - ); - } - - let viewport = vec![vk::Viewport { - x: 0.0, - y: 0.0, - width: swapchain_extent.width as f32, - height: swapchain_extent.height as f32, - min_depth: 0.0, - max_depth: 1.0, - }]; - - unsafe { - device - .cmd_set_viewport( - command_buffer, - 0, - viewport, - ); - } - - let scissor = vec![vk::Rect2D { - offset: vk::Offset2D { x: 0, y: 0 }, - extent: swapchain_extent, - }]; - - unsafe { - device - .cmd_set_scissor( - command_buffer, - 0, - &scissor - ); - } - - let offsets = 0 as vk::DeviceSize; - - unsafe { - device - .cmd_bind_vertex_buffers( - command_buffer, - 0, - shader_storage_buffers[current_frame], - offsets, - ); - device - .cmd_draw( - command_buffer, - PARTICLE_COUNT, - 1, - 0, - 0, - ); - device - .cmd_end_render_pass( - command_buffer - ); - device - .end_command_buffer(command_buffer) - .expect("failed to end command buffer"); - } -} diff --git a/src/utility/structures.rs b/src/utility/structures.rs index 5058d9b..a5cc0ac 100644 --- a/src/utility/structures.rs +++ b/src/utility/structures.rs @@ -6,7 +6,8 @@ use cgmath::Matrix4; use memoffset::offset_of; use super::platforms; -use super::share::*; +use crate::render::App; +use crate::render::*; pub struct DeviceExtension { pub names: [&'static str; 1], @@ -51,7 +52,7 @@ pub struct SwapChainStuff { pub swapchain_format: vk::Format, pub swapchain_extent: vk::Extent2D, pub swapchain_imageviews: Vec, - pub swapchain_framebuffers: Vec,* + pub swapchain_framebuffers: Vec, } impl SwapChainStuff { @@ -63,11 +64,11 @@ impl SwapChainStuff { surface_stuff: &SurfaceStuff, queue_family: &QueueFamilyIndices, ) -> Self { - let swapchain_support = query_swapchain_support(physical_device, surface_stuff); + let swapchain_support = App::query_swapchain_support(physical_device, surface_stuff); let surface_format = choose_swapchain_format(&swapchain_support.formats); let present_mode = choose_swapchain_present_mode(&swapchain_support.present_modes); - let extent = choose_swapchain_extent(&swapchain_support.capabilities, window); + let extent = Self::choose_swapchain_extent(&swapchain_support.capabilities, window); let image_count = swapchain_support.capabilities.min_image_count + 1; let image_count = if swapchain_support.capabilities.max_image_count > 0 { @@ -77,7 +78,7 @@ impl SwapChainStuff { }; let (image_sharing_mode, queue_family_index_count, queue_family_indices) = - if queue_family.graphics_family != queue_family.present_family { + if queue_family.graphics_and_compute_family != queue_family.present_family { ( vk::SharingMode::CONCURRENT, 2, @@ -130,9 +131,78 @@ impl SwapChainStuff { swapchain_format: surface_format.format, swapchain_extent: extent, swapchain_images, + swapchain_imageviews: vec![], + swapchain_framebuffers: vec![], } } + + pub fn cleanup_swapchain(&self, device: &ash::Device) { + for framebuffer in &self.swapchain_framebuffers { + unsafe { + device + .destroy_framebuffer(*framebuffer, None); + } + } + + for imageview in &self.swapchain_imageviews { + unsafe{ + device + .destroy_image_view(*imageview, None) + } + } + } + + pub fn recreate_swapchain(app: &mut App) { + unsafe { + app.device + .device_wait_idle(); + } + + app.swapchain_stuff.cleanup_swapchain(&app.device); + + app.swapchain_stuff = SwapChainStuff::new( + &app.instance, + &app.device, + app.physical_device, + &app.window, + &app.surface_stuff, + &app.queue_family, + ); + + App::create_image_views(&app.device, &app.swapchain_stuff.swapchain_format, &app.swapchain_stuff.swapchain_images); + App::create_framebuffers(&app.device, app.render_pass, &app.swapchain_stuff.swapchain_imageviews, &app.swapchain_stuff.swapchain_extent); + } + + pub fn choose_swapchain_extent( + capabilities: &vk::SurfaceCapabilitiesKHR, + window: &winit::window::Window, + ) -> vk::Extent2D { + if capabilities.current_extent.width != u32::max_value() { + capabilities.current_extent + } else { + use num::clamp; + + let window_size = window.inner_size(); + println!( + "\t\tInner Window Size: ({}, {})", + window_size.width, window_size.height + ); + + vk::Extent2D { + width: clamp( + window_size.width as u32, + capabilities.min_image_extent.width, + capabilities.max_image_extent.width, + ), + height: clamp( + window_size.height as u32, + capabilities.min_image_extent.height, + capabilities.max_image_extent.height, + ), + } + } + } } pub struct SwapChainSupportDetails { @@ -219,11 +289,11 @@ impl SyncObjects { sync_objects.inflight_fences.push(inflight_fence); sync_objects - .image_available_semaphores - .push(image_available_semaphore); + .compute_finished_semaphores + .push(compute_finished_semaphore); sync_objects - .image_available_semaphores - .push(image_available_semaphore); + .compute_inflight_fences + .push(compute_inflight_fence); } } @@ -236,6 +306,13 @@ impl SyncObjects { #[repr(C)] #[derive(Clone, Debug, Copy)] pub struct UniformBufferObject { - pub delta_time = 1.0, + pub delta_time: f32, } +impl Default for UniformBufferObject { + fn default() -> Self { + UniformBufferObject { + delta_time: 1.0 + } + } +}