aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/smoke.rs28
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs6
2 files changed, 31 insertions, 3 deletions
diff --git a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs
index b3d5ab3..4ad1c1b 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs
@@ -1252,6 +1252,34 @@ impl VulkanSmokeRenderer {
self.shutdown_inner()
}
+ /// Returns the latest submitted frame using the existing optional readback copy.
+ ///
+ /// This synchronizes the device before mapping the host-coherent buffer, so
+ /// callers should use it only for bounded diagnostic captures.
+ pub fn readback_last_submitted_frame(
+ &self,
+ ) -> Result<Option<VulkanReadbackArtifact>, VulkanSmokeRendererError> {
+ let device = self.device_ref()?;
+ // SAFETY: The renderer owns this device and all submitted work; idling
+ // prevents the last readback transfer from racing the host buffer map.
+ unsafe { device.device().device_wait_idle() }.map_err(|error| {
+ VulkanSmokeRendererError::VulkanOperation {
+ context: "vkDeviceWaitIdle(readback frame)",
+ result: error,
+ }
+ })?;
+ let Some(bytes) = self.completed_readback(device)? else {
+ return Ok(None);
+ };
+ let format = self.swapchain_ref()?.report.plan.format.format;
+ Ok(Some(VulkanReadbackArtifact {
+ format,
+ width: self.report.swapchain_extent.0,
+ height: self.report.swapchain_extent.1,
+ bytes,
+ }))
+ }
+
/// Requests swapchain recreation for a new drawable extent.
pub fn request_resize(&mut self, extent: (u32, u32)) {
self.pending_extent = Some(extent);
diff --git a/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs b/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs
index 8abc53b..ac31e9a 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs
@@ -1295,7 +1295,7 @@ pub struct VulkanValidationReport {
pub vuids: Vec<String>,
}
-/// CPU-owned copy of the final completed swapchain image readback.
+/// CPU-owned copy of a completed swapchain image readback.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VulkanReadbackArtifact {
/// Vulkan swapchain format as a raw enum value.
@@ -1304,8 +1304,8 @@ pub struct VulkanReadbackArtifact {
pub width: u32,
/// Height of each image in pixels.
pub height: u32,
- /// One raw four-byte-per-pixel image: the last successfully submitted
- /// swapchain image before synchronized teardown.
+ /// One raw four-byte-per-pixel image from the last successfully submitted
+ /// swapchain image at the synchronization point.
pub bytes: Vec<u8>,
}