Skip to content

Commit de2cef8

Browse files
committed
compile_codegen: add clap feature, make SpirvBuilder args the same as cargo gpu
1 parent 5235161 commit de2cef8

File tree

3 files changed

+67
-14
lines changed

3 files changed

+67
-14
lines changed

Cargo.lock

+7-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/spirv-builder/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use-compiled-tools = ["rustc_codegen_spirv", "rustc_codegen_spirv?/use-compiled-
2828
skip-toolchain-check = ["rustc_codegen_spirv?/skip-toolchain-check"]
2929

3030
watch = ["dep:notify"]
31+
clap = ["dep:clap"]
3132

3233
[dependencies]
3334
# See comment in `src/lib.rs` `invoke_rustc` regarding `rustc_codegen_spirv` dep.
@@ -44,3 +45,5 @@ serde_json = "1.0"
4445
thiserror = "2.0.12"
4546

4647
notify = { version = "7.0", optional = true }
48+
# Pinning clap, as newer versions have raised min rustc version without being marked a breaking change
49+
clap = { version = "=4.5.37", optional = true, features = ["derive"] }

crates/spirv-builder/src/lib.rs

+57-8
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ pub enum SpirvBuilderError {
124124
const 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))]
127128
pub 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))]
140142
pub 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))]
153156
pub 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))]
236241
pub 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))]
305317
pub 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))]
320334
pub 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))]
329355
pub 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+
380431
impl 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

Comments
 (0)