@@ -124,6 +124,7 @@ pub enum SpirvBuilderError {
124124const SPIRV_TARGET_PREFIX : & str = "spirv-unknown-" ;
125125
126126#[ derive( Debug , PartialEq , Eq , Clone , Copy , Default , serde:: Deserialize , serde:: Serialize ) ]
127+ #[ cfg_attr( feature = "clap" , derive( clap:: ValueEnum ) ) ]
127128pub enum MetadataPrintout {
128129 /// Print no cargo metadata.
129130 None ,
@@ -137,6 +138,7 @@ pub enum MetadataPrintout {
137138}
138139
139140#[ derive( Debug , PartialEq , Eq , Clone , Copy , Default , serde:: Deserialize , serde:: Serialize ) ]
141+ #[ cfg_attr( feature = "clap" , derive( clap:: ValueEnum ) ) ]
140142pub enum SpirvMetadata {
141143 /// Strip all names and other debug information from SPIR-V output.
142144 #[ default]
@@ -150,6 +152,7 @@ pub enum SpirvMetadata {
150152
151153/// Strategy used to handle Rust `panic!`s in shaders compiled to SPIR-V.
152154#[ derive( Debug , PartialEq , Eq , Clone , Copy , Default , serde:: Deserialize , serde:: Serialize ) ]
155+ #[ cfg_attr( feature = "clap" , derive( clap:: ValueEnum ) ) ]
153156pub enum ShaderPanicStrategy {
154157 /// Return from shader entry-point with no side-effects **(default)**.
155158 ///
@@ -202,6 +205,7 @@ pub enum ShaderPanicStrategy {
202205 /// their `debugPrintf` support can be done during instance creation
203206 /// * *optional*: integrating [`VK_EXT_debug_utils`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_debug_utils.html)
204207 /// allows more reporting flexibility than `DEBUG_PRINTF_TO_STDOUT=1`)
208+ #[ cfg_attr( feature = "clap" , clap( skip) ) ]
205209 DebugPrintfThenExit {
206210 /// Whether to also print the entry-point inputs (excluding buffers/resources),
207211 /// which should uniquely identify the panicking shader invocation.
@@ -233,6 +237,7 @@ pub enum ShaderPanicStrategy {
233237/// Options for specifying the behavior of the validator
234238/// Copied from `spirv-tools/src/val.rs` struct `ValidatorOptions`, with some fields disabled.
235239#[ derive( Default , Clone , serde:: Deserialize , serde:: Serialize ) ]
240+ #[ cfg_attr( feature = "clap" , derive( clap:: Parser ) ) ]
236241pub struct ValidatorOptions {
237242 /// Record whether or not the validator should relax the rules on types for
238243 /// stores to structs. When relaxed, it will allow a type mismatch as long as
@@ -244,13 +249,15 @@ pub struct ValidatorOptions {
244249 ///
245250 /// 2) the decorations that affect the memory layout are identical for both
246251 /// types. Other decorations are not relevant.
252+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
247253 pub relax_struct_store : bool ,
248254 /// Records whether or not the validator should relax the rules on pointer usage
249255 /// in logical addressing mode.
250256 ///
251257 /// When relaxed, it will allow the following usage cases of pointers:
252258 /// 1) `OpVariable` allocating an object whose type is a pointer type
253259 /// 2) `OpReturnValue` returning a pointer value
260+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
254261 pub relax_logical_pointer : bool ,
255262 // /// Records whether or not the validator should relax the rules because it is
256263 // /// expected that the optimizations will make the code legal.
@@ -271,9 +278,11 @@ pub struct ValidatorOptions {
271278 ///
272279 /// This is enabled by default when targeting Vulkan 1.1 or later.
273280 /// Relaxed layout is more permissive than the default rules in Vulkan 1.0.
281+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "None" ) ) ]
274282 pub relax_block_layout : Option < bool > ,
275283 /// Records whether the validator should use standard block layout rules for
276284 /// uniform blocks.
285+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
277286 pub uniform_buffer_standard_layout : bool ,
278287 /// Records whether the validator should use "scalar" block layout rules.
279288 /// Scalar layout rules are more permissive than relaxed block layout.
@@ -291,9 +300,11 @@ pub struct ValidatorOptions {
291300 /// - a member Offset must be a multiple of the member's scalar alignment
292301 /// - `ArrayStride` or `MatrixStride` must be a multiple of the array or matrix
293302 /// scalar alignment
303+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
294304 pub scalar_block_layout : bool ,
295305 /// Records whether or not the validator should skip validating standard
296306 /// uniform/storage block layout.
307+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
297308 pub skip_block_layout : bool ,
298309 // /// Applies a maximum to one or more Universal limits
299310 // pub max_limits: Vec<(ValidatorLimits, u32)>,
@@ -302,60 +313,86 @@ pub struct ValidatorOptions {
302313/// Options for specifying the behavior of the optimizer
303314/// Copied from `spirv-tools/src/opt.rs` struct `Options`, with some fields disabled.
304315#[ derive( Default , Clone , serde:: Deserialize , serde:: Serialize ) ]
316+ #[ cfg_attr( feature = "clap" , derive( clap:: Parser ) ) ]
305317pub struct OptimizerOptions {
306318 // /// Records the validator options that should be passed to the validator,
307319 // /// the validator will run with the options before optimizer.
308320 // pub validator_options: Option<crate::val::ValidatorOptions>,
309321 // /// Records the maximum possible value for the id bound.
310322 // pub max_id_bound: Option<u32>,
311323 /// Records whether all bindings within the module should be preserved.
324+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
312325 pub preserve_bindings : bool ,
313326 // /// Records whether all specialization constants within the module
314327 // /// should be preserved.
315328 // pub preserve_spec_constants: bool,
316329}
317330
318331/// Cargo features specification for building the shader crate.
319- #[ derive( Default , Clone , serde:: Deserialize , serde:: Serialize ) ]
332+ #[ derive( Clone , serde:: Deserialize , serde:: Serialize ) ]
333+ #[ cfg_attr( feature = "clap" , derive( clap:: Parser ) ) ]
320334pub struct ShaderCrateFeatures {
321335 /// Set --default-features for the target shader crate.
322- pub default_features : Option < bool > ,
336+ #[ cfg_attr( feature = "clap" , clap( long = "no-default-features" , default_value = "true" , action = clap:: ArgAction :: SetFalse ) ) ]
337+ pub default_features : bool ,
323338 /// Set --features for the target shader crate.
339+ #[ cfg_attr( feature = "clap" , clap( long) ) ]
324340 pub features : Vec < String > ,
325341}
326342
343+ impl Default for ShaderCrateFeatures {
344+ fn default ( ) -> Self {
345+ Self {
346+ default_features : true ,
347+ features : Vec :: new ( ) ,
348+ }
349+ }
350+ }
351+
327352#[ non_exhaustive]
328353#[ derive( Clone , serde:: Deserialize , serde:: Serialize ) ]
354+ #[ cfg_attr( feature = "clap" , derive( clap:: Parser ) ) ]
329355pub struct SpirvBuilder {
330356 pub path_to_crate : Option < PathBuf > ,
331357 /// Whether to print build.rs cargo metadata (e.g. cargo:rustc-env=var=val). Defaults to [`MetadataPrintout::Full`].
332358 pub print_metadata : MetadataPrintout ,
333359 /// Build in release. Defaults to true.
360+ #[ cfg_attr( feature = "clap" , clap( long = "debug" , default_value = "true" , action = clap:: ArgAction :: SetFalse ) ) ]
334361 pub release : bool ,
335362 /// The target triple, eg. `spirv-unknown-vulkan1.2`
363+ #[ cfg_attr(
364+ feature = "clap" ,
365+ clap( long, default_value = "spirv-unknown-vulkan1.2" )
366+ ) ]
336367 pub target : Option < String > ,
337368 /// Cargo features specification for building the shader crate.
369+ #[ cfg_attr( feature = "clap" , clap( flatten) ) ]
338370 pub shader_crate_features : ShaderCrateFeatures ,
339371 /// Deny any warnings, as they may never be printed when building within a build script. Defaults to false.
372+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
340373 pub deny_warnings : bool ,
341374 /// Splits the resulting SPIR-V file into one module per entry point. This is useful in cases
342375 /// where ecosystem tooling has bugs around multiple entry points per module - having all entry
343376 /// points bundled into a single file is the preferred system.
377+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
344378 pub multimodule : bool ,
345379 /// Sets the level of metadata (primarily `OpName` and `OpLine`) included in the SPIR-V binary.
346380 /// Including metadata significantly increases binary size.
381+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "none" ) ) ]
347382 pub spirv_metadata : SpirvMetadata ,
348383 /// Adds a capability to the SPIR-V module. Checking if a capability is enabled in code can be
349384 /// done via `#[cfg(target_feature = "TheCapability")]`.
385+ #[ cfg_attr( feature = "clap" , arg( long, value_parser=Self :: parse_spirv_capability) ) ]
350386 pub capabilities : Vec < Capability > ,
351387 /// Adds an extension to the SPIR-V module. Checking if an extension is enabled in code can be
352388 /// done via `#[cfg(target_feature = "ext:the_extension")]`.
389+ #[ cfg_attr( feature = "clap" , arg( long) ) ]
353390 pub extensions : Vec < String > ,
354391 /// Set additional "codegen arg". Note: the `RUSTGPU_CODEGEN_ARGS` environment variable
355392 /// takes precedence over any set arguments using this function.
356393 pub extra_args : Vec < String > ,
357394 // Location of a known `rustc_codegen_spirv` dylib, only required without feature `rustc_codegen_spirv`.
358- pub rustc_codegen_spirv_location : Option < std :: path :: PathBuf > ,
395+ pub rustc_codegen_spirv_location : Option < PathBuf > ,
359396
360397 /// The path of the "target specification" file.
361398 ///
@@ -371,12 +408,26 @@ pub struct SpirvBuilder {
371408 pub shader_panic_strategy : ShaderPanicStrategy ,
372409
373410 /// spirv-val flags
411+ #[ cfg_attr( feature = "clap" , clap( flatten) ) ]
374412 pub validator : ValidatorOptions ,
375413
376414 /// spirv-opt flags
415+ #[ cfg_attr( feature = "clap" , clap( flatten) ) ]
377416 pub optimizer : OptimizerOptions ,
378417}
379418
419+ #[ cfg( feature = "clap" ) ]
420+ impl SpirvBuilder {
421+ /// Clap value parser for `Capability`.
422+ fn parse_spirv_capability ( capability : & str ) -> Result < Capability , clap:: Error > {
423+ use core:: str:: FromStr ;
424+ Capability :: from_str ( capability) . map_or_else (
425+ |( ) | Err ( clap:: Error :: new ( clap:: error:: ErrorKind :: InvalidValue ) ) ,
426+ Ok ,
427+ )
428+ }
429+ }
430+
380431impl Default for SpirvBuilder {
381432 fn default ( ) -> Self {
382433 Self {
@@ -547,7 +598,7 @@ impl SpirvBuilder {
547598 /// Set --default-features for the target shader crate.
548599 #[ must_use]
549600 pub fn shader_crate_default_features ( mut self , default_features : bool ) -> Self {
550- self . shader_crate_features . default_features = Some ( default_features) ;
601+ self . shader_crate_features . default_features = default_features;
551602 self
552603 }
553604
@@ -897,10 +948,8 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
897948 . join ( format ! ( "{}.json" , target) )
898949 } ) ) ;
899950
900- if let Some ( default_features) = builder. shader_crate_features . default_features {
901- if !default_features {
902- cargo. arg ( "--no-default-features" ) ;
903- }
951+ if !builder. shader_crate_features . default_features {
952+ cargo. arg ( "--no-default-features" ) ;
904953 }
905954
906955 if !builder. shader_crate_features . features . is_empty ( ) {
0 commit comments