diff options
| author | Valentin Popov <valentin@popov.link> | 2026-09-06 04:22:12 +0300 |
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2026-09-06 04:22:12 +0300 |
| commit | aa51f3574d3d4d4e0fa59653eedd718fceb5d1bd (patch) | |
| tree | 9a43f6a3f3c86767e4e2b7316051562d96789f06 /adapters/fparkan-render-vulkan/src/ffi | |
| parent | da03e77f53bb33b2fe203ac45578289953a1b524 (diff) | |
| download | fparkan-aa51f3574d3d4d4e0fa59653eedd718fceb5d1bd.tar.xz fparkan-aa51f3574d3d4d4e0fa59653eedd718fceb5d1bd.zip | |
chore: simplify project to engine docs and tests
Remove planning and acceptance scaffolding while retaining the native Vulkan mission preview, format readers, runtime algorithms, and ordinary Rust tests. Keep the book aligned with the runnable project and validate checked-in shaders without generated tool metadata.
Diffstat (limited to 'adapters/fparkan-render-vulkan/src/ffi')
7 files changed, 28 insertions, 349 deletions
diff --git a/adapters/fparkan-render-vulkan/src/ffi/instance.rs b/adapters/fparkan-render-vulkan/src/ffi/instance.rs index 42b9bdb..463fa03 100644 --- a/adapters/fparkan-render-vulkan/src/ffi/instance.rs +++ b/adapters/fparkan-render-vulkan/src/ffi/instance.rs @@ -1,7 +1,6 @@ #![allow(unsafe_code)] use ash::vk; -use serde::Serialize; use std::collections::BTreeSet; use std::ffi::{CStr, CString}; use std::os::raw::c_char; @@ -10,7 +9,6 @@ use super::{ EXT_DEBUG_UTILS_EXTENSION, KHR_PORTABILITY_ENUMERATION_EXTENSION, MIN_VULKAN_API_VERSION, VALIDATION_LAYER_NAME, }; -use crate::policy::{format_api_version, serialize_json_or_fallback}; /// Vulkan instance bootstrap configuration. #[derive(Clone, Debug, Eq, PartialEq)] @@ -236,28 +234,6 @@ pub fn create_vulkan_instance_probe( }) } -/// Renders a deterministic JSON Vulkan instance plan. -#[must_use] -pub fn render_instance_plan_json(plan: &VulkanInstancePlan) -> String { - #[derive(Serialize)] - struct InstancePlanJson<'a> { - schema: u32, - create_flags: u32, - validation_requested: bool, - enabled_extensions: &'a [String], - } - - serialize_json_or_fallback( - &InstancePlanJson { - schema: plan.schema, - create_flags: plan.create_flags, - validation_requested: plan.validation_requested, - enabled_extensions: &plan.enabled_extensions, - }, - "{\"schema\":0,\"create_flags\":0,\"validation_requested\":false,\"enabled_extensions\":[]}", - ) -} - /// Opens the Vulkan loader and reports the supported instance API version. /// /// # Errors @@ -288,26 +264,6 @@ pub fn vulkan_entry_symbol_name() -> &'static CStr { c"vkGetInstanceProcAddr" } -/// Renders a deterministic JSON Vulkan loader report. -#[must_use] -pub fn render_loader_probe_report_json(report: &VulkanLoaderProbeReport) -> String { - #[derive(Serialize)] - struct LoaderProbeReportJson { - schema: u32, - loader_available: bool, - instance_api: String, - } - - serialize_json_or_fallback( - &LoaderProbeReportJson { - schema: report.schema, - loader_available: report.loader_available, - instance_api: format_api_version(report.instance_api_version), - }, - "{\"schema\":0,\"loader_available\":false,\"instance_api\":\"0.0.0\"}", - ) -} - fn available_instance_extensions(entry: &ash::Entry) -> Result<Vec<String>, VulkanInstanceError> { let available_extensions = // SAFETY: Enumerating instance extensions reads loader-owned immutable metadata. diff --git a/adapters/fparkan-render-vulkan/src/ffi/resources.rs b/adapters/fparkan-render-vulkan/src/ffi/resources.rs index 1d38503..f1fd579 100644 --- a/adapters/fparkan-render-vulkan/src/ffi/resources.rs +++ b/adapters/fparkan-render-vulkan/src/ffi/resources.rs @@ -26,7 +26,6 @@ pub(super) struct VulkanDepthAttachment { pub(super) format: vk::Format, } -#[allow(clippy::too_many_lines)] pub(super) fn create_depth_attachment( instance: &VulkanInstanceProbe, device: &VulkanLogicalDeviceProbe, @@ -249,7 +248,6 @@ pub(super) fn create_static_mesh_index_buffer( ) } -#[allow(clippy::too_many_lines)] pub(super) fn create_static_texture_image( instance: &VulkanInstanceProbe, device: &VulkanLogicalDeviceProbe, @@ -376,7 +374,6 @@ pub(super) fn create_static_texture_image( }) } -#[allow(clippy::too_many_lines)] fn upload_static_texture( device: &VulkanLogicalDeviceProbe, command_pool: vk::CommandPool, diff --git a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs index e41f0f9..e2f6c34 100644 --- a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs +++ b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs @@ -17,7 +17,7 @@ use super::{ VulkanValidationReport, }; use crate::policy::KHR_PORTABILITY_SUBSET_EXTENSION; -use crate::shader_manifest::{triangle_shader_manifest, validate_shader_manifest}; +use crate::shader::validate_triangle_shaders; #[cfg(test)] fn take_runtime_owners_in_dependency_order<Instance, Validation, Surface, Device, Swapchain>( @@ -103,7 +103,7 @@ 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> { @@ -120,8 +120,7 @@ impl VulkanSmokeRenderer { resolve_draw_texture_indices(&create_info.mesh.draw_ranges, &create_info.materials) .map_err(|context| VulkanSmokeRendererError::InvalidStaticMesh { context })?; let bootstrap_progress = create_info.bootstrap_progress.as_ref(); - let shader_manifest = validate_shader_manifest(&triangle_shader_manifest()) - .map_err(VulkanSmokeRendererError::ShaderManifest)?; + validate_triangle_shaders().map_err(VulkanSmokeRendererError::Shader)?; let surface_plan = plan_vulkan_surface(Some(create_info.native_handles)) .map_err(VulkanSmokeRendererError::Surface)?; let mut instance_config = VulkanInstanceConfig::smoke(&create_info.application_name); @@ -240,7 +239,6 @@ impl VulkanSmokeRenderer { pending_extent: None, swapchain_recreate_count: 0, report: VulkanSmokeRendererReport { - shader_manifest_hash: shader_manifest.manifest_hash.clone(), portability_enumeration: instance_config.enable_portability_enumeration, portability_subset_enabled: false, device_name: String::new(), @@ -260,7 +258,6 @@ impl VulkanSmokeRenderer { let device_ref = renderer.device_ref()?; let swapchain_ref = renderer.swapchain_ref()?; renderer.report = VulkanSmokeRendererReport { - shader_manifest_hash: shader_manifest.manifest_hash, portability_enumeration: renderer .instance .as_ref() @@ -426,7 +423,7 @@ impl VulkanSmokeRenderer { /// /// Returns [`VulkanSmokeRendererError`] when synchronization, command recording, /// submission, or presentation fails. - #[allow(clippy::too_many_lines)] + pub fn draw_frame(&mut self) -> Result<VulkanSmokeFrameOutcome, VulkanSmokeRendererError> { if let Some(extent) = self.pending_extent.take() { if extent.0 == 0 || extent.1 == 0 { @@ -632,7 +629,6 @@ impl VulkanSmokeRenderer { Ok(()) } - #[allow(clippy::too_many_lines)] fn record_command_buffer( &mut self, image_index: usize, diff --git a/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs b/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs index 4686eaf..217df3f 100644 --- a/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs +++ b/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs @@ -10,7 +10,7 @@ use super::{ VulkanSurfaceProbe, VulkanSwapchainProbe, VulkanSwapchainProbeError, VulkanSwapchainResources, VulkanValidationMessenger, }; -use crate::shader_manifest::VulkanShaderManifestError; +use crate::shader::VulkanShaderError; /// Creates a live native Vulkan renderer for the Stage 0 smoke loop. #[derive(Clone, Debug)] @@ -536,7 +536,7 @@ impl VulkanSmokeBootstrapProgress { /// 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, @@ -562,8 +562,6 @@ const BOOTSTRAP_SWAPCHAIN_CREATED: u8 = 1 << 5; /// 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, /// Whether the logical device enabled `VK_KHR_portability_subset`. @@ -652,8 +650,8 @@ pub enum VulkanSmokeRendererError { LogicalDevice(VulkanLogicalDeviceError), /// Swapchain bootstrap failed. Swapchain(VulkanSwapchainProbeError), - /// Shader manifest validation failed. - ShaderManifest(VulkanShaderManifestError), + /// Checked-in shader validation failed. + Shader(VulkanShaderError), /// Vulkan operation failed. VulkanOperation { /// Operation context. @@ -695,7 +693,7 @@ impl std::fmt::Display for VulkanSmokeRendererError { 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::Shader(error) => write!(f, "{error}"), Self::VulkanOperation { context, result } => { write!(f, "{context}: {result:?}") } diff --git a/adapters/fparkan-render-vulkan/src/ffi/surface.rs b/adapters/fparkan-render-vulkan/src/ffi/surface.rs index 8fc9c5a..65a8b7f 100644 --- a/adapters/fparkan-render-vulkan/src/ffi/surface.rs +++ b/adapters/fparkan-render-vulkan/src/ffi/surface.rs @@ -2,12 +2,10 @@ use ash::{khr::surface, vk}; use fparkan_platform::NativeWindowHandles; -use serde::Serialize; use std::ffi::CStr; use std::os::raw::c_char; use super::VulkanInstanceProbe; -use crate::policy::serialize_json_or_fallback; /// Deterministic Vulkan surface creation plan. #[derive(Clone, Debug, Eq, PartialEq)] @@ -132,24 +130,6 @@ pub fn create_vulkan_surface_probe( }) } -/// Renders a deterministic JSON Vulkan surface plan. -#[must_use] -pub fn render_surface_plan_json(plan: &VulkanSurfacePlan) -> String { - #[derive(Serialize)] - struct SurfacePlanJson<'a> { - schema: u32, - required_instance_extensions: &'a [String], - } - - serialize_json_or_fallback( - &SurfacePlanJson { - schema: plan.schema, - required_instance_extensions: &plan.required_instance_extensions, - }, - "{\"schema\":0,\"required_instance_extensions\":[]}", - ) -} - pub(super) fn extension_name(extension: *const c_char) -> Result<String, VulkanSurfaceError> { // SAFETY: `ash-window` returns extension pointers to static NUL-terminated Vulkan names. let name = unsafe { CStr::from_ptr(extension) }; diff --git a/adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs b/adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs index 7558db6..c175f0d 100644 --- a/adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs +++ b/adapters/fparkan-render-vulkan/src/ffi/swapchain_resources.rs @@ -45,7 +45,6 @@ struct PartialSwapchainResources { command_buffers: Vec<vk::CommandBuffer>, } -#[allow(clippy::too_many_arguments, clippy::too_many_lines)] pub(super) fn create_swapchain_resources( instance: &VulkanInstanceProbe, device: &VulkanLogicalDeviceProbe, @@ -205,7 +204,6 @@ fn create_swapchain_image_views( Ok(image_views) } -#[allow(clippy::type_complexity)] fn create_swapchain_pipeline_bundle( instance: &VulkanInstanceProbe, device: &VulkanLogicalDeviceProbe, @@ -433,7 +431,6 @@ fn create_pipeline_layout( }) } -#[allow(clippy::too_many_lines)] fn create_texture_descriptor_bundle( device: &VulkanLogicalDeviceProbe, textures: &[VulkanAllocatedImage], @@ -554,12 +551,10 @@ fn create_texture_descriptor_bundle( Ok((layout, pool, descriptor_sets, sampler)) } -#[allow(clippy::cast_precision_loss)] fn extent_component_to_f32(value: u32) -> f32 { value as f32 } -#[allow(clippy::too_many_lines)] fn create_graphics_pipeline_cache( device: &VulkanLogicalDeviceProbe, render_pass: vk::RenderPass, @@ -596,7 +591,6 @@ fn create_graphics_pipeline_cache( Ok(pipelines) } -#[allow(clippy::too_many_lines)] fn create_graphics_pipeline( device: &VulkanLogicalDeviceProbe, render_pass: vk::RenderPass, diff --git a/adapters/fparkan-render-vulkan/src/ffi/tests.rs b/adapters/fparkan-render-vulkan/src/ffi/tests.rs index a842c73..740c13d 100644 --- a/adapters/fparkan-render-vulkan/src/ffi/tests.rs +++ b/adapters/fparkan-render-vulkan/src/ffi/tests.rs @@ -1,114 +1,9 @@ use super::*; +use crate::ffi::{SPIRV_MAGIC, SPIRV_VERSION_1_0}; use crate::policy::{KHR_PORTABILITY_SUBSET_EXTENSION, KHR_SWAPCHAIN_EXTENSION}; -use crate::shader_manifest::{ - SHADER_COMPILER_BINARY_SHA256, SHADER_COMPILER_NAME, SHADER_COMPILER_VERSION, - SHADER_MANIFEST_SCHEMA, SHADER_TARGET_ENV, SPIRV_MAGIC, SPIRV_VALIDATOR_BINARY_SHA256, - SPIRV_VALIDATOR_NAME, SPIRV_VALIDATOR_VERSION, SPIRV_VERSION_1_0, - TRIANGLE_VERTEX_COMPILE_COMMAND, TRIANGLE_VERTEX_SOURCE_PATH, TRIANGLE_VERTEX_SOURCE_SHA256, - TRIANGLE_VERTEX_SPIRV_PATH, TRIANGLE_VERTEX_VALIDATE_COMMAND, -}; +use crate::shader::{validate_spirv_container, validate_triangle_shaders, VulkanShaderError}; use crate::*; use fparkan_platform::{DepthStencilSupport, RenderRequest}; -use fparkan_render::{ - DrawCommand, DrawId, GpuMaterialId, GpuMeshId, IndexRange, LegacyPipelineState, RenderCommand, - RenderPhase, -}; -use fparkan_render::{RenderBackend, RenderError}; - -#[test] -fn planning_backend_tracks_render_request_and_simulated_present() -> Result<(), RenderError> { - let mut backend = VulkanPlanningBackend::new(); - let request = RenderRequest { - presentation: fparkan_platform::PresentationMode::Immediate, - ..RenderRequest::conservative() - }; - backend.set_render_request(request); - assert_eq!(backend.render_request(), request); - assert_eq!(backend.report().request.current_request, request); - assert_eq!(backend.report().request.request_updates, 1); - - let commands = fparkan_render::RenderCommandList { - commands: vec![ - RenderCommand::BeginFrame, - RenderCommand::Draw(DrawCommand { - id: DrawId(11), - phase: RenderPhase::Opaque, - object_id: None, - mesh: GpuMeshId(1), - material: GpuMaterialId(2), - pipeline_key: LegacyPipelineState::default().into(), - transform: [1.0; 16], - range: IndexRange { start: 0, count: 3 }, - stable_order: 7, - }), - RenderCommand::EndFrame, - ], - }; - - backend.execute(&commands)?; - assert_eq!(backend.state(), VulkanPlanningBackendState::Configured); - assert_eq!(backend.report().execution.planned_frames, 1); - assert_eq!(backend.report().execution.submission_plans, 1); - assert_eq!(backend.report().execution.simulated_presents, 1); - assert!(backend.report().execution.last_capture_size > 0); - assert_eq!( - backend.report().last_frame_submission, - Some(VulkanFrameSubmissionPlan { - schema: 1, - frames_in_flight: 2, - command_buffers: 2, - semaphores_per_frame: 2, - fences_per_frame: 1, - draw_count: 1, - indexed_vertex_count: 3, - }) - ); - Ok(()) -} - -#[test] -fn frame_submission_plan_json_is_stable() -> Result<(), RenderError> { - let commands = fparkan_render::RenderCommandList { - commands: vec![ - RenderCommand::BeginFrame, - RenderCommand::Draw(DrawCommand { - id: DrawId(11), - phase: RenderPhase::Opaque, - object_id: None, - mesh: GpuMeshId(1), - material: GpuMaterialId(2), - pipeline_key: LegacyPipelineState::default().into(), - transform: [1.0; 16], - range: IndexRange { start: 0, count: 3 }, - stable_order: 7, - }), - RenderCommand::EndFrame, - ], - }; - let swapchain = VulkanSwapchainPlan { - schema: 1, - extent: (1, 1), - format: VulkanSurfaceFormat { - format: vk::Format::B8G8R8A8_SRGB.as_raw(), - color_space: vk::ColorSpaceKHR::SRGB_NONLINEAR.as_raw(), - }, - present_mode: vk::PresentModeKHR::FIFO.as_raw(), - image_count: 3, - image_usage: vk::ImageUsageFlags::COLOR_ATTACHMENT.as_raw(), - }; - - let plan = plan_vulkan_frame_submission(&swapchain, &commands)?; - - assert_eq!(plan.frames_in_flight, 2); - assert_eq!(plan.command_buffers, 3); - assert_eq!(plan.draw_count, 1); - assert_eq!(plan.indexed_vertex_count, 3); - assert_eq!( - render_frame_submission_plan_json(&plan), - "{\"schema\":1,\"frames_in_flight\":2,\"command_buffers\":3,\"semaphores_per_frame\":2,\"fences_per_frame\":1,\"draw_count\":1,\"indexed_vertex_count\":3}" - ); - Ok(()) -} #[test] fn device_scoring_is_deterministic_and_prefers_discrete_unified_queue() { @@ -391,38 +286,6 @@ fn capability_report_preserves_informational_sampled_formats_and_limits() { } #[test] -fn capability_report_json_is_stable() { - let mut rejected = device("Rejected", VulkanDeviceType::IntegratedGpu, 0, true, false); - rejected.present_modes.clear(); - let report = select_physical_device(&[ - rejected, - device("GPU \"A\"", VulkanDeviceType::DiscreteGpu, 3, true, false), - ]) - .expect("selected device"); - - assert_eq!( - render_capability_report_json(&report), - "{\"schema\":1,\"vulkan_api\":\"1.1.0\",\"device_name\":\"GPU \\\"A\\\"\",\"score\":1101,\"graphics_queue_family\":3,\"present_queue_family\":3,\"portability_subset\":false,\"enabled_extensions\":[\"VK_KHR_swapchain\"],\"informational_capabilities\":{\"sampled_color_formats\":[50],\"sampled_depth_formats\":[126],\"limits\":{\"max_image_dimension_2d\":4096,\"max_sampler_allocation_count\":4096,\"max_per_stage_descriptor_samplers\":16,\"max_bound_descriptor_sets\":4}},\"rejected_devices\":[{\"device_name\":\"Rejected\",\"reason_code\":\"missing_present_mode\",\"reason\":\"Vulkan device Rejected has no supported present mode\"}]}" - ); -} - -#[test] -fn loader_probe_report_json_is_stable() { - assert_eq!( - vulkan_entry_symbol_name().to_bytes(), - b"vkGetInstanceProcAddr" - ); - assert_eq!( - render_loader_probe_report_json(&VulkanLoaderProbeReport { - schema: 1, - loader_available: true, - instance_api_version: vk::API_VERSION_1_2, - }), - "{\"schema\":1,\"loader_available\":true,\"instance_api\":\"1.2.0\"}" - ); -} - -#[test] fn loader_error_display_is_actionable() { assert_eq!( VulkanLoaderError::Unavailable { @@ -446,9 +309,15 @@ fn instance_plan_is_sorted_deduplicated_and_portability_aware() { enable_validation: true, }); + assert_eq!(plan.create_flags, 1); + assert!(plan.validation_requested); assert_eq!( - render_instance_plan_json(&plan), - "{\"schema\":1,\"create_flags\":1,\"validation_requested\":true,\"enabled_extensions\":[\"VK_EXT_debug_utils\",\"VK_KHR_portability_enumeration\",\"VK_KHR_surface\"]}" + plan.enabled_extensions, + vec![ + "VK_EXT_debug_utils".to_string(), + KHR_PORTABILITY_ENUMERATION_EXTENSION.to_string(), + "VK_KHR_surface".to_string(), + ] ); } @@ -510,20 +379,6 @@ fn surface_plan_requires_native_handles() { } #[test] -fn surface_plan_json_is_stable() { - assert_eq!( - render_surface_plan_json(&VulkanSurfacePlan { - schema: 1, - required_instance_extensions: vec![ - "VK_KHR_surface".to_string(), - "VK_EXT_metal_surface".to_string(), - ], - }), - "{\"schema\":1,\"required_instance_extensions\":[\"VK_KHR_surface\",\"VK_EXT_metal_surface\"]}" - ); -} - -#[test] fn static_surface_extension_name_is_decoded() { let name = extension_name(ash::khr::surface::NAME.as_ptr()).expect("extension name"); @@ -620,128 +475,31 @@ fn swapchain_plan_rejects_missing_surface_data_and_empty_extent() { } #[test] -fn swapchain_plan_json_and_recreation_reports_are_stable() { - let plan = plan_vulkan_swapchain(&swapchain_request()).expect("swapchain plan"); - assert_eq!( - render_swapchain_plan_json(&plan), - "{\"schema\":1,\"extent\":[1024,720],\"format\":50,\"color_space\":0,\"present_mode\":1,\"image_count\":3,\"image_usage\":16}" - ); - - let report = swapchain_recreation_report( - VulkanSwapchainRecreationReason::OutOfDate, - (1024, 720), - (1280, 720), - ); - assert_eq!( - render_swapchain_recreation_report_json(&report), - "{\"schema\":1,\"reason\":\"out_of_date\",\"previous_extent\":[1024,720],\"next_extent\":[1280,720]}" - ); -} - -#[test] -fn triangle_shader_manifest_hashes_are_stable() { - let report = validate_shader_manifest(&triangle_shader_manifest()).expect("shader manifest"); - - assert_eq!(report.schema, SHADER_MANIFEST_SCHEMA); - assert_eq!(report.target_env, SHADER_TARGET_ENV); - assert_eq!( - report.compiler, - VulkanShaderToolManifest { - name: SHADER_COMPILER_NAME, - version: SHADER_COMPILER_VERSION, - binary_sha256: SHADER_COMPILER_BINARY_SHA256, - } - ); - assert_eq!( - report.validator, - VulkanShaderToolManifest { - name: SPIRV_VALIDATOR_NAME, - version: SPIRV_VALIDATOR_VERSION, - binary_sha256: SPIRV_VALIDATOR_BINARY_SHA256, - } - ); - assert_eq!(report.modules.len(), 2); - assert_eq!(report.modules[0].name, "triangle.vert"); - assert_eq!(report.modules[0].stage, VulkanShaderStage::Vertex); - assert_eq!(report.modules[0].source_path, TRIANGLE_VERTEX_SOURCE_PATH); - assert_eq!( - report.modules[0].source_sha256, - TRIANGLE_VERTEX_SOURCE_SHA256 - ); - assert_eq!(report.modules[0].spirv_path, TRIANGLE_VERTEX_SPIRV_PATH); - assert_eq!(report.modules[0].word_count, 358); - assert_eq!( - report.modules[0].sha256, - "4e2051ac43b933a57e5557e596bcc95952b4efbfcb45315180f89581e094398d" - ); - assert_eq!(report.modules[0].descriptor_sets, 0); - assert_eq!(report.modules[0].push_constant_bytes, 64); - assert_eq!( - report.modules[0].compile_command, - TRIANGLE_VERTEX_COMPILE_COMMAND - ); - assert_eq!( - report.modules[0].validate_command, - TRIANGLE_VERTEX_VALIDATE_COMMAND - ); - assert!(!report.modules[0].interface_hash.is_empty()); - assert_eq!( - report.modules[1].sha256, - "8ab7bf835e166892b04b10fa1100258daf355d2f693ad311d014dbee22de5c7b" - ); - assert_eq!( - report.manifest_hash, - "cf471972978ddb5c8919711ad64c93d0d64e18b1f590a89ce014f1e2a743cfb5" - ); -} - -#[test] -fn shader_manifest_report_json_is_stable() { - let report = validate_shader_manifest(&triangle_shader_manifest()).expect("shader manifest"); - let json = render_shader_manifest_report_json(&report); - - assert!(json.contains(SHADER_COMPILER_NAME)); - assert!(json.contains(SPIRV_VALIDATOR_NAME)); - assert!(json.contains(TRIANGLE_VERTEX_SOURCE_PATH)); - assert!(json.contains(TRIANGLE_VERTEX_COMPILE_COMMAND)); -} - -#[test] -fn checked_in_shader_manifest_matches_generated_report() { - let report = validate_shader_manifest(&triangle_shader_manifest()).expect("shader manifest"); - assert_eq!( - render_shader_manifest_report_json(&report), - include_str!("../../shaders/manifest.json").trim() - ); +fn checked_in_shaders_have_valid_spirv_containers() { + assert_eq!(validate_triangle_shaders(), Ok(())); } #[test] -fn shader_manifest_rejects_invalid_spirv_containers() { - let mut module = triangle_shader_manifest().remove(0); - module.words = &[0xFFFF_FFFF, SPIRV_VERSION_1_0, 0, 1, 0]; +fn shader_container_rejects_invalid_spirv() { assert_eq!( - validate_shader_manifest(&[module]), - Err(VulkanShaderManifestError::InvalidMagic { + validate_spirv_container("triangle.vert", &[0xFFFF_FFFF, SPIRV_VERSION_1_0, 0, 1, 0]), + Err(VulkanShaderError::InvalidMagic { name: "triangle.vert", found: 0xFFFF_FFFF, }) ); - let mut module = triangle_shader_manifest().remove(0); - module.words = &[SPIRV_MAGIC, 0, 0, 1, 0]; assert_eq!( - validate_shader_manifest(&[module]), - Err(VulkanShaderManifestError::UnsupportedVersion { + validate_spirv_container("triangle.vert", &[SPIRV_MAGIC, 0, 0, 1, 0]), + Err(VulkanShaderError::UnsupportedVersion { name: "triangle.vert", found: 0, }) ); - let mut module = triangle_shader_manifest().remove(0); - module.words = &[SPIRV_MAGIC, SPIRV_VERSION_1_0, 0, 0, 0]; assert_eq!( - validate_shader_manifest(&[module]), - Err(VulkanShaderManifestError::InvalidBound { + validate_spirv_container("triangle.vert", &[SPIRV_MAGIC, SPIRV_VERSION_1_0, 0, 0, 0]), + Err(VulkanShaderError::InvalidBound { name: "triangle.vert", }) ); |
