spirv_tools/val/
tool.rs

1use std::process::Command;
2
3#[derive(Default)]
4pub struct ToolValidator {
5    target_env: crate::TargetEnv,
6}
7
8use super::Validator;
9
10impl Validator for ToolValidator {
11    fn with_env(target_env: crate::TargetEnv) -> Self {
12        Self { target_env }
13    }
14
15    fn validate(
16        &self,
17        binary: impl AsRef<[u32]>,
18        options: Option<super::ValidatorOptions>,
19    ) -> Result<(), crate::error::Error> {
20        let mut cmd = Command::new("spirv-val");
21
22        cmd.arg("--target-env").arg(self.target_env.to_string());
23
24        if let Some(opts) = options {
25            // We reuse add options when we run the validator before optimizing,
26            // however the optimizer does not recognize limits, so we split them
27            // out into a separate function
28            add_limits(&mut cmd, &opts.max_limits);
29            add_options(&mut cmd, opts);
30        }
31
32        let input = crate::binary::from_binary(binary.as_ref());
33
34        crate::cmd::exec(cmd, Some(input), crate::cmd::Output::Ignore)?;
35        Ok(())
36    }
37}
38
39pub(crate) fn add_options(cmd: &mut Command, opts: super::ValidatorOptions) {
40    if opts.relax_logical_pointer {
41        cmd.arg("--relax-logical-pointer");
42    }
43
44    if let Some(true) = opts.relax_block_layout {
45        cmd.arg("--relax-block-layout");
46    }
47
48    if opts.uniform_buffer_standard_layout {
49        cmd.arg("--uniform-buffer-standard-layout");
50    }
51
52    if opts.scalar_block_layout {
53        cmd.arg("--scalar-block-layout");
54    }
55
56    if opts.skip_block_layout {
57        cmd.arg("--skip-block-layout");
58    }
59
60    if opts.relax_struct_store {
61        cmd.arg("--relax-struct-store");
62    }
63
64    if opts.before_legalization {
65        cmd.arg("--before-hlsl-legalization");
66    }
67}
68
69fn add_limits(cmd: &mut Command, limits: &[(spirv_tools_sys::val::ValidatorLimits, u32)]) {
70    use spirv_tools_sys::val::ValidatorLimits;
71
72    for (limit, val) in limits {
73        cmd.arg(format!(
74            "--max-{}={}",
75            match limit {
76                ValidatorLimits::StructMembers => "struct-members",
77                ValidatorLimits::StructDepth => "struct-depth",
78                ValidatorLimits::LocalVariables => "local-variables",
79                ValidatorLimits::GlobalVariables => "global-variables",
80                ValidatorLimits::SwitchBranches => "switch-branches",
81                ValidatorLimits::FunctionArgs => "function-args",
82                ValidatorLimits::ControlFlowNestingDepth => "control-flow-nesting-depth",
83                ValidatorLimits::AccessChainIndexes => "access-chain-indexes",
84                ValidatorLimits::IdBound => "id-bound",
85            },
86            val
87        ));
88    }
89}