@@ -124,6 +124,7 @@ pub enum SpirvBuilderError {
124
124
const SPIRV_TARGET_PREFIX : & str = "spirv-unknown-" ;
125
125
126
126
#[ derive( Debug , PartialEq , Eq , Clone , Copy , Default , serde:: Deserialize , serde:: Serialize ) ]
127
+ #[ cfg_attr( feature = "clap" , derive( clap:: ValueEnum ) ) ]
127
128
pub enum MetadataPrintout {
128
129
/// Print no cargo metadata.
129
130
None ,
@@ -137,6 +138,7 @@ pub enum MetadataPrintout {
137
138
}
138
139
139
140
#[ derive( Debug , PartialEq , Eq , Clone , Copy , Default , serde:: Deserialize , serde:: Serialize ) ]
141
+ #[ cfg_attr( feature = "clap" , derive( clap:: ValueEnum ) ) ]
140
142
pub enum SpirvMetadata {
141
143
/// Strip all names and other debug information from SPIR-V output.
142
144
#[ default]
@@ -150,6 +152,7 @@ pub enum SpirvMetadata {
150
152
151
153
/// Strategy used to handle Rust `panic!`s in shaders compiled to SPIR-V.
152
154
#[ derive( Debug , PartialEq , Eq , Clone , Copy , Default , serde:: Deserialize , serde:: Serialize ) ]
155
+ #[ cfg_attr( feature = "clap" , derive( clap:: ValueEnum ) ) ]
153
156
pub enum ShaderPanicStrategy {
154
157
/// Return from shader entry-point with no side-effects **(default)**.
155
158
///
@@ -202,6 +205,7 @@ pub enum ShaderPanicStrategy {
202
205
/// their `debugPrintf` support can be done during instance creation
203
206
/// * *optional*: integrating [`VK_EXT_debug_utils`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_debug_utils.html)
204
207
/// allows more reporting flexibility than `DEBUG_PRINTF_TO_STDOUT=1`)
208
+ #[ cfg_attr( feature = "clap" , clap( skip) ) ]
205
209
DebugPrintfThenExit {
206
210
/// Whether to also print the entry-point inputs (excluding buffers/resources),
207
211
/// which should uniquely identify the panicking shader invocation.
@@ -233,6 +237,7 @@ pub enum ShaderPanicStrategy {
233
237
/// Options for specifying the behavior of the validator
234
238
/// Copied from `spirv-tools/src/val.rs` struct `ValidatorOptions`, with some fields disabled.
235
239
#[ derive( Default , Clone , serde:: Deserialize , serde:: Serialize ) ]
240
+ #[ cfg_attr( feature = "clap" , derive( clap:: Parser ) ) ]
236
241
pub struct ValidatorOptions {
237
242
/// Record whether or not the validator should relax the rules on types for
238
243
/// stores to structs. When relaxed, it will allow a type mismatch as long as
@@ -244,13 +249,15 @@ pub struct ValidatorOptions {
244
249
///
245
250
/// 2) the decorations that affect the memory layout are identical for both
246
251
/// types. Other decorations are not relevant.
252
+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
247
253
pub relax_struct_store : bool ,
248
254
/// Records whether or not the validator should relax the rules on pointer usage
249
255
/// in logical addressing mode.
250
256
///
251
257
/// When relaxed, it will allow the following usage cases of pointers:
252
258
/// 1) `OpVariable` allocating an object whose type is a pointer type
253
259
/// 2) `OpReturnValue` returning a pointer value
260
+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
254
261
pub relax_logical_pointer : bool ,
255
262
// /// Records whether or not the validator should relax the rules because it is
256
263
// /// expected that the optimizations will make the code legal.
@@ -271,9 +278,11 @@ pub struct ValidatorOptions {
271
278
///
272
279
/// This is enabled by default when targeting Vulkan 1.1 or later.
273
280
/// Relaxed layout is more permissive than the default rules in Vulkan 1.0.
281
+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "None" ) ) ]
274
282
pub relax_block_layout : Option < bool > ,
275
283
/// Records whether the validator should use standard block layout rules for
276
284
/// uniform blocks.
285
+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
277
286
pub uniform_buffer_standard_layout : bool ,
278
287
/// Records whether the validator should use "scalar" block layout rules.
279
288
/// Scalar layout rules are more permissive than relaxed block layout.
@@ -291,9 +300,11 @@ pub struct ValidatorOptions {
291
300
/// - a member Offset must be a multiple of the member's scalar alignment
292
301
/// - `ArrayStride` or `MatrixStride` must be a multiple of the array or matrix
293
302
/// scalar alignment
303
+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
294
304
pub scalar_block_layout : bool ,
295
305
/// Records whether or not the validator should skip validating standard
296
306
/// uniform/storage block layout.
307
+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
297
308
pub skip_block_layout : bool ,
298
309
// /// Applies a maximum to one or more Universal limits
299
310
// pub max_limits: Vec<(ValidatorLimits, u32)>,
@@ -302,60 +313,86 @@ pub struct ValidatorOptions {
302
313
/// Options for specifying the behavior of the optimizer
303
314
/// Copied from `spirv-tools/src/opt.rs` struct `Options`, with some fields disabled.
304
315
#[ derive( Default , Clone , serde:: Deserialize , serde:: Serialize ) ]
316
+ #[ cfg_attr( feature = "clap" , derive( clap:: Parser ) ) ]
305
317
pub struct OptimizerOptions {
306
318
// /// Records the validator options that should be passed to the validator,
307
319
// /// the validator will run with the options before optimizer.
308
320
// pub validator_options: Option<crate::val::ValidatorOptions>,
309
321
// /// Records the maximum possible value for the id bound.
310
322
// pub max_id_bound: Option<u32>,
311
323
/// Records whether all bindings within the module should be preserved.
324
+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
312
325
pub preserve_bindings : bool ,
313
326
// /// Records whether all specialization constants within the module
314
327
// /// should be preserved.
315
328
// pub preserve_spec_constants: bool,
316
329
}
317
330
318
331
/// 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 ) ) ]
320
334
pub struct ShaderCrateFeatures {
321
335
/// 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 ,
323
338
/// Set --features for the target shader crate.
339
+ #[ cfg_attr( feature = "clap" , clap( long) ) ]
324
340
pub features : Vec < String > ,
325
341
}
326
342
343
+ impl Default for ShaderCrateFeatures {
344
+ fn default ( ) -> Self {
345
+ Self {
346
+ default_features : true ,
347
+ features : Vec :: new ( ) ,
348
+ }
349
+ }
350
+ }
351
+
327
352
#[ non_exhaustive]
328
353
#[ derive( Clone , serde:: Deserialize , serde:: Serialize ) ]
354
+ #[ cfg_attr( feature = "clap" , derive( clap:: Parser ) ) ]
329
355
pub struct SpirvBuilder {
330
356
pub path_to_crate : Option < PathBuf > ,
331
357
/// Whether to print build.rs cargo metadata (e.g. cargo:rustc-env=var=val). Defaults to [`MetadataPrintout::Full`].
332
358
pub print_metadata : MetadataPrintout ,
333
359
/// Build in release. Defaults to true.
360
+ #[ cfg_attr( feature = "clap" , clap( long = "debug" , default_value = "true" , action = clap:: ArgAction :: SetFalse ) ) ]
334
361
pub release : bool ,
335
362
/// The target triple, eg. `spirv-unknown-vulkan1.2`
363
+ #[ cfg_attr(
364
+ feature = "clap" ,
365
+ clap( long, default_value = "spirv-unknown-vulkan1.2" )
366
+ ) ]
336
367
pub target : Option < String > ,
337
368
/// Cargo features specification for building the shader crate.
369
+ #[ cfg_attr( feature = "clap" , clap( flatten) ) ]
338
370
pub shader_crate_features : ShaderCrateFeatures ,
339
371
/// 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" ) ) ]
340
373
pub deny_warnings : bool ,
341
374
/// Splits the resulting SPIR-V file into one module per entry point. This is useful in cases
342
375
/// where ecosystem tooling has bugs around multiple entry points per module - having all entry
343
376
/// points bundled into a single file is the preferred system.
377
+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "false" ) ) ]
344
378
pub multimodule : bool ,
345
379
/// Sets the level of metadata (primarily `OpName` and `OpLine`) included in the SPIR-V binary.
346
380
/// Including metadata significantly increases binary size.
381
+ #[ cfg_attr( feature = "clap" , arg( long, default_value = "none" ) ) ]
347
382
pub spirv_metadata : SpirvMetadata ,
348
383
/// Adds a capability to the SPIR-V module. Checking if a capability is enabled in code can be
349
384
/// done via `#[cfg(target_feature = "TheCapability")]`.
385
+ #[ cfg_attr( feature = "clap" , arg( long, value_parser=Self :: parse_spirv_capability) ) ]
350
386
pub capabilities : Vec < Capability > ,
351
387
/// Adds an extension to the SPIR-V module. Checking if an extension is enabled in code can be
352
388
/// done via `#[cfg(target_feature = "ext:the_extension")]`.
389
+ #[ cfg_attr( feature = "clap" , arg( long) ) ]
353
390
pub extensions : Vec < String > ,
354
391
/// Set additional "codegen arg". Note: the `RUSTGPU_CODEGEN_ARGS` environment variable
355
392
/// takes precedence over any set arguments using this function.
356
393
pub extra_args : Vec < String > ,
357
394
// 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 > ,
359
396
360
397
/// The path of the "target specification" file.
361
398
///
@@ -371,12 +408,26 @@ pub struct SpirvBuilder {
371
408
pub shader_panic_strategy : ShaderPanicStrategy ,
372
409
373
410
/// spirv-val flags
411
+ #[ cfg_attr( feature = "clap" , clap( flatten) ) ]
374
412
pub validator : ValidatorOptions ,
375
413
376
414
/// spirv-opt flags
415
+ #[ cfg_attr( feature = "clap" , clap( flatten) ) ]
377
416
pub optimizer : OptimizerOptions ,
378
417
}
379
418
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
+
380
431
impl Default for SpirvBuilder {
381
432
fn default ( ) -> Self {
382
433
Self {
@@ -547,7 +598,7 @@ impl SpirvBuilder {
547
598
/// Set --default-features for the target shader crate.
548
599
#[ must_use]
549
600
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;
551
602
self
552
603
}
553
604
@@ -897,10 +948,8 @@ fn invoke_rustc(builder: &SpirvBuilder) -> Result<PathBuf, SpirvBuilderError> {
897
948
. join ( format ! ( "{}.json" , target) )
898
949
} ) ) ;
899
950
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" ) ;
904
953
}
905
954
906
955
if !builder. shader_crate_features . features . is_empty ( ) {
0 commit comments