Skip to content

show-targets #36 #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jun 6, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions crates/cargo-gpu/src/show.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Display various information about `cargo gpu`, eg its cache directory.

use std::process::{Command, Stdio};

use crate::cache_dir;

/// Show the computed source of the spirv-std dependency.
Expand All @@ -21,6 +23,9 @@ pub enum Info {
Commitsh,
/// All the available SPIR-V capabilities that can be set with `--capabilities`
Capabilities,

/// All available SPIR-V targets
Targets,
}

/// `cargo gpu show`
Expand Down Expand Up @@ -63,6 +68,10 @@ impl Show {
println!(" {capability:?}");
}
}
Info::Targets => {
let target_info = get_spirv_targets()?.join("\n");
println!("{}", target_info);
}
}

Ok(())
Expand All @@ -77,3 +86,42 @@ impl Show {
(0..=last_capability).filter_map(spirv_builder::Capability::from_u32)
}
}

/// Gets available SPIR-V targets by calling the `spirv-tools`' validator:
/// ```sh
/// $ spirv-val --version
/// SPIRV-Tools v2022.2-dev unknown hash, 2022-02-16T16:37:15
/// Targets:
/// SPIR-V 1.0
/// SPIR-V 1.1
/// SPIR-V 1.2
/// ... snip for brevity
/// SPIR-V 1.6 (under Vulkan 1.3 semantics)
/// ```
fn get_spirv_targets() -> anyhow::Result<Vec<String>> {
// Defaults that have been tested, 1.2 is the existing default in the shader-crate-template.toml
let mut targets = vec![
"spirv-unknown-vulkan1.0",
"spirv-unknown-vulkan1.1",
"spirv-unknown-vulkan1.2",
];

let output = Command::new("spirv-val")
Copy link
Member

@Firestar99 Firestar99 Jun 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot guarantee that the end user has spirv-val installed on their system. Cargo gpu compiles spirv-tools itself when building rustc_codegen_spirv and statically links it, and in theory you'd have to ask that one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep -- had feeling there'd be a better way. TY

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can just use pub use include_str::TARGET_SPECS; no?

~/.cache/rust-gpu/codegen/<version_string>/target-specs/'s dir contents would be more tedious & obviously non friendly to those unfortunate enough to have to develop on Windows.

It wouldn't be too hard (I think?) to whip up a const fn that just lists of the ones that were used to compile cargo gpu itself, but it seems a shame to support only specs that were compiled in during install... no?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note where that symbol is coming from:

//! Legacy target specs are spec jsons for versions before `rustc_codegen_spirv-target-specs`
//! came bundled with them. Instead, cargo gpu needs to bundle these legacy spec files. Luckily,
//! they are the same for all versions, as bundling target specs with the codegen backend was
//! introduced before the first target spec update.

If future versions of rust-gpu introduce new targets (such as spirv-unknown-vulkan1.3), they won't be listed. Which also means targets are dependent on the version of rust-gpu used. I'd recommend doing the same as cargo build does, have a --shader-crate arg that defaults to ./.

.arg("--version")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output();

if let Ok(output) = output {
let version_info = String::from_utf8_lossy(&output.stdout);
if version_info.contains("SPIR-V 1.3") {
targets.push("spirv-unknown-vulkan1.3");
}
if version_info.contains("SPIR-V 1.4") {
targets.push("spirv-unknown-vulkan1.4");
}
// Exhaustively, manually put in all possible versions? or regex them out?
}

Ok(targets.into_iter().map(String::from).collect())
}