This commit is contained in:
Jérôme Bousquié
2026-09-21 10:07:32 +02:00
parent 4bfd712496
commit 5ae978da23
49 changed files with 1640 additions and 611 deletions
+18 -18
View File
@@ -1,21 +1,21 @@
//! # Validation WGSL (naga)
//!
//! Le shader `standard_shader.wgsl` n'est pas encore chargé par un `RenderPipeline` (voir Étapes 3–5) :
//! cette validation hors-ligne via `wgpu::naga` est donc la **seule** garantie de sa validité tant qu'il
//! n'est pas branché. Elle protège contre les régressions futures (ré-édition du shader, changement de
//! layout) sans nécessiter de contexte GPU.
//! The `standard_shader.wgsl` shader is not yet loaded by a `RenderPipeline` (see Steps 3–5):
//! this offline validation via `wgpu::naga` is therefore the **only** guarantee of its validity until
//! it is wired in. It protects against future regressions (shader re-edits, layout changes)
//! without requiring a GPU context.
//!
//! Aucune nouvelle dépendance n'est introduite : `wgpu` ré-exporte `naga`, déjà dépendance de `wsg-lib`.
//! No new dependency is introduced: `wgpu` re-exports `naga`, already a `wsg-lib` dependency.
use wgpu::naga;
/// Parse et valide complètement le shader embarqué `standard_shader.wgsl` via naga.
/// Un échec ici signifie que le shader serait rejeté par `Device::create_shader_module` à l'Étape 3.
/// Parses and fully validates the embedded `standard_shader.wgsl` shader via naga.
/// A failure here means the shader would be rejected by `Device::create_shader_module` at Step 3.
#[test]
fn standard_shader_is_valid_wgsl() {
let src = include_str!("../src/shaders/standard_shader.wgsl");
let module = naga::front::wgsl::parse_str(src)
.unwrap_or_else(|e| panic!("standard_shader.wgsl : erreur de parsing : {e:?}"));
.unwrap_or_else(|e| panic!("standard_shader.wgsl: parsing error: {e:?}"));
let mut validator = naga::valid::Validator::new(
naga::valid::ValidationFlags::all(),
@@ -23,21 +23,21 @@ fn standard_shader_is_valid_wgsl() {
);
validator
.validate(&module)
.unwrap_or_else(|e| panic!("standard_shader.wgsl : échec de validation : {e:?}"));
.unwrap_or_else(|e| panic!("standard_shader.wgsl: validation failed: {e:?}"));
// Contrat : exactement les deux entrées vs_main / fs_main attendues.
assert!(module.entry_points.len() >= 2, "vs_main + fs_main attendus");
// Contract: exactly the two expected entry points vs_main / fs_main.
assert!(module.entry_points.len() >= 2, "vs_main + fs_main expected");
}
/// Parse et valide complètement le shader embarqué `shadow_shader.wgsl` (Étape 14, D4) via naga.
/// Le pipeline « shadow » est câblé directement par `build_shadow_pipeline` (sans passer par le
/// PipelineCache), donc cette validation hors-ligne est la garantie de sa validité. Le contrat
/// n'attend qu'une seule entrée (`vs_main` — pipeline sans fragment stage).
/// Parses and fully validates the embedded `shadow_shader.wgsl` shader (Step 14, D4) via naga.
/// The "shadow" pipeline is wired directly by `build_shadow_pipeline` (bypassing the
/// PipelineCache), so this offline validation is the guarantee of its validity. The contract
/// expects a single entry point (`vs_main` — pipeline with no fragment stage).
#[test]
fn shadow_shader_is_valid_wgsl() {
let src = include_str!("../src/shaders/shadow_shader.wgsl");
let module = naga::front::wgsl::parse_str(src)
.unwrap_or_else(|e| panic!("shadow_shader.wgsl : erreur de parsing : {e:?}"));
.unwrap_or_else(|e| panic!("shadow_shader.wgsl: parsing error: {e:?}"));
let mut validator = naga::valid::Validator::new(
naga::valid::ValidationFlags::all(),
@@ -45,12 +45,12 @@ fn shadow_shader_is_valid_wgsl() {
);
validator
.validate(&module)
.unwrap_or_else(|e| panic!("shadow_shader.wgsl : échec de validation : {e:?}"));
.unwrap_or_else(|e| panic!("shadow_shader.wgsl: validation failed: {e:?}"));
let entry_names: Vec<&str> = module
.entry_points
.iter()
.map(|ep| ep.name.as_str())
.collect();
assert_eq!(entry_names, vec!["vs_main"], "seule vs_main attendue");
assert_eq!(entry_names, vec!["vs_main"], "only vs_main expected");
}