Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
624e6f4
Update rspirv/spirv to sdk-update branch with newer SPIR-V opcodes
LegNeato Jan 24, 2026
92f877a
Switch spirv-tools to Rust-GPU/SPIRV-Tools git dependency
LegNeato Jan 24, 2026
221f68d
Update for rspirv sdk-update branch API changes
LegNeato Jan 24, 2026
25f2433
Add rich validation error messages with source spans
LegNeato Jan 24, 2026
a4ec233
Update feature docs and test expectations for pure Rust spirv-tools
LegNeato Jan 24, 2026
9382914
Pass Module directly to do_spirv_val instead of re-parsing binary
LegNeato Jan 24, 2026
15513e1
Add rich error handling for NotALogicalPointer validation errors
LegNeato Jan 24, 2026
e36f9be
Remove redundant 'spirv-val failed' note from validation errors
LegNeato Jan 25, 2026
0fa745e
Add rich error handling for additional validation errors
LegNeato Jan 25, 2026
a21804d
Remove replacements and comments no longer needed
LegNeato Jan 27, 2026
2fcb8ad
rustfmt
LegNeato Jan 27, 2026
a71afb8
Update SPIRV-Tools to include vendored grammar and license fix
LegNeato Jan 27, 2026
efc70c1
Allow MPL-2.0 license for egglog transitive deps
LegNeato Jan 27, 2026
968a71c
Fix clippy lints in validation_err.rs and codegen_cx/mod.rs
LegNeato Feb 2, 2026
e36569c
Update SPIRV-Tools to include VulkanMemoryModel validation fix
LegNeato Feb 2, 2026
7214cf1
Update SPIRV-Tools to include assembler float literal fix
LegNeato Feb 2, 2026
667adba
Fix rustfmt formatting in validation_err.rs
LegNeato Feb 2, 2026
18b8018
Update SPIRV-Tools to include ported validation rules
LegNeato Feb 2, 2026
6d2d81c
Fix member_ref_arg-broken.stderr line numbers after normalize comment…
LegNeato Feb 2, 2026
f78f99d
Update SPIRV-Tools to fix extension version requirements
LegNeato Feb 2, 2026
76ffa3a
Update SPIRV-Tools to remove ray tracing extension version check
LegNeato Feb 2, 2026
58c37ff
Fix CI: add missing capability deps and patch difftest rspirv
LegNeato Feb 2, 2026
5393ce4
Update SPIRV-Tools to fix capability extension validation
LegNeato Feb 2, 2026
9da9eeb
Update SPIRV-Tools to fix operand extension validation
LegNeato Feb 2, 2026
e4a8d39
Add missing ClipDistance and CullDistance capabilities to all-builtin…
LegNeato Feb 2, 2026
bcbe168
Update SPIRV-Tools to fix optimizer 'use of undefined id' errors
LegNeato Feb 2, 2026
1d10a6c
Update SPIRV-Tools to fix duplicate ID definitions in optimizer
LegNeato Feb 3, 2026
45d6479
Update SPIRV-Tools to fix materialized constants duplicate ID bug
LegNeato Feb 4, 2026
ae4a387
Update SPIRV-Tools (formatting)
LegNeato Feb 4, 2026
190bdff
Update SPIRV-Tools to fix ViewIndex validation
LegNeato Feb 4, 2026
02f0802
Update SPIRV-Tools with InstanceId validation fix
LegNeato Feb 4, 2026
0bf9d1b
Update SPIRV-Tools with builtin direction validation fix
LegNeato Feb 4, 2026
8af66e5
Update SPIRV-Tools to allow extensions for Universal targets
LegNeato Feb 4, 2026
e86cc3c
Update SPIRV-Tools to fix block layout std430 array stride validation
LegNeato Feb 4, 2026
56ac96b
Update SPIRV-Tools with block layout strictness fixes
LegNeato Feb 4, 2026
3c17715
Update SPIRV-Tools to fix row-major matrix layout validation
LegNeato Feb 5, 2026
cfb1225
Update SPIRV-Tools to enable relaxed block layout for Universal 1.3+
LegNeato Feb 5, 2026
1c2cfd9
Update SPIRV-Tools to split large files into submodules
LegNeato Feb 5, 2026
971cb87
Update SPIRV-Tools with post-dominator computation and validation fixes
LegNeato Feb 6, 2026
7fe76ec
Update SPIRV-Tools to include cargo fmt pass
LegNeato Feb 6, 2026
7d4418e
Update SPIRV-Tools to remove Vulkan-only restriction on mesh EXT buil…
LegNeato Feb 6, 2026
a8118ed
Update SPIRV-Tools with image capability and query validation checks
LegNeato Feb 6, 2026
eff75f3
Update SPIRV-Tools with formatting fixes
LegNeato Feb 6, 2026
55dbc5d
Update SPIRV-Tools with clippy fixes
LegNeato Feb 6, 2026
a21d7eb
Update SPIRV-Tools with formatting fix
LegNeato Feb 6, 2026
02c56a1
Update SPIRV-Tools with clippy and formatting fixes
LegNeato Feb 6, 2026
78052b1
Update SPIRV-Tools to remove SubpassData Vulkan-only restriction
LegNeato Feb 6, 2026
ec373b7
Update cargo.lock to fix cargo deny
LegNeato Feb 6, 2026
65103da
Update SPIRV-Tools: fix IEqual/INotEqual signedness and add cooperati…
LegNeato Feb 6, 2026
8c3d11c
Update SPIRV-Tools: separate boolean constants from integer constants…
LegNeato Feb 6, 2026
af5e94f
Update SPIRV-Tools to fix optimizer reconstruction bugs
LegNeato Feb 6, 2026
d06c26b
Update SPIRV-Tools: add egraph-level type tracking to prevent cross-t…
LegNeato Feb 6, 2026
b7817c2
Update SPIRV-Tools: fix extraction type inference, loop detection, an…
LegNeato Feb 6, 2026
ee26932
Update SPIRV-Tools: strict type-class validation in optimizer
LegNeato Feb 6, 2026
8a6ceed
Update SPIRV-Tools to e2dadb15
LegNeato Feb 9, 2026
8c5fbac
Update SPIRV-Tools to 1b2819a2
LegNeato Feb 9, 2026
d3a8358
Update SPIRV-Tools to 22bcfb12
LegNeato Feb 9, 2026
85e4f21
Update SPIRV-Tools to a9b807bf
LegNeato Feb 9, 2026
85f7f81
Update spirv-tools to b8a5f5db
LegNeato Feb 9, 2026
cf9af46
Update SPIRV-Tools to fix sort validation in egglog optimizer
LegNeato Feb 9, 2026
5723972
Update SPIRV-Tools to fix Theta/Gamma sort mismatches
LegNeato Feb 9, 2026
61676eb
Update SPIRV-Tools to latest
LegNeato Feb 13, 2026
60655c2
Update spirv-tools to pick up emission layer simplifications
LegNeato Feb 14, 2026
caef1f8
Update SPIRV-Tools: constant key fixes, dead code removal, emission p…
LegNeato Feb 14, 2026
8f7e9e1
Update SPIRV-Tools: fix CompositeExtract lookup failure
LegNeato Feb 14, 2026
fd4b975
Update SPIRV-Tools: bridge wrapping for composite sort mismatches
LegNeato Feb 14, 2026
d203db3
Update SPIRV-Tools: systematic sort-mismatch fix for Expr-sort constr…
LegNeato Feb 14, 2026
0c7df5e
Update SPIRV-Tools to fix sort mismatches, missing constructors, div-…
LegNeato Feb 14, 2026
8b97987
Update SPIRV-Tools to 4934cae7 (sort-coercion consistency pass)
LegNeato Feb 14, 2026
0c8edfb
Update SPIRV-Tools: fix loop continue, store types, int signedness, OOM
LegNeato Feb 15, 2026
9d00099
Update SPIRV-Tools: remove matrix decomposition rules, add regression…
LegNeato Feb 15, 2026
ec92983
Update SPIRV-Tools: revert signed-int preference
LegNeato Feb 15, 2026
56a68be
Update SPIRV-Tools: fix emit type propagation, strip unsafe egraph rules
LegNeato Feb 15, 2026
df240cf
Update SPIRV-Tools to e489df7b (AccessChainDyn emission fix)
LegNeato Feb 15, 2026
1582d12
Update SPIRV-Tools to 43ff6203 (AccessChainDyn idx_type fix)
LegNeato Feb 15, 2026
1fca1ad
Update SPIRV-Tools to e9157f15 (corrected_type removal, iteration lim…
LegNeato Feb 15, 2026
77fe4c6
Update SPIRV-Tools to ad8bdfb8 (revert signed int preference)
LegNeato Feb 15, 2026
061871e
Update SPIRV-Tools to d4280cf0 (element types, continue block protect…
LegNeato Feb 15, 2026
0b5525c
Update SPIRV-Tools to 3d85fc69 (EffGamma condition, loop guards, alia…
LegNeato Feb 15, 2026
961985e
Update SPIRV-Tools to 33561fc8 (CFG loop body, remove Theta union, DC…
LegNeato Feb 15, 2026
769599c
Update SPIRV-Tools to 73d87aba (type-safe aliases, BFS loop body)
LegNeato Feb 15, 2026
f0d08b9
Update SPIRV-Tools to 2f43dba9 (VecShuffle identity VecSize guards)
LegNeato Feb 15, 2026
61ee12e
Update SPIRV-Tools to 7f7961e0 (switch-in-loop guard, width validation)
LegNeato Feb 15, 2026
5576324
Update SPIRV-Tools to 7054230c (signed int preference)
LegNeato Feb 15, 2026
9b4e14b
Update SPIRV-Tools to 78aee01a (reduce egraph iterations)
LegNeato Feb 15, 2026
50b8ffd
Update SPIRV-Tools to eb06849a (per-operation signed int resolution)
LegNeato Feb 15, 2026
6264b32
Update SPIRV-Tools to eee67f19 (id_map rollback on width validation f…
LegNeato Feb 15, 2026
76dab8c
Update SPIRV-Tools to 6fef24a3 (skip CopyObject on type mismatch, id_…
LegNeato Feb 15, 2026
f54883d
Update SPIRV-Tools: guard continue blocks, validate output IDs
LegNeato Feb 15, 2026
52c59ef
Update SPIRV-Tools: fix both CopyObject type-match paths
LegNeato Feb 15, 2026
6e42c34
Update SPIRV-Tools: disable unsound egraph integer rules
LegNeato Feb 15, 2026
46ecf1e
Update SPIRV-Tools: fix continue block guards, BitAnd carry, ShrU shift
LegNeato Feb 15, 2026
4520d88
Update SPIRV-Tools: fix NaN correctness and egraph explosion rules
LegNeato Feb 15, 2026
b90be6b
Update SPIRV-Tools to fix OpSwitch validator false positives
LegNeato Feb 16, 2026
bef6612
Update SPIRV-Tools to fix PRE hoisting branch collapse bug
LegNeato Feb 16, 2026
90e3da2
Update SPIRV-Tools with PRE hoisting improvements
LegNeato Feb 16, 2026
90091ff
Update SPIRV-Tools to fix sky-shader egraph OOM
LegNeato Feb 16, 2026
3819cf2
Update SPIRV-Tools to fix mouse-shader egraph OOM
LegNeato Feb 16, 2026
898209b
Update SPIRV-Tools to fix constant chain merging egraph explosion
LegNeato Feb 16, 2026
dfe213f
Update SPIRV-Tools to fix debug build panic
LegNeato Feb 16, 2026
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
1,205 changes: 1,017 additions & 188 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ spirv-builder = { path = "./crates/spirv-builder", version = "=0.9.0", default-f
spirv-std = { path = "./crates/spirv-std", version = "=0.9.0" }
spirv-std-types = { path = "./crates/spirv-std/shared", version = "=0.9.0" }
spirv-std-macros = { path = "./crates/spirv-std/macros", version = "=0.9.0" }
spirv-tools = { version = "0.13.0", default-features = false }
spirv-tools = { git = "https://github.com/Rust-GPU/SPIRV-Tools", default-features = false }
rustc_codegen_spirv = { path = "./crates/rustc_codegen_spirv", version = "=0.9.0", default-features = false }
rustc_codegen_spirv-types = { path = "./crates/rustc_codegen_spirv-types", version = "=0.9.0" }

Expand All @@ -61,6 +61,12 @@ glam = { version = ">=0.30.8", default-features = false }
libm = { version = "0.2.5", default-features = false }
bytemuck = { version = "1.23", features = ["derive"] }

# Patch rspirv/spirv to use newer versions with additional SPIR-V opcodes needed by spirv-tools.
# TODO: Once a newer rspirv is published that includes these opcodes, switch to a crates.io version.
[patch.crates-io]
rspirv = { git = "https://github.com/gfx-rs/rspirv", branch = "sdk-update" }
spirv = { git = "https://github.com/gfx-rs/rspirv", branch = "sdk-update", package = "spirv" }

# Enable incremental by default in release mode.
[profile.release]
incremental = true
Expand Down
17 changes: 4 additions & 13 deletions crates/rustc_codegen_spirv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,11 @@ repository.workspace = true
crate-type = ["dylib"]

[features]
# By default, the use-compiled-tools is enabled, as doesn't require additional
# setup steps for the user. This does however mean that you will need to disable
# default features and explicitly enable `use-installed-tools` if you are using
# this in an environment with spirv-tools in PATH, and you don't want to take
# the compile time cost
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"]
# 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"]
# These features are no-ops kept for compatibility with existing build configurations.
use-installed-tools = []
use-compiled-tools = []
# 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,
# appropriate channel. rustc_codegen_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 = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn ordering_to_semantics_def(&mut self, ordering: AtomicOrdering) -> SpirvValue {
let mut invalid_seq_cst = false;
let semantics = match ordering {
AtomicOrdering::Relaxed => MemorySemantics::NONE,
AtomicOrdering::Relaxed => MemorySemantics::RELAXED,
AtomicOrdering::Acquire => MemorySemantics::MAKE_VISIBLE | MemorySemantics::ACQUIRE,
AtomicOrdering::Release => MemorySemantics::MAKE_AVAILABLE | MemorySemantics::RELEASE,
AtomicOrdering::AcqRel => {
Expand Down
79 changes: 58 additions & 21 deletions crates/rustc_codegen_spirv/src/builder/spirv_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,23 @@ pub struct InstructionTable {

impl InstructionTable {
pub fn new() -> Self {
let table = rspirv::grammar::CoreInstructionTable::iter()
let mut table: FxHashMap<_, _> = rspirv::grammar::CoreInstructionTable::iter()
.map(|inst| (inst.opname, inst))
.collect();

// Add aliases for EXT/KHR instructions whose suffixes were removed
for inst in rspirv::grammar::CoreInstructionTable::iter() {
match inst.opname {
"DemoteToHelperInvocation" => {
table.insert("DemoteToHelperInvocationEXT", inst);
}
"IsHelperInvocation" => {
table.insert("IsHelperInvocationEXT", inst);
}
_ => {}
}
}

Self { table }
}
}
Expand Down Expand Up @@ -1529,6 +1543,38 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> {
Ok(x) => inst.operands.push(dr::Operand::StoreCacheControl(x)),
Err(()) => self.err(format!("unknown StoreCacheControl {word}")),
},
// New operand kinds added in newer SPIR-V versions - not yet supported in inline asm
(OperandKind::RawAccessChainOperands, Some(word)) => {
self.err(format!("RawAccessChainOperands not yet supported: {word}"));
}
(OperandKind::CooperativeMatrixReduce, Some(word)) => {
self.err(format!("CooperativeMatrixReduce not yet supported: {word}"));
}
(OperandKind::TensorClampMode, Some(word)) => {
self.err(format!("TensorClampMode not yet supported: {word}"));
}
(OperandKind::TensorAddressingOperands, Some(word)) => {
self.err(format!(
"TensorAddressingOperands not yet supported: {word}"
));
}
(OperandKind::FPEncoding, Some(word)) => {
self.err(format!("FPEncoding not yet supported: {word}"));
}
(OperandKind::NamedMaximumNumberOfRegisters, Some(word)) => {
self.err(format!(
"NamedMaximumNumberOfRegisters not yet supported: {word}"
));
}
(OperandKind::MatrixMultiplyAccumulateOperands, Some(word)) => {
self.err(format!(
"MatrixMultiplyAccumulateOperands not yet supported: {word}"
));
}
// Catch-all for any other new operand kinds
(kind, Some(word)) => {
self.err(format!("unsupported operand kind {kind:?}: {word}"));
}
(kind, None) => match token {
Token::Word(_) => bug!(),
Token::String(_) => {
Expand Down Expand Up @@ -1563,16 +1609,13 @@ pub const IMAGE_OPERANDS: &[(&str, ImageOperands)] = &[
("Sample", ImageOperands::SAMPLE),
("MinLod", ImageOperands::MIN_LOD),
("MakeTexelAvailable", ImageOperands::MAKE_TEXEL_AVAILABLE),
(
"MakeTexelAvailableKHR",
ImageOperands::MAKE_TEXEL_AVAILABLE_KHR,
),
("MakeTexelAvailableKHR", ImageOperands::MAKE_TEXEL_AVAILABLE),
("MakeTexelVisible", ImageOperands::MAKE_TEXEL_VISIBLE),
("MakeTexelVisibleKHR", ImageOperands::MAKE_TEXEL_VISIBLE_KHR),
("MakeTexelVisibleKHR", ImageOperands::MAKE_TEXEL_VISIBLE),
("NonPrivateTexel", ImageOperands::NON_PRIVATE_TEXEL),
("NonPrivateTexelKHR", ImageOperands::NON_PRIVATE_TEXEL_KHR),
("NonPrivateTexelKHR", ImageOperands::NON_PRIVATE_TEXEL),
("VolatileTexel", ImageOperands::VOLATILE_TEXEL),
("VolatileTexelKHR", ImageOperands::VOLATILE_TEXEL_KHR),
("VolatileTexelKHR", ImageOperands::VOLATILE_TEXEL),
("SignExtend", ImageOperands::SIGN_EXTEND),
("ZeroExtend", ImageOperands::ZERO_EXTEND),
];
Expand Down Expand Up @@ -1610,7 +1653,7 @@ pub const FUNCTION_CONTROL: &[(&str, FunctionControl)] = &[
];
pub const MEMORY_SEMANTICS: &[(&str, MemorySemantics)] = &[
("Relaxed", MemorySemantics::RELAXED),
("None", MemorySemantics::NONE),
("None", MemorySemantics::RELAXED),
("Acquire", MemorySemantics::ACQUIRE),
("Release", MemorySemantics::RELEASE),
("AcquireRelease", MemorySemantics::ACQUIRE_RELEASE),
Expand All @@ -1631,11 +1674,11 @@ pub const MEMORY_SEMANTICS: &[(&str, MemorySemantics)] = &[
),
("ImageMemory", MemorySemantics::IMAGE_MEMORY),
("OutputMemory", MemorySemantics::OUTPUT_MEMORY),
("OutputMemoryKHR", MemorySemantics::OUTPUT_MEMORY_KHR),
("OutputMemoryKHR", MemorySemantics::OUTPUT_MEMORY),
("MakeAvailable", MemorySemantics::MAKE_AVAILABLE),
("MakeAvailableKHR", MemorySemantics::MAKE_AVAILABLE_KHR),
("MakeAvailableKHR", MemorySemantics::MAKE_AVAILABLE),
("MakeVisible", MemorySemantics::MAKE_VISIBLE),
("MakeVisibleKHR", MemorySemantics::MAKE_VISIBLE_KHR),
("MakeVisibleKHR", MemorySemantics::MAKE_VISIBLE),
("Volatile", MemorySemantics::VOLATILE),
];
pub const MEMORY_ACCESS: &[(&str, MemoryAccess)] = &[
Expand All @@ -1646,18 +1689,12 @@ pub const MEMORY_ACCESS: &[(&str, MemoryAccess)] = &[
("MakePointerAvailable", MemoryAccess::MAKE_POINTER_AVAILABLE),
(
"MakePointerAvailableKHR",
MemoryAccess::MAKE_POINTER_AVAILABLE_KHR,
MemoryAccess::MAKE_POINTER_AVAILABLE,
),
("MakePointerVisible", MemoryAccess::MAKE_POINTER_VISIBLE),
(
"MakePointerVisibleKHR",
MemoryAccess::MAKE_POINTER_VISIBLE_KHR,
),
("MakePointerVisibleKHR", MemoryAccess::MAKE_POINTER_VISIBLE),
("NonPrivatePointer", MemoryAccess::NON_PRIVATE_POINTER),
(
"NonPrivatePointerKHR",
MemoryAccess::NON_PRIVATE_POINTER_KHR,
),
("NonPrivatePointerKHR", MemoryAccess::NON_PRIVATE_POINTER),
];
pub const KERNEL_PROFILING_INFO: &[(&str, KernelProfilingInfo)] = &[
("None", KernelProfilingInfo::NONE),
Expand Down
9 changes: 9 additions & 0 deletions crates/rustc_codegen_spirv/src/codegen_cx/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::abi::ConvSpirvType;
use crate::attr::{AggregatedSpirvAttributes, Entry, Spanned, SpecConstant};
use crate::builder::Builder;
use crate::builder_spirv::{SpirvFunctionCursor, SpirvValue, SpirvValueExt};
use crate::custom_decorations::{CustomDecoration, SrcLocDecoration};
use crate::spirv_type::SpirvType;
use rspirv::dr::Operand;
use rspirv::spirv::{
Expand Down Expand Up @@ -987,6 +988,14 @@ impl<'tcx> CodegenCx<'tcx> {
self.emit_global()
.variable(var_ptr_spirv_type, Some(var), storage_class, None);

// Add SrcLocDecoration to the variable for rich error messages.
let src_loc_inst = SrcLocDecoration::from_rustc_span(hir_param.span, &self.builder)
.map(|src_loc| src_loc.encode_to_inst(var));
self.emit_global()
.module_mut()
.annotations
.extend(src_loc_inst);

// Record this `OpVariable` as needing to be added (if applicable),
// to the *Interface* operands of the `OpEntryPoint` instruction.
if self.emit_global().version().unwrap() > (1, 3) {
Expand Down
12 changes: 12 additions & 0 deletions crates/rustc_codegen_spirv/src/codegen_cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,10 @@ pub struct CodegenArgs {

pub run_spirv_opt: bool,

/// Preserve internal debug decorations (`SrcLocDecoration`, `ZombieDecoration`) in the output.
/// These are normally stripped after validation. Enable for debugging or testing.
pub preserve_debug_decorations: bool,

/// All options pertinent to `rustc_codegen_spirv::linker` specifically.
//
// FIXME(eddyb) should these be handled as `-C linker-args="..."` instead?
Expand Down Expand Up @@ -384,6 +388,12 @@ impl CodegenArgs {
"disables running spirv-opt on the final output",
);

opts.optflag(
"",
"preserve-debug-decorations",
"preserve internal debug decorations (SrcLocDecoration, ZombieDecoration) in the output",
);

opts.optflag(
"",
"preserve-bindings",
Expand Down Expand Up @@ -652,6 +662,8 @@ impl CodegenArgs {

run_spirv_opt,

preserve_debug_decorations: matches.opt_present("preserve-debug-decorations"),

linker_opts,

// NOTE(eddyb) these are debugging options that used to be env vars
Expand Down
11 changes: 7 additions & 4 deletions crates/rustc_codegen_spirv/src/custom_decorations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::{fmt, iter, slice, str};

/// Decorations not native to SPIR-V require some form of encoding into existing
/// SPIR-V constructs, for which we use `OpDecorateString` with decoration type
/// `UserTypeGOOGLE` and some encoded Rust value as the decoration string.
/// `UserSemantic` and some encoded Rust value as the decoration string.
///
/// Each decoration type has to implement this trait, and use a different
/// `ENCODING_PREFIX` from any other decoration type, to disambiguate them.
Expand All @@ -27,7 +27,10 @@ use std::{fmt, iter, slice, str};
/// ideally as soon as they're no longer needed, because no other tools
/// processing the SPIR-V would understand them correctly.
///
/// TODO: uses `non_semantic` instead of piggybacking off of `UserTypeGOOGLE`
/// Custom decorations are encoded using `OpDecorateString` with `UserSemantic`,
/// which is a standard SPIR-V decoration that doesn't require any extension.
///
/// TODO: consider using `non_semantic` instead for even cleaner separation
/// <https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/KHR/SPV_KHR_non_semantic_info.html>
pub trait CustomDecoration<'a>: Sized {
const ENCODING_PREFIX: &'static str;
Expand All @@ -45,15 +48,15 @@ pub trait CustomDecoration<'a>: Sized {
None,
vec![
Operand::IdRef(id),
Operand::Decoration(Decoration::UserTypeGOOGLE),
Operand::Decoration(Decoration::UserSemantic),
Operand::LiteralString(encoded),
],
)
}

fn try_decode_from_inst(inst: &Instruction) -> Option<(Word, LazilyDecoded<'_, Self>)> {
if inst.class.opcode == Op::DecorateString
&& inst.operands[1].unwrap_decoration() == Decoration::UserTypeGOOGLE
&& inst.operands[1].unwrap_decoration() == Decoration::UserSemantic
{
let id = inst.operands[0].unwrap_id_ref();
let prefixed_encoded = inst.operands[2].unwrap_literal_string();
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 @@ -138,6 +138,7 @@ mod spirv_type_constraints;
mod symbols;
mod target;
mod target_feature;
mod validation_err;

use builder::Builder;
use codegen_cx::CodegenCx;
Expand Down
40 changes: 33 additions & 7 deletions crates/rustc_codegen_spirv/src/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,26 @@ fn post_link_single_module(
out_filename: &Path,
dump_prefix: Option<&OsStr>,
) {
cg_args.do_disassemble(&module);
let spv_binary = module.assemble();
use crate::custom_decorations::{CustomDecoration, SrcLocDecoration, ZombieDecoration};

// Strip internal debug decorations (SrcLocDecoration, ZombieDecoration) BEFORE
// disassembly/validation/optimization unless preserve_debug_decorations is set.
// These decorations are only valid on certain targets (variables), but rust-gpu
// also places them on functions for span tracking which is invalid SPIR-V.
// Keep the original module for span lookup in error messages.
let (module_for_output, original_module_for_spans) = if cg_args.preserve_debug_decorations {
// When preserving decorations, use the same module for both
(module.clone(), module)
} else {
let mut stripped = module.clone();
SrcLocDecoration::remove_all(&mut stripped);
ZombieDecoration::remove_all(&mut stripped);
(stripped, module)
};

// Disassemble the stripped module (unless preserving decorations)
cg_args.do_disassemble(&module_for_output);
let spv_binary = module_for_output.assemble();

if let Some(dir) = &cg_args.dump_post_link {
// FIXME(eddyb) rename `filename` with `file_path` to make this less confusing.
Expand Down Expand Up @@ -305,7 +323,13 @@ fn post_link_single_module(
};

if cg_args.run_spirv_val {
do_spirv_val(sess, &spv_binary, out_filename, val_options);
do_spirv_val(
sess,
&spv_binary,
&original_module_for_spans,
out_filename,
val_options,
);
}

{
Expand Down Expand Up @@ -393,18 +417,20 @@ fn do_spirv_opt(
fn do_spirv_val(
sess: &Session,
spv_binary: &[u32],
original_module_for_spans: &Module,
filename: &Path,
options: spirv_tools::val::ValidatorOptions,
) {
use crate::validation_err::ValidationErrorContext;
use spirv_tools::val::{self, Validator};

let validator = val::create(sess.target.options.env.parse().ok());

if let Err(e) = validator.validate(spv_binary, Some(options)) {
let mut err = sess.dcx().struct_err(e.to_string());
err.note("spirv-val failed");
err.note(format!("module `{}`", filename.display()));
err.emit();
// Use the ORIGINAL module (with SrcLocDecoration) to look up source spans
// Note: We validate the stripped binary, but look up spans in the original
let mut ctx = ValidationErrorContext::new(sess, Some(original_module_for_spans), filename);
ctx.emit_error(&e);
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/rustc_codegen_spirv/src/linker/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ impl LegalGlobal {
let global = match inst.class.opcode {
Op::TypePointer => Self::TypePointer(inst.operands[0].unwrap_storage_class()),
Op::Variable => Self::Variable,
op if rspirv::grammar::reflect::is_type(op) => Self::TypeNonPointer,
op if rspirv::grammar::reflect::is_constant(op) => Self::Const,
op if op.is_type() => Self::TypeNonPointer,
op if op.is_constant() => Self::Const,

// FIXME(eddyb) should this be `unreachable!()`?
_ => continue,
Expand Down
12 changes: 4 additions & 8 deletions crates/rustc_codegen_spirv/src/linker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ mod zombies;
use std::borrow::Cow;

use crate::codegen_cx::{ModuleOutputType, SpirvMetadata};
use crate::custom_decorations::{CustomDecoration, SrcLocDecoration, ZombieDecoration};
use crate::custom_insts;
use either::Either;
use rspirv::binary::Assemble;
Expand Down Expand Up @@ -768,13 +767,10 @@ pub fn link(
output.header.as_mut().unwrap().bound = simple_passes::compact_ids(output);
};

// FIXME(eddyb) convert these into actual `OpLine`s with a SPIR-T pass,
// but that'd require keeping the modules in SPIR-T form (once lowered),
// and never loading them back into `rspirv` once lifted back to SPIR-V.
SrcLocDecoration::remove_all(output);

// FIXME(eddyb) might make more sense to rewrite these away on SPIR-T.
ZombieDecoration::remove_all(output);
// NOTE: We keep SrcLocDecoration and ZombieDecoration in the module
// so that they can be used for rich error messages during validation.
// These are encoded as OpDecorateString with UserSemantic, which is
// valid SPIR-V and should not cause validation failures.
}

Ok(output)
Expand Down
Loading
Loading