From f850d8b1862acf05293df4d8bd20947534f96aba Mon Sep 17 00:00:00 2001 From: Erin Power Date: Tue, 4 May 2021 09:46:59 +0200 Subject: [PATCH] Add is_helper_invocation, and cleanup arch & asm functions --- crates/spirv-std/src/arch.rs | 17 +++++++ .../arch/demote_to_helper_invocation_ext.rs | 48 +++++++++++++++++++ crates/spirv-std/src/arch/derivative.rs | 29 ++++------- crates/spirv-std/src/arch/ray_tracing.rs | 19 ++++---- crates/spirv-std/src/lib.rs | 20 -------- crates/spirv-std/src/ray_tracing.rs | 17 +++---- tests/ui/arch/demote_to_helper_invocation.rs | 9 ++++ tests/ui/arch/emit_stream_vertex.rs | 2 +- tests/ui/arch/emit_vertex.rs | 2 +- tests/ui/arch/end_primitive.rs | 2 +- tests/ui/arch/end_stream_primitive.rs | 2 +- tests/ui/arch/execute_callable.rs | 3 +- tests/ui/arch/kill.rs | 6 +++ tests/ui/image/issue_527.rs | 5 +- tests/ui/image/query/query_levels.rs | 2 +- tests/ui/image/query/query_levels_err.rs | 2 +- tests/ui/image/query/query_lod.rs | 2 +- tests/ui/image/query/query_lod_err.rs | 2 +- tests/ui/image/query/query_samples.rs | 2 +- tests/ui/image/query/query_size.rs | 2 +- tests/ui/image/query/query_size_err.rs | 2 +- tests/ui/image/query/query_size_lod.rs | 2 +- tests/ui/image/query/query_size_lod_err.rs | 2 +- tests/ui/image/read.rs | 2 +- tests/ui/image/write.rs | 2 +- tests/ui/lang/consts/nested-ref.rs | 2 +- tests/ui/target_features_err.rs | 1 - 27 files changed, 129 insertions(+), 77 deletions(-) create mode 100644 crates/spirv-std/src/arch/demote_to_helper_invocation_ext.rs create mode 100644 tests/ui/arch/demote_to_helper_invocation.rs create mode 100644 tests/ui/arch/kill.rs diff --git a/crates/spirv-std/src/arch.rs b/crates/spirv-std/src/arch.rs index b4ee3bf13c..1783bdcf2d 100644 --- a/crates/spirv-std/src/arch.rs +++ b/crates/spirv-std/src/arch.rs @@ -8,6 +8,7 @@ use crate::{scalar::Scalar, vector::Vector}; mod arithmetic; #[cfg(feature = "const-generics")] mod barrier; +mod demote_to_helper_invocation_ext; mod derivative; mod primitive; mod ray_tracing; @@ -15,6 +16,7 @@ mod ray_tracing; pub use arithmetic::*; #[cfg(feature = "const-generics")] pub use barrier::*; +pub use demote_to_helper_invocation_ext::*; pub use derivative::*; pub use primitive::*; pub use ray_tracing::*; @@ -140,3 +142,18 @@ pub unsafe fn vector_insert_dynamic, const N: usize>( result } + +/// Fragment-shader discard. Equivalvent to `discard()` from GLSL +/// +/// Ceases all further processing in any invocation that executes it: Only +/// instructions these invocations executed before [kill] have observable side +/// effects. +#[spirv_std_macros::gpu_only] +#[doc(alias = "OpKill", alias = "discard")] +#[allow(clippy::empty_loop)] +pub fn kill() -> ! { + unsafe { + asm!("OpKill", "%unused = OpLabel"); + } + loop {} +} diff --git a/crates/spirv-std/src/arch/demote_to_helper_invocation_ext.rs b/crates/spirv-std/src/arch/demote_to_helper_invocation_ext.rs new file mode 100644 index 0000000000..4a0633fca2 --- /dev/null +++ b/crates/spirv-std/src/arch/demote_to_helper_invocation_ext.rs @@ -0,0 +1,48 @@ +/// Demote fragment shader invocation to a helper invocation. Equivalvent to +/// `discard()` in HLSL. Any stores to memory after this instruction are +/// suppressed and the fragment does not write outputs to the framebuffer. +/// +/// Unlike [super::kill], this does not necessarily terminate the invocation. It +/// is not considered a flow control instruction (flow control does not become +/// non-uniform) and does not terminate the block. +/// +/// - **Required Capabilities** `DemoteToHelperInvocationEXT` +/// - **Required Extensions** `SPV_EXT_demote_to_helper_invocation` +/// +/// # Safety +/// After this instruction executes, the value of a `helper_invocation` builtin +/// variable is undefined. Use `is_helper_invocation` to determine whether +/// invocations are helper invocations in the presence +/// of [demote_to_helper_invocation]. +#[spirv_std_macros::gpu_only] +#[doc(alias = "OpDemoteToHelperInvocationEXT", alias = "discard")] +pub unsafe fn demote_to_helper_invocation() { + asm!("OpDemoteToHelperInvocationEXT"); +} + +/// Returns `true` if the invocation is currently a helper invocation, otherwise +/// result is `false`. An invocation is currently a helper invocation if it was +/// originally invoked as a helper invocation or if it has been demoted to a +/// helper invocation by [demote_to_helper_invocation]. +/// +/// - **Required Capabilities** `DemoteToHelperInvocationEXT` +/// - **Required Extensions** `SPV_EXT_demote_to_helper_invocation` +#[spirv_std_macros::gpu_only] +#[doc(alias = "OpIsHelperInvocationEXT")] +pub fn is_helper_invocation() -> bool { + let result: u32; + + unsafe { + asm! { + "%bool = OpTypeBool", + "%u32 = OpTypeInt 32 0", + "%zero = OpConstant %u32 0", + "%one = OpConstant %u32 1", + "%result = OpIsHelperInvocationEXT %bool", + "{} = OpSelect %u32 %result %one %zero", + out(reg) result + }; + } + + result != 0 +} diff --git a/crates/spirv-std/src/arch/derivative.rs b/crates/spirv-std/src/arch/derivative.rs index 8217c843c8..f3187ff806 100644 --- a/crates/spirv-std/src/arch/derivative.rs +++ b/crates/spirv-std/src/arch/derivative.rs @@ -1,19 +1,10 @@ use crate::float::Float; -#[cfg(target_arch = "spirv")] -macro_rules! deriv_caps { - (true) => { - asm!("OpCapability DerivativeControl") - }; - (false) => {}; -} - #[cfg(target_arch = "spirv")] macro_rules! deriv_fn { - ($p:ident, $inst:ident, $needs_caps:tt) => { + ($p:ident, $inst:ident) => { unsafe { let mut o = Default::default(); - deriv_caps!($needs_caps); asm!( "%input = OpLoad _ {0}", concat!("%result = ", stringify!($inst), " _ %input"), @@ -32,7 +23,7 @@ macro_rules! deriv_fn { #[crate::macros::vectorized] #[crate::macros::gpu_only] pub fn ddx(component: F) -> F { - deriv_fn!(component, OpDPdx, false) + deriv_fn!(component, OpDPdx) } /// Returns the partial derivative of `component` with respect to the window's X @@ -41,7 +32,7 @@ pub fn ddx(component: F) -> F { #[crate::macros::vectorized] #[crate::macros::gpu_only] pub fn ddx_fine(component: F) -> F { - deriv_fn!(component, OpDPdxFine, true) + deriv_fn!(component, OpDPdxFine) } /// Returns the partial derivative of `component` with respect to the window's X @@ -53,7 +44,7 @@ pub fn ddx_fine(component: F) -> F { #[crate::macros::vectorized] #[crate::macros::gpu_only] pub fn ddx_coarse(component: F) -> F { - deriv_fn!(component, OpDPdxCoarse, true) + deriv_fn!(component, OpDPdxCoarse) } /// Returns the partial derivative of `component` with respect to the window's Y @@ -62,7 +53,7 @@ pub fn ddx_coarse(component: F) -> F { #[crate::macros::vectorized] #[crate::macros::gpu_only] pub fn ddy(component: F) -> F { - deriv_fn!(component, OpDPdy, false) + deriv_fn!(component, OpDPdy) } /// Returns the partial derivative of `component` with respect to the window's Y @@ -71,7 +62,7 @@ pub fn ddy(component: F) -> F { #[crate::macros::vectorized] #[crate::macros::gpu_only] pub fn ddy_fine(component: F) -> F { - deriv_fn!(component, OpDPdyFine, true) + deriv_fn!(component, OpDPdyFine) } /// Returns the partial derivative of `component` with respect to the window's Y @@ -83,7 +74,7 @@ pub fn ddy_fine(component: F) -> F { #[crate::macros::vectorized] #[crate::macros::gpu_only] pub fn ddy_coarse(component: F) -> F { - deriv_fn!(component, OpDPdyCoarse, true) + deriv_fn!(component, OpDPdyCoarse) } /// Returns the sum of the absolute values of [`ddx`] and [`ddy`] as a single @@ -91,7 +82,7 @@ pub fn ddy_coarse(component: F) -> F { #[crate::macros::vectorized] #[crate::macros::gpu_only] pub fn fwidth(component: F) -> F { - deriv_fn!(component, OpFwidth, false) + deriv_fn!(component, OpFwidth) } /// Returns the sum of the absolute values of [`ddx_fine`] and [`ddy_fine`] as a @@ -99,7 +90,7 @@ pub fn fwidth(component: F) -> F { #[crate::macros::vectorized] #[crate::macros::gpu_only] pub fn fwidth_fine(component: F) -> F { - deriv_fn!(component, OpFwidthFine, true) + deriv_fn!(component, OpFwidthFine) } /// Returns the sum of the absolute values of [`ddx_coarse`] and [`ddy_coarse`] @@ -107,5 +98,5 @@ pub fn fwidth_fine(component: F) -> F { #[crate::macros::vectorized] #[crate::macros::gpu_only] pub fn fwidth_coarse(component: F) -> F { - deriv_fn!(component, OpFwidthCoarse, true) + deriv_fn!(component, OpFwidthCoarse) } diff --git a/crates/spirv-std/src/arch/ray_tracing.rs b/crates/spirv-std/src/arch/ray_tracing.rs index 55738f9470..d8b432dd4c 100644 --- a/crates/spirv-std/src/arch/ray_tracing.rs +++ b/crates/spirv-std/src/arch/ray_tracing.rs @@ -38,24 +38,27 @@ pub unsafe fn report_intersection(hit: f32, hit_kind: u32) -> bool { /// Ignores the current potential intersection, terminating the invocation that /// executes it, and continues the ray traversal. This instruction is allowed -/// only in `any_hit` execution model. This instruction must be the last -/// instruction in a block. +/// only in `any_hit` execution model. #[spirv_std_macros::gpu_only] #[doc(alias = "OpIgnoreIntersectionKHR")] #[inline] -pub unsafe fn ignore_intersection() { - asm!("OpIgnoreIntersectionKHR", "%unused = OpLabel") +#[allow(clippy::empty_loop)] +pub unsafe fn ignore_intersection() -> ! { + asm!("OpIgnoreIntersectionKHR", "%unused = OpLabel"); + loop {} } /// Terminates the invocation that executes it, stops the ray traversal, accepts /// the current hit, and invokes the `closest_hit` execution model -/// (if active). This instruction is allowed only in the `any_hit` -/// execution model. This instruction must be the last instruction in a block. +/// (if active). This instruction is allowed only in the `any_hit` +/// execution model. #[spirv_std_macros::gpu_only] #[doc(alias = "OpTerminateRayKHR")] #[inline] -pub unsafe fn terminate_ray() { - asm!("OpTerminateRayKHR", "%unused = OpLabel") +#[allow(clippy::empty_loop)] +pub unsafe fn terminate_ray() -> ! { + asm!("OpTerminateRayKHR", "%unused = OpLabel"); + loop {} } /// Invoke a callable shader. diff --git a/crates/spirv-std/src/lib.rs b/crates/spirv-std/src/lib.rs index e6965a2885..9337c126a9 100644 --- a/crates/spirv-std/src/lib.rs +++ b/crates/spirv-std/src/lib.rs @@ -93,26 +93,6 @@ pub use crate::macros::Image; pub use num_traits; pub use textures::*; -/// Calls the `OpDemoteToHelperInvocationEXT` instruction, which corresponds to discard() in HLSL -#[spirv_std_macros::gpu_only] -pub fn demote_to_helper_invocation() { - unsafe { - asm!( - "OpExtension \"SPV_EXT_demote_to_helper_invocation\"", - "OpCapability DemoteToHelperInvocationEXT", - "OpDemoteToHelperInvocationEXT" - ); - } -} - -/// Calls the `OpKill` instruction, which corresponds to discard() in GLSL -#[spirv_std_macros::gpu_only] -pub fn discard() { - unsafe { - asm!("OpKill", "%unused = OpLabel"); - } -} - #[cfg(all(not(test), target_arch = "spirv"))] #[panic_handler] fn panic(_: &core::panic::PanicInfo<'_>) -> ! { diff --git a/crates/spirv-std/src/ray_tracing.rs b/crates/spirv-std/src/ray_tracing.rs index a75f67ae09..0892ba9810 100644 --- a/crates/spirv-std/src/ray_tracing.rs +++ b/crates/spirv-std/src/ray_tracing.rs @@ -491,17 +491,15 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionFrontFaceKHR")] #[inline] pub unsafe fn get_intersection_front_face(&self) -> bool { - let mut result = 0u8; + let mut result: u32; asm! { - "%u8 = OpTypeInt 8 0", "%u32 = OpTypeInt 32 0", "%intersection = OpConstant %u32 {intersection}", - "%result = OpRayQueryGetIntersectionFrontFaceKHR %u8 {ray_query} %intersection", - "OpStore {result} %result", + "{result} = OpRayQueryGetIntersectionFrontFaceKHR %u32 {ray_query} %intersection", ray_query = in(reg) self, intersection = const INTERSECTION, - result = in(reg) &mut result, + result = out(reg) result, } result != 0 @@ -513,14 +511,13 @@ impl RayQuery { #[doc(alias = "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR")] #[inline] pub unsafe fn get_intersection_candidate_aabb_opaque(&self) -> bool { - let mut result = 0u8; + let result: u32; asm! { - "%u8 = OpTypeInt 8 0", - "%result = OpRayQueryGetIntersectionCandidateAABBOpaqueKHR %u8 {ray_query}", - "OpStore {result} %result", + "%u32 = OpTypeInt 8 0", + "{result} = OpRayQueryGetIntersectionCandidateAABBOpaqueKHR %u32 {ray_query}", ray_query = in(reg) self, - result = in(reg) &mut result, + result = out(reg) result, } result != 0 diff --git a/tests/ui/arch/demote_to_helper_invocation.rs b/tests/ui/arch/demote_to_helper_invocation.rs new file mode 100644 index 0000000000..e0dd428106 --- /dev/null +++ b/tests/ui/arch/demote_to_helper_invocation.rs @@ -0,0 +1,9 @@ +// build-pass +// +// compile-flags: -C target-feature=+DemoteToHelperInvocationEXT,+ext:SPV_EXT_demote_to_helper_invocation + +#[spirv(fragment)] +pub fn main() { + unsafe { spirv_std::arch::demote_to_helper_invocation() }; + assert!(spirv_std::arch::is_helper_invocation()); +} diff --git a/tests/ui/arch/emit_stream_vertex.rs b/tests/ui/arch/emit_stream_vertex.rs index 004eda45c1..3f0a1ac538 100644 --- a/tests/ui/arch/emit_stream_vertex.rs +++ b/tests/ui/arch/emit_stream_vertex.rs @@ -1,9 +1,9 @@ // build-pass +// compile-flags: -C target-feature=+GeometryStreams #[spirv(geometry(input_lines = 2, output_points = 2))] pub fn main() { unsafe { - asm!("OpCapability GeometryStreams"); spirv_std::arch::emit_stream_vertex::<2>(); }; } diff --git a/tests/ui/arch/emit_vertex.rs b/tests/ui/arch/emit_vertex.rs index e25cc06f3f..da1f3fe1ea 100644 --- a/tests/ui/arch/emit_vertex.rs +++ b/tests/ui/arch/emit_vertex.rs @@ -1,9 +1,9 @@ // build-pass +// compile-flags: -Ctarget-feature=+Geometry #[spirv(geometry(input_lines = 2, output_points = 2))] pub fn main() { unsafe { - asm!("OpCapability Geometry"); spirv_std::arch::emit_vertex(); }; } diff --git a/tests/ui/arch/end_primitive.rs b/tests/ui/arch/end_primitive.rs index 4fd14a367a..cb3014d320 100644 --- a/tests/ui/arch/end_primitive.rs +++ b/tests/ui/arch/end_primitive.rs @@ -1,9 +1,9 @@ // build-pass +// compile-flags: -Ctarget-feature=+Geometry #[spirv(geometry(input_lines = 2, output_points = 2))] pub fn main() { unsafe { - asm!("OpCapability Geometry"); spirv_std::arch::end_primitive(); }; } diff --git a/tests/ui/arch/end_stream_primitive.rs b/tests/ui/arch/end_stream_primitive.rs index 849fa982ea..e578da32e2 100644 --- a/tests/ui/arch/end_stream_primitive.rs +++ b/tests/ui/arch/end_stream_primitive.rs @@ -1,9 +1,9 @@ // build-pass +// compile-flags: -C target-feature=+GeometryStreams #[spirv(geometry(input_lines = 2, output_points = 2))] pub fn main() { unsafe { - asm!("OpCapability GeometryStreams"); spirv_std::arch::end_stream_primitive::<2>(); }; } diff --git a/tests/ui/arch/execute_callable.rs b/tests/ui/arch/execute_callable.rs index 81c4fee848..f8c6032b7b 100644 --- a/tests/ui/arch/execute_callable.rs +++ b/tests/ui/arch/execute_callable.rs @@ -1,4 +1,5 @@ // build-pass +// compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing #[spirv(ray_generation)] // Rustfmt will eat long attributes (https://github.com/rust-lang/rustfmt/issues/4579) @@ -9,8 +10,6 @@ pub fn main( #[spirv(incoming_callable_data)] payload: &glam::Vec3, ) { unsafe { - asm!(r#"OpExtension "SPV_KHR_ray_tracing""#); - asm!("OpCapability RayTracingKHR"); spirv_std::arch::execute_callable::<_, 5>(payload); } } diff --git a/tests/ui/arch/kill.rs b/tests/ui/arch/kill.rs new file mode 100644 index 0000000000..361f0e1f35 --- /dev/null +++ b/tests/ui/arch/kill.rs @@ -0,0 +1,6 @@ +// build-pass + +#[spirv(fragment)] +pub fn main() { + spirv_std::arch::kill(); +} diff --git a/tests/ui/image/issue_527.rs b/tests/ui/image/issue_527.rs index 7d9a43d8e9..d9fffb26cb 100644 --- a/tests/ui/image/issue_527.rs +++ b/tests/ui/image/issue_527.rs @@ -1,3 +1,7 @@ +// build-pass +// +// compile-flags: -C target-feature=+StorageImageWriteWithoutFormat + use glam::*; #[spirv(compute(threads(1)))] @@ -6,7 +10,6 @@ pub fn main_cs( #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] points_buffer: &mut [UVec2; 100], #[spirv(descriptor_set = 1, binding = 1)] image: &spirv_std::Image!(2D, type=f32, sampled=false), ) { - unsafe { asm!("OpCapability StorageImageWriteWithoutFormat") }; let position = id.xy(); for i in 0..100usize { let p0 = &points_buffer[i]; diff --git a/tests/ui/image/query/query_levels.rs b/tests/ui/image/query/query_levels.rs index 7055a847da..67fba3df6c 100644 --- a/tests/ui/image/query/query_levels.rs +++ b/tests/ui/image/query/query_levels.rs @@ -1,4 +1,5 @@ // build-pass +// compile-flags: -C target-feature=+ImageQuery use spirv_std::{arch, Image}; @@ -7,6 +8,5 @@ pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), output: &mut u32, ) { - unsafe { asm!("OpCapability ImageQuery") }; *output = image.query_levels(); } diff --git a/tests/ui/image/query/query_levels_err.rs b/tests/ui/image/query/query_levels_err.rs index 12a2ec853a..31b2ce05bb 100644 --- a/tests/ui/image/query/query_levels_err.rs +++ b/tests/ui/image/query/query_levels_err.rs @@ -1,5 +1,6 @@ // build-fail // normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" +// compile-flags: -C target-feature=+ImageQuery use spirv_std::{arch, Image}; @@ -8,6 +9,5 @@ pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(rect, type=f32, sampled), output: &mut u32, ) { - unsafe { asm!("OpCapability ImageQuery") }; *output = image.query_levels(); } diff --git a/tests/ui/image/query/query_lod.rs b/tests/ui/image/query/query_lod.rs index 955db5c4b3..121f9200a0 100644 --- a/tests/ui/image/query/query_lod.rs +++ b/tests/ui/image/query/query_lod.rs @@ -1,4 +1,5 @@ // build-pass +// compile-flags: -C target-feature=+ImageQuery use spirv_std::{arch, Image, Sampler}; @@ -8,6 +9,5 @@ pub fn main( #[spirv(descriptor_set = 0, binding = 1)] sampler: &Sampler, output: &mut glam::Vec2, ) { - unsafe { asm!("OpCapability ImageQuery") }; *output = image.query_lod(*sampler, glam::Vec2::new(0.0, 1.0)); } diff --git a/tests/ui/image/query/query_lod_err.rs b/tests/ui/image/query/query_lod_err.rs index b7048173a4..28fd763d57 100644 --- a/tests/ui/image/query/query_lod_err.rs +++ b/tests/ui/image/query/query_lod_err.rs @@ -1,5 +1,6 @@ // build-fail // normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" +// compile-flags: -C target-feature=+ImageQuery use spirv_std::{arch, Image, Sampler}; @@ -9,6 +10,5 @@ pub fn main( #[spirv(descriptor_set = 0, binding = 1)] sampler: &Sampler, output: &mut glam::Vec2, ) { - unsafe { asm!("OpCapability ImageQuery") }; *output = image.query_lod(*sampler, glam::Vec2::new(0.0, 1.0)); } diff --git a/tests/ui/image/query/query_samples.rs b/tests/ui/image/query/query_samples.rs index 8186af55e9..3af6fd456f 100644 --- a/tests/ui/image/query/query_samples.rs +++ b/tests/ui/image/query/query_samples.rs @@ -1,4 +1,5 @@ // build-pass +// compile-flags: -C target-feature=+ImageQuery use spirv_std::{arch, Image}; @@ -7,6 +8,5 @@ pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled, multisampled), output: &mut u32, ) { - unsafe { asm!("OpCapability ImageQuery") }; *output = image.query_samples(); } diff --git a/tests/ui/image/query/query_size.rs b/tests/ui/image/query/query_size.rs index b52bcecb5c..971f163fd4 100644 --- a/tests/ui/image/query/query_size.rs +++ b/tests/ui/image/query/query_size.rs @@ -1,4 +1,5 @@ // build-pass +// compile-flags: -C target-feature=+ImageQuery use spirv_std::{arch, Image}; @@ -7,6 +8,5 @@ pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled=false), output: &mut glam::UVec2, ) { - unsafe { asm!("OpCapability ImageQuery") }; *output = image.query_size(); } diff --git a/tests/ui/image/query/query_size_err.rs b/tests/ui/image/query/query_size_err.rs index 993d094a82..59e1606150 100644 --- a/tests/ui/image/query/query_size_err.rs +++ b/tests/ui/image/query/query_size_err.rs @@ -1,5 +1,6 @@ // build-fail // normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" +// compile-flags: -C target-feature=+ImageQuery use spirv_std::{arch, Image}; @@ -8,6 +9,5 @@ pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), output: &mut glam::UVec2, ) { - unsafe { asm!("OpCapability ImageQuery") }; *output = image.query_size(); } diff --git a/tests/ui/image/query/query_size_lod.rs b/tests/ui/image/query/query_size_lod.rs index e9fb0fb60c..2a03c1c734 100644 --- a/tests/ui/image/query/query_size_lod.rs +++ b/tests/ui/image/query/query_size_lod.rs @@ -1,4 +1,5 @@ // build-pass +// compile-flags: -C target-feature=+ImageQuery use spirv_std::{arch, Image}; @@ -7,6 +8,5 @@ pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), output: &mut glam::UVec2, ) { - unsafe { asm!("OpCapability ImageQuery") }; *output = image.query_size_lod(0); } diff --git a/tests/ui/image/query/query_size_lod_err.rs b/tests/ui/image/query/query_size_lod_err.rs index 5a5b9bc8b8..e7546a96ca 100644 --- a/tests/ui/image/query/query_size_lod_err.rs +++ b/tests/ui/image/query/query_size_lod_err.rs @@ -1,5 +1,6 @@ // build-fail // normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" +// compile-flags: -C target-feature=+ImageQuery use spirv_std::{arch, Image}; @@ -8,6 +9,5 @@ pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(rect, type=f32, sampled), output: &mut glam::UVec2, ) { - unsafe { asm!("OpCapability ImageQuery") }; *output = image.query_size_lod(0); } diff --git a/tests/ui/image/read.rs b/tests/ui/image/read.rs index 7f13a9e96e..6e047592f6 100644 --- a/tests/ui/image/read.rs +++ b/tests/ui/image/read.rs @@ -1,5 +1,6 @@ // Test `OpImageRead` // build-pass +// compile-flags: -C target-feature=+StorageImageReadWithoutFormat use spirv_std::{arch, Image}; @@ -8,7 +9,6 @@ pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled=false), output: &mut glam::Vec4, ) { - unsafe { asm!("OpCapability StorageImageReadWithoutFormat") }; let coords = image.read(glam::IVec2::new(0, 1)); *output = coords; } diff --git a/tests/ui/image/write.rs b/tests/ui/image/write.rs index 4950f4e4ab..0ef3e8c9e5 100644 --- a/tests/ui/image/write.rs +++ b/tests/ui/image/write.rs @@ -1,5 +1,6 @@ // Test `OpImageWrite` // build-pass +// compile-flags: -C target-feature=+StorageImageWriteWithoutFormat use spirv_std::{arch, Image}; @@ -9,7 +10,6 @@ pub fn main( #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled=false), ) { unsafe { - asm!("OpCapability StorageImageWriteWithoutFormat"); image.write(glam::UVec2::new(0, 1), texels); } } diff --git a/tests/ui/lang/consts/nested-ref.rs b/tests/ui/lang/consts/nested-ref.rs index 096550abcf..4aab299ee4 100644 --- a/tests/ui/lang/consts/nested-ref.rs +++ b/tests/ui/lang/consts/nested-ref.rs @@ -2,6 +2,7 @@ // contain references, and where the `T` values aren't immediatelly loaded from. // build-pass +// compile-flags: -C target-feature=+VariablePointers use spirv_std as _; @@ -26,7 +27,6 @@ pub fn main( bool_out: &mut bool, vec_out: &mut Vec2, ) { - unsafe { asm!("OpCapability VariablePointers") }; *scalar_out = deep_load(&&123); *bool_out = vec_in == &Vec2::ZERO; *vec_out = deep_transpose(&ROT90) * *vec_in; diff --git a/tests/ui/target_features_err.rs b/tests/ui/target_features_err.rs index e3633b7187..30169eb8b7 100644 --- a/tests/ui/target_features_err.rs +++ b/tests/ui/target_features_err.rs @@ -7,4 +7,3 @@ use spirv_std as _; pub fn main() { unsafe { spirv_std::arch::terminate_ray() } } -