refactor(vulkan-ffi): extract smoke renderer types

This commit is contained in:
2026-06-25 06:48:48 +04:00
parent 079e531166
commit 07e30cd040
2 changed files with 145 additions and 132 deletions
+5 -132
View File
@@ -31,6 +31,7 @@ mod instance;
mod resources;
mod runtime;
mod smoke;
mod smoke_types;
mod surface;
mod validation;
@@ -54,6 +55,10 @@ pub use self::runtime::{
VulkanRuntimeCapabilityError, VulkanRuntimeCapabilityProbe, VulkanSwapchainProbe,
VulkanSwapchainProbeError, VulkanSwapchainReport,
};
pub use self::smoke_types::{
VulkanSmokeFrameOutcome, VulkanSmokeRenderer, VulkanSmokeRendererCreateInfo,
VulkanSmokeRendererError, VulkanSmokeRendererReport, VulkanValidationReport,
};
#[cfg(test)]
use self::surface::extension_name;
pub use self::surface::{
@@ -61,9 +66,7 @@ pub use self::surface::{
VulkanSurfacePlan, VulkanSurfaceProbe,
};
use self::validation::{create_validation_messenger, VulkanValidationMessenger};
use crate::shader_manifest::VulkanShaderManifestError;
use ash::vk;
use fparkan_platform::NativeWindowHandles;
/// Minimum Vulkan API version accepted by the Stage 0 backend.
pub const MIN_VULKAN_API_VERSION: u32 = vk::API_VERSION_1_1;
const KHR_PORTABILITY_ENUMERATION_EXTENSION: &str = "VK_KHR_portability_enumeration";
@@ -454,136 +457,6 @@ pub(crate) const TRIANGLE_FRAGMENT_SHADER_WORDS: &[u32] = &[
0x0001_0038,
];
/// Creates a live native Vulkan renderer for the Stage 0 smoke loop.
#[derive(Clone, Debug)]
pub struct VulkanSmokeRendererCreateInfo {
/// Application name reported to the Vulkan loader.
pub application_name: String,
/// Native window/display handles borrowed from a live window.
pub native_handles: NativeWindowHandles,
/// Initial drawable extent.
pub drawable_extent: (u32, u32),
/// Whether validation layers must be enabled.
pub enable_validation: bool,
}
/// Stable smoke renderer bootstrap report.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VulkanSmokeRendererReport {
/// Checked-in shader manifest hash used by the renderer.
pub shader_manifest_hash: String,
/// Whether portability enumeration was enabled at instance creation.
pub portability_enumeration: bool,
/// Selected device name.
pub device_name: String,
/// Graphics queue-family index.
pub graphics_queue_family: u32,
/// Present queue-family index.
pub present_queue_family: u32,
/// Enabled logical-device extension count.
pub enabled_extension_count: u32,
/// Current swapchain extent.
pub swapchain_extent: (u32, u32),
/// Current swapchain image count.
pub swapchain_image_count: u32,
}
/// Measured validation counters from the live smoke loop.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VulkanValidationReport {
/// Validation warnings observed by the debug messenger.
pub warning_count: u32,
/// Validation errors observed by the debug messenger.
pub error_count: u32,
/// Stable sorted VUID list.
pub vuids: Vec<String>,
}
/// Result of one rendered smoke frame.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum VulkanSmokeFrameOutcome {
/// A frame was submitted and presented.
Presented,
/// Rendering was skipped because the swapchain had to be recreated.
Recreated,
/// Rendering was skipped because the drawable extent is zero.
ZeroExtent,
}
/// Live smoke renderer error.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum VulkanSmokeRendererError {
/// Instance bootstrap failed.
Instance(VulkanInstanceError),
/// Surface bootstrap failed.
Surface(VulkanSurfaceError),
/// Logical-device bootstrap failed.
LogicalDevice(VulkanLogicalDeviceError),
/// Swapchain bootstrap failed.
Swapchain(VulkanSwapchainProbeError),
/// Shader manifest validation failed.
ShaderManifest(VulkanShaderManifestError),
/// Vulkan operation failed.
VulkanOperation {
/// Operation context.
context: &'static str,
/// Raw Vulkan result code.
result: vk::Result,
},
/// No suitable memory type exists for the required properties.
MissingMemoryType {
/// Operation context.
context: &'static str,
},
/// Internal smoke renderer state was unexpectedly absent.
InvariantViolation {
/// Missing state context.
context: &'static str,
},
}
impl std::fmt::Display for VulkanSmokeRendererError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Instance(error) => write!(f, "{error}"),
Self::Surface(error) => write!(f, "{error}"),
Self::LogicalDevice(error) => write!(f, "{error}"),
Self::Swapchain(error) => write!(f, "{error}"),
Self::ShaderManifest(error) => write!(f, "{error}"),
Self::VulkanOperation { context, result } => {
write!(f, "{context}: {result:?}")
}
Self::MissingMemoryType { context } => {
write!(f, "{context}: no compatible Vulkan memory type")
}
Self::InvariantViolation { context } => {
write!(f, "renderer invariant violated: {context}")
}
}
}
}
impl std::error::Error for VulkanSmokeRendererError {}
/// Live Stage 0 Vulkan triangle renderer used by the smoke app.
pub struct VulkanSmokeRenderer {
instance: Option<VulkanInstanceProbe>,
validation: Option<VulkanValidationMessenger>,
surface: Option<VulkanSurfaceProbe>,
device: Option<VulkanLogicalDeviceProbe>,
swapchain: Option<VulkanSwapchainProbe>,
command_pool: vk::CommandPool,
swapchain_resources: Option<VulkanSwapchainResources>,
vertex_buffer: Option<VulkanAllocatedBuffer>,
index_buffer: Option<VulkanAllocatedBuffer>,
frame_sync: Vec<VulkanFrameSync>,
images_in_flight: Vec<vk::Fence>,
current_frame: usize,
pending_extent: Option<(u32, u32)>,
swapchain_recreate_count: u32,
report: VulkanSmokeRendererReport,
}
#[cfg(test)]
mod tests {
use super::*;
@@ -0,0 +1,140 @@
use ash::vk;
use fparkan_platform::NativeWindowHandles;
use super::{
VulkanAllocatedBuffer, VulkanFrameSync, VulkanInstanceError, VulkanInstanceProbe,
VulkanLogicalDeviceError, VulkanLogicalDeviceProbe, VulkanSurfaceError, VulkanSurfaceProbe,
VulkanSwapchainProbe, VulkanSwapchainProbeError, VulkanSwapchainResources,
VulkanValidationMessenger,
};
use crate::shader_manifest::VulkanShaderManifestError;
/// Creates a live native Vulkan renderer for the Stage 0 smoke loop.
#[derive(Clone, Debug)]
pub struct VulkanSmokeRendererCreateInfo {
/// Application name reported to the Vulkan loader.
pub application_name: String,
/// Native window/display handles borrowed from a live window.
pub native_handles: NativeWindowHandles,
/// Initial drawable extent.
pub drawable_extent: (u32, u32),
/// Whether validation layers must be enabled.
pub enable_validation: bool,
}
/// Stable smoke renderer bootstrap report.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VulkanSmokeRendererReport {
/// Checked-in shader manifest hash used by the renderer.
pub shader_manifest_hash: String,
/// Whether portability enumeration was enabled at instance creation.
pub portability_enumeration: bool,
/// Selected device name.
pub device_name: String,
/// Graphics queue-family index.
pub graphics_queue_family: u32,
/// Present queue-family index.
pub present_queue_family: u32,
/// Enabled logical-device extension count.
pub enabled_extension_count: u32,
/// Current swapchain extent.
pub swapchain_extent: (u32, u32),
/// Current swapchain image count.
pub swapchain_image_count: u32,
}
/// Measured validation counters from the live smoke loop.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VulkanValidationReport {
/// Validation warnings observed by the debug messenger.
pub warning_count: u32,
/// Validation errors observed by the debug messenger.
pub error_count: u32,
/// Stable sorted VUID list.
pub vuids: Vec<String>,
}
/// Result of one rendered smoke frame.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum VulkanSmokeFrameOutcome {
/// A frame was submitted and presented.
Presented,
/// Rendering was skipped because the swapchain had to be recreated.
Recreated,
/// Rendering was skipped because the drawable extent is zero.
ZeroExtent,
}
/// Live smoke renderer error.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum VulkanSmokeRendererError {
/// Instance bootstrap failed.
Instance(VulkanInstanceError),
/// Surface bootstrap failed.
Surface(VulkanSurfaceError),
/// Logical-device bootstrap failed.
LogicalDevice(VulkanLogicalDeviceError),
/// Swapchain bootstrap failed.
Swapchain(VulkanSwapchainProbeError),
/// Shader manifest validation failed.
ShaderManifest(VulkanShaderManifestError),
/// Vulkan operation failed.
VulkanOperation {
/// Operation context.
context: &'static str,
/// Raw Vulkan result code.
result: vk::Result,
},
/// No suitable memory type exists for the required properties.
MissingMemoryType {
/// Operation context.
context: &'static str,
},
/// Internal smoke renderer state was unexpectedly absent.
InvariantViolation {
/// Missing state context.
context: &'static str,
},
}
impl std::fmt::Display for VulkanSmokeRendererError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Instance(error) => write!(f, "{error}"),
Self::Surface(error) => write!(f, "{error}"),
Self::LogicalDevice(error) => write!(f, "{error}"),
Self::Swapchain(error) => write!(f, "{error}"),
Self::ShaderManifest(error) => write!(f, "{error}"),
Self::VulkanOperation { context, result } => {
write!(f, "{context}: {result:?}")
}
Self::MissingMemoryType { context } => {
write!(f, "{context}: no compatible Vulkan memory type")
}
Self::InvariantViolation { context } => {
write!(f, "renderer invariant violated: {context}")
}
}
}
}
impl std::error::Error for VulkanSmokeRendererError {}
/// Live Stage 0 Vulkan triangle renderer used by the smoke app.
pub struct VulkanSmokeRenderer {
pub(super) instance: Option<VulkanInstanceProbe>,
pub(super) validation: Option<VulkanValidationMessenger>,
pub(super) surface: Option<VulkanSurfaceProbe>,
pub(super) device: Option<VulkanLogicalDeviceProbe>,
pub(super) swapchain: Option<VulkanSwapchainProbe>,
pub(super) command_pool: vk::CommandPool,
pub(super) swapchain_resources: Option<VulkanSwapchainResources>,
pub(super) vertex_buffer: Option<VulkanAllocatedBuffer>,
pub(super) index_buffer: Option<VulkanAllocatedBuffer>,
pub(super) frame_sync: Vec<VulkanFrameSync>,
pub(super) images_in_flight: Vec<vk::Fence>,
pub(super) current_frame: usize,
pub(super) pending_extent: Option<(u32, u32)>,
pub(super) swapchain_recreate_count: u32,
pub(super) report: VulkanSmokeRendererReport,
}