Add multisample antialiasing

This commit is contained in:
Timothy Warren 2023-04-25 09:39:50 -04:00
parent 2e9cdf2bd1
commit 9ac0d69f73

View File

@ -47,6 +47,7 @@ pub(crate) struct AppData {
pub(super) surface: vk::SurfaceKHR, pub(super) surface: vk::SurfaceKHR,
// Physical Device / Logical Device // Physical Device / Logical Device
physical_device: vk::PhysicalDevice, physical_device: vk::PhysicalDevice,
msaa_samples: vk::SampleCountFlags,
pub(super) graphics_queue: vk::Queue, pub(super) graphics_queue: vk::Queue,
pub(super) present_queue: vk::Queue, pub(super) present_queue: vk::Queue,
// Swapchain // Swapchain
@ -64,6 +65,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,
// Color
color_image: vk::Image,
color_image_memory: vk::DeviceMemory,
color_image_view: vk::ImageView,
// Depth // Depth
depth_image: vk::Image, depth_image: vk::Image,
depth_image_memory: vk::DeviceMemory, depth_image_memory: vk::DeviceMemory,
@ -117,6 +122,7 @@ impl AppData {
self.create_descriptor_set_layout(&device)?; self.create_descriptor_set_layout(&device)?;
self.create_pipeline(&device)?; self.create_pipeline(&device)?;
self.create_command_pool(&instance, &device)?; self.create_command_pool(&instance, &device)?;
self.create_color_objects(&instance, &device)?;
self.create_depth_objects(&instance, &device)?; self.create_depth_objects(&instance, &device)?;
self.create_framebuffers(&device)?; self.create_framebuffers(&device)?;
self.create_texture_image(&instance, &device)?; self.create_texture_image(&instance, &device)?;
@ -256,6 +262,9 @@ impl AppData {
/// # Safety /// # Safety
/// Here be Dragons /// Here be Dragons
unsafe fn destroy_swapchain(&mut self, device: &Device) { unsafe fn destroy_swapchain(&mut self, device: &Device) {
device.destroy_image_view(self.color_image_view, None);
device.free_memory(self.color_image_memory, None);
device.destroy_image(self.color_image, None);
device.destroy_descriptor_pool(self.descriptor_pool, None); device.destroy_descriptor_pool(self.descriptor_pool, None);
self.uniform_buffers self.uniform_buffers
.iter() .iter()
@ -296,6 +305,7 @@ impl AppData {
} else { } else {
info!("Selected physical device (`{}`).", properties.device_name); info!("Selected physical device (`{}`).", properties.device_name);
self.physical_device = physical_device; self.physical_device = physical_device;
self.msaa_samples = self.get_max_msaa_samples(instance);
return Ok(()); return Ok(());
} }
} }
@ -323,6 +333,25 @@ impl AppData {
Ok(()) Ok(())
} }
unsafe fn get_max_msaa_samples(&self, instance: &Instance) -> vk::SampleCountFlags {
let properties = instance.get_physical_device_properties(self.physical_device);
let counts = properties.limits.framebuffer_color_sample_counts
& properties.limits.framebuffer_depth_sample_counts;
[
vk::SampleCountFlags::_64,
vk::SampleCountFlags::_32,
vk::SampleCountFlags::_16,
vk::SampleCountFlags::_8,
vk::SampleCountFlags::_4,
vk::SampleCountFlags::_2,
]
.iter()
.cloned()
.find(|c| counts.contains(*c))
.unwrap_or(vk::SampleCountFlags::_1)
}
} }
unsafe fn check_physical_device_extensions( unsafe fn check_physical_device_extensions(
@ -482,6 +511,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_color_objects(instance, device)?;
self.create_depth_objects(instance, 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)?;
@ -561,17 +591,17 @@ impl AppData {
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(self.msaa_samples)
.load_op(vk::AttachmentLoadOp::CLEAR) .load_op(vk::AttachmentLoadOp::CLEAR)
.store_op(vk::AttachmentStoreOp::STORE) .store_op(vk::AttachmentStoreOp::STORE)
.stencil_load_op(vk::AttachmentLoadOp::DONT_CARE) .stencil_load_op(vk::AttachmentLoadOp::DONT_CARE)
.stencil_store_op(vk::AttachmentStoreOp::DONT_CARE) .stencil_store_op(vk::AttachmentStoreOp::DONT_CARE)
.initial_layout(vk::ImageLayout::UNDEFINED) .initial_layout(vk::ImageLayout::UNDEFINED)
.final_layout(vk::ImageLayout::PRESENT_SRC_KHR); .final_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL);
let depth_stencil_attachment = vk::AttachmentDescription::builder() let depth_stencil_attachment = vk::AttachmentDescription::builder()
.format(self.get_depth_format(instance)?) .format(self.get_depth_format(instance)?)
.samples(vk::SampleCountFlags::_1) .samples(self.msaa_samples)
.load_op(vk::AttachmentLoadOp::CLEAR) .load_op(vk::AttachmentLoadOp::CLEAR)
.store_op(vk::AttachmentStoreOp::DONT_CARE) .store_op(vk::AttachmentStoreOp::DONT_CARE)
.stencil_load_op(vk::AttachmentLoadOp::DONT_CARE) .stencil_load_op(vk::AttachmentLoadOp::DONT_CARE)
@ -579,6 +609,16 @@ impl AppData {
.initial_layout(vk::ImageLayout::UNDEFINED) .initial_layout(vk::ImageLayout::UNDEFINED)
.final_layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL); .final_layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
let color_resolve_attachment = vk::AttachmentDescription::builder()
.format(self.swapchain_format)
.samples(vk::SampleCountFlags::_1)
.load_op(vk::AttachmentLoadOp::DONT_CARE)
.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 // Subpasses
let color_attachment_ref = vk::AttachmentReference::builder() let color_attachment_ref = vk::AttachmentReference::builder()
.attachment(0) .attachment(0)
@ -586,11 +626,16 @@ impl AppData {
let depth_stencil_attachment_ref = vk::AttachmentReference::builder() let depth_stencil_attachment_ref = vk::AttachmentReference::builder()
.attachment(1) .attachment(1)
.layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL); .layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
let color_resolve_attachment_ref = vk::AttachmentReference::builder()
.attachment(2)
.layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL);
let color_attachments = &[color_attachment_ref]; let color_attachments = &[color_attachment_ref];
let resolve_attachments = &[color_resolve_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); .depth_stencil_attachment(&depth_stencil_attachment_ref)
.resolve_attachments(resolve_attachments);
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)
@ -608,7 +653,11 @@ impl AppData {
| vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE, | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE,
); );
let attachments = &[color_attachment, depth_stencil_attachment]; let attachments = &[
color_attachment,
depth_stencil_attachment,
color_resolve_attachment,
];
let subpasses = &[subpass]; let subpasses = &[subpass];
let dependencies = &[dependency]; let dependencies = &[dependency];
let info = vk::RenderPassCreateInfo::builder() let info = vk::RenderPassCreateInfo::builder()
@ -698,7 +747,7 @@ impl AppData {
let multisample_state = vk::PipelineMultisampleStateCreateInfo::builder() let multisample_state = vk::PipelineMultisampleStateCreateInfo::builder()
.sample_shading_enable(false) .sample_shading_enable(false)
.rasterization_samples(vk::SampleCountFlags::_1); .rasterization_samples(self.msaa_samples);
let depth_stencil_state = vk::PipelineDepthStencilStateCreateInfo::builder() let depth_stencil_state = vk::PipelineDepthStencilStateCreateInfo::builder()
.depth_test_enable(true) .depth_test_enable(true)
@ -777,7 +826,7 @@ impl AppData {
.swapchain_image_views .swapchain_image_views
.iter() .iter()
.map(|i| { .map(|i| {
let attachments = &[*i, self.depth_image_view]; let attachments = &[self.color_image_view, self.depth_image_view, *i];
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)
@ -810,6 +859,40 @@ impl AppData {
} }
} }
//================================================
// Color Objects
//================================================
impl AppData {
unsafe fn create_color_objects(&mut self, instance: &Instance, device: &Device) -> Result<()> {
let (color_image, color_image_memory) = self.create_image(
instance,
device,
self.swapchain_extent.width,
self.swapchain_extent.height,
1,
self.msaa_samples,
self.swapchain_format,
vk::ImageTiling::OPTIMAL,
vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::TRANSIENT_ATTACHMENT,
vk::MemoryPropertyFlags::DEVICE_LOCAL,
)?;
self.color_image = color_image;
self.color_image_memory = color_image_memory;
self.color_image_view = create_image_view(
device,
self.color_image,
self.swapchain_format,
vk::ImageAspectFlags::COLOR,
1,
)?;
Ok(())
}
}
//================================================ //================================================
// Depth Objects // Depth Objects
//================================================ //================================================
@ -823,6 +906,7 @@ impl AppData {
self.swapchain_extent.width, self.swapchain_extent.width,
self.swapchain_extent.height, self.swapchain_extent.height,
1, 1,
self.msaa_samples,
format, format,
vk::ImageTiling::OPTIMAL, vk::ImageTiling::OPTIMAL,
vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT, vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT,
@ -928,6 +1012,7 @@ impl AppData {
width, width,
height, height,
self.mip_levels, self.mip_levels,
vk::SampleCountFlags::_1,
vk::Format::R8G8B8A8_SRGB, vk::Format::R8G8B8A8_SRGB,
vk::ImageTiling::OPTIMAL, vk::ImageTiling::OPTIMAL,
vk::ImageUsageFlags::SAMPLED vk::ImageUsageFlags::SAMPLED
@ -1530,6 +1615,7 @@ impl AppData {
width: u32, width: u32,
height: u32, height: u32,
mip_levels: u32, mip_levels: u32,
samples: vk::SampleCountFlags,
format: vk::Format, format: vk::Format,
tiling: vk::ImageTiling, tiling: vk::ImageTiling,
usage: vk::ImageUsageFlags, usage: vk::ImageUsageFlags,
@ -1548,7 +1634,7 @@ impl AppData {
.tiling(tiling) .tiling(tiling)
.initial_layout(vk::ImageLayout::UNDEFINED) .initial_layout(vk::ImageLayout::UNDEFINED)
.usage(usage) .usage(usage)
.samples(vk::SampleCountFlags::_1) .samples(samples)
.sharing_mode(vk::SharingMode::EXCLUSIVE); .sharing_mode(vk::SharingMode::EXCLUSIVE);
let image = device.create_image(&info, None)?; let image = device.create_image(&info, None)?;