preparing to create app init function for computed particles, lots of errors

main
Nathan Buck 10 months ago
parent 8801d9268d
commit 7f32c3a64f

@ -0,0 +1,131 @@
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("<sfile>: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("<sfile>: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 :

@ -25,6 +25,10 @@ fn main() -> std::io::Result<()> {
shader_path_string
);
let shader_file: &OsStr = OsStr::new::<str>(shader_path_string.as_str());
println!(
"cargo:warning=compiling destination: {:?}",
shader_file
);
Command::new("glslc")
.arg("-c")
.arg(shader_path)

602
diffs

@ -0,0 +1,602 @@
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<vk::Image>,
@@ -41,14 +60,31 @@ pub struct VulkanApp {
swapchain_framebuffers: Vec<vk::Framebuffer>,
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<vk::Buffer>,
+ shader_storage_buffers_memory: Vec<vk::DeviceMemory>,
+
+ uniform_buffers: Vec<vk::Buffer>,
+ uniform_buffers_memory: Vec<vk::DeviceMemory>,
+ uniform_buffers_mapped: Vec<*mut c_void>,
+
- vertex_buffer: vk::Buffer,
- vertex_buffer_memory: vk::DeviceMemory,
+ descriptor_pool: vk::DescriptorPool,
+ compute_descriptor_sets: Vec<vk::DescriptorSet>,
command_pool: vk::CommandPool,
command_buffers: Vec<vk::CommandBuffer>,
+ compute_command_buffers: Vec<vk::CommandBuffer>,
image_available_semaphores: Vec<vk::Semaphore>,
render_finished_semaphores: Vec<vk::Semaphore>,
@@ -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<vk::Framebuffer>,
@@ -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<vk::PipelineShaderStageCreateInfo> = 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!")
- };
- }
- _ => (),
- })
- }
-}

943
rnd.rs

@ -0,0 +1,943 @@
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<vk::Image>,
swapchain_format: vk::Format,
swapchain_extent: vk::Extent2D,
swapchain_imageviews: Vec<vk::ImageView>,
swapchain_framebuffers: Vec<vk::Framebuffer>,
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<vk::Buffer>,
shader_storage_buffers_memory: Vec<vk::DeviceMemory>,
uniform_buffers: Vec<vk::Buffer>,
uniform_buffers_memory: Vec<vk::DeviceMemory>,
uniform_buffers_mapped: Vec<*mut c_void>,
descriptor_pool: vk::DescriptorPool,
compute_descriptor_sets: Vec<vk::DescriptorSet>,
command_pool: vk::CommandPool,
command_buffers: Vec<vk::CommandBuffer>,
compute_command_buffers: Vec<vk::CommandBuffer>,
image_available_semaphores: Vec<vk::Semaphore>,
render_finished_semaphores: Vec<vk::Semaphore>,
in_flight_fences: Vec<vk::Fence>,
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<vk::Framebuffer>,
render_pass: vk::RenderPass,
surface_extent: vk::Extent2D,
vertex_buffer: vk::Buffer,
) -> Vec<vk::CommandBuffer> {
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.

@ -9,7 +9,7 @@ use rand::{
use crate::utility::constants::*;
use std::f32::consts::PI;
const PARTICLE_COUNT: i32 = 1000;
pub const PARTICLE_COUNT: i32 = 1000;
#[repr(C)]
#[derive(Clone, Debug, Copy)]
@ -44,8 +44,35 @@ impl Particle {
}
res
}
pub fn get_binding_description() -> [vk::VertexInputBindingDescription; 1] {
[vk::VertexInputBindingDescription {
binding: 0,
stride: std::mem::size_of::<Particle>() 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!(Particle, pos) as u32,
},
vk::VertexInputAttributeDescription {
binding: 0,
location: 1,
format: vk::Format::R32G32B32_SFLOAT,
offset: offset_of!(Particle, color) as u32,
},
]
}
}
#[repr(C)]
#[derive(Clone, Debug, Copy)]
pub struct Vertex {

File diff suppressed because it is too large Load Diff

@ -0,0 +1,979 @@
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<vk::Image>,
swapchain_format: vk::Format,
swapchain_extent: vk::Extent2D,
swapchain_imageviews: Vec<vk::ImageView>,
swapchain_framebuffers: Vec<vk::Framebuffer>,
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<vk::Buffer>,
shader_storage_buffers_memory: Vec<vk::DeviceMemory>,
uniform_buffers: Vec<vk::Buffer>,
uniform_buffers_memory: Vec<vk::DeviceMemory>,
uniform_buffers_mapped: Vec<*mut c_void>,
descriptor_pool: vk::DescriptorPool,
compute_descriptor_sets: Vec<vk::DescriptorSet>,
command_pool: vk::CommandPool,
command_buffers: Vec<vk::CommandBuffer>,
compute_command_buffers: Vec<vk::CommandBuffer>,
image_available_semaphores: Vec<vk::Semaphore>,
render_finished_semaphores: Vec<vk::Semaphore>,
in_flight_fences: Vec<vk::Fence>,
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<vk::Framebuffer>,
render_pass: vk::RenderPass,
surface_extent: vk::Extent2D,
vertex_buffer: vk::Buffer,
) -> Vec<vk::CommandBuffer> {
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);
}
}
}

@ -4,4 +4,5 @@ pub fn shaders() -> Vec<(Vec<u8>, ShaderStageFlags)> {
vec![
(include_bytes!("../target/shaders/tri.frag.spv").to_vec(), ShaderStageFlags::FRAGMENT),
(include_bytes!("../target/shaders/tri.vert.spv").to_vec(), ShaderStageFlags::VERTEX),
(include_bytes!("../target/shaders/tri.comp.spv").to_vec(), ShaderStageFlags::COMPUTE),
]}

@ -1,21 +1,40 @@
#version 450
#extension GL_ARB_separate_shader_objects: enable
struct Particle {
vec2 position;
vec2 velocity;
vec4 color;
}
vec4 color;
};
layout (std140, binding = 1) readonly buffer ParticleSSBOIn {
Particle particlesIn[ ];
layout (binding = 0) uniform ParameterUBO {
float deltaTime;
} ubo;
layout(std140, binding = 1) readonly buffer ParticleSSBOIn {
Particle particlesIn[ ];
};
layout (std140, binding = 2) buffer ParticleSSBOOut {
Particle particlesOut[ ];
layout(std140, binding = 2) buffer ParticleSSBOOut {
Particle particlesOut[ ];
};
void main() {
particlesOut[index].position = particlesIn[index].position + particlesIn[index].velocity.xy * ubo.deltaTime;
layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
void main()
{
uint index = gl_GlobalInvocationID.x;
Particle particleIn = particlesIn[index];
particlesOut[index].position = particleIn.position + particleIn.velocity.xy * ubo.deltaTime;
particlesOut[index].velocity = particleIn.velocity;
// 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;
}
if ((particlesOut[index].position.y <= -1.0) || (particlesOut[index].position.y >= 1.0)) {
particlesOut[index].velocity.y = -particlesOut[index].velocity.y;
}
}

@ -5,4 +5,3 @@ pub mod platforms;
pub mod share;
pub mod structures;
pub mod tools;
pub mod window;

File diff suppressed because it is too large Load Diff

@ -1,8 +1,13 @@
use std::ptr;
use ash::vk;
use cgmath::Matrix4;
use memoffset::offset_of;
use super::platforms;
use super::share::*;
pub struct DeviceExtension {
pub names: [&'static str; 1],
// pub raw_names: [*const i8; 1],
@ -15,121 +20,222 @@ pub struct SurfaceStuff {
pub screen_width: u32,
pub screen_height: u32,
}
impl SurfaceStuff {
pub fn new(
entry: &ash::Entry,
instance: &ash::Instance,
window: &winit::window::Window,
screen_width: u32,
screen_height: u32,
) -> SurfaceStuff {
let surface = unsafe {
platforms::create_surface(entry, instance, window).expect("Failed to create surface.")
};
let surface_loader = ash::extensions::khr::Surface::new(entry, instance);
SurfaceStuff {
surface_loader,
surface,
screen_width,
screen_height,
}
}
}
pub struct SwapChainStuff {
pub swapchain_loader: ash::extensions::khr::Swapchain,
pub swapchain: vk::SwapchainKHR,
pub swapchain_images: Vec<vk::Image>,
pub swapchain_format: vk::Format,
pub swapchain_extent: vk::Extent2D,
pub swapchain_imageviews: Vec<vk::ImageView>,
pub swapchain_framebuffers: Vec<vk::Framebuffer>,*
}
impl SwapChainStuff {
pub fn new(
instance: &ash::Instance,
device: &ash::Device,
physical_device: vk::PhysicalDevice,
window: &winit::window::Window,
surface_stuff: &SurfaceStuff,
queue_family: &QueueFamilyIndices,
) -> Self {
let swapchain_support = 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 image_count = swapchain_support.capabilities.min_image_count + 1;
let image_count = if swapchain_support.capabilities.max_image_count > 0 {
image_count.min(swapchain_support.capabilities.max_image_count)
} else {
image_count
};
let (image_sharing_mode, queue_family_index_count, queue_family_indices) =
if queue_family.graphics_family != queue_family.present_family {
(
vk::SharingMode::CONCURRENT,
2,
vec![
queue_family.graphics_and_compute_family.unwrap(),
queue_family.present_family.unwrap(),
],
)
} else {
(vk::SharingMode::EXCLUSIVE, 0, vec![])
};
let swapchain_create_info = vk::SwapchainCreateInfoKHR {
s_type: vk::StructureType::SWAPCHAIN_CREATE_INFO_KHR,
p_next: ptr::null(),
flags: vk::SwapchainCreateFlagsKHR::empty(),
surface: surface_stuff.surface,
min_image_count: image_count,
image_color_space: surface_format.color_space,
image_format: surface_format.format,
image_extent: extent,
image_usage: vk::ImageUsageFlags::COLOR_ATTACHMENT,
image_sharing_mode,
p_queue_family_indices: queue_family_indices.as_ptr(),
queue_family_index_count,
pre_transform: swapchain_support.capabilities.current_transform,
composite_alpha: vk::CompositeAlphaFlagsKHR::OPAQUE,
present_mode,
clipped: vk::TRUE,
old_swapchain: vk::SwapchainKHR::null(),
image_array_layers: 1,
};
let swapchain_loader = ash::extensions::khr::Swapchain::new(instance, device);
let swapchain = unsafe {
swapchain_loader
.create_swapchain(&swapchain_create_info, None)
.expect("Failed to create Swapchain!")
};
let swapchain_images = unsafe {
swapchain_loader
.get_swapchain_images(swapchain)
.expect("Failed to get Swapchain Images.")
};
SwapChainStuff {
swapchain_loader,
swapchain,
swapchain_format: surface_format.format,
swapchain_extent: extent,
swapchain_images,
}
}
}
pub struct SwapChainSupportDetail {
pub struct SwapChainSupportDetails {
pub capabilities: vk::SurfaceCapabilitiesKHR,
pub formats: Vec<vk::SurfaceFormatKHR>,
pub present_modes: Vec<vk::PresentModeKHR>,
}
pub struct QueueFamilyIndices {
pub graphics_family: Option<u32>,
pub graphics_and_compute_family: Option<u32>,
pub present_family: Option<u32>,
}
impl QueueFamilyIndices {
pub fn new() -> QueueFamilyIndices {
QueueFamilyIndices {
graphics_family: None,
graphics_and_compute_family: None,
present_family: None,
}
}
pub fn is_complete(&self) -> bool {
self.graphics_family.is_some() && self.present_family.is_some()
self.graphics_and_compute_family.is_some() && self.present_family.is_some()
}
}
pub struct SyncObjects {
pub image_available_semaphores: Vec<vk::Semaphore>,
pub render_finished_semaphores: Vec<vk::Semaphore>,
pub compute_finished_semaphores: Vec<vk::Semaphore>,
pub inflight_fences: Vec<vk::Fence>,
pub compute_inflight_fences: Vec<vk::Fence>
}
#[repr(C)]
#[derive(Clone, Debug, Copy)]
pub struct UniformBufferObject {
pub model: Matrix4<f32>,
pub view: Matrix4<f32>,
pub proj: Matrix4<f32>,
}
impl SyncObjects {
//createSyncObjects in C++
pub fn new(device: &ash::Device, max_frame_in_flight: usize) -> Self {
let mut sync_objects = SyncObjects {
image_available_semaphores: vec![],
render_finished_semaphores: vec![],
compute_finished_semaphores: vec![],
inflight_fences: vec![],
compute_inflight_fences: vec![],
};
#[repr(C)]
#[derive(Clone, Debug, Copy)]
pub struct VertexV1 {
pub pos: [f32; 2],
pub color: [f32; 3],
}
impl VertexV1 {
pub fn get_binding_description() -> [vk::VertexInputBindingDescription; 1] {
[vk::VertexInputBindingDescription {
binding: 0,
stride: ::std::mem::size_of::<VertexV1>() as u32,
input_rate: vk::VertexInputRate::VERTEX,
}]
}
let semaphore_create_info = vk::SemaphoreCreateInfo {
s_type: vk::StructureType::SEMAPHORE_CREATE_INFO,
p_next: ptr::null(),
flags: vk::SemaphoreCreateFlags::empty(),
};
let fence_create_info = vk::FenceCreateInfo {
s_type: vk::StructureType::FENCE_CREATE_INFO,
p_next: ptr::null(),
flags: vk::FenceCreateFlags::SIGNALED,
};
for _ in 0..max_frame_in_flight {
unsafe {
let image_available_semaphore = device
.create_semaphore(&semaphore_create_info, None)
.expect("Failed to create Semaphore Object!");
let render_finished_semaphore = device
.create_semaphore(&semaphore_create_info, None)
.expect("Failed to create Semaphore Object!");
let inflight_fence = device
.create_fence(&fence_create_info, None)
.expect("Failed to create Fence Object!");
let compute_finished_semaphore = device
.create_semaphore(&semaphore_create_info, None)
.expect("Failed to create Semaphore Object!");
let compute_inflight_fence = device
.create_fence(&fence_create_info, None)
.expect("Failed to create Fence Object!");
sync_objects
.image_available_semaphores
.push(image_available_semaphore);
sync_objects
.render_finished_semaphores
.push(render_finished_semaphore);
sync_objects.inflight_fences.push(inflight_fence);
sync_objects
.image_available_semaphores
.push(image_available_semaphore);
sync_objects
.image_available_semaphores
.push(image_available_semaphore);
}
}
sync_objects
pub fn get_attribute_descriptions() -> [vk::VertexInputAttributeDescription; 2] {
[
vk::VertexInputAttributeDescription {
binding: 0,
location: 0,
format: vk::Format::R32G32_SFLOAT,
offset: offset_of!(VertexV1, pos) as u32,
},
vk::VertexInputAttributeDescription {
binding: 0,
location: 1,
format: vk::Format::R32G32B32_SFLOAT,
offset: offset_of!(VertexV1, color) as u32,
},
]
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct VertexV3 {
pub pos: [f32; 4],
pub color: [f32; 4],
pub tex_coord: [f32; 2],
#[derive(Clone, Debug, Copy)]
pub struct UniformBufferObject {
pub delta_time = 1.0,
}
impl VertexV3 {
pub fn get_binding_descriptions() -> [vk::VertexInputBindingDescription; 1] {
[vk::VertexInputBindingDescription {
binding: 0,
stride: ::std::mem::size_of::<Self>() as u32,
input_rate: vk::VertexInputRate::VERTEX,
}]
}
pub fn get_attribute_descriptions() -> [vk::VertexInputAttributeDescription; 3] {
[
vk::VertexInputAttributeDescription {
binding: 0,
location: 0,
format: vk::Format::R32G32B32A32_SFLOAT,
offset: offset_of!(Self, pos) as u32,
},
vk::VertexInputAttributeDescription {
binding: 0,
location: 1,
format: vk::Format::R32G32B32A32_SFLOAT,
offset: offset_of!(Self, color) as u32,
},
vk::VertexInputAttributeDescription {
binding: 0,
location: 2,
format: vk::Format::R32G32_SFLOAT,
offset: offset_of!(Self, tex_coord) as u32,
},
]
}
}

@ -1,88 +0,0 @@
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
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, delta_time: f32);
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 {
// init window stuff
let event_loop = EventLoop::new();
ProgramProc { event_loop }
}
pub fn main_loop<A: 'static + VulkanApp>(self, mut vulkan_app: A) {
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();
}
_ => (),
})
}
}
Loading…
Cancel
Save