Continue vulkan c++ tutorial
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 0s
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 0s
This commit is contained in:
parent
81e4212d8e
commit
b2d28ef408
9 changed files with 156 additions and 3 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
/target
|
||||
/.direnv
|
||||
/.direnv
|
||||
res/shaders/*.spv
|
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -490,6 +490,12 @@ dependencies = [
|
|||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.1"
|
||||
|
@ -1076,6 +1082,7 @@ dependencies = [
|
|||
"ash",
|
||||
"ash-window",
|
||||
"env_logger",
|
||||
"glob",
|
||||
"log",
|
||||
"winit",
|
||||
]
|
||||
|
|
|
@ -7,10 +7,13 @@ publish = false
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
winit = { version = "0.30", features = [ "rwh_06" ] }
|
||||
winit = { version = "0.30", features = ["rwh_06"] }
|
||||
ash = { version = "0.38", default-features = false, features = ["linked", "debug", "std"] }
|
||||
ash-window = "0.13"
|
||||
|
||||
# Log and tracing
|
||||
log = "0.4"
|
||||
env_logger = "0.11.5"
|
||||
env_logger = "0.11.5"
|
||||
|
||||
[build-dependencies]
|
||||
glob = "0.3"
|
24
build.rs
Normal file
24
build.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
for shader in glob::glob("res/shaders/*").unwrap().filter_map(Result::ok) {
|
||||
if !shader.is_file() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let shader_file_name = shader.to_str().unwrap();
|
||||
|
||||
let mut command = Command::new("glslc");
|
||||
command.arg(&shader);
|
||||
|
||||
let out_file = match shader.extension().unwrap().to_str().unwrap() {
|
||||
"vert" => shader_file_name.replace(".vert", ".vert.spv"),
|
||||
"frag" => shader_file_name.replace(".frag", ".frag.spv"),
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
command.arg("-o");
|
||||
command.arg(out_file);
|
||||
command.output().unwrap();
|
||||
}
|
||||
}
|
8
res/shaders/main.frag
Normal file
8
res/shaders/main.frag
Normal file
|
@ -0,0 +1,8 @@
|
|||
#version 450
|
||||
|
||||
layout (location = 0) in vec3 fragColor;
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
void main() {
|
||||
outColor = vec4(fragColor, 1.0);
|
||||
}
|
1
res/shaders/main.vert
Normal file
1
res/shaders/main.vert
Normal file
|
@ -0,0 +1 @@
|
|||
#version 450
out gl_PerVertex {
vec4 gl_Position;
};
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];
}
|
|
@ -17,3 +17,4 @@ pub(self) mod vk_swapchain;
|
|||
pub use vk_swapchain::VkSwapchain;
|
||||
|
||||
mod utils;
|
||||
mod vk_shader_module;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::vulkan::vk_shader_module::VkShaderModule;
|
||||
use crate::vulkan::{VkDevice, VkInstance, VkPhysicalDevice, VkSurface, VkSwapchain};
|
||||
use ash::vk;
|
||||
use ash::vk::PrimitiveTopology;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct VkRenderContext {
|
||||
|
@ -57,6 +60,69 @@ impl VkRenderContext {
|
|||
&physical_device,
|
||||
)?);
|
||||
|
||||
let shader_entry_name = CStr::from_bytes_with_nul(b"main\0")?;
|
||||
|
||||
let vert_shader_module =
|
||||
VkShaderModule::from_spv_file(device.clone(), "res/shaders/main.vert.spv")?;
|
||||
|
||||
let vert_shader_info = vk::PipelineShaderStageCreateInfo::default()
|
||||
.module(vert_shader_module.handle)
|
||||
.name(shader_entry_name)
|
||||
.stage(vk::ShaderStageFlags::VERTEX);
|
||||
|
||||
let frag_shader_module =
|
||||
VkShaderModule::from_spv_file(device.clone(), "res/shaders/main.frag.spv")?;
|
||||
|
||||
let frag_shader_info = vk::PipelineShaderStageCreateInfo::default()
|
||||
.module(frag_shader_module.handle)
|
||||
.name(shader_entry_name)
|
||||
.stage(vk::ShaderStageFlags::FRAGMENT);
|
||||
|
||||
let shader_stage_create_infos = [vert_shader_info, frag_shader_info];
|
||||
|
||||
let vertex_input_info = vk::PipelineVertexInputStateCreateInfo::default();
|
||||
|
||||
let input_assembly = vk::PipelineInputAssemblyStateCreateInfo::default()
|
||||
.topology(PrimitiveTopology::TRIANGLE_LIST);
|
||||
|
||||
let viewport = vk::Viewport::default()
|
||||
.width(swapchain.surface_resolution.width as f32)
|
||||
.height(swapchain.surface_resolution.height as f32)
|
||||
.max_depth(1.0);
|
||||
|
||||
let scissor = vk::Rect2D::default().extent(swapchain.surface_resolution);
|
||||
|
||||
let viewport_state = vk::PipelineViewportStateCreateInfo::default()
|
||||
.viewports(&[viewport])
|
||||
.scissors(&[scissor]);
|
||||
|
||||
let rasterizer = vk::PipelineRasterizationStateCreateInfo::default()
|
||||
.polygon_mode(vk::PolygonMode::FILL)
|
||||
.cull_mode(vk::CullModeFlags::BACK)
|
||||
.front_face(vk::FrontFace::CLOCKWISE);
|
||||
|
||||
let multisampling = vk::PipelineMultisampleStateCreateInfo::default()
|
||||
.rasterization_samples(vk::SampleCountFlags::TYPE_1)
|
||||
.min_sample_shading(1.0);
|
||||
|
||||
let color_blend_attachment = vk::PipelineColorBlendAttachmentState::default()
|
||||
.color_write_mask(vk::ColorComponentFlags::RGBA);
|
||||
|
||||
let color_blending =
|
||||
vk::PipelineColorBlendStateCreateInfo::default().attachments(&[color_blend_attachment]);
|
||||
|
||||
let dynamic_state = vk::PipelineDynamicStateCreateInfo::default()
|
||||
.dynamic_states(&[vk::DynamicState::VIEWPORT, vk::DynamicState::LINE_WIDTH]);
|
||||
|
||||
let pipeline_layout_info = vk::PipelineLayoutCreateInfo::default();
|
||||
let pipeline_layout = unsafe {
|
||||
device
|
||||
.handle
|
||||
.create_pipeline_layout(&pipeline_layout_info, None)?
|
||||
};
|
||||
|
||||
unsafe { device.handle.destroy_pipeline_layout(pipeline_layout, None) };
|
||||
|
||||
// let present_queue = device.get_device_queue(0);
|
||||
//
|
||||
// let pool_create_info = vk::CommandPoolCreateInfo::default()
|
||||
|
|
42
src/vulkan/vk_shader_module.rs
Normal file
42
src/vulkan/vk_shader_module.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
use crate::vulkan::VkDevice;
|
||||
use ash::vk;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct VkShaderModule {
|
||||
device: Arc<VkDevice>,
|
||||
|
||||
pub(super) handle: vk::ShaderModule,
|
||||
}
|
||||
|
||||
impl VkShaderModule {
|
||||
pub fn from_spv_file<P: AsRef<Path>>(device: Arc<VkDevice>, path: P) -> anyhow::Result<Self> {
|
||||
let mut file = std::fs::File::open(&path)?;
|
||||
let frag_shader_str = ash::util::read_spv(&mut file)?;
|
||||
|
||||
let shader_create_info = vk::ShaderModuleCreateInfo::default().code(&frag_shader_str);
|
||||
let shader_module = unsafe {
|
||||
device
|
||||
.handle
|
||||
.create_shader_module(&shader_create_info, None)?
|
||||
};
|
||||
log::debug!(
|
||||
"Shader module created ({shader_module:?}) from {:?}",
|
||||
path.as_ref()
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
device,
|
||||
handle: shader_module,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for VkShaderModule {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.device.handle.destroy_shader_module(self.handle, None);
|
||||
log::debug!("Shader module destroyed ({:?})", self.handle);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue