diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 1cb32bfb9e..157547670d 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -119,9 +119,17 @@ jobs:
compiletest:
name: Compiletest
strategy:
+ fail-fast: false
matrix:
os: [ ubuntu-24.04, windows-2022, macOS-latest ]
+ target_env: [ "vulkan1.1,vulkan1.2,vulkan1.3,vulkan1.4" ]
+ experimental: [ false ]
+ include:
+ - os: ubuntu-24.04
+ target_env: wgsl
+ experimental: true
runs-on: ${{ matrix.os }}
+ continue-on-error: ${{ matrix.experimental }}
steps:
- uses: actions/checkout@v4
- name: Install Vulkan SDK
@@ -134,7 +142,7 @@ jobs:
- name: cargo fetch --locked
run: cargo fetch --locked --target $TARGET
- name: compiletest
- run: cargo run -p compiletests --release --no-default-features --features "use-installed-tools" -- --target-env vulkan1.1,vulkan1.2,vulkan1.3,vulkan1.4,spv1.3
+ run: cargo run -p compiletests --release --no-default-features --features "use-installed-tools" -- --target-env ${{ matrix.target_env }}
difftest:
name: Difftest
diff --git a/Cargo.lock b/Cargo.lock
index 985d14bf2b..c7469e33aa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2433,6 +2433,7 @@ dependencies = [
"lazy_static",
"libc",
"log",
+ "naga",
"object",
"pretty_assertions",
"regex",
diff --git a/crates/rustc_codegen_spirv-target-specs/src/include_str.rs b/crates/rustc_codegen_spirv-target-specs/src/include_str.rs
index 93941e8da4..ab6b7a4415 100644
--- a/crates/rustc_codegen_spirv-target-specs/src/include_str.rs
+++ b/crates/rustc_codegen_spirv-target-specs/src/include_str.rs
@@ -59,6 +59,9 @@ impl SpirvTargetEnv {
SpirvTargetEnv::Vulkan_1_4 => {
include_str!("../target-specs/spirv-unknown-vulkan1.4.json")
}
+ SpirvTargetEnv::Wgsl => {
+ include_str!("../target-specs/spirv-unknown-wgsl.json")
+ }
}
}
}
diff --git a/crates/rustc_codegen_spirv-target-specs/src/lib.rs b/crates/rustc_codegen_spirv-target-specs/src/lib.rs
index 85f0bdcaea..deb1f12ab2 100644
--- a/crates/rustc_codegen_spirv-target-specs/src/lib.rs
+++ b/crates/rustc_codegen_spirv-target-specs/src/lib.rs
@@ -60,6 +60,8 @@ pub enum SpirvTargetEnv {
Vulkan_1_3,
#[strum(to_string = "vulkan1.4")]
Vulkan_1_4,
+ #[strum(to_string = "wgsl")]
+ Wgsl,
}
#[derive(Clone, Error, Eq, PartialEq)]
diff --git a/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-wgsl.json b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-wgsl.json
new file mode 100644
index 0000000000..602d077026
--- /dev/null
+++ b/crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-wgsl.json
@@ -0,0 +1,26 @@
+{
+ "allows-weak-linkage": false,
+ "arch": "spirv",
+ "crt-objects-fallback": "false",
+ "crt-static-allows-dylibs": true,
+ "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64",
+ "dll-prefix": "",
+ "dll-suffix": ".spv.json",
+ "dynamic-linking": true,
+ "emit-debug-gdb-scripts": false,
+ "env": "wgsl",
+ "linker-flavor": "unix",
+ "linker-is-gnu": false,
+ "llvm-target": "spirv-unknown-wgsl",
+ "main-needs-argc-argv": false,
+ "metadata": {
+ "description": null,
+ "host_tools": null,
+ "std": null,
+ "tier": null
+ },
+ "os": "unknown",
+ "panic-strategy": "abort",
+ "simd-types-indirect": false,
+ "target-pointer-width": "32"
+}
diff --git a/crates/rustc_codegen_spirv/Cargo.toml b/crates/rustc_codegen_spirv/Cargo.toml
index 5af8dbea20..ac45397f4a 100644
--- a/crates/rustc_codegen_spirv/Cargo.toml
+++ b/crates/rustc_codegen_spirv/Cargo.toml
@@ -20,15 +20,16 @@ crate-type = ["dylib"]
default = ["use-compiled-tools"]
# If enabled, uses spirv-tools binaries installed in PATH, instead of
# compiling and linking the spirv-tools C++ code
-use-installed-tools = ["spirv-tools/use-installed-tools"]
+use-installed-tools = ["spirv-tools/use-installed-tools", "naga"]
# If enabled will compile and link the C++ code for the spirv tools, the compiled
# version is preferred if both this and `use-installed-tools` are enabled
-use-compiled-tools = ["spirv-tools/use-compiled-tools"]
+use-compiled-tools = ["spirv-tools/use-compiled-tools", "naga"]
# If enabled, this will not check whether the current rustc version is set to the
# appropriate channel. rustc_cogeden_spirv requires a specific nightly version,
# and will likely produce compile errors when built against a different toolchain.
# Enable this feature to be able to experiment with other versions.
skip-toolchain-check = []
+naga = ["dep:naga"]
[dependencies]
# HACK(eddyb) these only exist to unify features across dependency trees,
@@ -60,6 +61,7 @@ itertools = "0.10.5"
tracing.workspace = true
tracing-subscriber.workspace = true
tracing-tree = "0.3.0"
+naga = { version = "25.0.1", features = ["spv-in", "wgsl-out"], optional = true }
# required for cargo gpu to resolve the needed target specs
rustc_codegen_spirv-target-specs.workspace = true
diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs
index 82d8e8e7a2..2422bc42a8 100644
--- a/crates/rustc_codegen_spirv/src/lib.rs
+++ b/crates/rustc_codegen_spirv/src/lib.rs
@@ -129,6 +129,7 @@ mod custom_decorations;
mod custom_insts;
mod link;
mod linker;
+mod naga_transpile;
mod spirv_type;
mod spirv_type_constraints;
mod symbols;
diff --git a/crates/rustc_codegen_spirv/src/link.rs b/crates/rustc_codegen_spirv/src/link.rs
index 4c702b7c78..760e107125 100644
--- a/crates/rustc_codegen_spirv/src/link.rs
+++ b/crates/rustc_codegen_spirv/src/link.rs
@@ -2,6 +2,7 @@
use crate::maybe_pqp_cg_ssa as rustc_codegen_ssa;
use crate::codegen_cx::{CodegenArgs, SpirvMetadata};
+use crate::naga_transpile::should_transpile;
use crate::{SpirvCodegenBackend, SpirvModuleBuffer, SpirvThinBuffer, linker};
use ar::{Archive, GnuBuilder, Header};
use rspirv::binary::Assemble;
@@ -311,6 +312,10 @@ fn post_link_single_module(
drop(save_modules_timer);
}
+
+ if let Ok(Some(transpile)) = should_transpile(sess) {
+ transpile(sess, cg_args, &spv_binary, out_filename).ok();
+ }
}
fn do_spirv_opt(
diff --git a/crates/rustc_codegen_spirv/src/naga_transpile.rs b/crates/rustc_codegen_spirv/src/naga_transpile.rs
new file mode 100644
index 0000000000..15bcc13f2a
--- /dev/null
+++ b/crates/rustc_codegen_spirv/src/naga_transpile.rs
@@ -0,0 +1,85 @@
+use crate::codegen_cx::CodegenArgs;
+use rustc_codegen_spirv_target_specs::SpirvTargetEnv;
+use rustc_session::Session;
+use rustc_span::ErrorGuaranteed;
+use std::path::Path;
+
+pub type NagaTranspile = fn(
+ sess: &Session,
+ cg_args: &CodegenArgs,
+ spv_binary: &[u32],
+ out_filename: &Path,
+) -> Result<(), ErrorGuaranteed>;
+
+pub fn should_transpile(sess: &Session) -> Result