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;
|
||||
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,
|
||||
};
|
||||
|
||||
@ -42,6 +42,7 @@ impl App {
|
||||
|
||||
create_swapchain(window, &instance, &device, &mut data)?;
|
||||
create_swapchain_image_views(&device, &mut data)?;
|
||||
create_render_pass(&instance, &device, &mut data)?;
|
||||
create_pipeline(&device, &mut data)?;
|
||||
|
||||
Ok(Self {
|
||||
@ -59,6 +60,9 @@ impl App {
|
||||
|
||||
/// Destroys our Vulkan app.
|
||||
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
|
||||
.swapchain_image_views
|
||||
.iter()
|
||||
@ -93,6 +97,8 @@ pub struct AppData {
|
||||
swapchain: vk::SwapchainKHR,
|
||||
swapchain_images: Vec<vk::Image>,
|
||||
swapchain_image_views: Vec<vk::ImageView>,
|
||||
render_pass: vk::RenderPass,
|
||||
pipeline_layout: vk::PipelineLayout,
|
||||
}
|
||||
|
||||
impl AppData {}
|
||||
|
@ -32,6 +32,10 @@ extern "system" fn debug_callback(
|
||||
vk::FALSE
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Physical Device
|
||||
//================================================
|
||||
|
||||
pub(super) unsafe fn create_instance(
|
||||
window: &Window,
|
||||
entry: &Entry,
|
||||
@ -168,6 +172,10 @@ unsafe fn check_physical_device_extensions(
|
||||
}
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Logical Device
|
||||
//================================================
|
||||
|
||||
pub(super) unsafe fn create_logical_device(
|
||||
instance: &Instance,
|
||||
data: &mut AppData,
|
||||
@ -230,45 +238,9 @@ pub(super) unsafe fn create_logical_device(
|
||||
Ok(device)
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
//================================================
|
||||
// Swapchain
|
||||
//================================================
|
||||
|
||||
pub(super) unsafe fn create_swapchain(
|
||||
window: &Window,
|
||||
@ -323,6 +295,46 @@ pub(super) unsafe fn create_swapchain(
|
||||
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(
|
||||
device: &Device,
|
||||
data: &mut AppData,
|
||||
@ -358,6 +370,45 @@ pub(super) unsafe fn create_swapchain_image_views(
|
||||
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<()> {
|
||||
let vert = include_bytes!("../../shaders/vert.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)
|
||||
.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(frag_shader_module, None);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user