diff options
| author | Valentin Popov <valentin@popov.link> | 2026-07-18 08:08:07 +0300 |
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2026-07-18 08:08:07 +0300 |
| commit | b24594c6a20e43b8080a368ad9a20708caddcde6 (patch) | |
| tree | 4bbe40191b2985a5af495cef520eebc18326ce47 /adapters/fparkan-render-vulkan/src | |
| parent | f9a13298c0d5ef9bc0df968d178983506c24c0a6 (diff) | |
| download | fparkan-b24594c6a20e43b8080a368ad9a20708caddcde6.tar.xz fparkan-b24594c6a20e43b8080a368ad9a20708caddcde6.zip | |
feat(vulkan): export readback artifacts
Diffstat (limited to 'adapters/fparkan-render-vulkan/src')
| -rw-r--r-- | adapters/fparkan-render-vulkan/src/ffi.rs | 10 | ||||
| -rw-r--r-- | adapters/fparkan-render-vulkan/src/ffi/smoke.rs | 46 | ||||
| -rw-r--r-- | adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs | 15 |
3 files changed, 49 insertions, 22 deletions
diff --git a/adapters/fparkan-render-vulkan/src/ffi.rs b/adapters/fparkan-render-vulkan/src/ffi.rs index eef9fc1..7b53c92 100644 --- a/adapters/fparkan-render-vulkan/src/ffi.rs +++ b/adapters/fparkan-render-vulkan/src/ffi.rs @@ -66,11 +66,11 @@ pub use self::runtime::{ VulkanLogicalDeviceError, VulkanLogicalDeviceProbe, VulkanLogicalDeviceReport, }; pub use self::smoke_types::{ - VulkanSmokeBootstrapProgress, VulkanSmokeBootstrapSnapshot, VulkanSmokeFrameOutcome, - VulkanSmokeRenderer, VulkanSmokeRendererCreateInfo, VulkanSmokeRendererError, - VulkanSmokeRendererReport, VulkanSmokeShutdownReport, VulkanStaticDrawRange, - VulkanStaticMaterial, VulkanStaticMesh, VulkanStaticTexture, VulkanStaticVertex, - VulkanValidationReport, + VulkanReadbackArtifact, VulkanSmokeBootstrapProgress, VulkanSmokeBootstrapSnapshot, + VulkanSmokeFrameOutcome, VulkanSmokeRenderer, VulkanSmokeRendererCreateInfo, + VulkanSmokeRendererError, VulkanSmokeRendererReport, VulkanSmokeShutdownReport, + VulkanStaticDrawRange, VulkanStaticMaterial, VulkanStaticMesh, VulkanStaticTexture, + VulkanStaticVertex, VulkanValidationReport, }; #[cfg(test)] use self::surface::extension_name; diff --git a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs index eee2f06..5ddfae6 100644 --- a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs +++ b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs @@ -10,10 +10,11 @@ use super::{ create_vulkan_logical_device_probe_for_request, create_vulkan_surface_probe, create_vulkan_swapchain_probe_for_extent, destroy_allocated_buffer, destroy_allocated_image, destroy_swapchain_resources, plan_vulkan_surface, readback_buffer_bytes, VulkanAllocatedBuffer, - VulkanInstanceConfig, VulkanInstanceProbe, VulkanLogicalDeviceProbe, VulkanSmokeFrameOutcome, - VulkanSmokeRenderer, VulkanSmokeRendererCreateInfo, VulkanSmokeRendererError, - VulkanSmokeRendererReport, VulkanSmokeShutdownReport, VulkanSurfaceProbe, VulkanSwapchainProbe, - VulkanSwapchainResources, VulkanValidationMessenger, VulkanValidationReport, + VulkanInstanceConfig, VulkanInstanceProbe, VulkanLogicalDeviceProbe, VulkanReadbackArtifact, + VulkanSmokeFrameOutcome, VulkanSmokeRenderer, VulkanSmokeRendererCreateInfo, + VulkanSmokeRendererError, VulkanSmokeRendererReport, VulkanSmokeShutdownReport, + VulkanSurfaceProbe, VulkanSwapchainProbe, VulkanSwapchainResources, VulkanValidationMessenger, + VulkanValidationReport, }; use crate::policy::KHR_PORTABILITY_SUBSET_EXTENSION; use crate::shader_manifest::{triangle_shader_manifest, validate_shader_manifest}; @@ -845,10 +846,18 @@ impl VulkanSmokeRenderer { } else { None }; - if let Some((byte_count, hash)) = completed_readback { - self.report.readback_byte_count = byte_count; - self.report.readback_fnv1a64 = hash; - } + let readback_artifact = completed_readback.map(|bytes| { + self.report.readback_byte_count = u64::try_from(bytes.len()).unwrap_or(u64::MAX); + self.report.readback_fnv1a64 = fnv1a64(&bytes); + VulkanReadbackArtifact { + format: self + .swapchain_ref() + .map_or(0, |swapchain| swapchain.report.plan.format.format), + width: self.report.swapchain_extent.0, + height: self.report.swapchain_extent.1, + bytes, + } + }); self.destroy_device_owned_resources(); let validation = take_runtime_children_with_validation_snapshot( &mut self.surface, @@ -862,6 +871,7 @@ impl VulkanSmokeRenderer { self.instance.take(); Ok(VulkanSmokeShutdownReport { renderer_report: self.report.clone(), + readback_artifact, swapchain_recreate_count: self.swapchain_recreate_count, validation, }) @@ -870,7 +880,7 @@ impl VulkanSmokeRenderer { fn completed_readback( &self, device: &VulkanLogicalDeviceProbe, - ) -> Result<Option<(u64, u64)>, VulkanSmokeRendererError> { + ) -> Result<Option<Vec<u8>>, VulkanSmokeRendererError> { let Some(resources) = self.swapchain_resources.as_ref() else { return Ok(None); }; @@ -888,17 +898,13 @@ impl VulkanSmokeRenderer { if resources.readback_buffers.is_empty() { return Ok(None); } - let mut hash = 0xcbf2_9ce4_8422_2325_u64; - let mut byte_count = 0_u64; + let mut artifact = + Vec::with_capacity(byte_len.saturating_mul(resources.readback_buffers.len())); for buffer in &resources.readback_buffers { let bytes = readback_buffer_bytes(device, buffer, byte_len)?; - for byte in bytes { - hash ^= u64::from(byte); - hash = hash.wrapping_mul(0x0000_0100_0000_01b3); - } - byte_count = byte_count.saturating_add(u64::try_from(byte_len).unwrap_or(u64::MAX)); + artifact.extend_from_slice(&bytes); } - Ok(Some((byte_count, hash))) + Ok(Some(artifact)) } fn teardown(&mut self) { @@ -919,6 +925,12 @@ impl VulkanSmokeRenderer { } } +fn fnv1a64(bytes: &[u8]) -> u64 { + bytes.iter().fold(0xcbf2_9ce4_8422_2325_u64, |hash, byte| { + (hash ^ u64::from(*byte)).wrapping_mul(0x0000_0100_0000_01b3) + }) +} + impl Drop for VulkanSmokeRenderer { fn drop(&mut self) { self.teardown(); diff --git a/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs b/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs index ce691b8..60f86e2 100644 --- a/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs +++ b/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs @@ -478,11 +478,26 @@ pub struct VulkanValidationReport { pub vuids: Vec<String>, } +/// CPU-owned copy of the final completed swapchain readback buffers. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VulkanReadbackArtifact { + /// Vulkan swapchain format as a raw enum value. + pub format: i32, + /// Width of each image in pixels. + pub width: u32, + /// Height of each image in pixels. + pub height: u32, + /// Concatenated raw four-byte-per-pixel images in swapchain order. + pub bytes: Vec<u8>, +} + /// Final smoke renderer shutdown evidence captured after explicit teardown. #[derive(Clone, Debug, Eq, PartialEq)] pub struct VulkanSmokeShutdownReport { /// Stable renderer bootstrap and swapchain report. pub renderer_report: VulkanSmokeRendererReport, + /// Optional raw GPU readback retained after synchronization and before teardown. + pub readback_artifact: Option<VulkanReadbackArtifact>, /// Measured swapchain recreation count for the completed smoke loop. pub swapchain_recreate_count: u32, /// Final validation snapshot captured before the debug messenger is destroyed. |
