Add support for SPV_KHR_ray_query

This commit is contained in:
Erin Power 2021-03-31 15:33:56 +02:00 committed by Eduard-Mihai Burtescu
parent ec131ca95c
commit 18ba6f322d
22 changed files with 703 additions and 1 deletions

View File

@ -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) {

View File

@ -73,6 +73,7 @@ pub enum IntrinsicType {
Sampler,
AccelerationStructureKhr,
SampledImage,
RayQueryKhr,
}
// NOTE(eddyb) when adding new `#[spirv(...)]` attributes, the tests found inside

View File

@ -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"),
}
}

View File

@ -312,6 +312,7 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> {
image_type: inst.operands[0].unwrap_id_ref(),
}
.def(self.span(), self),
Op::TypeRayQueryKHR => SpirvType::RayQueryKhr.def(self.span(), self),
Op::Variable if inst.operands[0].unwrap_storage_class() != StorageClass::Function => {
// OpVariable with Function storage class should be emitted inside the function,
// however, all other OpVariables should appear in the global scope instead.

View File

@ -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"),
}
}
}

View File

@ -179,6 +179,7 @@ impl<'tcx> BaseTypeMethods<'tcx> for CodegenCx<'tcx> {
| SpirvType::Sampler
| SpirvType::SampledImage { .. }
| SpirvType::AccelerationStructureKhr
| SpirvType::RayQueryKhr
=> TypeKind::Token,
}
}

View File

@ -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("RayQuery"),
}
}
}

View File

@ -811,7 +811,10 @@ 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 => {
// NOTE(eddyb) we actually use these despite not being in the standard yet.
// reserved!(SPV_KHR_ray_query)
}
// Instructions not present in current SPIR-V specification
// SPV_INTEL_function_pointers

View File

@ -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),

View File

@ -159,3 +159,492 @@ bitflags::bitflags! {
const SKIP_AABBS = 512;
}
}
/// A ray query type which is an opaque object representing a ray traversal.
#[spirv(ray_query)]
pub struct RayQuery {
_private: u32,
}
/// Constructs an uninitialized ray query variable. Using the syntax
/// `let (mut)? <name>`. Where `name` is the name of the ray query variable.
#[macro_export]
macro_rules! ray_query {
(let $name:ident) => {
$crate::ray_query!(@inner $name)
};
(let mut $name:ident) => {
$crate::ray_query!(@inner $name, mut)
};
(@inner $name:ident $(, $mut:tt)?) => {
let $name: &$($mut)? RayQuery = unsafe {
let $name : *mut RayQuery;
asm! {
"%ray_query = OpTypeRayQueryKHR",
"%ray_query_ptr = OpTypePointer Generic %ray_query",
"{name} = OpVariable %ray_query_ptr Function",
name = out(reg) $name,
}
&$($mut)? *$name
};
}
}
impl RayQuery {
/// Initialize a ray query object, defining parameters of traversal. After this
/// call, a new ray trace can be performed with [`Self::proceed`]. 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(
&mut self,
acceleration_structure: &AccelerationStructure,
ray_flags: RayFlags,
cull_mask: u32,
ray_origin: impl Vector<f32, 3>,
ray_tmin: f32,
ray_direction: impl Vector<f32, 3>,
ray_tmax: f32,
) {
asm! {
"%origin = OpLoad _ {ray_origin}",
"%direction = OpLoad _ {ray_direction}",
"OpRayQueryInitializeKHR \
{ray_query} \
{acceleration_structure} \
{ray_flags} \
{cull_mask} \
%origin \
{ray_tmin} \
%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,
}
}
/// Allow traversal to proceed. Returns `true` if traversal is incomplete,
/// and `false` when it has completed. A previous call to [`Self::proceed`]
/// with the same ray query object must not have already returned `false`.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpRayQueryProceedKHR")]
#[inline]
pub unsafe fn proceed(&self) -> bool {
let result: u32;
asm! {
"%u32 = OpTypeInt 32 0",
"%bool = OpTypeBool",
"%u32_0 = OpConstant %u32 0",
"%u32_1 = OpConstant %u32 1",
"%result = OpRayQueryProceedKHR %bool {ray_query}",
"{result} = OpSelect %u32 %result %u32_0 %u32_1",
ray_query = in(reg) self,
result = out(reg) result,
}
result != 0
}
/// Terminates further execution of a ray query; further calls to
/// [`Self::proceed`] will return `false`.The value returned by any prior
/// execution of [`Self::proceed`] 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<const INTERSECTION: u32>(&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<const INTERSECTION: u32>(&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<const INTERSECTION: u32>(&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<const INTERSECTION: u32>(&self) -> u32 {
let mut result;
asm! {
"%u32 = OpTypeInt 32 0",
"%intersection = OpConstant %u32 {intersection}",
"{result} = OpRayQueryGetIntersectionInstanceIdKHR %u32 {ray_query} %intersection",
ray_query = in(reg) self,
intersection = const INTERSECTION,
result = out(reg) 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<const INTERSECTION: u32>(
&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<const INTERSECTION: u32>(&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<const INTERSECTION: u32>(&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<V: Vector<f32, 2>, 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<const INTERSECTION: u32>(&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<f32, 3>,
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<V: Vector<f32, 3>, 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<V: Vector<f32, 3>, 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<V: Vector<f32, 3>, 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<V: Vector<f32, 3>, 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
}
}

View File

@ -0,0 +1,15 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let barycentric_coords: glam::Vec2 = handle.get_intersection_barycentrics::<_, 5>();
}
}

View File

@ -0,0 +1,15 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
assert!(handle.get_intersection_front_face::<5>());
}
}

View File

@ -0,0 +1,15 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let t = handle.get_intersection_geometry_index::<5>();
}
}

View File

@ -0,0 +1,15 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let index = handle.get_intersection_instance_custom_index::<5>();
}
}

View File

@ -0,0 +1,15 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let id = handle.get_intersection_instance_id::<5>();
}
}

View File

@ -0,0 +1,15 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let offset = handle.get_intersection_shader_binding_table_record_offset::<5>();
}
}

View File

@ -0,0 +1,15 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let t = handle.get_intersection_t::<5>();
}
}

View File

@ -0,0 +1,15 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
handle.get_intersection_type::<5>();
}
}

View File

@ -0,0 +1,15 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
let tmin = handle.get_ray_t_min();
}
}

View File

@ -0,0 +1,28 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
// Rustfmt eats long attributes <https://github.com/rust-lang/rustfmt/issues/4579>
#[rustfmt::skip]
pub fn main(
#[spirv(descriptor_set = 0, binding = 0)] acceleration_structure: &AccelerationStructure,
#[spirv(ray_payload)] payload: &mut Vec3,
) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut ray_query);
ray_query.initialize(
acceleration_structure,
RayFlags::NONE,
0,
glam::vec3(1.0, 2.0, 3.0),
0.5,
glam::vec3(3.0, 2.0, 1.0),
1.0,
);
}
}

View File

@ -0,0 +1,15 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
assert!(handle.proceed());
}
}

View File

@ -0,0 +1,15 @@
// build-pass
use glam::Vec3;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) {
unsafe {
asm!(r#"OpExtension "SPV_KHR_ray_query""#);
asm!("OpCapability RayQueryKHR");
spirv_std::ray_query!(let mut handle);
handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0);
handle.terminate();
}
}