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!") - }; - } - _ => (), - }) - } -}