Skip to content

add spirv-unknown-wgsl target via naga #280

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

Draft
wants to merge 6 commits into
base: target_env_enum
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
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
10 changes: 9 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/rustc_codegen_spirv-target-specs/src/include_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
}
}
}
2 changes: 2 additions & 0 deletions crates/rustc_codegen_spirv-target-specs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
}
6 changes: 4 additions & 2 deletions crates/rustc_codegen_spirv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions crates/rustc_codegen_spirv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions crates/rustc_codegen_spirv/src/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand Down
85 changes: 85 additions & 0 deletions crates/rustc_codegen_spirv/src/naga_transpile.rs
Original file line number Diff line number Diff line change
@@ -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<Option<NagaTranspile>, ErrorGuaranteed> {
let target = SpirvTargetEnv::parse_triple(sess.opts.target_triple.tuple())
.expect("parsing should fail earlier");
let result: Result<Option<NagaTranspile>, ()> = match target {
#[cfg(feature = "naga")]
SpirvTargetEnv::Wgsl => Ok(Some(transpile::wgsl_transpile)),
#[cfg(not(feature = "naga"))]
SpirvTargetEnv::Wgsl => Err(()),
_ => Ok(None),
};
result.map_err(|_e| {
sess.dcx().err(format!(
"Target {} requires feature \"naga\" on rustc_codegen_spirv",
target.target_triple()
))
})
}

#[cfg(feature = "naga")]
mod transpile {
use crate::codegen_cx::CodegenArgs;
use naga::error::ShaderError;
use naga::valid::Capabilities;
use rustc_session::Session;
use rustc_span::ErrorGuaranteed;
use std::path::Path;

pub fn wgsl_transpile(
sess: &Session,
_cg_args: &CodegenArgs,
spv_binary: &[u32],
out_filename: &Path,
) -> Result<(), ErrorGuaranteed> {
// these should be params via spirv-builder
let opts = naga::front::spv::Options::default();
let capabilities = Capabilities::default();
let writer_flags = naga::back::wgsl::WriterFlags::empty();

let module = naga::front::spv::parse_u8_slice(bytemuck::cast_slice(spv_binary), &opts)
.map_err(|err| {
sess.dcx()
.err(format!("Naga failed to parse spv: \n{}", ShaderError {
source: String::new(),
label: None,
inner: Box::new(err),
}))
})?;
let mut validator =
naga::valid::Validator::new(naga::valid::ValidationFlags::default(), capabilities);
let info = validator.validate(&module).map_err(|err| {
sess.dcx()
.err(format!("Naga validation failed: \n{}", ShaderError {
source: String::new(),
label: None,
inner: Box::new(err),
}))
})?;

let wgsl_dst = out_filename.with_extension("wgsl");
let wgsl = naga::back::wgsl::write_string(&module, &info, writer_flags).map_err(|err| {
sess.dcx()
.err(format!("Naga failed to write wgsl : \n{}", err))
})?;

std::fs::write(&wgsl_dst, wgsl).map_err(|err| {
sess.dcx()
.err(format!("failed to write wgsl to file: {}", err))
})?;

Ok(())
}
}
4 changes: 4 additions & 0 deletions crates/rustc_codegen_spirv/src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ impl TargetsExt for SpirvTargetEnv {
| SpirvTargetEnv::Vulkan_1_2
| SpirvTargetEnv::Vulkan_1_3
| SpirvTargetEnv::Vulkan_1_4 => MemoryModel::Vulkan,

SpirvTargetEnv::Wgsl => MemoryModel::Vulkan,
}
}

Expand All @@ -57,6 +59,8 @@ impl TargetsExt for SpirvTargetEnv {
SpirvTargetEnv::Vulkan_1_2 => spirv_tools::TargetEnv::Vulkan_1_2,
SpirvTargetEnv::Vulkan_1_3 => spirv_tools::TargetEnv::Vulkan_1_3,
SpirvTargetEnv::Vulkan_1_4 => spirv_tools::TargetEnv::Vulkan_1_4,

SpirvTargetEnv::Wgsl => spirv_tools::TargetEnv::Vulkan_1_2,
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/compiletests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use-compiled-tools = ["rustc_codegen_spirv/use-compiled-tools"]

[dependencies]
compiletest = { version = "0.11.2", package = "compiletest_rs" }
rustc_codegen_spirv = { workspace = true }
rustc_codegen_spirv = { workspace = true, features = ["naga"] }
rustc_codegen_spirv-target-specs = { workspace = true, features = ["dir_path"] }
clap = { version = "4", features = ["derive"] }
itertools = "0.10.5"
1 change: 1 addition & 0 deletions tests/compiletests/ui/arch/all_memory_barrier.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// build-pass
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
// compile-flags: -C llvm-args=--disassemble-fn=all_memory_barrier::all_memory_barrier
// ignore-wgsl

use spirv_std::spirv;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing
// ignore-wgsl

use spirv_std::spirv;

Expand Down
1 change: 1 addition & 0 deletions tests/compiletests/ui/arch/debug_printf.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+ext:SPV_KHR_non_semantic_info
// ignore-wgsl

use spirv_std::spirv;
use spirv_std::{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// build-pass
//
// compile-flags: -C target-feature=+DemoteToHelperInvocationEXT,+ext:SPV_EXT_demote_to_helper_invocation
// ignore-wgsl

use spirv_std::spirv;

Expand Down
1 change: 1 addition & 0 deletions tests/compiletests/ui/arch/emit_stream_vertex.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -C target-feature=+GeometryStreams
// ignore-wgsl

use spirv_std::spirv;

Expand Down
1 change: 1 addition & 0 deletions tests/compiletests/ui/arch/emit_vertex.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+Geometry
// ignore-wgsl

use spirv_std::spirv;

Expand Down
1 change: 1 addition & 0 deletions tests/compiletests/ui/arch/end_primitive.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+Geometry
// ignore-wgsl

use spirv_std::spirv;

Expand Down
1 change: 1 addition & 0 deletions tests/compiletests/ui/arch/end_stream_primitive.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -C target-feature=+GeometryStreams
// ignore-wgsl

use spirv_std::spirv;

Expand Down
1 change: 1 addition & 0 deletions tests/compiletests/ui/arch/execute_callable.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing
// ignore-wgsl

use spirv_std::spirv;

Expand Down
1 change: 1 addition & 0 deletions tests/compiletests/ui/arch/ignore_intersection_khr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing
// ignore-wgsl

use spirv_std::spirv;

Expand Down
1 change: 1 addition & 0 deletions tests/compiletests/ui/arch/memory_barrier.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// build-pass
// ignore-wgsl

#![feature(adt_const_params)]
#![allow(incomplete_features)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query
// ignore-wgsl

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query
// ignore-wgsl

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query
// ignore-wgsl

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query
// ignore-wgsl

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query
// ignore-wgsl

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query
// ignore-wgsl

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query
// ignore-wgsl

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query
// ignore-wgsl

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query
// ignore-wgsl

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// build-pass
// compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query
// ignore-wgsl

use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
Expand Down
Loading
Loading