mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-22 06:45:13 +00:00
Add support for SPV_KHR_ray_query
This commit is contained in:
parent
ec131ca95c
commit
18ba6f322d
@ -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) {
|
||||
|
@ -73,6 +73,7 @@ pub enum IntrinsicType {
|
||||
Sampler,
|
||||
AccelerationStructureKhr,
|
||||
SampledImage,
|
||||
RayQueryKhr,
|
||||
}
|
||||
|
||||
// NOTE(eddyb) when adding new `#[spirv(...)]` attributes, the tests found inside
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,6 +179,7 @@ impl<'tcx> BaseTypeMethods<'tcx> for CodegenCx<'tcx> {
|
||||
| SpirvType::Sampler
|
||||
| SpirvType::SampledImage { .. }
|
||||
| SpirvType::AccelerationStructureKhr
|
||||
| SpirvType::RayQueryKhr
|
||||
=> TypeKind::Token,
|
||||
}
|
||||
}
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
15
tests/ui/arch/ray_query_get_intersection_barycentrics_khr.rs
Normal file
15
tests/ui/arch/ray_query_get_intersection_barycentrics_khr.rs
Normal 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>();
|
||||
}
|
||||
}
|
15
tests/ui/arch/ray_query_get_intersection_front_face_khr.rs
Normal file
15
tests/ui/arch/ray_query_get_intersection_front_face_khr.rs
Normal 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>());
|
||||
}
|
||||
}
|
@ -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>();
|
||||
}
|
||||
}
|
@ -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>();
|
||||
}
|
||||
}
|
15
tests/ui/arch/ray_query_get_intersection_instance_id_khr.rs
Normal file
15
tests/ui/arch/ray_query_get_intersection_instance_id_khr.rs
Normal 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>();
|
||||
}
|
||||
}
|
@ -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>();
|
||||
}
|
||||
}
|
15
tests/ui/arch/ray_query_get_intersection_t_khr.rs
Normal file
15
tests/ui/arch/ray_query_get_intersection_t_khr.rs
Normal 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>();
|
||||
}
|
||||
}
|
15
tests/ui/arch/ray_query_get_intersection_type_khr.rs
Normal file
15
tests/ui/arch/ray_query_get_intersection_type_khr.rs
Normal 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>();
|
||||
}
|
||||
}
|
15
tests/ui/arch/ray_query_get_ray_t_min_khr.rs
Normal file
15
tests/ui/arch/ray_query_get_ray_t_min_khr.rs
Normal 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();
|
||||
}
|
||||
}
|
28
tests/ui/arch/ray_query_initialize_khr.rs
Normal file
28
tests/ui/arch/ray_query_initialize_khr.rs
Normal 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,
|
||||
);
|
||||
}
|
||||
}
|
15
tests/ui/arch/ray_query_proceed_khr.rs
Normal file
15
tests/ui/arch/ray_query_proceed_khr.rs
Normal 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());
|
||||
}
|
||||
}
|
15
tests/ui/arch/ray_query_terminate_khr.rs
Normal file
15
tests/ui/arch/ray_query_terminate_khr.rs
Normal 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();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user