diff --git a/crates/rustc_codegen_spirv/src/abi.rs b/crates/rustc_codegen_spirv/src/abi.rs index 3aaa9bd4f8..bd71990a2e 100644 --- a/crates/rustc_codegen_spirv/src/abi.rs +++ b/crates/rustc_codegen_spirv/src/abi.rs @@ -791,6 +791,7 @@ fn trans_intrinsic_type<'tcx>( IntrinsicType::AccelerationStructureKhr => { Ok(SpirvType::AccelerationStructureKhr.def(span, cx)) } + IntrinsicType::RayQueryKhr => Ok(SpirvType::RayQueryKhr.def(span, cx)), IntrinsicType::SampledImage => { // see SpirvType::sizeof if ty.size != Size::from_bytes(4) { diff --git a/crates/rustc_codegen_spirv/src/attr.rs b/crates/rustc_codegen_spirv/src/attr.rs index 75d86053cd..267c2709d5 100644 --- a/crates/rustc_codegen_spirv/src/attr.rs +++ b/crates/rustc_codegen_spirv/src/attr.rs @@ -73,6 +73,7 @@ pub enum IntrinsicType { Sampler, AccelerationStructureKhr, SampledImage, + RayQueryKhr, } // NOTE(eddyb) when adding new `#[spirv(...)]` attributes, the tests found inside diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index 3081976df8..2b5a3ce6b4 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -239,6 +239,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { SpirvType::AccelerationStructureKhr => { self.fatal("cannot memset acceleration structure") } + SpirvType::RayQueryKhr => self.fatal("cannot memset ray query"), } } @@ -299,6 +300,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { SpirvType::AccelerationStructureKhr => { self.fatal("cannot memset acceleration structure") } + SpirvType::RayQueryKhr => self.fatal("cannot memset ray query"), } } diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs index b6d8f3228d..d493a24b8c 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs @@ -534,6 +534,7 @@ impl<'tcx> CodegenCx<'tcx> { .tcx .sess .fatal("Cannot create a constant acceleration structure"), + SpirvType::RayQueryKhr => self.tcx.sess.fatal("Cannot create a constant ray query"), } } } diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs index 6e6d00c6a6..ec3c48424c 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs @@ -179,7 +179,8 @@ impl<'tcx> CodegenCx<'tcx> { SpirvType::Image { .. } | SpirvType::Sampler | SpirvType::SampledImage { .. } - | SpirvType::AccelerationStructureKhr => { + | SpirvType::AccelerationStructureKhr + | SpirvType::RayQueryKhr => { if is_ref { Some(StorageClass::UniformConstant) } else { diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs b/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs index 4424a5f6c1..0a42a50e60 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/type_.rs @@ -179,6 +179,7 @@ impl<'tcx> BaseTypeMethods<'tcx> for CodegenCx<'tcx> { | SpirvType::Sampler | SpirvType::SampledImage { .. } | SpirvType::AccelerationStructureKhr + | SpirvType::RayQueryKhr => TypeKind::Token, } } diff --git a/crates/rustc_codegen_spirv/src/spirv_type.rs b/crates/rustc_codegen_spirv/src/spirv_type.rs index b94a8bf04f..b5a3b91697 100644 --- a/crates/rustc_codegen_spirv/src/spirv_type.rs +++ b/crates/rustc_codegen_spirv/src/spirv_type.rs @@ -87,6 +87,7 @@ pub enum SpirvType { }, AccelerationStructureKhr, + RayQueryKhr, } impl SpirvType { @@ -251,6 +252,7 @@ impl SpirvType { ), Self::Sampler => cx.emit_global().type_sampler(), Self::AccelerationStructureKhr => cx.emit_global().type_acceleration_structure_khr(), + Self::RayQueryKhr => cx.emit_global().type_ray_query_khr(), Self::SampledImage { image_type } => cx.emit_global().type_sampled_image(image_type), Self::InterfaceBlock { inner_type } => { @@ -352,6 +354,7 @@ impl SpirvType { Self::Pointer { .. } => cx.tcx.data_layout.pointer_size, Self::Image { .. } | Self::AccelerationStructureKhr + | Self::RayQueryKhr | Self::Sampler | Self::SampledImage { .. } => Size::from_bytes(4), @@ -383,6 +386,7 @@ impl SpirvType { Self::Pointer { .. } => cx.tcx.data_layout.pointer_align.abi, Self::Image { .. } | Self::AccelerationStructureKhr + | Self::RayQueryKhr | Self::Sampler | Self::SampledImage { .. } => Align::from_bytes(4).unwrap(), @@ -529,6 +533,7 @@ impl fmt::Debug for SpirvTypePrinter<'_, '_> { .field("inner_type", &self.cx.debug_type(inner_type)) .finish(), SpirvType::AccelerationStructureKhr => f.debug_struct("AccelerationStructure").finish(), + SpirvType::RayQueryKhr => f.debug_struct("RayQuery").finish(), }; { let mut debug_stack = DEBUG_STACK.lock().unwrap(); @@ -684,6 +689,7 @@ impl SpirvTypePrinter<'_, '_> { f.write_str(" }") } SpirvType::AccelerationStructureKhr => f.write_str("AccelerationStructureKhr"), + SpirvType::RayQueryKhr => f.write_str("RayQueryKhr"), } } } diff --git a/crates/rustc_codegen_spirv/src/spirv_type_constraints.rs b/crates/rustc_codegen_spirv/src/spirv_type_constraints.rs index 8325d053bc..e7ca98706a 100644 --- a/crates/rustc_codegen_spirv/src/spirv_type_constraints.rs +++ b/crates/rustc_codegen_spirv/src/spirv_type_constraints.rs @@ -803,7 +803,7 @@ pub fn instruction_signatures(op: Op) -> Option<&'static [InstSig<'static>]> { | Op::RayQueryGetWorldRayDirectionKHR | Op::RayQueryGetWorldRayOriginKHR | Op::RayQueryGetIntersectionObjectToWorldKHR - | Op::RayQueryGetIntersectionWorldToObjectKHR => reserved!(SPV_KHR_ray_query), + | Op::RayQueryGetIntersectionWorldToObjectKHR => {} // Instructions not present in current SPIR-V specification // SPV_INTEL_function_pointers diff --git a/crates/rustc_codegen_spirv/src/symbols.rs b/crates/rustc_codegen_spirv/src/symbols.rs index abaccb5c55..401fe7aa07 100644 --- a/crates/rustc_codegen_spirv/src/symbols.rs +++ b/crates/rustc_codegen_spirv/src/symbols.rs @@ -321,6 +321,10 @@ impl Symbols { "acceleration_structure", SpirvAttribute::IntrinsicType(IntrinsicType::AccelerationStructureKhr), ), + ( + "ray_query", + SpirvAttribute::IntrinsicType(IntrinsicType::RayQueryKhr), + ), ("block", SpirvAttribute::Block), ("flat", SpirvAttribute::Flat), ("invariant", SpirvAttribute::Invariant), diff --git a/crates/spirv-std/src/ray_tracing.rs b/crates/spirv-std/src/ray_tracing.rs index 9ae62a2e1e..e9575b5048 100644 --- a/crates/spirv-std/src/ray_tracing.rs +++ b/crates/spirv-std/src/ray_tracing.rs @@ -159,3 +159,450 @@ bitflags::bitflags! { const SKIP_AABBS = 512; } } + +/// A ray query type which is an opaque object representing a ray traversal. +#[spirv(ray_query)] +#[derive(Clone, Default)] +pub struct RayQuery { + _private: (), +} + +impl RayQuery { + /// Create a new uninitalized ray query handle. + #[inline(always)] + pub unsafe fn new() -> Self { + Self { _private: () } + } + + /// Initialize a ray query object, defining parameters of traversal. After this + /// call, a new ray trace can be performed with `ray_query_proceed_khr`. Any + /// previous traversal state stored in the object is lost. + /// + /// - `ray_query` is a pointer to the ray query to initialize. + /// - `acceleration_structure` is the descriptor for the acceleration structure + /// to trace into. + /// - `ray_flags` contains one or more of the Ray Flag values. + /// - `cull_mask` is the mask to test against the instance mask. Only the 8 + /// least-significant bits of `cull_mask` are used by this instruction - other + /// bits are ignored. + /// - `ray_origin`, `ray_tmin`, `ray_direction`, and `ray_tmax` control the + /// basic parameters of the ray to be traced. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryInitializeKHR")] + #[inline] + #[allow(clippy::too_many_arguments)] + pub unsafe fn initialize( + &self, + acceleration_structure: &AccelerationStructure, + ray_flags: RayFlags, + cull_mask: u32, + ray_origin: impl Vector, + ray_tmin: f32, + ray_direction: impl Vector, + ray_tmax: f32, + ) { + asm! { + "OpRayQueryInitializeKHR \ + {ray_query} \ + {acceleration_structure} \ + {ray_flags} \ + {cull_mask} \ + {ray_origin} \ + {ray_tmin} \ + {ray_direction} \ + {ray_tmax}", + ray_query = in(reg) self, + acceleration_structure = in(reg) acceleration_structure, + ray_flags = in(reg) ray_flags.bits(), + cull_mask = in(reg) cull_mask, + ray_origin = in(reg) &ray_origin, + ray_tmin = in(reg) ray_tmin, + ray_direction = in(reg) &ray_direction, + ray_tmax = in(reg) ray_tmax, + } + } + + /// Terminates further execution of a ray query; further calls to + /// [`ray_query_proceed_khr`] will return `false`.The value returned by any prior + /// execution of [`ray_query_proceed_khr`] with the same ray query object must have + /// been true. Refer to the client API specification for more details. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryTerminateKHR")] + #[inline] + pub unsafe fn terminate(self) { + asm!("OpRayQueryTerminateKHR {}", in(reg) &self) + } + + /// Returns the type of the current candidate or committed intersection. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionTypeKHR")] + #[inline] + pub unsafe fn get_intersection_type(&self) -> u32 { + let mut result = 0; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetIntersectionTypeKHR %u32 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Returns the "Ray Tmin" value used by the ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetRayTMinKHR")] + #[inline] + pub unsafe fn get_ray_t_min(&self) -> f32 { + let mut result = 0.0; + + asm! { + "%f32 = OpTypeFloat 32", + "%result = OpRayQueryGetRayTMinKHR %f32 {ray_query}", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } + + result + } + + /// Returns the "Ray Flags" value used by the ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetRayFlagsKHR")] + #[inline] + pub unsafe fn get_ray_flags(&self) -> RayFlags { + let mut result = 0; + + asm! { + "%u32 = OpTypeInt 32 0", + "%result = OpRayQueryGetRayFlagsKHR %u32 {ray_query}", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } + + RayFlags::from_bits_truncate(result) + } + + /// Gets the "T" value for the current or previous intersection considered in a + /// ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionTKHR")] + #[inline] + pub unsafe fn get_intersection_t(&self) -> f32 { + let mut result = 0.0; + + asm! { + "%f32 = OpTypeFloat 32", + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetIntersectionTKHR %f32 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Gets the custom index of the instance for the current intersection + /// considered in a ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionInstanceCustomIndexKHR")] + #[inline] + pub unsafe fn get_intersection_instance_custom_index(&self) -> u32 { + let mut result = 0; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetIntersectionInstanceCustomIndexKHR %u32 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Gets the id of the instance for the current intersection considered in a + /// ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionInstanceIdKHR")] + #[inline] + pub unsafe fn get_intersection_instance_id(&self) -> u32 { + let mut result = 0; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetIntersectionInstanceIdKHR %u32 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Gets the shader binding table record offset for the current intersection + /// considered in a ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR")] + #[inline] + pub unsafe fn get_intersection_shader_binding_table_record_offset( + &self, + ) -> u32 { + let mut result = 0; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %u32 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Gets the geometry index for the current intersection considered in a + /// ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionGeometryIndexKHR")] + #[inline] + pub unsafe fn get_intersection_geometry_index(&self) -> u32 { + let mut result = 0; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetIntersectionGeometryIndexKHR %u32 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Gets the primitive index for the current intersection considered in a + /// ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionPrimitiveIndexKHR")] + #[inline] + pub unsafe fn get_intersection_primitive_index(&self) -> u32 { + let mut result = 0; + + asm! { + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetIntersectionPrimitiveIndexKHR %u32 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Gets the second and third barycentric coordinates of the current + /// intersection considered in a ray query against the primitive it hit. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionBarycentricsKHR")] + #[inline] + pub unsafe fn get_intersection_barycentrics, const INTERSECTION: u32>( + &self, + ) -> V { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%f32 = OpTypeFloat 32", + "%f32x2 = OpTypeVector %f32 2", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetIntersectionBarycentricsKHR %f32x2 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Returns whether the current intersection considered in a ray query was with + /// the front face (`true`) or back face (`false`) of a primitive. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionFrontFaceKHR")] + #[inline] + pub unsafe fn get_intersection_front_face(&self) -> bool { + let mut result = 0u8; + + asm! { + "%u8 = OpTypeInt 8 0", + "%u32 = OpTypeInt 32 0", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetIntersectionFrontFaceKHR %u8 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result != 0 + } + + /// Returns whether a candidate intersection considered in a ray query was with + /// an opaque AABB (Axis Aligned Bounding Box) or not. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR")] + #[inline] + pub unsafe fn get_intersection_candidate_aabb_opaque(&self) -> bool { + let mut result = 0u8; + + asm! { + "%u8 = OpTypeInt 8 0", + "%result = OpRayQueryGetIntersectionCandidateAABBOpaqueKHR %u8 {ray_query}", + "OpStore {result} %result", + ray_query = in(reg) self, + result = in(reg) &mut result, + } + + result != 0 + } + + /// Gets the object-space ray direction for the current intersection considered + /// in a ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionObjectRayDirectionKHR")] + #[inline] + pub unsafe fn get_intersection_object_ray_direction< + V: Vector, + const INTERSECTION: u32, + >( + &self, + ) -> V { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%f32 = OpTypeFloat 32", + "%f32x3 = OpTypeVector %f32 3", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetIntersectionObjectRayDirectionKHR %f32x3 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Gets the object-space ray origin for the current intersection considered in + /// a ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionObjectRayOriginKHR")] + #[inline] + pub unsafe fn get_intersection_object_ray_origin, const INTERSECTION: u32>( + &self, + ) -> V { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%f32 = OpTypeFloat 32", + "%f32x3 = OpTypeVector %f32 3", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetIntersectionObjectRayOriginKHR %f32x3 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Gets the world-space direction for the ray traced in a ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetWorldRayDirectionKHR")] + #[inline] + pub unsafe fn get_world_ray_direction, const INTERSECTION: u32>(&self) -> V { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%f32 = OpTypeFloat 32", + "%f32x3 = OpTypeVector %f32 3", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetWorldRayDirectionKHR %f32x3 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Gets the world-space origin for the ray traced in a ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetWorldRayOriginKHR")] + #[inline] + pub unsafe fn get_world_ray_origin, const INTERSECTION: u32>(&self) -> V { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%f32 = OpTypeFloat 32", + "%f32x3 = OpTypeVector %f32 3", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetWorldRayOriginKHR %f32x3 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } + + /// Gets a matrix that transforms values to world-space from the object-space of + /// the current intersection considered in a ray query. + #[spirv_std_macros::gpu_only] + #[doc(alias = "OpRayQueryGetIntersectionObjectToWorldKHR")] + #[inline] + pub unsafe fn get_intersection_object_to_world, const INTERSECTION: u32>( + &self, + ) -> V { + let mut result = Default::default(); + + asm! { + "%u32 = OpTypeInt 32 0", + "%f32 = OpTypeFloat 32", + "%f32x3 = OpTypeVector %f32 3", + "%intersection = OpConstant %u32 {intersection}", + "%result = OpRayQueryGetWorldRayOriginKHR %f32x3 {ray_query} %intersection", + "OpStore {result} %result", + ray_query = in(reg) self, + intersection = const INTERSECTION, + result = in(reg) &mut result, + } + + result + } +} diff --git a/tests/ui/arch/ray_query_get_intersection_barycentrics_khr.rs b/tests/ui/arch/ray_query_get_intersection_barycentrics_khr.rs new file mode 100644 index 0000000000..ef7970fa63 --- /dev/null +++ b/tests/ui/arch/ray_query_get_intersection_barycentrics_khr.rs @@ -0,0 +1,11 @@ +// build-pass + +#[spirv(fragment)] +pub fn main() { + unsafe { + asm!(r#"OpExtension "SPV_KHR_ray_query""#); + asm!("OpCapability RayQueryKHR"); + let ray_query = spirv_std::ray_tracing::RayQuery::new(); + let barycentric_coords: glam::Vec2 = ray_query.get_intersection_barycentrics::<_, 5>(); + } +} diff --git a/tests/ui/arch/ray_query_get_intersection_front_face_khr.rs b/tests/ui/arch/ray_query_get_intersection_front_face_khr.rs new file mode 100644 index 0000000000..01fe425302 --- /dev/null +++ b/tests/ui/arch/ray_query_get_intersection_front_face_khr.rs @@ -0,0 +1,11 @@ +// build-pass + +#[spirv(fragment)] +pub fn main() { + unsafe { + asm!(r#"OpExtension "SPV_KHR_ray_query""#); + asm!("OpCapability RayQueryKHR"); + let ray_query = spirv_std::ray_tracing::RayQuery::new(); + assert!(ray_query.get_intersection_front_face::<5>()); + } +} diff --git a/tests/ui/arch/ray_query_get_intersection_geometry_index_khr.rs b/tests/ui/arch/ray_query_get_intersection_geometry_index_khr.rs new file mode 100644 index 0000000000..8d12c93ecc --- /dev/null +++ b/tests/ui/arch/ray_query_get_intersection_geometry_index_khr.rs @@ -0,0 +1,11 @@ +// build-pass + +#[spirv(fragment)] +pub fn main() { + unsafe { + asm!(r#"OpExtension "SPV_KHR_ray_query""#); + asm!("OpCapability RayQueryKHR"); + let ray_query = spirv_std::ray_tracing::RayQuery::new(); + let t = ray_query.get_intersection_geometry_index::<5>(); + } +} diff --git a/tests/ui/arch/ray_query_get_intersection_instance_custom_index_khr.rs b/tests/ui/arch/ray_query_get_intersection_instance_custom_index_khr.rs new file mode 100644 index 0000000000..ac4fe16fe0 --- /dev/null +++ b/tests/ui/arch/ray_query_get_intersection_instance_custom_index_khr.rs @@ -0,0 +1,11 @@ +// build-pass + +#[spirv(fragment)] +pub fn main() { + unsafe { + asm!(r#"OpExtension "SPV_KHR_ray_query""#); + asm!("OpCapability RayQueryKHR"); + let ray_query = spirv_std::ray_tracing::RayQuery::new(); + let t = ray_query.get_intersection_instance_custom_index::<5>(); + } +} diff --git a/tests/ui/arch/ray_query_get_intersection_instance_id_khr.rs b/tests/ui/arch/ray_query_get_intersection_instance_id_khr.rs new file mode 100644 index 0000000000..26e6eff7ef --- /dev/null +++ b/tests/ui/arch/ray_query_get_intersection_instance_id_khr.rs @@ -0,0 +1,11 @@ +// build-pass + +#[spirv(fragment)] +pub fn main() { + unsafe { + asm!(r#"OpExtension "SPV_KHR_ray_query""#); + asm!("OpCapability RayQueryKHR"); + let ray_query = spirv_std::ray_tracing::RayQuery::new(); + let t = ray_query.get_intersection_instance_id::<5>(); + } +} diff --git a/tests/ui/arch/ray_query_get_intersection_shader_binding_table_record_offset_khr.rs b/tests/ui/arch/ray_query_get_intersection_shader_binding_table_record_offset_khr.rs new file mode 100644 index 0000000000..47cd431eb7 --- /dev/null +++ b/tests/ui/arch/ray_query_get_intersection_shader_binding_table_record_offset_khr.rs @@ -0,0 +1,11 @@ +// build-pass + +#[spirv(fragment)] +pub fn main() { + unsafe { + asm!(r#"OpExtension "SPV_KHR_ray_query""#); + asm!("OpCapability RayQueryKHR"); + let ray_query = spirv_std::ray_tracing::RayQuery::new(); + let t = ray_query.get_intersection_shader_binding_table_record_offset::<5>(); + } +} diff --git a/tests/ui/arch/ray_query_get_intersection_t_khr.rs b/tests/ui/arch/ray_query_get_intersection_t_khr.rs new file mode 100644 index 0000000000..21fe31311a --- /dev/null +++ b/tests/ui/arch/ray_query_get_intersection_t_khr.rs @@ -0,0 +1,10 @@ +// build-pass + +#[spirv(fragment)] +pub fn main(#[spirv(descriptor_set = 0, binding = 0)] handle: &spirv_std::ray_tracing::RayQuery) { + unsafe { + asm!(r#"OpExtension "SPV_KHR_ray_query""#); + asm!("OpCapability RayQueryKHR"); + let t = handle.get_intersection_t::<5>(); + } +} diff --git a/tests/ui/arch/ray_query_get_intersection_type_khr.rs b/tests/ui/arch/ray_query_get_intersection_type_khr.rs new file mode 100644 index 0000000000..30de2736ad --- /dev/null +++ b/tests/ui/arch/ray_query_get_intersection_type_khr.rs @@ -0,0 +1,11 @@ +// build-pass + +#[spirv(fragment)] +pub fn main() { + unsafe { + asm!(r#"OpExtension "SPV_KHR_ray_query""#); + asm!("OpCapability RayQueryKHR"); + let ray_query = spirv_std::ray_tracing::RayQuery::new(); + ray_query.get_intersection_type::<5>(); + } +} diff --git a/tests/ui/arch/ray_query_get_ray_t_min_khr.rs b/tests/ui/arch/ray_query_get_ray_t_min_khr.rs new file mode 100644 index 0000000000..4fa7a717fc --- /dev/null +++ b/tests/ui/arch/ray_query_get_ray_t_min_khr.rs @@ -0,0 +1,11 @@ +// build-pass + +#[spirv(fragment)] +pub fn main() { + unsafe { + asm!(r#"OpExtension "SPV_KHR_ray_query""#); + asm!("OpCapability RayQueryKHR"); + let ray_query = spirv_std::ray_tracing::RayQuery::new(); + let tmin = ray_query.get_ray_t_min(); + } +} diff --git a/tests/ui/arch/ray_query_initialize_khr.rs b/tests/ui/arch/ray_query_initialize_khr.rs new file mode 100644 index 0000000000..dc63c1a3c4 --- /dev/null +++ b/tests/ui/arch/ray_query_initialize_khr.rs @@ -0,0 +1,24 @@ +// build-pass + +#[spirv(fragment)] +// Rustfmt eats long attributes +#[rustfmt::skip] +pub fn main( + #[spirv(descriptor_set = 0, binding = 0)] acceleration_structure: &spirv_std::ray_tracing::AccelerationStructure, + #[spirv(descriptor_set = 0, binding = 0)] handle: &spirv_std::ray_tracing::RayQuery, + #[spirv(ray_payload)] payload: &mut glam::Vec3, +) { + unsafe { + asm!(r#"OpExtension "SPV_KHR_ray_query""#); + asm!("OpCapability RayQueryKHR"); + handle.initialize( + acceleration_structure, + spirv_std::ray_tracing::RayFlags::NONE, + 0, + glam::vec3(1.0, 2.0, 3.0), + 0.5, + glam::vec3(3.0, 2.0, 1.0), + 1.0, + ); + } +} diff --git a/tests/ui/arch/ray_query_terminate_khr.rs b/tests/ui/arch/ray_query_terminate_khr.rs new file mode 100644 index 0000000000..e6d34a3432 --- /dev/null +++ b/tests/ui/arch/ray_query_terminate_khr.rs @@ -0,0 +1,11 @@ +// build-pass + +#[spirv(fragment)] +pub fn main() { + unsafe { + asm!(r#"OpExtension "SPV_KHR_ray_query""#); + asm!("OpCapability RayQueryKHR"); + let ray_query = spirv_std::ray_tracing::RayQuery::new(); + ray_query.terminate(); + } +}