Create pipeline and shader modules
This commit is contained in:
parent
cc941caa71
commit
6f9d56d370
8
justfile
Normal file
8
justfile
Normal file
@ -0,0 +1,8 @@
|
||||
# Lists the available actions
|
||||
default:
|
||||
@just --list
|
||||
|
||||
# Convert the human-readable shader code to Vulkan bytecode
|
||||
compile-shaders:
|
||||
glslc shaders/shader.vert -o shaders/vert.spv
|
||||
glslc shaders/shader.frag -o shaders/frag.spv
|
BIN
shaders/frag.spv
Normal file
BIN
shaders/frag.spv
Normal file
Binary file not shown.
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];
|
||||
}
|
BIN
shaders/vert.spv
Normal file
BIN
shaders/vert.spv
Normal file
Binary file not shown.
17
src/app.rs
17
src/app.rs
@ -1,7 +1,7 @@
|
||||
mod functions;
|
||||
use functions::{
|
||||
create_instance, create_logical_device, create_swapchain, create_swapchain_image_views,
|
||||
pick_physical_device,
|
||||
create_instance, create_logical_device, create_pipeline, create_swapchain,
|
||||
create_swapchain_image_views, pick_physical_device,
|
||||
};
|
||||
|
||||
use crate::VALIDATION_ENABLED;
|
||||
@ -32,13 +32,17 @@ impl App {
|
||||
pub unsafe fn create(window: &Window) -> Result<Self> {
|
||||
let loader = LibloadingLoader::new(LIBRARY)?;
|
||||
let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?;
|
||||
|
||||
let mut data = AppData::default();
|
||||
let instance = create_instance(window, &entry, &mut data)?;
|
||||
data.surface = vk_window::create_surface(&instance, window)?;
|
||||
|
||||
pick_physical_device(&instance, &mut data)?;
|
||||
let device = create_logical_device(&instance, &mut data)?;
|
||||
|
||||
create_swapchain(window, &instance, &device, &mut data)?;
|
||||
create_swapchain_image_views(&device, &mut data)?;
|
||||
create_pipeline(&device, &mut data)?;
|
||||
|
||||
Ok(Self {
|
||||
entry,
|
||||
@ -61,13 +65,13 @@ impl App {
|
||||
.for_each(|v| self.device.destroy_image_view(*v, None));
|
||||
self.device.destroy_swapchain_khr(self.data.swapchain, None);
|
||||
self.device.destroy_device(None);
|
||||
self.instance.destroy_surface_khr(self.data.surface, None);
|
||||
|
||||
if VALIDATION_ENABLED {
|
||||
self.instance
|
||||
.destroy_debug_utils_messenger_ext(self.data.messenger, None);
|
||||
}
|
||||
|
||||
self.instance.destroy_surface_khr(self.data.surface, None);
|
||||
self.instance.destroy_instance(None);
|
||||
}
|
||||
}
|
||||
@ -83,6 +87,7 @@ pub struct AppData {
|
||||
physical_device: vk::PhysicalDevice,
|
||||
graphics_queue: vk::Queue,
|
||||
present_queue: vk::Queue,
|
||||
// Swapchain
|
||||
swapchain_format: vk::Format,
|
||||
swapchain_extent: vk::Extent2D,
|
||||
swapchain: vk::SwapchainKHR,
|
||||
@ -90,17 +95,19 @@ pub struct AppData {
|
||||
swapchain_image_views: Vec<vk::ImageView>,
|
||||
}
|
||||
|
||||
impl AppData {}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[error("Missing {0}.")]
|
||||
pub struct SuitabilityError(pub &'static str);
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub(crate) struct QueueFamilyIndicies {
|
||||
pub(crate) struct QueueFamilyIndices {
|
||||
graphics: u32,
|
||||
present: u32,
|
||||
}
|
||||
|
||||
impl QueueFamilyIndicies {
|
||||
impl QueueFamilyIndices {
|
||||
unsafe fn get(
|
||||
instance: &Instance,
|
||||
data: &AppData,
|
||||
|
@ -133,12 +133,12 @@ pub(super) unsafe fn pick_physical_device(instance: &Instance, data: &mut AppDat
|
||||
Err(anyhow!("Failed to find suitable physical device."))
|
||||
}
|
||||
|
||||
pub(super) unsafe fn check_physical_device(
|
||||
unsafe fn check_physical_device(
|
||||
instance: &Instance,
|
||||
data: &AppData,
|
||||
physical_device: vk::PhysicalDevice,
|
||||
) -> Result<()> {
|
||||
QueueFamilyIndicies::get(instance, data, physical_device)?;
|
||||
QueueFamilyIndices::get(instance, data, physical_device)?;
|
||||
check_physical_device_extensions(instance, physical_device)?;
|
||||
|
||||
let support = SwapchainSupport::get(instance, data, physical_device)?;
|
||||
@ -149,7 +149,7 @@ pub(super) unsafe fn check_physical_device(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) unsafe fn check_physical_device_extensions(
|
||||
unsafe fn check_physical_device_extensions(
|
||||
instance: &Instance,
|
||||
physical_device: vk::PhysicalDevice,
|
||||
) -> Result<()> {
|
||||
@ -173,7 +173,7 @@ pub(super) unsafe fn create_logical_device(
|
||||
data: &mut AppData,
|
||||
) -> Result<Device> {
|
||||
// Queue Create Infos
|
||||
let indices = QueueFamilyIndicies::get(instance, data, data.physical_device)?;
|
||||
let indices = QueueFamilyIndices::get(instance, data, data.physical_device)?;
|
||||
|
||||
let mut unique_indices = HashSet::new();
|
||||
unique_indices.insert(indices.graphics);
|
||||
@ -230,9 +230,7 @@ pub(super) unsafe fn create_logical_device(
|
||||
Ok(device)
|
||||
}
|
||||
|
||||
pub(super) fn get_swapchain_surface_format(
|
||||
formats: &[vk::SurfaceFormatKHR],
|
||||
) -> vk::SurfaceFormatKHR {
|
||||
fn get_swapchain_surface_format(formats: &[vk::SurfaceFormatKHR]) -> vk::SurfaceFormatKHR {
|
||||
formats
|
||||
.iter()
|
||||
.cloned()
|
||||
@ -243,9 +241,7 @@ pub(super) fn get_swapchain_surface_format(
|
||||
.unwrap_or_else(|| formats[0])
|
||||
}
|
||||
|
||||
pub(super) fn get_swapchain_present_mode(
|
||||
present_modes: &[vk::PresentModeKHR],
|
||||
) -> vk::PresentModeKHR {
|
||||
fn get_swapchain_present_mode(present_modes: &[vk::PresentModeKHR]) -> vk::PresentModeKHR {
|
||||
present_modes
|
||||
.iter()
|
||||
.cloned()
|
||||
@ -253,10 +249,7 @@ pub(super) fn get_swapchain_present_mode(
|
||||
.unwrap_or(vk::PresentModeKHR::FIFO)
|
||||
}
|
||||
|
||||
pub(super) fn get_swapchain_extent(
|
||||
window: &Window,
|
||||
capabilities: vk::SurfaceCapabilitiesKHR,
|
||||
) -> vk::Extent2D {
|
||||
fn get_swapchain_extent(window: &Window, capabilities: vk::SurfaceCapabilitiesKHR) -> vk::Extent2D {
|
||||
if capabilities.current_extent.width != u32::MAX {
|
||||
capabilities.current_extent
|
||||
} else {
|
||||
@ -283,7 +276,7 @@ pub(super) unsafe fn create_swapchain(
|
||||
device: &Device,
|
||||
data: &mut AppData,
|
||||
) -> Result<()> {
|
||||
let indices = QueueFamilyIndicies::get(instance, data, data.physical_device)?;
|
||||
let indices = QueueFamilyIndices::get(instance, data, data.physical_device)?;
|
||||
let support = SwapchainSupport::get(instance, data, data.physical_device)?;
|
||||
|
||||
let surface_format = get_swapchain_surface_format(&support.formats);
|
||||
@ -364,3 +357,40 @@ pub(super) unsafe fn create_swapchain_image_views(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) unsafe fn create_pipeline(device: &Device, data: &mut AppData) -> Result<()> {
|
||||
let vert = include_bytes!("../../shaders/vert.spv");
|
||||
let frag = include_bytes!("../../shaders/frag.spv");
|
||||
|
||||
let vert_shader_module = create_shader_module(device, &vert[..])?;
|
||||
let frag_shader_module = create_shader_module(device, &frag[..])?;
|
||||
|
||||
let vert_stage = vk::PipelineShaderStageCreateInfo::builder()
|
||||
.stage(vk::ShaderStageFlags::VERTEX)
|
||||
.module(vert_shader_module)
|
||||
.name(b"main\0");
|
||||
|
||||
let frag_stage = vk::PipelineShaderStageCreateInfo::builder()
|
||||
.stage(vk::ShaderStageFlags::FRAGMENT)
|
||||
.module(frag_shader_module)
|
||||
.name(b"main\0");
|
||||
|
||||
device.destroy_shader_module(vert_shader_module, None);
|
||||
device.destroy_shader_module(frag_shader_module, None);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn create_shader_module(device: &Device, bytecode: &[u8]) -> Result<vk::ShaderModule> {
|
||||
let bytecode = Vec::<u8>::from(bytecode);
|
||||
let (prefix, code, suffix) = bytecode.align_to::<u32>();
|
||||
if !prefix.is_empty() || !suffix.is_empty() {
|
||||
return Err(anyhow!("Shader bytecode is not properly aligned."));
|
||||
}
|
||||
|
||||
let info = vk::ShaderModuleCreateInfo::builder()
|
||||
.code_size(bytecode.len())
|
||||
.code(code);
|
||||
|
||||
Ok(device.create_shader_module(&info, None)?)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user