Set up depth buffering

This commit is contained in:
Timothy Warren 2023-04-19 10:55:49 -04:00
parent 0a3cd3e809
commit e88564d894
5 changed files with 176 additions and 26 deletions

View File

@ -6,7 +6,7 @@ layout(binding = 0) uniform UniformBufferObject {
mat4 proj; mat4 proj;
} ubo; } ubo;
layout(location = 0) in vec2 inPosition; layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor; layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord; layout(location = 2) in vec2 inTexCoord;
@ -14,7 +14,7 @@ layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTexCoord; layout(location = 1) out vec2 fragTexCoord;
void main() { void main() {
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0); gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
fragColor = inColor; fragColor = inColor;
fragTexCoord = inTexCoord; fragTexCoord = inTexCoord;
} }

Binary file not shown.

View File

@ -33,29 +33,49 @@ pub const MAX_FRAMES_IN_FLIGHT: usize = 2;
lazy_static! { lazy_static! {
pub static ref VERTICES: Vec<Vertex> = vec![ pub static ref VERTICES: Vec<Vertex> = vec![
Vertex::new( Vertex::new(
glm::vec2(-0.5, -0.5), glm::vec3(-0.5, -0.5, 0.0),
glm::vec3(1.0, 0.0, 0.0), glm::vec3(1.0, 0.0, 0.0),
glm::vec2(1.0, 0.0) glm::vec2(1.0, 0.0)
), ),
Vertex::new( Vertex::new(
glm::vec2(0.5, -0.5), glm::vec3(0.5, -0.5, 0.0),
glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 1.0, 0.0),
glm::vec2(0.0, 0.0) glm::vec2(0.0, 0.0)
), ),
Vertex::new( Vertex::new(
glm::vec2(0.5, 0.5), glm::vec3(0.5, 0.5, 0.0),
glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, 0.0, 1.0),
glm::vec2(0.0, 1.0) glm::vec2(0.0, 1.0)
), ),
Vertex::new( Vertex::new(
glm::vec2(-0.5, 0.5), glm::vec3(-0.5, 0.5, 0.0),
glm::vec3(1.0, 1.0, 1.0),
glm::vec2(1.0, 1.0)
),
Vertex::new(
glm::vec3(-0.5, -0.5, -0.5),
glm::vec3(1.0, 0.0, 0.0),
glm::vec2(1.0, 0.0)
),
Vertex::new(
glm::vec3(0.5, -0.5, -0.5),
glm::vec3(0.0, 1.0, 0.0),
glm::vec2(0.0, 0.0)
),
Vertex::new(
glm::vec3(0.5, 0.5, -0.5),
glm::vec3(0.0, 0.0, 1.0),
glm::vec2(0.0, 1.0)
),
Vertex::new(
glm::vec3(-0.5, 0.5, -0.5),
glm::vec3(1.0, 1.0, 1.0), glm::vec3(1.0, 1.0, 1.0),
glm::vec2(1.0, 1.0) glm::vec2(1.0, 1.0)
), ),
]; ];
} }
pub const INDICES: &[u16] = &[0, 1, 2, 2, 3, 0]; pub const INDICES: &[u16] = &[0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4];
/// Our Vulkan app. /// Our Vulkan app.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -194,7 +214,7 @@ impl App {
&glm::vec3(0.0, 0.0, 1.0), &glm::vec3(0.0, 0.0, 1.0),
); );
let mut proj = glm::perspective( let mut proj = glm::perspective_rh_zo(
self.data.swapchain_extent.width as f32 / self.data.swapchain_extent.height as f32, self.data.swapchain_extent.width as f32 / self.data.swapchain_extent.height as f32,
glm::radians(&glm::vec1(45.0))[0], glm::radians(&glm::vec1(45.0))[0],
0.1, 0.1,
@ -326,9 +346,10 @@ pub(crate) unsafe fn create_image_view(
device: &Device, device: &Device,
image: vk::Image, image: vk::Image,
format: vk::Format, format: vk::Format,
aspects: vk::ImageAspectFlags,
) -> Result<vk::ImageView> { ) -> Result<vk::ImageView> {
let subresource_range = vk::ImageSubresourceRange::builder() let subresource_range = vk::ImageSubresourceRange::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR) .aspect_mask(aspects)
.base_mip_level(0) .base_mip_level(0)
.level_count(1) .level_count(1)
.base_array_layer(0) .base_array_layer(0)

View File

@ -62,6 +62,10 @@ pub(crate) struct AppData {
framebuffers: Vec<vk::Framebuffer>, framebuffers: Vec<vk::Framebuffer>,
// Command Pool // Command Pool
command_pool: vk::CommandPool, command_pool: vk::CommandPool,
// Depth
depth_image: vk::Image,
depth_image_memory: vk::DeviceMemory,
depth_image_view: vk::ImageView,
// Texture // Texture
texture_image: vk::Image, texture_image: vk::Image,
texture_image_memory: vk::DeviceMemory, texture_image_memory: vk::DeviceMemory,
@ -107,8 +111,9 @@ impl AppData {
self.create_render_pass(&instance, &device)?; self.create_render_pass(&instance, &device)?;
self.create_descriptor_set_layout(&device)?; self.create_descriptor_set_layout(&device)?;
self.create_pipeline(&device)?; self.create_pipeline(&device)?;
self.create_framebuffers(&device)?;
self.create_command_pool(&instance, &device)?; self.create_command_pool(&instance, &device)?;
self.create_depth_objects(&instance, &device)?;
self.create_framebuffers(&device)?;
self.create_texture_image(&instance, &device)?; self.create_texture_image(&instance, &device)?;
self.create_texture_image_view(&device)?; self.create_texture_image_view(&device)?;
self.create_texture_sampler(&device)?; self.create_texture_sampler(&device)?;
@ -215,6 +220,9 @@ impl AppData {
self.uniform_buffers_memory self.uniform_buffers_memory
.iter() .iter()
.for_each(|m| device.free_memory(*m, None)); .for_each(|m| device.free_memory(*m, None));
device.destroy_image_view(self.depth_image_view, None);
device.free_memory(self.depth_image_memory, None);
device.destroy_image(self.depth_image, None);
self.framebuffers self.framebuffers
.iter() .iter()
.for_each(|f| device.destroy_framebuffer(*f, None)); .for_each(|f| device.destroy_framebuffer(*f, None));
@ -445,6 +453,7 @@ impl AppData {
self.create_swapchain_image_views(device)?; self.create_swapchain_image_views(device)?;
self.create_render_pass(instance, device)?; self.create_render_pass(instance, device)?;
self.create_pipeline(device)?; self.create_pipeline(device)?;
self.create_depth_objects(instance, device)?;
self.create_framebuffers(device)?; self.create_framebuffers(device)?;
self.create_uniform_buffers(instance, device)?; self.create_uniform_buffers(instance, device)?;
self.create_descriptor_pool(device)?; self.create_descriptor_pool(device)?;
@ -461,7 +470,14 @@ impl AppData {
self.swapchain_image_views = self self.swapchain_image_views = self
.swapchain_images .swapchain_images
.iter() .iter()
.map(|i| create_image_view(device, *i, self.swapchain_format)) .map(|i| {
create_image_view(
device,
*i,
self.swapchain_format,
vk::ImageAspectFlags::COLOR,
)
})
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
Ok(()) Ok(())
@ -471,7 +487,7 @@ impl AppData {
// Pipeline // Pipeline
//================================================ //================================================
unsafe fn create_render_pass(&mut self, _instance: &Instance, device: &Device) -> Result<()> { unsafe fn create_render_pass(&mut self, instance: &Instance, device: &Device) -> Result<()> {
let color_attachment = vk::AttachmentDescription::builder() let color_attachment = vk::AttachmentDescription::builder()
.format(self.swapchain_format) .format(self.swapchain_format)
.samples(vk::SampleCountFlags::_1) .samples(vk::SampleCountFlags::_1)
@ -482,23 +498,46 @@ impl AppData {
.initial_layout(vk::ImageLayout::UNDEFINED) .initial_layout(vk::ImageLayout::UNDEFINED)
.final_layout(vk::ImageLayout::PRESENT_SRC_KHR); .final_layout(vk::ImageLayout::PRESENT_SRC_KHR);
let depth_stencil_attachment = vk::AttachmentDescription::builder()
.format(self.get_depth_format(instance)?)
.samples(vk::SampleCountFlags::_1)
.load_op(vk::AttachmentLoadOp::CLEAR)
.store_op(vk::AttachmentStoreOp::DONT_CARE)
.stencil_load_op(vk::AttachmentLoadOp::DONT_CARE)
.stencil_store_op(vk::AttachmentStoreOp::DONT_CARE)
.initial_layout(vk::ImageLayout::UNDEFINED)
.final_layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
// Subpasses // Subpasses
let color_attachment_ref = vk::AttachmentReference::builder() let color_attachment_ref = vk::AttachmentReference::builder()
.attachment(0) .attachment(0)
.layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL); .layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL);
let depth_stencil_attachment_ref = vk::AttachmentReference::builder()
.attachment(1)
.layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
let color_attachments = &[color_attachment_ref]; let color_attachments = &[color_attachment_ref];
let subpass = vk::SubpassDescription::builder() let subpass = vk::SubpassDescription::builder()
.pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS) .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS)
.color_attachments(color_attachments); .color_attachments(color_attachments)
.depth_stencil_attachment(&depth_stencil_attachment_ref);
let dependency = vk::SubpassDependency::builder() let dependency = vk::SubpassDependency::builder()
.src_subpass(vk::SUBPASS_EXTERNAL) .src_subpass(vk::SUBPASS_EXTERNAL)
.dst_subpass(0) .dst_subpass(0)
.src_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) .src_stage_mask(
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT
| vk::PipelineStageFlags::EARLY_FRAGMENT_TESTS,
)
.src_access_mask(vk::AccessFlags::empty()) .src_access_mask(vk::AccessFlags::empty())
.dst_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT) .dst_stage_mask(
.dst_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE); vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT
| vk::PipelineStageFlags::EARLY_FRAGMENT_TESTS,
)
.dst_access_mask(
vk::AccessFlags::COLOR_ATTACHMENT_WRITE
| vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE,
);
let attachments = &[color_attachment]; let attachments = &[color_attachment, depth_stencil_attachment];
let subpasses = &[subpass]; let subpasses = &[subpass];
let dependencies = &[dependency]; let dependencies = &[dependency];
let info = vk::RenderPassCreateInfo::builder() let info = vk::RenderPassCreateInfo::builder()
@ -590,6 +629,13 @@ impl AppData {
.sample_shading_enable(false) .sample_shading_enable(false)
.rasterization_samples(vk::SampleCountFlags::_1); .rasterization_samples(vk::SampleCountFlags::_1);
let depth_stencil_state = vk::PipelineDepthStencilStateCreateInfo::builder()
.depth_test_enable(true)
.depth_write_enable(true)
.depth_compare_op(vk::CompareOp::LESS)
.depth_bounds_test_enable(false)
.stencil_test_enable(false);
let attachment = vk::PipelineColorBlendAttachmentState::builder() let attachment = vk::PipelineColorBlendAttachmentState::builder()
.color_write_mask(vk::ColorComponentFlags::all()) .color_write_mask(vk::ColorComponentFlags::all())
.blend_enable(false) .blend_enable(false)
@ -619,6 +665,7 @@ impl AppData {
.viewport_state(&viewport_state) .viewport_state(&viewport_state)
.rasterization_state(&rasterization_state) .rasterization_state(&rasterization_state)
.multisample_state(&multisample_state) .multisample_state(&multisample_state)
.depth_stencil_state(&depth_stencil_state)
.color_blend_state(&color_blend_state) .color_blend_state(&color_blend_state)
.layout(self.pipeline_layout) .layout(self.pipeline_layout)
.render_pass(self.render_pass) .render_pass(self.render_pass)
@ -644,7 +691,7 @@ impl AppData {
.swapchain_image_views .swapchain_image_views
.iter() .iter()
.map(|i| { .map(|i| {
let attachments = &[*i]; let attachments = &[*i, self.depth_image_view];
let create_info = vk::FramebufferCreateInfo::builder() let create_info = vk::FramebufferCreateInfo::builder()
.render_pass(self.render_pass) .render_pass(self.render_pass)
.attachments(attachments) .attachments(attachments)
@ -675,6 +722,77 @@ impl AppData {
Ok(()) Ok(())
} }
//================================================
// Depth Objects
//================================================
unsafe fn create_depth_objects(&mut self, instance: &Instance, device: &Device) -> Result<()> {
let format = self.get_depth_format(instance)?;
let (depth_image, depth_image_memory) = self.create_image(
instance,
device,
self.swapchain_extent.width,
self.swapchain_extent.height,
format,
vk::ImageTiling::OPTIMAL,
vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT,
vk::MemoryPropertyFlags::DEVICE_LOCAL,
)?;
self.depth_image = depth_image;
self.depth_image_memory = depth_image_memory;
self.depth_image_view = create_image_view(
device,
self.depth_image,
format,
vk::ImageAspectFlags::DEPTH,
)?;
Ok(())
}
unsafe fn get_depth_format(&self, instance: &Instance) -> Result<vk::Format> {
let candidates = &[
vk::Format::D32_SFLOAT,
vk::Format::D32_SFLOAT_S8_UINT,
vk::Format::D24_UNORM_S8_UINT,
];
self.get_supported_format(
instance,
candidates,
vk::ImageTiling::OPTIMAL,
vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT,
)
}
unsafe fn get_supported_format(
&self,
instance: &Instance,
candidates: &[vk::Format],
tiling: vk::ImageTiling,
features: vk::FormatFeatureFlags,
) -> Result<vk::Format> {
candidates
.iter()
.cloned()
.find(|f| {
let properties =
instance.get_physical_device_format_properties(self.physical_device, *f);
match tiling {
vk::ImageTiling::LINEAR => properties.linear_tiling_features.contains(features),
vk::ImageTiling::OPTIMAL => {
properties.optimal_tiling_features.contains(features)
}
_ => false,
}
})
.ok_or_else(|| anyhow!("Failed to find supported depth image format."))
}
//================================================ //================================================
// Texture // Texture
//================================================ //================================================
@ -752,8 +870,12 @@ impl AppData {
} }
unsafe fn create_texture_image_view(&mut self, device: &Device) -> Result<()> { unsafe fn create_texture_image_view(&mut self, device: &Device) -> Result<()> {
self.texture_image_view = self.texture_image_view = create_image_view(
create_image_view(device, self.texture_image, vk::Format::R8G8B8A8_SRGB)?; device,
self.texture_image,
vk::Format::R8G8B8A8_SRGB,
vk::ImageAspectFlags::COLOR,
)?;
Ok(()) Ok(())
} }
@ -981,7 +1103,14 @@ impl AppData {
}, },
}; };
let clear_values = &[color_clear_value]; let depth_clear_value = vk::ClearValue {
depth_stencil: vk::ClearDepthStencilValue {
depth: 1.0,
stencil: 0,
},
};
let clear_values = &[color_clear_value, depth_clear_value];
let info = vk::RenderPassBeginInfo::builder() let info = vk::RenderPassBeginInfo::builder()
.render_pass(self.render_pass) .render_pass(self.render_pass)
.framebuffer(self.framebuffers[i]) .framebuffer(self.framebuffers[i])

View File

@ -97,13 +97,13 @@ impl SwapchainSupport {
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct Vertex { pub struct Vertex {
pos: glm::Vec2, pos: glm::Vec3,
color: glm::Vec3, color: glm::Vec3,
tex_coord: glm::Vec2, tex_coord: glm::Vec2,
} }
impl Vertex { impl Vertex {
pub fn new(pos: glm::Vec2, color: glm::Vec3, tex_coord: glm::Vec2) -> Self { pub fn new(pos: glm::Vec3, color: glm::Vec3, tex_coord: glm::Vec2) -> Self {
Self { Self {
pos, pos,
color, color,
@ -123,7 +123,7 @@ impl Vertex {
let pos = vk::VertexInputAttributeDescription::builder() let pos = vk::VertexInputAttributeDescription::builder()
.binding(0) .binding(0)
.location(0) .location(0)
.format(vk::Format::R32G32_SFLOAT) .format(vk::Format::R32G32B32_SFLOAT)
.offset(0) .offset(0)
.build(); .build();
@ -131,14 +131,14 @@ impl Vertex {
.binding(0) .binding(0)
.location(1) .location(1)
.format(vk::Format::R32G32B32_SFLOAT) .format(vk::Format::R32G32B32_SFLOAT)
.offset(size_of::<glm::Vec2>() as u32) .offset(size_of::<glm::Vec3>() as u32)
.build(); .build();
let tex_coord = vk::VertexInputAttributeDescription::builder() let tex_coord = vk::VertexInputAttributeDescription::builder()
.binding(0) .binding(0)
.location(2) .location(2)
.format(vk::Format::R32G32_SFLOAT) .format(vk::Format::R32G32_SFLOAT)
.offset((size_of::<glm::Vec2>() + size_of::<glm::Vec3>()) as u32) .offset((size_of::<glm::Vec3>() + size_of::<glm::Vec3>()) as u32)
.build(); .build();
[pos, color, tex_coord] [pos, color, tex_coord]