Compare commits

..

No commits in common. '0029f3984004ab1dbf29daf02fead57edcc1d2fd' and '1d23169dcc27aa085c7efb53b99d93c9dd894b7e' have entirely different histories.

@ -5,7 +5,7 @@ edition = "2021"
[dependencies] [dependencies]
winit = "0.20.0" winit = "0.20.0"
ash = "0.37.3" ash = "0.29.0"
num = "0.2" num = "0.2"
cgmath = "0.17.0" cgmath = "0.17.0"
image = "0.22" image = "0.22"

@ -1,16 +1,18 @@
use std::process::Command;
use std::path::Path;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fs::File; use std::fs::File;
use std::io::prelude::*;
use std::io::Write; use std::io::Write;
use std::path::Path; use std::io::prelude::*;
use std::process::Command;
fn main() -> std::io::Result<()> { fn main() -> std::io::Result<()> {
println!("building shaders..."); println!("building shaders...");
//shaders path //shaders path
let shaders = Path::new("./src/shaders"); let shaders = Path::new("./src/shaders");
//shader target path //shader target path
let out = Command::new("mkdir").arg("target/shaders/").output(); let out = Command::new("mkdir")
.arg("target/shaders/")
.output();
let shader_target = Path::new("./target/shaders/"); let shader_target = Path::new("./target/shaders/");
//compile all glsl shaders //compile all glsl shaders
@ -18,48 +20,29 @@ fn main() -> std::io::Result<()> {
if let Ok(entry) = entry { if let Ok(entry) = entry {
let shader_path = entry.path(); let shader_path = entry.path();
println!("compiling shader: {:?}", shader_path); println!("compiling shader: {:?}", shader_path);
let shader_path_string: String = "./target/shaders/".to_string() let shader_path_string: String = "./target/shaders/".to_string() + shader_path.file_name().unwrap().to_str().unwrap() + ".spv";
+ shader_path.file_name().unwrap().to_str().unwrap()
+ ".spv";
let shader_file: &OsStr = OsStr::new::<str>(shader_path_string.as_str()); let shader_file: &OsStr = OsStr::new::<str>(shader_path_string.as_str());
Command::new("glslc") let out = Command::new("glslc")
.arg("-c") .arg("-c")
.arg(shader_path) .arg(shader_path)
.arg("-o") .arg("-o")
.arg(shader_file) .arg(shader_file)
.status(); .output();
} }
} }
//include all compiled shaders in shaders.rs file in src dir //include all compiled shaders in shaders.rs file in src dir
let mut txt = "use ash::vk::ShaderStageFlags;\n\n".to_string() let mut txt: String = String::new();
+ "pub fn shaders() -> Vec<(Vec<u8>, ShaderStageFlags)> {\nvec![\n"; for entry in shader_target.read_dir().expect("reading compiled shader target directory failed") {
for entry in shader_target
.read_dir()
.expect("reading compiled shader target directory failed")
{
if let Ok(entry) = entry { if let Ok(entry) = entry {
let bin_path = entry.path(); let bin_path = entry.path();
let bin_path_string = bin_path.file_name().unwrap().to_str().unwrap().to_string(); let bin_path_string = bin_path.file_name().unwrap().to_str().unwrap().to_string();
txt += &("const ".to_owned() +
let shader_type = ( &bin_path_string.replace(".spv", "").replace(".", "_").to_uppercase() +
match bin_path_string.split(".").nth(1).unwrap() { " = include_bytes!(\"../target/shaders/" +
"vert" => "VERTEX", &bin_path_string +
"frag" => "FRAGMENT", "\");\n");
"comp" => "COMPUTE",
"tesc" => "TESSELLATION_CONTROL",
"tese" => "TESSELLATION_EVALUATION",
"geom" => "GEOMETRY",
_ => panic!("unknown shader type"),
}
).to_string();
txt += &("(include_bytes!(\"../target/shaders/".to_owned()
+ &bin_path_string
+ "\").to_vec(), ShaderStageFlags::"
+ &shader_type
+ "),\n");
} }
} }
txt += "]}";
let mut file = File::create("./src/shaders.rs")?; let mut file = File::create("./src/shaders.rs")?;
file.write_all(txt.as_bytes())?; file.write_all(txt.as_bytes())?;
Ok(()) Ok(())

@ -1,21 +1,24 @@
pub mod shaders;
pub mod utility; pub mod utility;
use crate::{ use crate::{
shaders::*, utility::constants::*, utility::debug::*, utility::share, utility::structures::*, utility::constants::*,
utility::debug::*,
utility::share,
utility::structures::*,
}; };
use ash::{vk, Entry}; use ash::version::DeviceV1_0;
use ash::version::InstanceV1_0;
use ash::vk;
use memoffset::offset_of; use memoffset::offset_of;
use vk::*; use winit::event::{Event, VirtualKeyCode, ElementState, KeyboardInput, WindowEvent};
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}; use winit::event_loop::{EventLoop, ControlFlow};
use winit::event_loop::{ControlFlow, EventLoop};
use std::ffi::CString; use std::ffi::CString;
use std::ptr; use std::ptr;
// Constants // Constants
const WINDOW_TITLE: &'static str = "Template"; const WINDOW_TITLE: &'static str = "18.Vertex Buffer";
#[repr(C)] #[repr(C)]
#[derive(Clone, Debug, Copy)] #[derive(Clone, Debug, Copy)]
@ -111,11 +114,11 @@ struct VulkanApp {
impl VulkanApp { impl VulkanApp {
pub fn new(event_loop: &winit::event_loop::EventLoop<()>) -> VulkanApp { pub fn new(event_loop: &winit::event_loop::EventLoop<()>) -> VulkanApp {
let window =
utility::window::init_window(event_loop, WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT); let window = utility::window::init_window(event_loop, WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT);
// init vulkan stuff // init vulkan stuff
let entry = unsafe { Entry::load().unwrap() }; let entry = ash::Entry::new().unwrap();
let instance = share::create_instance( let instance = share::create_instance(
&entry, &entry,
WINDOW_TITLE, WINDOW_TITLE,
@ -235,9 +238,7 @@ impl VulkanApp {
p_next: ptr::null(), p_next: ptr::null(),
flags: vk::BufferCreateFlags::empty(), flags: vk::BufferCreateFlags::empty(),
size: std::mem::size_of_val(&VERTICES_DATA) as u64, size: std::mem::size_of_val(&VERTICES_DATA) as u64,
usage: vk::BufferUsageFlags::VERTEX_BUFFER usage: vk::BufferUsageFlags::VERTEX_BUFFER,
| vk::BufferUsageFlags::STORAGE_BUFFER
| vk::BufferUsageFlags::TRANSFER_DST,
sharing_mode: vk::SharingMode::EXCLUSIVE, sharing_mode: vk::SharingMode::EXCLUSIVE,
queue_family_index_count: 0, queue_family_index_count: 0,
p_queue_family_indices: ptr::null(), p_queue_family_indices: ptr::null(),
@ -410,22 +411,39 @@ impl VulkanApp {
render_pass: vk::RenderPass, render_pass: vk::RenderPass,
swapchain_extent: vk::Extent2D, swapchain_extent: vk::Extent2D,
) -> (vk::Pipeline, vk::PipelineLayout) { ) -> (vk::Pipeline, vk::PipelineLayout) {
let mut shader_modules: Vec<vk::PipelineShaderStageCreateInfo> = vec![]; let vert_shader_module = share::create_shader_module(
let main_function = CString::new("main").unwrap(); device,
for (shader, stage_i) in shaders() { include_bytes!("../target/shaders/tri.vert.spv").to_vec(),
shader_modules.push( );
vk::PipelineShaderStageCreateInfo { let frag_shader_module = share::create_shader_module(
device,
include_bytes!("../target/shaders/tri.frag.spv").to_vec(),
);
let main_function_name = CString::new("main").unwrap(); // the beginning function name in shader code.
let shader_stages = [
vk::PipelineShaderStageCreateInfo {
// Vertex Shader
s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO,
p_next: ptr::null(), p_next: ptr::null(),
flags: vk::PipelineShaderStageCreateFlags::empty(), flags: vk::PipelineShaderStageCreateFlags::empty(),
module: share::create_shader_module(device, shader), module: vert_shader_module,
p_name: main_function.as_ptr(), p_name: main_function_name.as_ptr(),
stage: stage_i, stage: vk::ShaderStageFlags::VERTEX,
p_specialization_info: ptr::null(), p_specialization_info: ptr::null(),
},
} vk::PipelineShaderStageCreateInfo {
) // Fragment Shader
} s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO,
p_next: ptr::null(),
flags: vk::PipelineShaderStageCreateFlags::empty(),
module: frag_shader_module,
p_name: main_function_name.as_ptr(),
stage: vk::ShaderStageFlags::FRAGMENT,
p_specialization_info: ptr::null(),
},
];
let binding_description = Vertex::get_binding_description(); let binding_description = Vertex::get_binding_description();
let attribute_description = Vertex::get_attribute_descriptions(); let attribute_description = Vertex::get_attribute_descriptions();
@ -526,7 +544,7 @@ impl VulkanApp {
let color_blend_attachment_states = [vk::PipelineColorBlendAttachmentState { let color_blend_attachment_states = [vk::PipelineColorBlendAttachmentState {
blend_enable: vk::FALSE, blend_enable: vk::FALSE,
color_write_mask: vk::ColorComponentFlags::RGBA, color_write_mask: vk::ColorComponentFlags::all(),
src_color_blend_factor: vk::BlendFactor::ONE, src_color_blend_factor: vk::BlendFactor::ONE,
dst_color_blend_factor: vk::BlendFactor::ZERO, dst_color_blend_factor: vk::BlendFactor::ZERO,
color_blend_op: vk::BlendOp::ADD, color_blend_op: vk::BlendOp::ADD,
@ -566,8 +584,8 @@ impl VulkanApp {
s_type: vk::StructureType::GRAPHICS_PIPELINE_CREATE_INFO, s_type: vk::StructureType::GRAPHICS_PIPELINE_CREATE_INFO,
p_next: ptr::null(), p_next: ptr::null(),
flags: vk::PipelineCreateFlags::empty(), flags: vk::PipelineCreateFlags::empty(),
stage_count: shader_modules.len() as u32, stage_count: shader_stages.len() as u32,
p_stages: shader_modules.as_ptr(), p_stages: shader_stages.as_ptr(),
p_vertex_input_state: &vertex_input_state_create_info, p_vertex_input_state: &vertex_input_state_create_info,
p_input_assembly_state: &vertex_input_assembly_state_info, p_input_assembly_state: &vertex_input_assembly_state_info,
p_tessellation_state: ptr::null(), p_tessellation_state: ptr::null(),
@ -595,9 +613,8 @@ impl VulkanApp {
}; };
unsafe { unsafe {
for shader in shader_modules { device.destroy_shader_module(vert_shader_module, None);
device.destroy_shader_module(shader.module, None) device.destroy_shader_module(frag_shader_module, None);
}
} }
(graphics_pipelines[0], pipeline_layout) (graphics_pipelines[0], pipeline_layout)
@ -806,51 +823,62 @@ impl Drop for VulkanApp {
} }
} }
impl VulkanApp { impl VulkanApp {
pub fn main_loop(mut self, event_loop: EventLoop<()>) { pub fn main_loop(mut self, event_loop: EventLoop<()>) {
let mut tick_counter = utility::fps_limiter::FPSLimiter::new(); let mut tick_counter = utility::fps_limiter::FPSLimiter::new();
event_loop.run(move |event, _, control_flow| match event { event_loop.run(move |event, _, control_flow| {
Event::WindowEvent { event, .. } => match event {
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, match event {
WindowEvent::KeyboardInput { input, .. } => match input { | Event::WindowEvent { event, .. } => {
KeyboardInput { match event {
virtual_keycode, | WindowEvent::CloseRequested => {
state,
..
} => match (virtual_keycode, state) {
(Some(VirtualKeyCode::Escape), ElementState::Pressed) => {
*control_flow = ControlFlow::Exit *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::MainEventsCleared => { },
self.window.request_redraw(); | Event::RedrawRequested(_window_id) => {
} self.draw_frame();
Event::RedrawRequested(_window_id) => {
self.draw_frame();
tick_counter.tick_frame(); tick_counter.tick_frame();
if true { if IS_PAINT_FPS_COUNTER {
print!("FPS: {}\r", tick_counter.fps()); print!("FPS: {}\r", tick_counter.fps());
} }
} },
Event::LoopDestroyed => { | Event::LoopDestroyed => {
unsafe { unsafe {
self.device self.device.device_wait_idle()
.device_wait_idle() .expect("Failed to wait device idle!")
.expect("Failed to wait device idle!") };
}; },
_ => (),
} }
_ => (),
}) })
} }
} }
fn main() { fn main() {
let event_loop = EventLoop::new(); let event_loop = EventLoop::new();
let vulkan_app = VulkanApp::new(&event_loop); let vulkan_app = VulkanApp::new(&event_loop);

@ -1,7 +1,2 @@
use ash::vk::ShaderStageFlags; const TRI_FRAG = include_bytes!("../target/shaders/tri.frag.spv");
const TRI_VERT = include_bytes!("../target/shaders/tri.vert.spv");
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),
]}

@ -1,21 +0,0 @@
#version 450
#extension GL_ARB_separate_shader_objects: enable
struct Particle {
vec2 position;
vec2 velocity;
vec4 color;
}
layout (std140, binding = 1) readonly buffer ParticleSSBOIn {
Particle particlesIn[ ];
};
layout (std140, binding = 2) buffer ParticleSSBOOut {
Particle particlesOut[ ];
};
void main() {
particlesOut[index].position = particlesIn[index].position + particlesIn[index].velocity.xy * ubo.deltaTime;
}

@ -1,12 +1,12 @@
use crate::utility::debug::ValidationInfo; use crate::utility::debug::ValidationInfo;
use crate::utility::structures::DeviceExtension; use crate::utility::structures::DeviceExtension;
use ash::vk::make_api_version; use ash::vk_make_version;
use std::os::raw::c_char; use std::os::raw::c_char;
pub const APPLICATION_VERSION: u32 = make_api_version(1, 0, 0, 0); pub const APPLICATION_VERSION: u32 = vk_make_version!(1, 0, 0);
pub const ENGINE_VERSION: u32 = make_api_version(1, 0, 0, 0); pub const ENGINE_VERSION: u32 = vk_make_version!(1, 0, 0);
pub const API_VERSION: u32 = make_api_version(1, 3, 251, 0); pub const API_VERSION: u32 = vk_make_version!(1, 0, 92);
pub const WINDOW_WIDTH: u32 = 800; pub const WINDOW_WIDTH: u32 = 800;
pub const WINDOW_HEIGHT: u32 = 600; pub const WINDOW_HEIGHT: u32 = 600;

@ -1,5 +1,5 @@
use ash::version::EntryV1_0;
use ash::vk; use ash::vk;
use vk::*;
use std::ffi::CStr; use std::ffi::CStr;
use std::os::raw::c_void; use std::os::raw::c_void;

@ -1,4 +1,5 @@
use ash::{vk, Entry, Instance}; use ash::version::{EntryV1_0, InstanceV1_0};
use ash::vk;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use ash::extensions::khr::Win32Surface; use ash::extensions::khr::Win32Surface;
@ -50,9 +51,9 @@ pub fn required_extension_names() -> Vec<*const i8> {
// create surface --------------------------------------------------------- // create surface ---------------------------------------------------------
#[cfg(all(unix, not(target_os = "android"), not(target_os = "macos")))] #[cfg(all(unix, not(target_os = "android"), not(target_os = "macos")))]
pub unsafe fn create_surface( pub unsafe fn create_surface<E: EntryV1_0, I: InstanceV1_0>(
entry: &Entry, entry: &E,
instance: &Instance, instance: &I,
window: &winit::window::Window, window: &winit::window::Window,
) -> Result<vk::SurfaceKHR, vk::Result> { ) -> Result<vk::SurfaceKHR, vk::Result> {
use std::ptr; use std::ptr;
@ -72,9 +73,9 @@ pub unsafe fn create_surface(
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub unsafe fn create_surface( pub unsafe fn create_surface<E: EntryV1_0, I: InstanceV1_0>(
entry: &Entry, entry: &E,
instance: &Instance, instance: &I,
window: &winit::window::Window, window: &winit::window::Window,
) -> Result<vk::SurfaceKHR, vk::Result> { ) -> Result<vk::SurfaceKHR, vk::Result> {
use std::mem; use std::mem;
@ -108,9 +109,9 @@ pub unsafe fn create_surface(
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub unsafe fn create_surface( pub unsafe fn create_surface<E: EntryV1_0, I: InstanceV1_0>(
entry: &Entry, entry: &E,
instance: &Instance, instance: &I,
window: &winit::window::Window, window: &winit::window::Window,
) -> Result<vk::SurfaceKHR, vk::Result> { ) -> Result<vk::SurfaceKHR, vk::Result> {
use std::os::raw::c_void; use std::os::raw::c_void;

@ -72,6 +72,216 @@ pub mod v1 {
} }
} }
pub fn create_graphics_pipeline(
device: &ash::Device,
render_pass: vk::RenderPass,
swapchain_extent: vk::Extent2D,
) -> (vk::Pipeline, vk::PipelineLayout) {
let vert_shader_module = create_shader_module(
device,
include_bytes!("../../target/shaders/tri.vert.spv").to_vec(),
);
let frag_shader_module = create_shader_module(
device,
include_bytes!("../../target/shaders/tri.frag.spv").to_vec(),
);
let main_function_name = CString::new("main").unwrap(); // the beginning function name in shader code.
let shader_stages = [
vk::PipelineShaderStageCreateInfo {
// Vertex Shader
s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO,
p_next: ptr::null(),
flags: vk::PipelineShaderStageCreateFlags::empty(),
module: vert_shader_module,
p_name: main_function_name.as_ptr(),
p_specialization_info: ptr::null(),
stage: vk::ShaderStageFlags::VERTEX,
},
vk::PipelineShaderStageCreateInfo {
// Fragment Shader
s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO,
p_next: ptr::null(),
flags: vk::PipelineShaderStageCreateFlags::empty(),
module: frag_shader_module,
p_name: main_function_name.as_ptr(),
p_specialization_info: ptr::null(),
stage: vk::ShaderStageFlags::FRAGMENT,
},
];
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: 0,
p_vertex_attribute_descriptions: ptr::null(),
vertex_binding_description_count: 0,
p_vertex_binding_descriptions: ptr::null(),
};
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(),
primitive_restart_enable: vk::FALSE,
topology: vk::PrimitiveTopology::TRIANGLE_LIST,
};
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(),
flags: vk::PipelineRasterizationStateCreateFlags::empty(),
depth_clamp_enable: vk::FALSE,
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_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::all(),
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],
};
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!")
};
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_stages.len() as u32,
p_stages: shader_stages.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,
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,
}];
let graphics_pipelines = unsafe {
device
.create_graphics_pipelines(
vk::PipelineCache::null(),
&graphic_pipeline_create_infos,
None,
)
.expect("Failed to create Graphics Pipeline!.")
};
unsafe {
device.destroy_shader_module(vert_shader_module, None);
device.destroy_shader_module(frag_shader_module, None);
}
(graphics_pipelines[0], pipeline_layout)
}
pub fn create_framebuffers( pub fn create_framebuffers(
device: &ash::Device, device: &ash::Device,
render_pass: vk::RenderPass, render_pass: vk::RenderPass,
@ -530,8 +740,7 @@ pub mod v1 {
.expect("Failed to create Texture Image!") .expect("Failed to create Texture Image!")
}; };
let image_memory_requirement = let image_memory_requirement = unsafe { device.get_image_memory_requirements(texture_image) };
unsafe { device.get_image_memory_requirements(texture_image) };
let memory_allocate_info = vk::MemoryAllocateInfo { let memory_allocate_info = vk::MemoryAllocateInfo {
s_type: vk::StructureType::MEMORY_ALLOCATE_INFO, s_type: vk::StructureType::MEMORY_ALLOCATE_INFO,
p_next: ptr::null(), p_next: ptr::null(),
@ -1162,6 +1371,9 @@ pub mod v2 {
} }
} }
use ash::version::DeviceV1_0;
use ash::version::EntryV1_0;
use ash::version::InstanceV1_0;
use ash::vk; use ash::vk;
use std::ffi::CString; use std::ffi::CString;
@ -1170,6 +1382,7 @@ use std::os::raw::c_void;
use std::path::Path; use std::path::Path;
use std::ptr; use std::ptr;
use crate::utility::constants::*; use crate::utility::constants::*;
use crate::utility::debug; use crate::utility::debug;
use crate::utility::platforms; use crate::utility::platforms;
@ -1217,7 +1430,8 @@ pub fn create_instance(
let create_info = vk::InstanceCreateInfo { let create_info = vk::InstanceCreateInfo {
s_type: vk::StructureType::INSTANCE_CREATE_INFO, s_type: vk::StructureType::INSTANCE_CREATE_INFO,
p_next: if VALIDATION.is_enable { p_next: if VALIDATION.is_enable {
&debug_utils_create_info as *const vk::DebugUtilsMessengerCreateInfoEXT as *const c_void &debug_utils_create_info as *const vk::DebugUtilsMessengerCreateInfoEXT
as *const c_void
} else { } else {
ptr::null() ptr::null()
}, },
@ -1428,7 +1642,6 @@ pub fn find_queue_family(
index as u32, index as u32,
surface_stuff.surface, surface_stuff.surface,
) )
.unwrap()
}; };
if queue_family.queue_count > 0 && is_present_support { if queue_family.queue_count > 0 && is_present_support {
queue_family_indices.present_family = Some(index); queue_family_indices.present_family = Some(index);
@ -1583,6 +1796,7 @@ pub fn create_swapchain(
pub fn choose_swapchain_format( pub fn choose_swapchain_format(
available_formats: &Vec<vk::SurfaceFormatKHR>, available_formats: &Vec<vk::SurfaceFormatKHR>,
) -> vk::SurfaceFormatKHR { ) -> vk::SurfaceFormatKHR {
for available_format in available_formats { for available_format in available_formats {
if available_format.format == vk::Format::B8G8R8A8_SRGB if available_format.format == vk::Format::B8G8R8A8_SRGB
&& available_format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR && available_format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR
@ -1615,7 +1829,8 @@ pub fn choose_swapchain_extent(
} else { } else {
use num::clamp; use num::clamp;
let window_size = window.inner_size(); let window_size = window
.inner_size();
println!( println!(
"\t\tInner Window Size: ({}, {})", "\t\tInner Window Size: ({}, {})",
window_size.width, window_size.height window_size.width, window_size.height

@ -1,5 +1,6 @@
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}; use winit::event::{Event, VirtualKeyCode, ElementState, KeyboardInput, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop}; use winit::event_loop::{EventLoop, ControlFlow};
const IS_PAINT_FPS_COUNTER: bool = true; const IS_PAINT_FPS_COUNTER: bool = true;
@ -30,6 +31,7 @@ pub struct ProgramProc {
} }
impl ProgramProc { impl ProgramProc {
pub fn new() -> ProgramProc { pub fn new() -> ProgramProc {
// init window stuff // init window stuff
let event_loop = EventLoop::new(); let event_loop = EventLoop::new();
@ -38,38 +40,42 @@ impl ProgramProc {
} }
pub fn main_loop<A: 'static + VulkanApp>(self, mut vulkan_app: A) { pub fn main_loop<A: 'static + VulkanApp>(self, mut vulkan_app: A) {
let mut tick_counter = super::fps_limiter::FPSLimiter::new(); let mut tick_counter = super::fps_limiter::FPSLimiter::new();
self.event_loop self.event_loop.run(move |event, _, control_flow| {
.run(move |event, _, control_flow| match event {
Event::WindowEvent { event, .. } => match event { match event {
WindowEvent::CloseRequested => { | Event::WindowEvent { event, .. } => {
vulkan_app.wait_device_idle(); match event {
*control_flow = ControlFlow::Exit | WindowEvent::CloseRequested => {
} vulkan_app.wait_device_idle();
WindowEvent::KeyboardInput { input, .. } => match input { *control_flow = ControlFlow::Exit
KeyboardInput { },
virtual_keycode, | WindowEvent::KeyboardInput { input, .. } => {
state, match input {
.. | KeyboardInput { virtual_keycode, state, .. } => {
} => match (virtual_keycode, state) { match (virtual_keycode, state) {
(Some(VirtualKeyCode::Escape), ElementState::Pressed) => { | (Some(VirtualKeyCode::Escape), ElementState::Pressed) => {
vulkan_app.wait_device_idle(); vulkan_app.wait_device_idle();
*control_flow = ControlFlow::Exit *control_flow = ControlFlow::Exit
},
| _ => {},
}
},
} }
_ => {}
}, },
}, | WindowEvent::Resized(_new_size) => {
WindowEvent::Resized(_new_size) => { vulkan_app.wait_device_idle();
vulkan_app.wait_device_idle(); vulkan_app.resize_framebuffer();
vulkan_app.resize_framebuffer(); },
| _ => {},
} }
_ => {}
}, },
Event::MainEventsCleared => { | Event::MainEventsCleared => {
vulkan_app.window_ref().request_redraw(); vulkan_app.window_ref().request_redraw();
} },
Event::RedrawRequested(_window_id) => { | Event::RedrawRequested(_window_id) => {
let delta_time = tick_counter.delta_time(); let delta_time = tick_counter.delta_time();
vulkan_app.draw_frame(delta_time); vulkan_app.draw_frame(delta_time);
@ -78,11 +84,14 @@ impl ProgramProc {
} }
tick_counter.tick_frame(); tick_counter.tick_frame();
} },
Event::LoopDestroyed => { | Event::LoopDestroyed => {
vulkan_app.wait_device_idle(); vulkan_app.wait_device_idle();
} },
_ => (), _ => (),
}) }
})
} }
} }

Loading…
Cancel
Save