Add fix-function pipeline steps, and set up the render pass
This commit is contained in:
parent
6f9d56d370
commit
2ea377d91f
@ -1,6 +1,6 @@
|
|||||||
mod functions;
|
mod functions;
|
||||||
use functions::{
|
use functions::{
|
||||||
create_instance, create_logical_device, create_pipeline, create_swapchain,
|
create_instance, create_logical_device, create_pipeline, create_render_pass, create_swapchain,
|
||||||
create_swapchain_image_views, pick_physical_device,
|
create_swapchain_image_views, pick_physical_device,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,6 +42,7 @@ impl App {
|
|||||||
|
|
||||||
create_swapchain(window, &instance, &device, &mut data)?;
|
create_swapchain(window, &instance, &device, &mut data)?;
|
||||||
create_swapchain_image_views(&device, &mut data)?;
|
create_swapchain_image_views(&device, &mut data)?;
|
||||||
|
create_render_pass(&instance, &device, &mut data)?;
|
||||||
create_pipeline(&device, &mut data)?;
|
create_pipeline(&device, &mut data)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -59,6 +60,9 @@ impl App {
|
|||||||
|
|
||||||
/// Destroys our Vulkan app.
|
/// Destroys our Vulkan app.
|
||||||
pub unsafe fn destroy(&mut self) {
|
pub unsafe fn destroy(&mut self) {
|
||||||
|
self.device
|
||||||
|
.destroy_pipeline_layout(self.data.pipeline_layout, None);
|
||||||
|
self.device.destroy_render_pass(self.data.render_pass, None);
|
||||||
self.data
|
self.data
|
||||||
.swapchain_image_views
|
.swapchain_image_views
|
||||||
.iter()
|
.iter()
|
||||||
@ -93,6 +97,8 @@ pub struct AppData {
|
|||||||
swapchain: vk::SwapchainKHR,
|
swapchain: vk::SwapchainKHR,
|
||||||
swapchain_images: Vec<vk::Image>,
|
swapchain_images: Vec<vk::Image>,
|
||||||
swapchain_image_views: Vec<vk::ImageView>,
|
swapchain_image_views: Vec<vk::ImageView>,
|
||||||
|
render_pass: vk::RenderPass,
|
||||||
|
pipeline_layout: vk::PipelineLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppData {}
|
impl AppData {}
|
||||||
|
@ -32,6 +32,10 @@ extern "system" fn debug_callback(
|
|||||||
vk::FALSE
|
vk::FALSE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================
|
||||||
|
// Physical Device
|
||||||
|
//================================================
|
||||||
|
|
||||||
pub(super) unsafe fn create_instance(
|
pub(super) unsafe fn create_instance(
|
||||||
window: &Window,
|
window: &Window,
|
||||||
entry: &Entry,
|
entry: &Entry,
|
||||||
@ -168,6 +172,10 @@ unsafe fn check_physical_device_extensions(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================
|
||||||
|
// Logical Device
|
||||||
|
//================================================
|
||||||
|
|
||||||
pub(super) unsafe fn create_logical_device(
|
pub(super) unsafe fn create_logical_device(
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
data: &mut AppData,
|
data: &mut AppData,
|
||||||
@ -230,45 +238,9 @@ pub(super) unsafe fn create_logical_device(
|
|||||||
Ok(device)
|
Ok(device)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_swapchain_surface_format(formats: &[vk::SurfaceFormatKHR]) -> vk::SurfaceFormatKHR {
|
//================================================
|
||||||
formats
|
// Swapchain
|
||||||
.iter()
|
//================================================
|
||||||
.cloned()
|
|
||||||
.find(|f| {
|
|
||||||
f.format == vk::Format::B8G8R8A8_SRGB
|
|
||||||
&& f.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR
|
|
||||||
})
|
|
||||||
.unwrap_or_else(|| formats[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_swapchain_present_mode(present_modes: &[vk::PresentModeKHR]) -> vk::PresentModeKHR {
|
|
||||||
present_modes
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.find(|m| *m == vk::PresentModeKHR::MAILBOX)
|
|
||||||
.unwrap_or(vk::PresentModeKHR::FIFO)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_swapchain_extent(window: &Window, capabilities: vk::SurfaceCapabilitiesKHR) -> vk::Extent2D {
|
|
||||||
if capabilities.current_extent.width != u32::MAX {
|
|
||||||
capabilities.current_extent
|
|
||||||
} else {
|
|
||||||
let size = window.inner_size();
|
|
||||||
let clamp = |min: u32, max: u32, v: u32| min.max(max.min(v));
|
|
||||||
vk::Extent2D::builder()
|
|
||||||
.width(clamp(
|
|
||||||
capabilities.min_image_extent.width,
|
|
||||||
capabilities.max_image_extent.width,
|
|
||||||
size.width,
|
|
||||||
))
|
|
||||||
.height(clamp(
|
|
||||||
capabilities.min_image_extent.height,
|
|
||||||
capabilities.max_image_extent.height,
|
|
||||||
size.height,
|
|
||||||
))
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) unsafe fn create_swapchain(
|
pub(super) unsafe fn create_swapchain(
|
||||||
window: &Window,
|
window: &Window,
|
||||||
@ -323,6 +295,46 @@ pub(super) unsafe fn create_swapchain(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_swapchain_surface_format(formats: &[vk::SurfaceFormatKHR]) -> vk::SurfaceFormatKHR {
|
||||||
|
formats
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.find(|f| {
|
||||||
|
f.format == vk::Format::B8G8R8A8_SRGB
|
||||||
|
&& f.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| formats[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_swapchain_present_mode(present_modes: &[vk::PresentModeKHR]) -> vk::PresentModeKHR {
|
||||||
|
present_modes
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.find(|m| *m == vk::PresentModeKHR::MAILBOX)
|
||||||
|
.unwrap_or(vk::PresentModeKHR::FIFO)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_swapchain_extent(window: &Window, capabilities: vk::SurfaceCapabilitiesKHR) -> vk::Extent2D {
|
||||||
|
if capabilities.current_extent.width != u32::MAX {
|
||||||
|
capabilities.current_extent
|
||||||
|
} else {
|
||||||
|
let size = window.inner_size();
|
||||||
|
let clamp = |min: u32, max: u32, v: u32| min.max(max.min(v));
|
||||||
|
vk::Extent2D::builder()
|
||||||
|
.width(clamp(
|
||||||
|
capabilities.min_image_extent.width,
|
||||||
|
capabilities.max_image_extent.width,
|
||||||
|
size.width,
|
||||||
|
))
|
||||||
|
.height(clamp(
|
||||||
|
capabilities.min_image_extent.height,
|
||||||
|
capabilities.max_image_extent.height,
|
||||||
|
size.height,
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) unsafe fn create_swapchain_image_views(
|
pub(super) unsafe fn create_swapchain_image_views(
|
||||||
device: &Device,
|
device: &Device,
|
||||||
data: &mut AppData,
|
data: &mut AppData,
|
||||||
@ -358,6 +370,45 @@ pub(super) unsafe fn create_swapchain_image_views(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================
|
||||||
|
// Pipeline
|
||||||
|
//================================================
|
||||||
|
|
||||||
|
pub(super) unsafe fn create_render_pass(
|
||||||
|
instance: &Instance,
|
||||||
|
device: &Device,
|
||||||
|
data: &mut AppData,
|
||||||
|
) -> Result<()> {
|
||||||
|
let color_attachment = vk::AttachmentDescription::builder()
|
||||||
|
.format(data.swapchain_format)
|
||||||
|
.samples(vk::SampleCountFlags::_1)
|
||||||
|
.load_op(vk::AttachmentLoadOp::CLEAR)
|
||||||
|
.store_op(vk::AttachmentStoreOp::STORE)
|
||||||
|
.stencil_load_op(vk::AttachmentLoadOp::DONT_CARE)
|
||||||
|
.stencil_store_op(vk::AttachmentStoreOp::DONT_CARE)
|
||||||
|
.initial_layout(vk::ImageLayout::UNDEFINED)
|
||||||
|
.final_layout(vk::ImageLayout::PRESENT_SRC_KHR);
|
||||||
|
|
||||||
|
// Subpasses
|
||||||
|
let color_attachment_ref = vk::AttachmentReference::builder()
|
||||||
|
.attachment(0)
|
||||||
|
.layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
let color_attachments = &[color_attachment_ref];
|
||||||
|
let subpass = vk::SubpassDescription::builder()
|
||||||
|
.pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS)
|
||||||
|
.color_attachments(color_attachments);
|
||||||
|
|
||||||
|
let attachments = &[color_attachment];
|
||||||
|
let subpasses = &[subpass];
|
||||||
|
let info = vk::RenderPassCreateInfo::builder()
|
||||||
|
.attachments(attachments)
|
||||||
|
.subpasses(subpasses);
|
||||||
|
|
||||||
|
data.render_pass = device.create_render_pass(&info, None)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) unsafe fn create_pipeline(device: &Device, data: &mut AppData) -> Result<()> {
|
pub(super) unsafe fn create_pipeline(device: &Device, data: &mut AppData) -> Result<()> {
|
||||||
let vert = include_bytes!("../../shaders/vert.spv");
|
let vert = include_bytes!("../../shaders/vert.spv");
|
||||||
let frag = include_bytes!("../../shaders/frag.spv");
|
let frag = include_bytes!("../../shaders/frag.spv");
|
||||||
@ -375,6 +426,64 @@ pub(super) unsafe fn create_pipeline(device: &Device, data: &mut AppData) -> Res
|
|||||||
.module(frag_shader_module)
|
.module(frag_shader_module)
|
||||||
.name(b"main\0");
|
.name(b"main\0");
|
||||||
|
|
||||||
|
let vertex_input_state = vk::PipelineVertexInputStateCreateInfo::builder();
|
||||||
|
|
||||||
|
let input_assembly_state = vk::PipelineInputAssemblyStateCreateInfo::builder()
|
||||||
|
.topology(vk::PrimitiveTopology::TRIANGLE_LIST)
|
||||||
|
.primitive_restart_enable(false);
|
||||||
|
|
||||||
|
let viewport = vk::Viewport::builder()
|
||||||
|
.x(0.0)
|
||||||
|
.y(0.0)
|
||||||
|
.width(data.swapchain_extent.width as f32)
|
||||||
|
.height(data.swapchain_extent.height as f32)
|
||||||
|
.min_depth(0.0)
|
||||||
|
.max_depth(1.0);
|
||||||
|
|
||||||
|
let scissor = vk::Rect2D::builder()
|
||||||
|
.offset(vk::Offset2D { x: 0, y: 0 })
|
||||||
|
.extent(data.swapchain_extent);
|
||||||
|
|
||||||
|
let viewports = &[viewport];
|
||||||
|
let scissors = &[scissor];
|
||||||
|
let viewport_state = vk::PipelineViewportStateCreateInfo::builder()
|
||||||
|
.viewports(viewports)
|
||||||
|
.scissors(scissors);
|
||||||
|
|
||||||
|
let rasterization_state = vk::PipelineRasterizationStateCreateInfo::builder()
|
||||||
|
.depth_clamp_enable(false)
|
||||||
|
.rasterizer_discard_enable(false)
|
||||||
|
.polygon_mode(vk::PolygonMode::FILL)
|
||||||
|
.line_width(1.0)
|
||||||
|
.cull_mode(vk::CullModeFlags::BACK)
|
||||||
|
.front_face(vk::FrontFace::CLOCKWISE)
|
||||||
|
.depth_bias_enable(false);
|
||||||
|
|
||||||
|
let multisample_state = vk::PipelineMultisampleStateCreateInfo::builder()
|
||||||
|
.sample_shading_enable(false)
|
||||||
|
.rasterization_samples(vk::SampleCountFlags::_1);
|
||||||
|
|
||||||
|
let attachment = vk::PipelineColorBlendAttachmentState::builder()
|
||||||
|
.color_write_mask(vk::ColorComponentFlags::all())
|
||||||
|
.blend_enable(false)
|
||||||
|
.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 attachments = &[attachment];
|
||||||
|
let color_blend_state = vk::PipelineColorBlendStateCreateInfo::builder()
|
||||||
|
.logic_op_enable(false)
|
||||||
|
.logic_op(vk::LogicOp::COPY)
|
||||||
|
.attachments(attachments)
|
||||||
|
.blend_constants([0.0, 0.0, 0.0, 0.0]);
|
||||||
|
|
||||||
|
let layout_info = vk::PipelineLayoutCreateInfo::builder();
|
||||||
|
data.pipeline_layout = device.create_pipeline_layout(&layout_info, None)?;
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
device.destroy_shader_module(vert_shader_module, None);
|
device.destroy_shader_module(vert_shader_module, None);
|
||||||
device.destroy_shader_module(frag_shader_module, None);
|
device.destroy_shader_module(frag_shader_module, None);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user