fix(vulkan-smoke): track bootstrap timeout evidence
This commit is contained in:
@@ -58,8 +58,9 @@ pub use self::runtime::{
|
||||
VulkanLogicalDeviceReport,
|
||||
};
|
||||
pub use self::smoke_types::{
|
||||
VulkanSmokeFrameOutcome, VulkanSmokeRenderer, VulkanSmokeRendererCreateInfo,
|
||||
VulkanSmokeRendererError, VulkanSmokeRendererReport, VulkanValidationReport,
|
||||
VulkanSmokeBootstrapProgress, VulkanSmokeBootstrapSnapshot, VulkanSmokeFrameOutcome,
|
||||
VulkanSmokeRenderer, VulkanSmokeRendererCreateInfo, VulkanSmokeRendererError,
|
||||
VulkanSmokeRendererReport, VulkanValidationReport,
|
||||
};
|
||||
#[cfg(test)]
|
||||
use self::surface::extension_name;
|
||||
|
||||
@@ -76,9 +76,11 @@ impl VulkanSmokeRenderer {
|
||||
///
|
||||
/// Returns [`VulkanSmokeRendererError`] when Vulkan bootstrap, pipeline creation,
|
||||
/// memory allocation, or synchronization resource creation fails.
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn new(
|
||||
create_info: &VulkanSmokeRendererCreateInfo,
|
||||
) -> Result<Self, VulkanSmokeRendererError> {
|
||||
let bootstrap_progress = create_info.bootstrap_progress.as_ref();
|
||||
let shader_manifest = validate_shader_manifest(&triangle_shader_manifest())
|
||||
.map_err(VulkanSmokeRendererError::ShaderManifest)?;
|
||||
let surface_plan = plan_vulkan_surface(Some(create_info.native_handles))
|
||||
@@ -90,6 +92,10 @@ impl VulkanSmokeRenderer {
|
||||
instance_config.enable_validation = create_info.enable_validation;
|
||||
let instance = create_vulkan_instance_probe(&instance_config)
|
||||
.map_err(VulkanSmokeRendererError::Instance)?;
|
||||
if let Some(progress) = bootstrap_progress {
|
||||
progress.mark_loader_available();
|
||||
progress.mark_instance_created();
|
||||
}
|
||||
let validation = if create_info.enable_validation {
|
||||
Some(create_validation_messenger(&instance)?)
|
||||
} else {
|
||||
@@ -97,9 +103,15 @@ impl VulkanSmokeRenderer {
|
||||
};
|
||||
let surface = create_vulkan_surface_probe(&instance, Some(create_info.native_handles))
|
||||
.map_err(VulkanSmokeRendererError::Surface)?;
|
||||
if let Some(progress) = bootstrap_progress {
|
||||
progress.mark_surface_created();
|
||||
}
|
||||
let device =
|
||||
create_vulkan_logical_device_probe(&instance, &surface, create_info.drawable_extent)
|
||||
.map_err(VulkanSmokeRendererError::LogicalDevice)?;
|
||||
if let Some(progress) = bootstrap_progress {
|
||||
progress.mark_logical_device_created();
|
||||
}
|
||||
let swapchain = create_vulkan_swapchain_probe_for_extent(
|
||||
&instance,
|
||||
&surface,
|
||||
@@ -108,6 +120,9 @@ impl VulkanSmokeRenderer {
|
||||
vk::SwapchainKHR::null(),
|
||||
)
|
||||
.map_err(VulkanSmokeRendererError::Swapchain)?;
|
||||
if let Some(progress) = bootstrap_progress {
|
||||
progress.mark_swapchain_created();
|
||||
}
|
||||
let command_pool = create_command_pool(&device)?;
|
||||
let vertex_buffer = match create_triangle_vertex_buffer(&instance, &device) {
|
||||
Ok(buffer) => buffer,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use ash::vk;
|
||||
use fparkan_platform::NativeWindowHandles;
|
||||
use std::sync::atomic::{AtomicU8, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{
|
||||
VulkanAllocatedBuffer, VulkanFrameSync, VulkanInstanceError, VulkanInstanceProbe,
|
||||
@@ -20,8 +22,86 @@ pub struct VulkanSmokeRendererCreateInfo {
|
||||
pub drawable_extent: (u32, u32),
|
||||
/// Whether validation layers must be enabled.
|
||||
pub enable_validation: bool,
|
||||
/// Optional shared bootstrap progress tracker for failure evidence.
|
||||
pub bootstrap_progress: Option<Arc<VulkanSmokeBootstrapProgress>>,
|
||||
}
|
||||
|
||||
/// Shared bootstrap progress used to report partial renderer startup evidence.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct VulkanSmokeBootstrapProgress {
|
||||
flags: AtomicU8,
|
||||
}
|
||||
|
||||
impl VulkanSmokeBootstrapProgress {
|
||||
/// Marks the Vulkan loader as available.
|
||||
pub fn mark_loader_available(&self) {
|
||||
self.set_flag(BOOTSTRAP_LOADER_AVAILABLE);
|
||||
}
|
||||
|
||||
/// Marks the Vulkan instance as created.
|
||||
pub fn mark_instance_created(&self) {
|
||||
self.set_flag(BOOTSTRAP_INSTANCE_CREATED);
|
||||
}
|
||||
|
||||
/// Marks the Vulkan surface as created.
|
||||
pub fn mark_surface_created(&self) {
|
||||
self.set_flag(BOOTSTRAP_SURFACE_CREATED);
|
||||
}
|
||||
|
||||
/// Marks a suitable Vulkan device as selected and the logical device as created.
|
||||
pub fn mark_logical_device_created(&self) {
|
||||
self.set_flag(BOOTSTRAP_DEVICE_SELECTED | BOOTSTRAP_LOGICAL_DEVICE_CREATED);
|
||||
}
|
||||
|
||||
/// Marks the Vulkan swapchain as created.
|
||||
pub fn mark_swapchain_created(&self) {
|
||||
self.set_flag(BOOTSTRAP_SWAPCHAIN_CREATED);
|
||||
}
|
||||
|
||||
/// Returns a stable snapshot of the measured bootstrap state.
|
||||
#[must_use]
|
||||
pub fn snapshot(&self) -> VulkanSmokeBootstrapSnapshot {
|
||||
let flags = self.flags.load(Ordering::SeqCst);
|
||||
VulkanSmokeBootstrapSnapshot {
|
||||
loader_available: flags & BOOTSTRAP_LOADER_AVAILABLE != 0,
|
||||
instance_created: flags & BOOTSTRAP_INSTANCE_CREATED != 0,
|
||||
surface_created: flags & BOOTSTRAP_SURFACE_CREATED != 0,
|
||||
device_selected: flags & BOOTSTRAP_DEVICE_SELECTED != 0,
|
||||
logical_device_created: flags & BOOTSTRAP_LOGICAL_DEVICE_CREATED != 0,
|
||||
swapchain_created: flags & BOOTSTRAP_SWAPCHAIN_CREATED != 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_flag(&self, flag: u8) {
|
||||
self.flags.fetch_or(flag, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
/// Stable snapshot of measured bootstrap progress.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct VulkanSmokeBootstrapSnapshot {
|
||||
/// Whether the Vulkan loader was resolved.
|
||||
pub loader_available: bool,
|
||||
/// Whether the Vulkan instance was created.
|
||||
pub instance_created: bool,
|
||||
/// Whether the Vulkan surface was created.
|
||||
pub surface_created: bool,
|
||||
/// Whether a suitable Vulkan device was selected.
|
||||
pub device_selected: bool,
|
||||
/// Whether the logical device was created.
|
||||
pub logical_device_created: bool,
|
||||
/// Whether the swapchain was created.
|
||||
pub swapchain_created: bool,
|
||||
}
|
||||
|
||||
const BOOTSTRAP_LOADER_AVAILABLE: u8 = 1 << 0;
|
||||
const BOOTSTRAP_INSTANCE_CREATED: u8 = 1 << 1;
|
||||
const BOOTSTRAP_SURFACE_CREATED: u8 = 1 << 2;
|
||||
const BOOTSTRAP_DEVICE_SELECTED: u8 = 1 << 3;
|
||||
const BOOTSTRAP_LOGICAL_DEVICE_CREATED: u8 = 1 << 4;
|
||||
const BOOTSTRAP_SWAPCHAIN_CREATED: u8 = 1 << 5;
|
||||
|
||||
/// Stable smoke renderer bootstrap report.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct VulkanSmokeRendererReport {
|
||||
|
||||
Reference in New Issue
Block a user