From 5223bd4fd36a472bc2a84b82f1766238a7071e3c Mon Sep 17 00:00:00 2001 From: buckn Date: Mon, 26 Feb 2024 19:45:31 -0500 Subject: [PATCH] update, still debugging --- Cargo.toml | 2 +- Session.vim | 131 ------ build.rs | 5 + rnd.rs | 943 -------------------------------------- src/entities.rs | 34 +- src/main.rs | 9 +- src/render.rs | 533 ++++++++++----------- src/shaders/tri.comp | 9 +- src/shaders/tri.frag | 3 +- src/shaders/tri.vert | 7 +- src/utility.rs | 2 +- src/utility/structures.rs | 11 +- src/utility/window.rs | 91 ++++ 13 files changed, 382 insertions(+), 1398 deletions(-) delete mode 100644 Session.vim delete mode 100644 rnd.rs diff --git a/Cargo.toml b/Cargo.toml index fad3c19..4d7fecb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "tri" +name = "particles" version = "0.1.0" edition = "2021" diff --git a/Session.vim b/Session.vim deleted file mode 100644 index 128cb2d..0000000 --- a/Session.vim +++ /dev/null @@ -1,131 +0,0 @@ -let SessionLoad = 1 -let s:so_save = &g:so | let s:siso_save = &g:siso | setg so=0 siso=0 | setl so=-1 siso=-1 -let v:this_session=expand(":p") -silent only -silent tabonly -cd ~/bin/rs/tri -if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == '' - let s:wipebuf = bufnr('%') -endif -let s:shortmess_save = &shortmess -if &shortmess =~ 'A' - set shortmess=aoOA -else - set shortmess=aoO -endif -badd +1 ~/bin/rs/tri -badd +1 src/render.rs -badd +0 src/utility/share.rs -argglobal -%argdel -$argadd ~/bin/rs/tri -edit src/render.rs -let s:save_splitbelow = &splitbelow -let s:save_splitright = &splitright -set splitbelow splitright -wincmd _ | wincmd | -vsplit -wincmd _ | wincmd | -vsplit -2wincmd h -wincmd w -wincmd w -let &splitbelow = s:save_splitbelow -let &splitright = s:save_splitright -wincmd t -let s:save_winminheight = &winminheight -let s:save_winminwidth = &winminwidth -set winminheight=0 -set winheight=1 -set winminwidth=0 -set winwidth=1 -exe 'vert 1resize ' . ((&columns * 71 + 107) / 214) -exe 'vert 2resize ' . ((&columns * 71 + 107) / 214) -exe 'vert 3resize ' . ((&columns * 70 + 107) / 214) -argglobal -setlocal fdm=manual -setlocal fde=0 -setlocal fmr={{{,}}} -setlocal fdi=# -setlocal fdl=0 -setlocal fml=1 -setlocal fdn=20 -setlocal fen -silent! normal! zE -let &fdl = &fdl -let s:l = 61 - ((45 * winheight(0) + 40) / 81) -if s:l < 1 | let s:l = 1 | endif -keepjumps exe s:l -normal! zt -keepjumps 61 -normal! 0 -lcd ~/bin/rs/tri -wincmd w -argglobal -if bufexists(fnamemodify("~/bin/rs/tri/src/utility/share.rs", ":p")) | buffer ~/bin/rs/tri/src/utility/share.rs | else | edit ~/bin/rs/tri/src/utility/share.rs | endif -if &buftype ==# 'terminal' - silent file ~/bin/rs/tri/src/utility/share.rs -endif -setlocal fdm=manual -setlocal fde=0 -setlocal fmr={{{,}}} -setlocal fdi=# -setlocal fdl=0 -setlocal fml=1 -setlocal fdn=20 -setlocal fen -silent! normal! zE -let &fdl = &fdl -let s:l = 190 - ((53 * winheight(0) + 40) / 81) -if s:l < 1 | let s:l = 1 | endif -keepjumps exe s:l -normal! zt -keepjumps 190 -normal! 013| -lcd ~/bin/rs/tri -wincmd w -argglobal -if bufexists(fnamemodify("~/bin/rs/tri/src/utility/share.rs", ":p")) | buffer ~/bin/rs/tri/src/utility/share.rs | else | edit ~/bin/rs/tri/src/utility/share.rs | endif -if &buftype ==# 'terminal' - silent file ~/bin/rs/tri/src/utility/share.rs -endif -setlocal fdm=manual -setlocal fde=0 -setlocal fmr={{{,}}} -setlocal fdi=# -setlocal fdl=0 -setlocal fml=1 -setlocal fdn=20 -setlocal fen -silent! normal! zE -let &fdl = &fdl -let s:l = 1651 - ((36 * winheight(0) + 40) / 81) -if s:l < 1 | let s:l = 1 | endif -keepjumps exe s:l -normal! zt -keepjumps 1651 -normal! 016| -lcd ~/bin/rs/tri -wincmd w -3wincmd w -exe 'vert 1resize ' . ((&columns * 71 + 107) / 214) -exe 'vert 2resize ' . ((&columns * 71 + 107) / 214) -exe 'vert 3resize ' . ((&columns * 70 + 107) / 214) -tabnext 1 -if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal' - silent exe 'bwipe ' . s:wipebuf -endif -unlet! s:wipebuf -set winheight=1 winwidth=20 -let &shortmess = s:shortmess_save -let &winminheight = s:save_winminheight -let &winminwidth = s:save_winminwidth -let s:sx = expand(":p:r")."x.vim" -if filereadable(s:sx) - exe "source " . fnameescape(s:sx) -endif -let &g:so = s:so_save | let &g:siso = s:siso_save -set hlsearch -doautoall SessionLoadPost -unlet SessionLoad -" vim: set ft=vim : diff --git a/build.rs b/build.rs index a8ae123..43089d2 100644 --- a/build.rs +++ b/build.rs @@ -6,6 +6,11 @@ use std::process::Command; fn main() -> std::io::Result<()> { println!("building shaders..."); + //rm shader target path if it exists + if Path::new("./target/shaders").exists() { + println!("exists"); + Command::new("rm").args(["-rf", "target/shaders"]).status().unwrap(); + } //shaders path let shaders = Path::new("./src/shaders"); //shader target path diff --git a/rnd.rs b/rnd.rs deleted file mode 100644 index f1c290f..0000000 --- a/rnd.rs +++ /dev/null @@ -1,943 +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"; - -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:: - /* - createInstance(); - setupDebugMessenger(); - createSurface(); - pickPhysicalDevice(); - createLogicalDevice(); - createSwapChain(); - createImageViews(); - createRenderPass(); - createComputeDescriptorSetLayout(); - createGraphicsPipeline(); - createComputePipeline(); - createFramebuffers(); - createCommandPool(); - createShaderStorageBuffers(); - 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 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, - } - } - - 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); - 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, - - 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 { - 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); - } - - 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. diff --git a/src/entities.rs b/src/entities.rs index 8670ff8..2652996 100644 --- a/src/entities.rs +++ b/src/entities.rs @@ -8,8 +8,9 @@ use rand::{ use crate::utility::constants::*; use std::f32::consts::PI; +use std::fmt; -pub const PARTICLE_COUNT: u64 = 1; +pub const PARTICLE_COUNT: u64 = 5; #[repr(C)] #[derive(Clone, Debug, Copy)] @@ -19,6 +20,30 @@ pub struct Particle { color: (f32, f32, f32, f32), } +pub struct ParticlesList(Vec); + +impl ParticlesList { + pub fn from_vec(particles: Vec) -> ParticlesList { + ParticlesList(particles) + } +} + +impl fmt::Display for ParticlesList { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "PARTICLES, LEN IS {}\n\n", self.0.len())?; + for (i, particle) in self.0.iter().enumerate() { + write!( + f, + " Particle {{\n pos: {:?}\n vel: {:?}\n color: {:?}\n }}", + particle.pos, + particle.vel, + particle.color, + )?; + } + Ok(()) + } +} + fn normalize(vec2: (f32, f32)) -> (f32, f32) { let magnitude = (vec2.0.powi(2) + vec2.1.powi(2)).sqrt(); @@ -45,11 +70,12 @@ impl Particle { let theta = between.sample(&mut rng) * 2.0 * PI; 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); + let y = r * theta.sin() * 1000.0; + //let (x, y) = (100000.0, 0.0); res.push(Particle { pos: (x, y), - vel: vec2_scalar_mul(normalize((x, y)), 0.00025), + //vel: vec2_scalar_mul(normalize((x, y)), 0.00025), + vel: (0.0, 0.0), color: ( between.sample(&mut rng), between.sample(&mut rng), diff --git a/src/main.rs b/src/main.rs index 924b699..4447449 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,15 +5,14 @@ pub mod render; pub mod shaders; pub mod utility; -use render::{ App, ProgramProc }; +use render::{ App }; +use utility::window::*; use winit::event_loop::EventLoop; fn main() { - let program = ProgramProc { - event_loop: EventLoop::new() - }; + let program = ProgramProc::new(); - let app = App::new(); + let app = App::new(&program.event_loop); program.main_loop(app); } // ------------------------------------------------------------------------------------------- diff --git a/src/render.rs b/src/render.rs index cc1cd24..05594ef 100644 --- a/src/render.rs +++ b/src/render.rs @@ -13,6 +13,7 @@ use crate::utility::fps_limiter::*; use crate::utility::{debug, platforms}; use crate::utility::tools::*; use crate::entities::*; +use crate::VulkanApp; use crate::shaders::shaders; use std::ffi::CString; @@ -27,76 +28,6 @@ const WINDOW_TITLE: &'static str = "Template"; const IS_PAINT_FPS_COUNTER: bool = true; -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, @@ -242,7 +173,6 @@ pub fn find_memory_type( pub struct App { pub window: winit::window::Window, - pub event_loop: winit::event_loop::EventLoop<()>, // vulkan stuff pub entry: ash::Entry, @@ -317,8 +247,7 @@ pub struct App { impl App { - pub fn new() -> Self { - let event_loop = winit::event_loop::EventLoop::new(); + pub fn new(event_loop: &winit::event_loop::EventLoop<()>) -> Self { let window = init_window(&event_loop, WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT); let entry = unsafe { ash::Entry::load().unwrap() }; @@ -400,7 +329,6 @@ impl App { Self { window, - event_loop, entry, instance, @@ -455,76 +383,6 @@ impl App { } - /*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 = App::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, @@ -549,6 +407,7 @@ impl App { for (shader, stage_i) in shaders() { //check if graphics shader if stage_i == vk::ShaderStageFlags::VERTEX || stage_i == vk::ShaderStageFlags::FRAGMENT { + println!("shader stage: {:?}", stage_i); shader_modules.push( vk::PipelineShaderStageCreateInfo { s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, @@ -853,158 +712,6 @@ impl App { } } - fn draw_frame(&mut self) { - //compute submission - let mut submit_infos; - - unsafe { - self.device - .wait_for_fences( - &[self.sync_objects.compute_inflight_fences[self.current_frame]], - true, - u64::MAX, - ); - } - - self.update_uniform_buffer(self.current_frame); - - unsafe { - self.device - .reset_fences(&[self.sync_objects.compute_inflight_fences[self.current_frame]]); - - self.device - .reset_command_buffer(self.compute_command_buffers[self.current_frame], vk::CommandBufferResetFlags::empty()); - } - - self.record_compute_command_buffer(&self.device, self.compute_command_buffers[self.current_frame]); - - submit_infos = [vk::SubmitInfo { - s_type: vk::StructureType::SUBMIT_INFO, - p_next: ptr::null(), - command_buffer_count: 1, - 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() - }]; - - - unsafe { - self.device - .queue_submit( - self.compute_queue, - &submit_infos, - self.sync_objects.compute_inflight_fences[self.current_frame] - ); - } - - //graphics submission - - unsafe { - self.device - .wait_for_fences( - &[self.sync_objects.inflight_fences[self.current_frame]], - true, - u64::MAX, - ); - } - - let (image_index, _is_sub_optimal) = unsafe { - let result = self.swapchain_stuff.swapchain_loader.acquire_next_image( - self.swapchain_stuff.swapchain, - std::u64::MAX, - self.sync_objects.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 => { - SwapChainStuff::recreate_swapchain(self); - return; - } - _ => panic!("Failed to acquire Swap Chain Image!"), - }, - } - }; - - unsafe { - self.device - .reset_fences(&[self.sync_objects.inflight_fences[self.current_frame]]); - self.device - .reset_command_buffer( - self.command_buffers[self.current_frame], - vk::CommandBufferResetFlags::empty(), - ); - } - - self.record_command_buffer(self.command_buffers[self.current_frame], image_index as usize); - - - let wait_semaphores = [ - self.sync_objects.compute_finished_semaphores[self.current_frame], - self.sync_objects.image_available_semaphores[self.current_frame], - ]; - let wait_stages = [ - vk::PipelineStageFlags::VERTEX_INPUT, - vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, - ]; - - submit_infos = [vk::SubmitInfo { - s_type: vk::StructureType::SUBMIT_INFO, - wait_semaphore_count: 2, - 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[self.current_frame], - ..Default::default() - }]; - - unsafe { - self.device - .queue_submit( - self.graphics_queue, - &submit_infos, - self.sync_objects.inflight_fences[self.current_frame], - ) - .expect("failed to submit draw command buffer"); - } - - let swapchains = [self.swapchain_stuff.swapchain]; - - let present_info = vk::PresentInfoKHR { - s_type: vk::StructureType::PRESENT_INFO_KHR, - p_next: ptr::null(), - wait_semaphore_count: 1, - 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, - p_results: ptr::null_mut(), - }; - let result = unsafe { - self.swapchain_stuff.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; - 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, @@ -1013,7 +720,12 @@ impl App { ) -> (Vec, Vec) { let mut particles = Particle::gen(); - let buffer_size: u64 = std::mem::size_of::() as u64 * PARTICLE_COUNT as u64; + let mut tst: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + + let buffer_size: u64 = std::mem::size_of::() as u64 * PARTICLE_COUNT as u64; + //let buffer_size: u64 = 16; + + println!("particles count: {}, particle size: {}, buffer size: {}", PARTICLE_COUNT, std::mem::size_of::(), buffer_size as usize); let (staging_buffer, staging_buffer_memory) = Self::create_buffer( @@ -1029,7 +741,8 @@ impl App { let mut shader_storage_buffers_memory = vec![]; unsafe { - let data = device + println!("mapping device memory"); + let mut data = device .map_memory( staging_buffer_memory, 0, @@ -1037,11 +750,16 @@ impl App { vk::MemoryMapFlags::empty(), ) .expect("failed to map shader storage buffer memory"); + + println!("copying to device memory"); ptr::copy_nonoverlapping( + tst.as_mut_ptr() as *mut c_void, data, - particles.as_mut_ptr() as *mut c_void, - buffer_size as usize, + 16 as usize, ); + //print mapped memory to make sure that the buffers are copied + + println!("shader storage buffers: {}", ParticlesList::from_vec((*(data as *const Vec)).clone())); device .unmap_memory(staging_buffer_memory); @@ -1052,7 +770,8 @@ impl App { vk::BufferUsageFlags::STORAGE_BUFFER | vk::BufferUsageFlags::VERTEX_BUFFER | vk::BufferUsageFlags::TRANSFER_DST, - vk::MemoryPropertyFlags::DEVICE_LOCAL, + vk::MemoryPropertyFlags::DEVICE_LOCAL | + vk::MemoryPropertyFlags::HOST_VISIBLE, physical_device_memory_properties, ); @@ -1134,6 +853,9 @@ impl App { device.end_command_buffer(alloced_command_buffer); } + println!("src_buffer: {:?}", src_buffer); + println!("dst_buffer: {:?}", dst_buffer); + let submit_info = vk::SubmitInfo { s_type: vk::StructureType::SUBMIT_INFO, command_buffer_count: 1, @@ -1177,6 +899,7 @@ impl App { p_queue_family_indices: ptr::null(), }; + println!("actual buffer size: {}", size); let buffer = unsafe { device .create_buffer(&buffer_create_info, None) @@ -1185,6 +908,8 @@ impl App { let mem_requirements = unsafe { device.get_buffer_memory_requirements(buffer) }; + println!("memory allocation size: {}", mem_requirements.size); + let allocate_info = vk::MemoryAllocateInfo { s_type: vk::StructureType::MEMORY_ALLOCATE_INFO, p_next: ptr::null(), @@ -1349,7 +1074,7 @@ impl App { } let clear_color = [vk::ClearValue { color: vk::ClearColorValue { - float32: [1.0, 1.0, 1.0, 1.0], + float32: [0.0, 0.0, 1.0, 1.0], }, }]; @@ -1986,3 +1711,207 @@ impl App { }; } } + +impl VulkanApp for App { + + fn wait_device_idle(&self) { + unsafe { + self.device + .device_wait_idle() + .expect("Failed to wait device idle!") + }; + } + + fn resize_framebuffer(&mut self) { + self.is_framebuffer_resized = true; + } + + fn window_ref(&self) -> &winit::window::Window { + &self.window + } + + fn cleanup_swapchain(&self) { + unimplemented!(); + } + + fn recreate_swapchain(&mut self) { + SwapChainStuff::recreate_swapchain(self); + } + + fn draw_frame(&mut self) { + //log shader storage buffers with Particle positions for debugging and recording purposes + + let buffer_size: u64 = std::mem::size_of::() as u64 * PARTICLE_COUNT as u64; + + for i in 0..MAX_FRAMES_IN_FLIGHT { + unsafe{ + let data = self.device + .map_memory( + self.shader_storage_buffers_memory[i], + 0, + buffer_size, + vk::MemoryMapFlags::empty(), + ) + .expect("failed to map shader storage buffer memory"); + //println!("buffer {} data: {:?}", i, *(data as *const Vec)); + self.device + .unmap_memory(self.shader_storage_buffers_memory[i]); + } + + } + + //compute submission + let mut submit_infos; + + unsafe { + self.device + .wait_for_fences( + &[self.sync_objects.compute_inflight_fences[self.current_frame]], + true, + u64::MAX, + ); + } + + self.update_uniform_buffer(self.current_frame); + + unsafe { + self.device + .reset_fences(&[self.sync_objects.compute_inflight_fences[self.current_frame]]); + + self.device + .reset_command_buffer(self.compute_command_buffers[self.current_frame], vk::CommandBufferResetFlags::empty()); + } + + self.record_compute_command_buffer(&self.device, self.compute_command_buffers[self.current_frame]); + + submit_infos = [vk::SubmitInfo { + s_type: vk::StructureType::SUBMIT_INFO, + p_next: ptr::null(), + command_buffer_count: 1, + 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() + }]; + + + unsafe { + self.device + .queue_submit( + self.compute_queue, + &submit_infos, + self.sync_objects.compute_inflight_fences[self.current_frame] + ); + } + + //graphics submission + + unsafe { + self.device + .wait_for_fences( + &[self.sync_objects.inflight_fences[self.current_frame]], + true, + u64::MAX, + ); + } + + let (image_index, _is_sub_optimal) = unsafe { + let result = self.swapchain_stuff.swapchain_loader.acquire_next_image( + self.swapchain_stuff.swapchain, + std::u64::MAX, + self.sync_objects.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 => { + SwapChainStuff::recreate_swapchain(self); + return; + } + _ => panic!("Failed to acquire Swap Chain Image!"), + }, + } + }; + + unsafe { + self.device + .reset_fences(&[self.sync_objects.inflight_fences[self.current_frame]]); + self.device + .reset_command_buffer( + self.command_buffers[self.current_frame], + vk::CommandBufferResetFlags::empty(), + ); + } + + self.record_command_buffer(self.command_buffers[self.current_frame], image_index as usize); + + + let wait_semaphores = [ + self.sync_objects.compute_finished_semaphores[self.current_frame], + self.sync_objects.image_available_semaphores[self.current_frame], + ]; + let wait_stages = [ + vk::PipelineStageFlags::VERTEX_INPUT, + vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, + ]; + + submit_infos = [vk::SubmitInfo { + s_type: vk::StructureType::SUBMIT_INFO, + wait_semaphore_count: 2, + 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[self.current_frame], + ..Default::default() + }]; + + unsafe { + self.device + .queue_submit( + self.graphics_queue, + &submit_infos, + self.sync_objects.inflight_fences[self.current_frame], + ) + .expect("failed to submit draw command buffer"); + } + + let swapchains = [self.swapchain_stuff.swapchain]; + + let present_info = vk::PresentInfoKHR { + s_type: vk::StructureType::PRESENT_INFO_KHR, + p_next: ptr::null(), + wait_semaphore_count: 1, + 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, + p_results: ptr::null_mut(), + }; + let result = unsafe { + self.swapchain_stuff.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; + SwapChainStuff::recreate_swapchain(self); + } + + //println!("resized {}", self.is_framebuffer_resized); + + self.current_frame = (self.current_frame + 1) % MAX_FRAMES_IN_FLIGHT; + } + +} + diff --git a/src/shaders/tri.comp b/src/shaders/tri.comp index 2bff93c..1b952ae 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 { @@ -27,10 +27,11 @@ void main() Particle particleIn = particlesIn[index]; //particlesOut[index].position = particleIn.position + particleIn.velocity.xy * ubo.deltaTime; - + //particlesOut[index].position = particleIn.position + vec2(1.0, 1.0) * ubo.deltaTime; + particlesOut[index].position = vec2(100.0, 100.0); + //particlesOut[index].position = vec2(100, 100); particlesOut[index].velocity = particleIn.velocity; - - particlesOut[index].position = vec2(5, 5) + particlesOut[index].color = vec4(150.0, 150.0, 150.0, 150.0); // Flip movement at window border if ((particlesOut[index].position.x <= -1.0) || (particlesOut[index].position.x >= 1.0)) { diff --git a/src/shaders/tri.frag b/src/shaders/tri.frag index 94517ec..171eb69 100644 --- a/src/shaders/tri.frag +++ b/src/shaders/tri.frag @@ -7,5 +7,6 @@ layout(location = 0) out vec4 outColor; void main() { vec2 coord = gl_PointCoord - vec2(0.5); - outColor = vec4(fragColor, 0.5 - length(coord)); + //outColor = vec4(fragColor, 0.5 - length(coord)); + outColor = vec4(fragColor, 1.0); } diff --git a/src/shaders/tri.vert b/src/shaders/tri.vert index 9730d27..8d7930d 100644 --- a/src/shaders/tri.vert +++ b/src/shaders/tri.vert @@ -7,7 +7,8 @@ layout(location = 0) out vec3 fragColor; void main() { - gl_PointSize = 14.0; - gl_Position = vec4(inPosition.xy, 1.0, 1.0); - fragColor = inColor.rgb; + gl_PointSize = 140.0; + gl_Position = vec4(inPosition, 1.0, 1.0); + //fragColor = inColor.rgb; + fragColor = vec3(1.0, 1.0, 1.0); } diff --git a/src/utility.rs b/src/utility.rs index 0c59107..bb4003e 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 window; pub mod structures; pub mod tools; diff --git a/src/utility/structures.rs b/src/utility/structures.rs index a5cc0ac..7a2ab73 100644 --- a/src/utility/structures.rs +++ b/src/utility/structures.rs @@ -151,6 +151,11 @@ impl SwapChainStuff { .destroy_image_view(*imageview, None) } } + + unsafe { + self.swapchain_loader + .destroy_swapchain(swapchain, None) + } } pub fn recreate_swapchain(app: &mut App) { @@ -159,7 +164,7 @@ impl SwapChainStuff { .device_wait_idle(); } - app.swapchain_stuff.cleanup_swapchain(&app.device); + app.cleanup_swapchain(&app.device); app.swapchain_stuff = SwapChainStuff::new( &app.instance, @@ -170,8 +175,8 @@ impl SwapChainStuff { &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); + app.swapchain_stuff.swapchain_imageviews = App::create_image_views(&app.device, &app.swapchain_stuff.swapchain_format, &app.swapchain_stuff.swapchain_images); + app.swapchain_stuff.swapchain_framebuffers = App::create_framebuffers(&app.device, app.render_pass, &app.swapchain_stuff.swapchain_imageviews, &app.swapchain_stuff.swapchain_extent); } pub fn choose_swapchain_extent( diff --git a/src/utility/window.rs b/src/utility/window.rs index e69de29..eb59735 100644 --- a/src/utility/window.rs +++ b/src/utility/window.rs @@ -0,0 +1,91 @@ + +use winit::event::{Event, VirtualKeyCode, ElementState, KeyboardInput, WindowEvent}; +use winit::event_loop::{EventLoop, ControlFlow}; + + +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 trait VulkanApp { + fn draw_frame(&mut self); + fn recreate_swapchain(&mut self); + fn cleanup_swapchain(&self); + fn wait_device_idle(&self); + fn resize_framebuffer(&mut self); + fn window_ref(&self) -> &winit::window::Window; +} + +pub struct ProgramProc { + pub event_loop: EventLoop<()>, +} + +impl ProgramProc { + pub fn new() -> ProgramProc { + ProgramProc { event_loop: EventLoop::new() } + } + + pub fn main_loop(self, mut vulkan_app: A) { + let mut tick_counter = super::fps_limiter::FPSLimiter::new(); + + self.event_loop + .run(move |event, _, control_flow| {/*println!("evl");*/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) => { + println!("resizing framebuffer event"); + vulkan_app.wait_device_idle(); + vulkan_app.resize_framebuffer(); + } + _ => {} + }, + Event::MainEventsCleared => { + vulkan_app.window_ref().request_redraw(); + } + Event::RedrawRequested(_window_id) => { + //println!("redraw req"); + let delta_time = tick_counter.delta_time(); + vulkan_app.draw_frame(); + //println!("frame drawn!"); + + if IS_PAINT_FPS_COUNTER { + print!("FPS: {}\r", tick_counter.fps()); + } + + tick_counter.tick_frame(); + } + Event::LoopDestroyed => { + vulkan_app.wait_device_idle(); + } + _ => (), + }}) + } +} +