aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-06-23 22:59:07 +0300
committerValentin Popov <valentin@popov.link>2026-06-23 22:59:07 +0300
commit0e127117e9f826ecf4be312b0c630121f38b4d95 (patch)
tree9a26dbe84c2ebebb8785ed5cc264076f630675e8
parent4d19728c392c6566358ad78f30bba769f8e723cf (diff)
downloadfparkan-0e127117e9f826ecf4be312b0c630121f38b4d95.tar.xz
fparkan-0e127117e9f826ecf4be312b0c630121f38b4d95.zip
feat: require created Vulkan smoke surface
-rw-r--r--apps/fparkan-vulkan-smoke/src/main.rs89
-rw-r--r--fixtures/acceptance/coverage.tsv1
-rw-r--r--fixtures/acceptance/stage_0_2_roadmap.md1
-rw-r--r--xtask/src/main.rs4
4 files changed, 74 insertions, 21 deletions
diff --git a/apps/fparkan-vulkan-smoke/src/main.rs b/apps/fparkan-vulkan-smoke/src/main.rs
index 045985f..90f7648 100644
--- a/apps/fparkan-vulkan-smoke/src/main.rs
+++ b/apps/fparkan-vulkan-smoke/src/main.rs
@@ -14,8 +14,8 @@
use fparkan_platform::{NativeWindowHandles, WindowPort};
use fparkan_platform_winit::{probe_smoke_window, WinitWindowPlan};
use fparkan_render_vulkan::{
- create_vulkan_instance_probe, plan_vulkan_surface, probe_vulkan_loader,
- triangle_shader_manifest, validate_shader_manifest, VulkanInstanceConfig,
+ create_vulkan_instance_probe, create_vulkan_surface_probe, probe_vulkan_loader,
+ triangle_shader_manifest, validate_shader_manifest, VulkanInstanceConfig, VulkanInstanceProbe,
};
use std::path::PathBuf;
use std::process::Command;
@@ -215,8 +215,8 @@ impl VulkanBootstrapProbe {
let mut probe = Self::probe_loader();
let window_handles = probe.probe_window(options);
- probe.probe_instance(options);
- probe.probe_surface(options, window_handles);
+ let instance = probe.probe_instance(options);
+ probe.probe_surface(options, instance.as_ref(), window_handles);
probe
}
@@ -303,7 +303,7 @@ impl VulkanBootstrapProbe {
}
}
- fn probe_instance(&mut self, options: &SmokeOptions) {
+ fn probe_instance(&mut self, options: &SmokeOptions) -> Option<VulkanInstanceProbe> {
if options.probes.vulkan.includes_instance()
&& self.loader_status == VulkanLoaderStatus::Available
{
@@ -313,6 +313,7 @@ impl VulkanBootstrapProbe {
Ok(instance) => {
self.instance_status = VulkanInstanceStatus::Created;
self.portability_enumeration = instance.report.create_flags != 0;
+ return Some(instance);
}
Err(err) => {
self.instance_status = VulkanInstanceStatus::Failed;
@@ -320,23 +321,30 @@ impl VulkanBootstrapProbe {
}
}
}
+ None
}
fn probe_surface(
&mut self,
options: &SmokeOptions,
+ instance: Option<&VulkanInstanceProbe>,
window_handles: Option<NativeWindowHandles>,
) {
if options.probes.vulkan.includes_surface()
&& self.instance_status == VulkanInstanceStatus::Created
{
- match plan_vulkan_surface(window_handles) {
+ match instance
+ .ok_or_else(|| "Vulkan instance probe was not retained".to_string())
+ .and_then(|instance| {
+ create_vulkan_surface_probe(instance, window_handles)
+ .map_err(|err| err.to_string())
+ }) {
Ok(_) => {
- self.surface_status = VulkanSurfaceStatus::Planned;
+ self.surface_status = VulkanSurfaceStatus::Created;
}
Err(err) => {
- self.surface_status = VulkanSurfaceStatus::MissingWindowHandles;
- self.surface_error = Some(err.to_string());
+ self.surface_status = VulkanSurfaceStatus::Failed;
+ self.surface_error = Some(err);
}
}
}
@@ -399,16 +407,16 @@ impl WinitWindowStatus {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum VulkanSurfaceStatus {
Skipped,
- Planned,
- MissingWindowHandles,
+ Created,
+ Failed,
}
impl VulkanSurfaceStatus {
const fn as_str(self) -> &'static str {
match self {
Self::Skipped => "skipped",
- Self::Planned => "planned",
- Self::MissingWindowHandles => "missing_window_handles",
+ Self::Created => "created",
+ Self::Failed => "failed",
}
}
}
@@ -511,7 +519,7 @@ fn validate_smoke_options(
"passed native smoke report requires successful --probe-window".to_string(),
);
}
- if bootstrap.surface_status != VulkanSurfaceStatus::Planned {
+ if bootstrap.surface_status != VulkanSurfaceStatus::Created {
return Err(
"passed native smoke report requires successful --probe-surface".to_string(),
);
@@ -757,7 +765,7 @@ mod tests {
window_width: Some(1280),
window_height: Some(720),
window_error: None,
- surface_status: VulkanSurfaceStatus::Planned,
+ surface_status: VulkanSurfaceStatus::Created,
surface_error: None,
},
),
@@ -840,7 +848,7 @@ mod tests {
window_width: Some(1280),
window_height: Some(720),
window_error: None,
- surface_status: VulkanSurfaceStatus::Planned,
+ surface_status: VulkanSurfaceStatus::Created,
surface_error: None,
},
),
@@ -926,7 +934,7 @@ mod tests {
window_width: None,
window_height: None,
window_error: None,
- surface_status: VulkanSurfaceStatus::Planned,
+ surface_status: VulkanSurfaceStatus::Created,
surface_error: None,
},
),
@@ -979,6 +987,49 @@ mod tests {
}
#[test]
+ fn rejects_passed_with_failed_surface() {
+ let options = SmokeOptions::parse(&strings(&[
+ "--platform",
+ "linux",
+ "--out",
+ "target/native.json",
+ "--status",
+ "passed",
+ "--frames",
+ "300",
+ "--resize-count",
+ "1",
+ "--swapchain-recreate-count",
+ "1",
+ "--validation-error-count",
+ "0",
+ "--probe-surface",
+ ]))
+ .expect("options");
+
+ assert_eq!(
+ validate_smoke_options(
+ &options,
+ &VulkanBootstrapProbe {
+ loader_status: VulkanLoaderStatus::Available,
+ instance_api: Some("1.3.0".to_string()),
+ loader_error: None,
+ instance_status: VulkanInstanceStatus::Created,
+ instance_error: None,
+ portability_enumeration: false,
+ window_status: WinitWindowStatus::Created,
+ window_width: Some(1280),
+ window_height: Some(720),
+ window_error: None,
+ surface_status: VulkanSurfaceStatus::Failed,
+ surface_error: Some("Vulkan surface creation failed".to_string()),
+ },
+ ),
+ Err("passed native smoke report requires successful --probe-surface".to_string())
+ );
+ }
+
+ #[test]
fn blocked_report_includes_shader_manifest_and_bootstrap_status() -> Result<(), String> {
let options = SmokeOptions::parse(&strings(&[
"--platform",
@@ -1004,7 +1055,7 @@ mod tests {
window_width: Some(1280),
window_height: Some(720),
window_error: None,
- surface_status: VulkanSurfaceStatus::MissingWindowHandles,
+ surface_status: VulkanSurfaceStatus::Failed,
surface_error: Some(
"native window/display handles are required for Vulkan surface creation"
.to_string(),
@@ -1029,7 +1080,7 @@ mod tests {
assert!(json.contains("\"window_width\": 1280"));
assert!(json.contains("\"window_height\": 720"));
assert!(json.contains("\"window_error\": null"));
- assert!(json.contains("\"vulkan_surface_status\": \"missing_window_handles\""));
+ assert!(json.contains("\"vulkan_surface_status\": \"failed\""));
assert!(json.contains(
"\"vulkan_surface_error\": \"native window/display handles are required for Vulkan surface creation\""
));
diff --git a/fixtures/acceptance/coverage.tsv b/fixtures/acceptance/coverage.tsv
index d050fab..051ffd5 100644
--- a/fixtures/acceptance/coverage.tsv
+++ b/fixtures/acceptance/coverage.tsv
@@ -59,6 +59,7 @@ S0-VK-026 covered cargo test -p fparkan-vulkan-smoke --offline rejects_passed_wi
S0-VK-027 covered cargo test -p fparkan-vulkan-smoke --offline rejects_passed_without_swapchain_recreation blocked_report_includes_shader_manifest_and_bootstrap_status
S0-VK-028 covered cargo test -p fparkan-vulkan-smoke --offline reports_rustc_host_triple blocked_report_includes_shader_manifest_and_bootstrap_status
S0-VK-029 covered cargo test -p xtask --offline native_smoke_audit_accepts_complete_three_platform_pass native_smoke_audit_rejects_blocked_or_incomplete_reports
+S0-VK-030 covered cargo test -p fparkan-vulkan-smoke --offline rejects_passed_with_failed_surface
S0-LIMIT-001 covered cargo test -p fparkan-binary --offline rejects_count_stride_overflow
S0-LIMIT-002 covered cargo test -p fparkan-binary --offline rejects_oversized_declared_allocation_before_read
L1-P1-NRES-001 covered cargo test -p fparkan-nres --offline licensed_corpora_nres_roundtrip_gates
diff --git a/fixtures/acceptance/stage_0_2_roadmap.md b/fixtures/acceptance/stage_0_2_roadmap.md
index 60974da..7976b52 100644
--- a/fixtures/acceptance/stage_0_2_roadmap.md
+++ b/fixtures/acceptance/stage_0_2_roadmap.md
@@ -59,6 +59,7 @@
`S0-VK-027`
`S0-VK-028`
`S0-VK-029`
+`S0-VK-030`
`S0-LIMIT-001`
`S0-LIMIT-002`
`L1-P1-NRES-001`
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index 5990022..dbe4983 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -1532,7 +1532,7 @@ fn validate_native_smoke_report(
platform,
report,
"vulkan_surface_status",
- "planned",
+ "created",
failures,
);
expect_u64_at_least(platform, report, "frames", 300, failures);
@@ -2233,7 +2233,7 @@ mod tests {
"vulkan_loader_status": "available",
"vulkan_instance_status": "created",
"window_status": "created",
- "vulkan_surface_status": "planned"
+ "vulkan_surface_status": "created"
}),
)
})