mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-25 08:14:12 +00:00
Add is_helper_invocation, and cleanup arch & asm functions (#612)
This commit is contained in:
parent
de23683aa3
commit
9c19414858
@ -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<T: Scalar, V: Vector<T, N>, 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 {}
|
||||
}
|
||||
|
48
crates/spirv-std/src/arch/demote_to_helper_invocation_ext.rs
Normal file
48
crates/spirv-std/src/arch/demote_to_helper_invocation_ext.rs
Normal file
@ -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
|
||||
}
|
@ -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<F: Float>(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<F: Float>(component: F) -> F {
|
||||
#[crate::macros::vectorized]
|
||||
#[crate::macros::gpu_only]
|
||||
pub fn ddx_fine<F: Float>(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<F: Float>(component: F) -> F {
|
||||
#[crate::macros::vectorized]
|
||||
#[crate::macros::gpu_only]
|
||||
pub fn ddx_coarse<F: Float>(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<F: Float>(component: F) -> F {
|
||||
#[crate::macros::vectorized]
|
||||
#[crate::macros::gpu_only]
|
||||
pub fn ddy<F: Float>(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<F: Float>(component: F) -> F {
|
||||
#[crate::macros::vectorized]
|
||||
#[crate::macros::gpu_only]
|
||||
pub fn ddy_fine<F: Float>(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<F: Float>(component: F) -> F {
|
||||
#[crate::macros::vectorized]
|
||||
#[crate::macros::gpu_only]
|
||||
pub fn ddy_coarse<F: Float>(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<F: Float>(component: F) -> F {
|
||||
#[crate::macros::vectorized]
|
||||
#[crate::macros::gpu_only]
|
||||
pub fn fwidth<F: Float>(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<F: Float>(component: F) -> F {
|
||||
#[crate::macros::vectorized]
|
||||
#[crate::macros::gpu_only]
|
||||
pub fn fwidth_fine<F: Float>(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<F: Float>(component: F) -> F {
|
||||
#[crate::macros::vectorized]
|
||||
#[crate::macros::gpu_only]
|
||||
pub fn fwidth_coarse<F: Float>(component: F) -> F {
|
||||
deriv_fn!(component, OpFwidthCoarse, true)
|
||||
deriv_fn!(component, OpFwidthCoarse)
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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<'_>) -> ! {
|
||||
|
@ -491,17 +491,15 @@ impl RayQuery {
|
||||
#[doc(alias = "OpRayQueryGetIntersectionFrontFaceKHR")]
|
||||
#[inline]
|
||||
pub unsafe fn get_intersection_front_face<const INTERSECTION: u32>(&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
|
||||
|
9
tests/ui/arch/demote_to_helper_invocation.rs
Normal file
9
tests/ui/arch/demote_to_helper_invocation.rs
Normal file
@ -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());
|
||||
}
|
@ -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>();
|
||||
};
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
@ -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>();
|
||||
};
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
6
tests/ui/arch/kill.rs
Normal file
6
tests/ui/arch/kill.rs
Normal file
@ -0,0 +1,6 @@
|
||||
// build-pass
|
||||
|
||||
#[spirv(fragment)]
|
||||
pub fn main() {
|
||||
spirv_std::arch::kill();
|
||||
}
|
@ -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];
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -7,4 +7,3 @@ use spirv_std as _;
|
||||
pub fn main() {
|
||||
unsafe { spirv_std::arch::terminate_ray() }
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user