aboutsummaryrefslogtreecommitdiff
path: root/adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-07-18 08:05:20 +0300
committerValentin Popov <valentin@popov.link>2026-07-18 08:05:20 +0300
commitf9a13298c0d5ef9bc0df968d178983506c24c0a6 (patch)
tree48a5e08d3f3dc614d9345fd937c6601eb8005518 /adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs
parent9f6b21638d396783809bbd941d4cf0d548122995 (diff)
downloadfparkan-f9a13298c0d5ef9bc0df968d178983506c24c0a6.tar.xz
fparkan-f9a13298c0d5ef9bc0df968d178983506c24c0a6.zip
feat(vulkan): capture swapchain pixels
Diffstat (limited to 'adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs')
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs b/adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs
index 529214d..6d87687 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs
@@ -16,6 +16,8 @@ use super::{
pub(super) struct VulkanSwapchainResources {
pub(super) image_views: Vec<vk::ImageView>,
+ pub(super) images: Vec<vk::Image>,
+ pub(super) readback_buffers: Vec<VulkanAllocatedBuffer>,
pub(super) depth_attachment: VulkanDepthAttachment,
pub(super) render_pass: vk::RenderPass,
pub(super) pipeline_layout: vk::PipelineLayout,
@@ -31,6 +33,7 @@ pub(super) struct VulkanSwapchainResources {
struct PartialSwapchainResources {
image_views: Vec<vk::ImageView>,
+ readback_buffers: Vec<VulkanAllocatedBuffer>,
depth_attachment: Option<VulkanDepthAttachment>,
render_pass: Option<vk::RenderPass>,
pipeline_layout: Option<vk::PipelineLayout>,
@@ -71,6 +74,7 @@ pub(super) fn create_swapchain_resources(
&images,
swapchain.report.plan.format.format,
)?,
+ readback_buffers: Vec::new(),
depth_attachment: None,
render_pass: None,
pipeline_layout: None,
@@ -127,6 +131,30 @@ pub(super) fn create_swapchain_resources(
}
};
partial.framebuffers = framebuffers;
+ if vk::ImageUsageFlags::from_raw(swapchain.report.plan.image_usage)
+ .contains(vk::ImageUsageFlags::TRANSFER_SRC)
+ {
+ let byte_len = usize::try_from(swapchain.report.plan.extent.0)
+ .ok()
+ .and_then(|width| {
+ usize::try_from(swapchain.report.plan.extent.1)
+ .ok()
+ .and_then(|height| width.checked_mul(height))
+ })
+ .and_then(|pixels| pixels.checked_mul(4))
+ .ok_or(VulkanSmokeRendererError::InvalidStaticMesh {
+ context: "swapchain readback byte length",
+ })?;
+ for _ in &images {
+ match super::create_readback_buffer(instance, device, byte_len) {
+ Ok(buffer) => partial.readback_buffers.push(buffer),
+ Err(error) => {
+ destroy_partial_swapchain_resources(device, command_pool, partial);
+ return Err(error);
+ }
+ }
+ }
+ }
reset_reusable_command_pool(device, command_pool, reuse_command_pool)?;
let command_buffers = match allocate_command_buffers(
device,
@@ -150,6 +178,8 @@ pub(super) fn create_swapchain_resources(
})?;
Ok(VulkanSwapchainResources {
image_views: partial.image_views,
+ images,
+ readback_buffers: partial.readback_buffers,
depth_attachment,
render_pass,
pipeline_layout,
@@ -795,6 +825,10 @@ pub(super) fn destroy_swapchain_resources(
for image_view in resources.image_views {
device.device().destroy_image_view(image_view, None);
}
+ for buffer in resources.readback_buffers {
+ device.device().destroy_buffer(buffer.buffer, None);
+ device.device().free_memory(buffer.memory, None);
+ }
}
}
@@ -843,5 +877,9 @@ fn destroy_partial_swapchain_resources(
for image_view in partial.image_views {
device.device().destroy_image_view(image_view, None);
}
+ for buffer in partial.readback_buffers {
+ device.device().destroy_buffer(buffer.buffer, None);
+ device.device().free_memory(buffer.memory, None);
+ }
}
}