From 4372f195d3313a8f2af280e5b2c70b85d7c108d8 Mon Sep 17 00:00:00 2001 From: khyperia Date: Mon, 18 Jan 2021 10:31:32 +0100 Subject: [PATCH] discard(), update rspirv, better capability computation --- Cargo.lock | 200 ++++++------------ crates/rustc_codegen_spirv/Cargo.toml | 2 +- .../src/builder/spirv_asm.rs | 22 +- .../src/linker/capability_computation.rs | 79 ++++++- crates/spirv-std/src/lib.rs | 20 ++ 5 files changed, 178 insertions(+), 145 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b646069d2..b76722481b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,9 +235,9 @@ checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -478,8 +478,8 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373c88d9506e2e9230f6107701b7d8425f4cb3f6df108ec3042a26e936666da5" dependencies = [ - "quote 1.0.8", - "syn 1.0.58", + "quote", + "syn", ] [[package]] @@ -511,10 +511,10 @@ checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.24", - "quote 1.0.8", + "proc-macro2", + "quote", "strsim 0.9.3", - "syn 1.0.58", + "syn", ] [[package]] @@ -524,8 +524,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" dependencies = [ "darling_core", - "quote 1.0.8", - "syn 1.0.58", + "quote", + "syn", ] [[package]] @@ -534,23 +534,20 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaed5874effa6cde088c644ddcdcb4ffd1511391c5be4fdd7a5ccd02c7e4a183" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "derive_more" -version = "0.15.0" +version = "0.99.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe" +checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c" dependencies = [ - "lazy_static", - "proc-macro2 0.4.30", - "quote 0.6.13", - "regex", - "rustc_version", - "syn 0.15.44", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -758,9 +755,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1323,9 +1320,9 @@ checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" dependencies = [ "darling", "proc-macro-crate", - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1427,9 +1424,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffa5a33ddddfee04c0283a7653987d634e880347e96b5b2ed64de07efb59db9d" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1540,9 +1537,9 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7bcc46b8f73443d15bc1c5fecbb315718491fa9187fa483f0e359323cde8b3a" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1606,9 +1603,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", "version_check", ] @@ -1618,8 +1615,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.8", + "proc-macro2", + "quote", "version_check", ] @@ -1635,31 +1632,13 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", -] - [[package]] name = "proc-macro2" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ - "unicode-xid 0.2.1", -] - -[[package]] -name = "quote" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" -dependencies = [ - "proc-macro2 0.4.30", + "unicode-xid", ] [[package]] @@ -1668,7 +1647,7 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" dependencies = [ - "proc-macro2 1.0.24", + "proc-macro2", ] [[package]] @@ -1825,12 +1804,12 @@ dependencies = [ [[package]] name = "rspirv" version = "0.7.0" -source = "git+https://github.com/gfx-rs/rspirv.git?rev=01ca0d2e5b667a0e4ff1bc1804511e38f9a08759#01ca0d2e5b667a0e4ff1bc1804511e38f9a08759" +source = "git+https://github.com/gfx-rs/rspirv.git?rev=7111e6c5a8bb43563d280825fa65623032ee052d#7111e6c5a8bb43563d280825fa65623032ee052d" dependencies = [ "derive_more", "fxhash", "num-traits", - "spirv_headers 1.5.0 (git+https://github.com/gfx-rs/rspirv.git?rev=01ca0d2e5b667a0e4ff1bc1804511e38f9a08759)", + "spirv_headers 1.5.0 (git+https://github.com/gfx-rs/rspirv.git?rev=7111e6c5a8bb43563d280825fa65623032ee052d)", ] [[package]] @@ -1857,15 +1836,6 @@ dependencies = [ "topological-sort", ] -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - [[package]] name = "rusttype" version = "0.9.2" @@ -1931,21 +1901,6 @@ dependencies = [ "version-compare", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.118" @@ -1961,9 +1916,9 @@ version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2112,7 +2067,7 @@ dependencies = [ [[package]] name = "spirv_headers" version = "1.5.0" -source = "git+https://github.com/gfx-rs/rspirv.git?rev=01ca0d2e5b667a0e4ff1bc1804511e38f9a08759#01ca0d2e5b667a0e4ff1bc1804511e38f9a08759" +source = "git+https://github.com/gfx-rs/rspirv.git?rev=7111e6c5a8bb43563d280825fa65623032ee052d#7111e6c5a8bb43563d280825fa65623032ee052d" dependencies = [ "bitflags", "num-traits", @@ -2164,9 +2119,9 @@ checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2185,20 +2140,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149" dependencies = [ "heck", - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", -] - -[[package]] -name = "syn" -version = "0.15.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2207,9 +2151,9 @@ version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.8", - "unicode-xid 0.2.1", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] @@ -2280,9 +2224,9 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2355,9 +2299,9 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2436,12 +2380,6 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - [[package]] name = "unicode-xid" version = "0.2.1" @@ -2525,9 +2463,9 @@ dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", "wasm-bindgen-shared", ] @@ -2549,7 +2487,7 @@ version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084" dependencies = [ - "quote 1.0.8", + "quote", "wasm-bindgen-macro-support", ] @@ -2559,9 +2497,9 @@ version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.8", - "syn 1.0.58", + "proc-macro2", + "quote", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2679,8 +2617,8 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "030f56009d932bd9400bb472764fea8109be1b0fc482d9cd75496c943ac30328" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.8", + "proc-macro2", + "quote", "xml-rs", ] @@ -2690,8 +2628,8 @@ version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7010ba5767b3fcd350decc59055390b4ebe6bd1b9279a9feb1f1888987f1133d" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.8", + "proc-macro2", + "quote", "xml-rs", ] diff --git a/crates/rustc_codegen_spirv/Cargo.toml b/crates/rustc_codegen_spirv/Cargo.toml index 215e7cc39a..305dd9a407 100644 --- a/crates/rustc_codegen_spirv/Cargo.toml +++ b/crates/rustc_codegen_spirv/Cargo.toml @@ -29,7 +29,7 @@ use-compiled-tools = ["spirv-tools/use-compiled-tools"] [dependencies] bimap = "0.6" indexmap = "1.6.0" -rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "01ca0d2e5b667a0e4ff1bc1804511e38f9a08759" } +rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "7111e6c5a8bb43563d280825fa65623032ee052d" } rustc-demangle = "0.1.18" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs b/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs index 7aeba84bff..e339835d40 100644 --- a/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs +++ b/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs @@ -5,8 +5,8 @@ use super::Builder; use rspirv::dr; use rspirv::grammar::{LogicalOperand, OperandKind, OperandQuantifier}; use rspirv::spirv::{ - FPFastMathMode, FunctionControl, ImageOperands, KernelProfilingInfo, LoopControl, MemoryAccess, - MemorySemantics, Op, RayFlags, SelectionControl, Word, + FPFastMathMode, FragmentShadingRate, FunctionControl, ImageOperands, KernelProfilingInfo, + LoopControl, MemoryAccess, MemorySemantics, Op, RayFlags, SelectionControl, Word, }; use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_codegen_ssa::mir::place::PlaceRef; @@ -851,6 +851,12 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> { Some(x) => inst.operands.push(dr::Operand::RayFlags(x)), None => self.err(&format!("Unknown RayFlags {}", word)), }, + (OperandKind::FragmentShadingRate, Some(word)) => { + match parse_bitflags_operand(FRAGMENT_SHADING_RATE, word) { + Some(x) => inst.operands.push(dr::Operand::FragmentShadingRate(x)), + None => self.err(&format!("Unknown FragmentShadingRate {}", word)), + } + } (OperandKind::SourceLanguage, Some(word)) => match word.parse() { Ok(x) => inst.operands.push(dr::Operand::SourceLanguage(x)), @@ -1126,6 +1132,18 @@ pub const RAY_FLAGS: &[(&str, RayFlags)] = &[ ("SkipTrianglesKHR", RayFlags::SKIP_TRIANGLES_KHR), ("SkipAabBsKHR", RayFlags::SKIP_AAB_BS_KHR), ]; +pub const FRAGMENT_SHADING_RATE: &[(&str, FragmentShadingRate)] = &[ + ("VERTICAL2_PIXELS", FragmentShadingRate::VERTICAL2_PIXELS), + ("VERTICAL4_PIXELS", FragmentShadingRate::VERTICAL4_PIXELS), + ( + "HORIZONTAL2_PIXELS", + FragmentShadingRate::HORIZONTAL2_PIXELS, + ), + ( + "HORIZONTAL4_PIXELS", + FragmentShadingRate::HORIZONTAL4_PIXELS, + ), +]; fn parse_bitflags_operand + Copy>( values: &'static [(&'static str, T)], diff --git a/crates/rustc_codegen_spirv/src/linker/capability_computation.rs b/crates/rustc_codegen_spirv/src/linker/capability_computation.rs index d46410cf58..fafd9925d8 100644 --- a/crates/rustc_codegen_spirv/src/linker/capability_computation.rs +++ b/crates/rustc_codegen_spirv/src/linker/capability_computation.rs @@ -1,4 +1,4 @@ -use rspirv::dr::Module; +use rspirv::dr::{Instruction, Module, Operand}; use rspirv::spirv::{Capability, Op}; use std::collections::HashSet; @@ -11,6 +11,8 @@ pub fn remove_extra_capabilities(module: &mut Module) { Capability::Float16, Capability::Float64, Capability::IntegerFunctions2INTEL, + Capability::DemoteToHelperInvocationEXT, + Capability::DerivativeControl, ] .iter() .copied() @@ -60,16 +62,71 @@ fn remove_capabilities(module: &mut Module, set: &HashSet) { }); } +// TODO: Move this to rspirv +fn operand_required_extensions(op: &Operand) -> &'static [&'static str] { + match op { + Operand::SourceLanguage(x) => x.required_extensions(), + Operand::ExecutionModel(x) => x.required_extensions(), + Operand::AddressingModel(x) => x.required_extensions(), + Operand::MemoryModel(x) => x.required_extensions(), + Operand::ExecutionMode(x) => x.required_extensions(), + Operand::StorageClass(x) => x.required_extensions(), + Operand::Dim(x) => x.required_extensions(), + Operand::SamplerAddressingMode(x) => x.required_extensions(), + Operand::SamplerFilterMode(x) => x.required_extensions(), + Operand::ImageFormat(x) => x.required_extensions(), + Operand::ImageChannelOrder(x) => x.required_extensions(), + Operand::ImageChannelDataType(x) => x.required_extensions(), + Operand::FPRoundingMode(x) => x.required_extensions(), + Operand::LinkageType(x) => x.required_extensions(), + Operand::AccessQualifier(x) => x.required_extensions(), + Operand::FunctionParameterAttribute(x) => x.required_extensions(), + Operand::Decoration(x) => x.required_extensions(), + Operand::BuiltIn(x) => x.required_extensions(), + Operand::Scope(x) => x.required_extensions(), + Operand::GroupOperation(x) => x.required_extensions(), + Operand::KernelEnqueueFlags(x) => x.required_extensions(), + Operand::Capability(x) => x.required_extensions(), + Operand::RayQueryIntersection(x) => x.required_extensions(), + Operand::RayQueryCommittedIntersectionType(x) => x.required_extensions(), + Operand::RayQueryCandidateIntersectionType(x) => x.required_extensions(), + _ => &[], + } +} + +// rspirv pulls its spec information from the latest version. However, we might not be compiling for +// the latest version. +// For example, we might run into this situation: +// OpCapability VulkanMemoryModel in SPIR-V v1.5 requires no extensions +// OpCapability VulkanMemoryModel in SPIR-V <= v1.4 requires OpExtension SPV_KHR_vulkan_memory_model +// rspirv uses SPIR-V v1.5 (as of now), and so it states that VulkanMemoryModel needs no extensions +// We're compiling for, say, SPIR-V 1.3, and ask rspirv if VulkanMemoryModel requires an extension +// It says no. We strip it. Things explode. +// So, this function is to encode any special version-specific rules that aren't in rspirv. +fn additional_extensions(module: &Module, inst: &Instruction) -> &'static [&'static str] { + if module.header.as_ref().unwrap().version() < (1, 5) + && inst.class.opcode == Op::Capability + && inst.operands[0].unwrap_capability() == Capability::VulkanMemoryModel + { + &["SPV_KHR_vulkan_memory_model"] + } else { + &[] + } +} + pub fn remove_extra_extensions(module: &mut Module) { - // TODO: Make this more generalized once this gets more advanced. - let has_intel_integer_cap = module.capabilities.iter().any(|inst| { - inst.class.opcode == Op::Capability - && inst.operands[0].unwrap_capability() == Capability::IntegerFunctions2INTEL - }); - if !has_intel_integer_cap { - module.extensions.retain(|inst| { - inst.class.opcode != Op::Extension - || inst.operands[0].unwrap_literal_string() != "SPV_INTEL_shader_integer_functions2" + let set: HashSet<&str> = module + .all_inst_iter() + .flat_map(|inst| { + inst.class + .extensions + .iter() + .chain(inst.operands.iter().flat_map(operand_required_extensions)) + .chain(additional_extensions(module, inst)) }) - } + .copied() + .collect(); + module.extensions.retain(|inst| { + inst.class.opcode != Op::Extension || set.contains(inst.operands[0].unwrap_literal_string()) + }) } diff --git a/crates/spirv-std/src/lib.rs b/crates/spirv-std/src/lib.rs index b9f1244638..98f4339b9e 100644 --- a/crates/spirv-std/src/lib.rs +++ b/crates/spirv-std/src/lib.rs @@ -51,6 +51,26 @@ pub use glam; pub use num_traits; pub use textures::*; +/// Calls the `OpDemoteToHelperInvocationEXT` instruction, which corresponds to discard() in HLSL +pub fn demote_to_helper_invocation() { + #[cfg(target_arch = "spirv")] + unsafe { + asm!( + "OpExtension \"SPV_EXT_demote_to_helper_invocation\"", + "OpCapability DemoteToHelperInvocationEXT", + "OpDemoteToHelperInvocationEXT" + ); + } +} + +/// Calls the `OpKill` instruction, which corresponds to discard() in GLSL +pub fn discard() { + #[cfg(target_arch = "spirv")] + unsafe { + asm!("OpKill", "%unused = OpLabel"); + } +} + #[cfg(all(not(test), target_arch = "spirv"))] #[panic_handler] fn panic(_: &core::panic::PanicInfo<'_>) -> ! {