WIP: "Graphics pipeline basics: Shader modules"
TODO: "Graphics pipeline basics: Fixed functions" https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Fixed_functions
This commit is contained in:
parent
41dbff12c3
commit
3aa79ef21a
4 changed files with 145 additions and 0 deletions
15
build.rs
15
build.rs
|
@ -1,5 +1,6 @@
|
|||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rustc-link-lib=vulkan");
|
||||
|
@ -17,4 +18,18 @@ fn main() {
|
|||
glfw_vk_bindings
|
||||
.write_to_file(out_path.join("glfw_vk_bindings.rs"))
|
||||
.expect("Couldn't write glfw bindings!");
|
||||
|
||||
let _vert_shader_out = Command::new("glslc")
|
||||
.arg("shaders/shader.vert")
|
||||
.arg("-o")
|
||||
.arg(out_path.join("vert.spv"))
|
||||
.output()
|
||||
.expect("Should be able to compile shader.vert!");
|
||||
|
||||
let _frag_shader_out = Command::new("glslc")
|
||||
.arg("shaders/shader.frag")
|
||||
.arg("-o")
|
||||
.arg(out_path.join("frag.spv"))
|
||||
.output()
|
||||
.expect("Should be able to compile shader.frag!");
|
||||
}
|
||||
|
|
9
shaders/shader.frag
Normal file
9
shaders/shader.frag
Normal file
|
@ -0,0 +1,9 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec3 fragColor;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
void main() {
|
||||
outColor = vec4(fragColor, 1.0);
|
||||
}
|
20
shaders/shader.vert
Normal file
20
shaders/shader.vert
Normal file
|
@ -0,0 +1,20 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) out vec3 fragColor;
|
||||
|
||||
vec2 positions[3] = vec2[](
|
||||
vec2( 0.0, -0.5),
|
||||
vec2( 0.5, 0.5),
|
||||
vec2(-0.5, 0.5)
|
||||
);
|
||||
|
||||
vec3 colors[3] = vec3[](
|
||||
vec3(1.0, 0.0, 0.0),
|
||||
vec3(0.0, 1.0, 0.0),
|
||||
vec3(0.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
||||
fragColor = colors[gl_VertexIndex];
|
||||
}
|
101
src/main.rs
101
src/main.rs
|
@ -131,6 +131,27 @@ impl Default for SwapChainSupportDetails {
|
|||
}
|
||||
}
|
||||
|
||||
struct ShaderModuleWrapper {
|
||||
module: ffi::VkShaderModule,
|
||||
device: ffi::VkDevice,
|
||||
}
|
||||
|
||||
impl ShaderModuleWrapper {
|
||||
pub fn get_module(&self) -> ffi::VkShaderModule {
|
||||
self.module
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ShaderModuleWrapper {
|
||||
fn drop(&mut self) {
|
||||
if !self.module.is_null() && !self.device.is_null() {
|
||||
unsafe {
|
||||
ffi::vkDestroyShaderModule(self.device, self.module, std::ptr::null());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct VulkanApp {
|
||||
window: *mut ffi::GLFWwindow,
|
||||
vk_instance: ffi::VkInstance,
|
||||
|
@ -198,6 +219,8 @@ impl VulkanApp {
|
|||
self.create_logical_device();
|
||||
self.create_swap_chain();
|
||||
self.create_image_views();
|
||||
self.create_graphics_pipeline()
|
||||
.expect("Should be able to set up graphics pipeline");
|
||||
}
|
||||
|
||||
fn create_instance(&mut self) {
|
||||
|
@ -807,6 +830,84 @@ impl VulkanApp {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_graphics_pipeline(&mut self) -> Result<(), String> {
|
||||
let vert_shader_module = self.create_vertex_shader_module()?;
|
||||
let frag_shader_module = self.create_fragment_shader_module()?;
|
||||
|
||||
let mut vert_shader_stage_info: ffi::VkPipelineShaderStageCreateInfo =
|
||||
unsafe { std::mem::zeroed() };
|
||||
vert_shader_stage_info.sType =
|
||||
ffi::VkStructureType_VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
vert_shader_stage_info.stage = ffi::VkShaderStageFlagBits_VK_SHADER_STAGE_VERTEX_BIT;
|
||||
vert_shader_stage_info.module = vert_shader_module.get_module();
|
||||
vert_shader_stage_info.pName = "main\x00".as_ptr() as *const i8;
|
||||
|
||||
let mut frag_shader_stage_info: ffi::VkPipelineShaderStageCreateInfo =
|
||||
unsafe { std::mem::zeroed() };
|
||||
frag_shader_stage_info.sType =
|
||||
ffi::VkStructureType_VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
frag_shader_stage_info.stage = ffi::VkShaderStageFlagBits_VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
frag_shader_stage_info.module = frag_shader_module.get_module();
|
||||
frag_shader_stage_info.pName = "main\x00".as_ptr() as *const i8;
|
||||
|
||||
// TODO: Use the *_shader_stage_info structs before vert/frag_shader_module is cleaned up.
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_vertex_shader_module(&mut self) -> Result<ShaderModuleWrapper, String> {
|
||||
let vertex_shader = std::include_bytes!(concat!(env!("OUT_DIR"), "/vert.spv"));
|
||||
|
||||
let mut create_info: ffi::VkShaderModuleCreateInfo = unsafe { std::mem::zeroed() };
|
||||
create_info.sType = ffi::VkStructureType_VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
create_info.codeSize = vertex_shader.len();
|
||||
create_info.pCode = vertex_shader.as_ptr() as *const u32;
|
||||
|
||||
let mut shader_module: ffi::VkShaderModule = unsafe { std::mem::zeroed() };
|
||||
let result = unsafe {
|
||||
ffi::vkCreateShaderModule(
|
||||
self.device,
|
||||
std::ptr::addr_of!(create_info),
|
||||
std::ptr::null(),
|
||||
std::ptr::addr_of_mut!(shader_module),
|
||||
)
|
||||
};
|
||||
if result != ffi::VkResult_VK_SUCCESS {
|
||||
Err(String::from("Failed to create vertex shader module!"))
|
||||
} else {
|
||||
Ok(ShaderModuleWrapper {
|
||||
module: shader_module,
|
||||
device: self.device,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn create_fragment_shader_module(&mut self) -> Result<ShaderModuleWrapper, String> {
|
||||
let fragment_shader = std::include_bytes!(concat!(env!("OUT_DIR"), "/frag.spv"));
|
||||
|
||||
let mut create_info: ffi::VkShaderModuleCreateInfo = unsafe { std::mem::zeroed() };
|
||||
create_info.sType = ffi::VkStructureType_VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
create_info.codeSize = fragment_shader.len();
|
||||
create_info.pCode = fragment_shader.as_ptr() as *const u32;
|
||||
|
||||
let mut shader_module: ffi::VkShaderModule = unsafe { std::mem::zeroed() };
|
||||
let result = unsafe {
|
||||
ffi::vkCreateShaderModule(
|
||||
self.device,
|
||||
std::ptr::addr_of!(create_info),
|
||||
std::ptr::null(),
|
||||
std::ptr::addr_of_mut!(shader_module),
|
||||
)
|
||||
};
|
||||
if result != ffi::VkResult_VK_SUCCESS {
|
||||
Err(String::from("Failed to create fragment shader module!"))
|
||||
} else {
|
||||
Ok(ShaderModuleWrapper {
|
||||
module: shader_module,
|
||||
device: self.device,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for VulkanApp {
|
||||
|
|
Loading…
Reference in a new issue