fix(vulkan-smoke): simplify swapchain image layout transitions

This commit is contained in:
2026-06-25 07:14:16 +04:00
parent b473b100c8
commit 17c3038a36
2 changed files with 10 additions and 60 deletions
@@ -3,7 +3,7 @@
use ash::vk;
use super::{
color_subresource_range, create_command_pool, create_frame_sync, create_swapchain_resources,
create_command_pool, create_frame_sync, create_swapchain_resources,
create_triangle_index_buffer, create_triangle_vertex_buffer, create_validation_messenger,
create_vulkan_instance_probe, create_vulkan_logical_device_probe, create_vulkan_surface_probe,
create_vulkan_swapchain_probe_for_extent, destroy_allocated_buffer,
@@ -438,38 +438,6 @@ impl VulkanSmokeRenderer {
result: error,
})?;
let pre_barrier = vk::ImageMemoryBarrier::default()
.old_layout(vk::ImageLayout::PRESENT_SRC_KHR)
.new_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.src_queue_family_index(vk::QUEUE_FAMILY_IGNORED)
.dst_queue_family_index(vk::QUEUE_FAMILY_IGNORED)
.subresource_range(color_subresource_range())
.src_access_mask(vk::AccessFlags::empty())
.dst_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE);
// SAFETY: The swapchain is live and queried only to resolve the current image handles.
let swapchain_images = unsafe {
swapchain
.loader()
.get_swapchain_images(swapchain.swapchain())
}
.map_err(|error| VulkanSmokeRendererError::VulkanOperation {
context: "vkGetSwapchainImagesKHR",
result: error,
})?;
let pre_barrier = pre_barrier.image(swapchain_images[image_index]);
// SAFETY: The barriers operate on the acquired swapchain image owned by this command buffer submission.
unsafe {
device.device().cmd_pipeline_barrier(
command_buffer,
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
vk::DependencyFlags::empty(),
&[],
&[],
&[pre_barrier],
);
}
let clear_values = [vk::ClearValue {
color: vk::ClearColorValue {
float32: [0.05, 0.08, 0.11, 1.0],
@@ -516,31 +484,12 @@ impl VulkanSmokeRenderer {
device.device().cmd_end_render_pass(command_buffer);
}
let post_barrier = vk::ImageMemoryBarrier::default()
.old_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.new_layout(vk::ImageLayout::PRESENT_SRC_KHR)
.src_queue_family_index(vk::QUEUE_FAMILY_IGNORED)
.dst_queue_family_index(vk::QUEUE_FAMILY_IGNORED)
.image(swapchain_images[image_index])
.subresource_range(color_subresource_range())
.src_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE)
.dst_access_mask(vk::AccessFlags::empty());
// SAFETY: The post-render barrier transitions the same live swapchain image into present layout.
unsafe {
device.device().cmd_pipeline_barrier(
command_buffer,
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
vk::PipelineStageFlags::BOTTOM_OF_PIPE,
vk::DependencyFlags::empty(),
&[],
&[],
&[post_barrier],
);
device.device().end_command_buffer(command_buffer)
}
.map_err(|error| VulkanSmokeRendererError::VulkanOperation {
context: "vkEndCommandBuffer",
result: error,
// SAFETY: The render pass owns the attachment layout transitions for this clear-and-present path.
unsafe { device.device().end_command_buffer(command_buffer) }.map_err(|error| {
VulkanSmokeRendererError::VulkanOperation {
context: "vkEndCommandBuffer",
result: error,
}
})?;
Ok(())
}
@@ -214,8 +214,8 @@ fn create_render_pass(
.samples(vk::SampleCountFlags::TYPE_1)
.load_op(vk::AttachmentLoadOp::CLEAR)
.store_op(vk::AttachmentStoreOp::STORE)
.initial_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.final_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL);
.initial_layout(vk::ImageLayout::UNDEFINED)
.final_layout(vk::ImageLayout::PRESENT_SRC_KHR);
let color_attachment_ref = vk::AttachmentReference::default()
.attachment(0)
.layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL);
@@ -228,6 +228,7 @@ fn create_render_pass(
.dst_subpass(0)
.src_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT)
.dst_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT)
.src_access_mask(vk::AccessFlags::empty())
.dst_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE);
let attachments = [color_attachment];
let subpasses = [subpass];