1#![allow(clippy::bad_bit_mask)]
5
6use crate::vector::Vector;
7#[cfg(target_arch = "spirv")]
8use core::arch::asm;
9
10#[spirv(acceleration_structure)]
13#[derive(Copy, Clone)]
14#[repr(C)]
16pub struct AccelerationStructure {
17 _anti_zst_padding: core::mem::MaybeUninit<u32>,
20}
21
22impl AccelerationStructure {
23 #[spirv_std_macros::gpu_only]
27 #[doc(alias = "OpConvertUToAccelerationStructureKHR")]
28 #[inline]
29 pub unsafe fn from_u64(id: u64) -> AccelerationStructure {
30 unsafe {
31 let mut result_slot = core::mem::MaybeUninit::uninit();
33 asm! {
34 "%ret = OpTypeAccelerationStructureKHR",
35 "%result = OpConvertUToAccelerationStructureKHR %ret {id}",
36 "OpStore {result_slot} %result",
37 id = in(reg) id,
38 result_slot = in(reg) result_slot.as_mut_ptr(),
39 }
40 result_slot.assume_init()
41 }
42 }
43
44 #[spirv_std_macros::gpu_only]
48 #[doc(alias = "OpConvertUToAccelerationStructureKHR")]
49 #[inline]
50 pub unsafe fn from_vec(id: impl Vector<u32, 2>) -> AccelerationStructure {
51 unsafe {
52 let mut result_slot = core::mem::MaybeUninit::uninit();
54 asm! {
55 "%ret = OpTypeAccelerationStructureKHR",
56 "%id = OpLoad _ {id}",
57 "%result = OpConvertUToAccelerationStructureKHR %ret %id",
58 "OpStore {result_slot} %result",
59 id = in(reg) &id,
60 result_slot = in(reg) result_slot.as_mut_ptr(),
61 }
62 result_slot.assume_init()
63 }
64 }
65
66 #[spirv_std_macros::gpu_only]
67 #[doc(alias = "OpTraceRayKHR")]
95 #[inline]
96 #[allow(clippy::too_many_arguments)]
97 pub unsafe fn trace_ray<T>(
98 &self,
99 ray_flags: RayFlags,
100 cull_mask: i32,
101 sbt_offset: i32,
102 sbt_stride: i32,
103 miss_index: i32,
104 ray_origin: impl Vector<f32, 3>,
105 ray_tmin: f32,
106 ray_direction: impl Vector<f32, 3>,
107 ray_tmax: f32,
108 payload: &mut T,
109 ) {
110 unsafe {
111 asm! {
112 "%acceleration_structure = OpLoad _ {acceleration_structure}",
113 "%ray_origin = OpLoad _ {ray_origin}",
114 "%ray_direction = OpLoad _ {ray_direction}",
115 "OpTraceRayKHR \
116 %acceleration_structure \
117 {ray_flags} \
118 {cull_mask} \
119 {sbt_offset} \
120 {sbt_stride} \
121 {miss_index} \
122 %ray_origin \
123 {ray_tmin} \
124 %ray_direction \
125 {ray_tmax} \
126 {payload}",
127 acceleration_structure = in(reg) self,
128 ray_flags = in(reg) ray_flags.bits(),
129 cull_mask = in(reg) cull_mask,
130 sbt_offset = in(reg) sbt_offset,
131 sbt_stride = in(reg) sbt_stride,
132 miss_index = in(reg) miss_index,
133 ray_origin = in(reg) &ray_origin,
134 ray_tmin = in(reg) ray_tmin,
135 ray_direction = in(reg) &ray_direction,
136 ray_tmax = in(reg) ray_tmax,
137 payload = in(reg) payload,
138 }
139 }
140 }
141}
142
143bitflags::bitflags! {
144 #[repr(transparent)]
151 #[cfg_attr(feature = "bytemuck", derive(bytemuck::Zeroable, bytemuck::Pod))]
152 pub struct RayFlags: u32 {
153 const NONE = 0;
155 const OPAQUE = 1;
157 const NO_OPAQUE = 2;
159 const TERMINATE_ON_FIRST_HIT = 4;
161 const SKIP_CLOSEST_HIT_SHADER = 8;
163 const CULL_BACK_FACING_TRIANGLES = 16;
165 const CULL_FRONT_FACING_TRIANGLES = 32;
167 const CULL_OPAQUE = 64;
169 const CULL_NO_OPAQUE = 128;
171 const SKIP_TRIANGLES = 256;
173 const SKIP_AABBS = 512;
175 }
176}
177
178#[repr(u32)]
181#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
182#[allow(clippy::upper_case_acronyms)]
183pub enum CandidateIntersection {
184 Triangle = 0,
186 AABB = 1,
188}
189
190#[repr(u32)]
193#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
194pub enum CommittedIntersection {
195 None = 0,
197 Triangle = 1,
199 Generated = 2,
201}
202
203#[spirv(ray_query)]
205#[repr(C)]
207#[allow(dead_code)]
209pub struct RayQuery {
210 _anti_zst_padding: core::mem::MaybeUninit<u32>,
213}
214
215#[macro_export]
218macro_rules! ray_query {
219 (let $name:ident) => {
220 $crate::ray_query!(@inner $name)
221 };
222 (let mut $name:ident) => {
223 $crate::ray_query!(@inner $name, mut)
224 };
225 (@inner $name:ident $(, $mut:tt)?) => {
226 let $name: &$($mut)? RayQuery = unsafe {
227 let $name : *mut RayQuery;
228 ::core::arch::asm! {
229 "%ray_query = OpTypeRayQueryKHR",
230 "%ray_query_ptr = OpTypePointer Generic %ray_query",
231 "{name} = OpVariable %ray_query_ptr Function",
232 name = out(reg) $name,
233 }
234
235 &$($mut)? *$name
236 };
237 }
238}
239
240impl RayQuery {
241 #[spirv_std_macros::gpu_only]
255 #[doc(alias = "OpRayQueryInitializeKHR")]
256 #[inline]
257 #[allow(clippy::too_many_arguments)]
258 pub unsafe fn initialize(
259 &mut self,
260 acceleration_structure: &AccelerationStructure,
261 ray_flags: RayFlags,
262 cull_mask: u32,
263 ray_origin: impl Vector<f32, 3>,
264 ray_tmin: f32,
265 ray_direction: impl Vector<f32, 3>,
266 ray_tmax: f32,
267 ) {
268 unsafe {
269 asm! {
270 "%acceleration_structure = OpLoad _ {acceleration_structure}",
271 "%origin = OpLoad _ {ray_origin}",
272 "%direction = OpLoad _ {ray_direction}",
273 "OpRayQueryInitializeKHR \
274 {ray_query} \
275 %acceleration_structure \
276 {ray_flags} \
277 {cull_mask} \
278 %origin \
279 {ray_tmin} \
280 %direction \
281 {ray_tmax}",
282 ray_query = in(reg) self,
283 acceleration_structure = in(reg) acceleration_structure,
284 ray_flags = in(reg) ray_flags.bits(),
285 cull_mask = in(reg) cull_mask,
286 ray_origin = in(reg) &ray_origin,
287 ray_tmin = in(reg) ray_tmin,
288 ray_direction = in(reg) &ray_direction,
289 ray_tmax = in(reg) ray_tmax,
290 }
291 }
292 }
293
294 #[spirv_std_macros::gpu_only]
298 #[doc(alias = "OpRayQueryProceedKHR")]
299 #[inline]
300 pub unsafe fn proceed(&self) -> bool {
301 unsafe {
302 let mut result = false;
303
304 asm! {
305 "%bool = OpTypeBool",
306 "%result = OpRayQueryProceedKHR %bool {ray_query}",
307 "OpStore {result} %result",
308 ray_query = in(reg) self,
309 result = in(reg) &mut result,
310 }
311
312 result
313 }
314 }
315
316 #[spirv_std_macros::gpu_only]
321 #[doc(alias = "OpRayQueryTerminateKHR")]
322 #[inline]
323 pub unsafe fn terminate(&self) {
324 unsafe { asm!("OpRayQueryTerminateKHR {}", in(reg) self) }
325 }
326
327 #[spirv_std_macros::gpu_only]
335 #[doc(alias = "OpRayQueryConfirmIntersectionKHR")]
336 #[inline]
337 pub unsafe fn confirm_intersection(&self) {
338 unsafe { asm!("OpRayQueryConfirmIntersectionKHR {}", in(reg) self) }
339 }
340
341 #[spirv_std_macros::gpu_only]
345 #[doc(alias = "OpRayQueryGetIntersectionTypeKHR")]
346 #[inline]
347 pub unsafe fn get_candidate_intersection_type(&self) -> CandidateIntersection {
348 unsafe {
349 let result: u32;
350
351 asm! {
352 "%u32 = OpTypeInt 32 0",
353 "%intersection = OpConstant %u32 0",
354 "{result} = OpRayQueryGetIntersectionTypeKHR %u32 {ray_query} %intersection",
355 ray_query = in(reg) self,
356 result = out(reg) result,
357 }
358
359 match result {
360 0 => CandidateIntersection::Triangle,
361 1 => CandidateIntersection::AABB,
362 _ => CandidateIntersection::Triangle,
363 }
364 }
365 }
366
367 #[spirv_std_macros::gpu_only]
369 #[doc(alias = "OpRayQueryGetIntersectionTypeKHR")]
370 #[inline]
371 pub unsafe fn get_committed_intersection_type(&self) -> CommittedIntersection {
372 unsafe {
373 let result: u32;
374
375 asm! {
376 "%u32 = OpTypeInt 32 0",
377 "%intersection = OpConstant %u32 1",
378 "{result} = OpRayQueryGetIntersectionTypeKHR %u32 {ray_query} %intersection",
379 ray_query = in(reg) self,
380 result = out(reg) result,
381 }
382
383 match result {
384 0 => CommittedIntersection::None,
385 1 => CommittedIntersection::Triangle,
386 2 => CommittedIntersection::Generated,
387 _ => CommittedIntersection::None,
388 }
389 }
390 }
391
392 #[spirv_std_macros::gpu_only]
394 #[doc(alias = "OpRayQueryGetRayTMinKHR")]
395 #[inline]
396 pub unsafe fn get_ray_t_min(&self) -> f32 {
397 unsafe {
398 let result;
399
400 asm! {
401 "%f32 = OpTypeFloat 32",
402 "{result} = OpRayQueryGetRayTMinKHR %f32 {ray_query}",
403 ray_query = in(reg) self,
404 result = out(reg) result,
405 }
406
407 result
408 }
409 }
410
411 #[spirv_std_macros::gpu_only]
413 #[doc(alias = "OpRayQueryGetRayFlagsKHR")]
414 #[inline]
415 pub unsafe fn get_ray_flags(&self) -> RayFlags {
416 unsafe {
417 let result;
418
419 asm! {
420 "{result} = OpRayQueryGetRayFlagsKHR typeof{result} {ray_query}",
421 ray_query = in(reg) self,
422 result = out(reg) result,
423 }
424
425 RayFlags::from_bits_truncate(result)
426 }
427 }
428
429 #[spirv_std_macros::gpu_only]
436 #[doc(alias = "OpRayQueryGetIntersectionTKHR")]
437 #[inline]
438 pub unsafe fn get_candidate_intersection_t(&self) -> f32 {
439 unsafe {
440 let result;
441
442 asm! {
443 "%u32 = OpTypeInt 32 0",
444 "%intersection = OpConstant %u32 0",
445 "{result} = OpRayQueryGetIntersectionTKHR typeof{result} {ray_query} %intersection",
446 ray_query = in(reg) self,
447 result = out(reg) result,
448 }
449
450 result
451 }
452 }
453
454 #[spirv_std_macros::gpu_only]
462 #[doc(alias = "OpRayQueryGetIntersectionTKHR")]
463 #[inline]
464 pub unsafe fn get_committed_intersection_t(&self) -> f32 {
465 unsafe {
466 let result;
467
468 asm! {
469 "%u32 = OpTypeInt 32 0",
470 "%intersection = OpConstant %u32 1",
471 "{result} = OpRayQueryGetIntersectionTKHR typeof{result} {ray_query} %intersection",
472 ray_query = in(reg) self,
473 result = out(reg) result,
474 }
475
476 result
477 }
478 }
479
480 #[spirv_std_macros::gpu_only]
485 #[doc(alias = "OpRayQueryGetIntersectionInstanceCustomIndexKHR")]
486 #[inline]
487 pub unsafe fn get_candidate_intersection_instance_custom_index(&self) -> u32 {
488 unsafe {
489 let result;
490
491 asm! {
492 "%u32 = OpTypeInt 32 0",
493 "%intersection = OpConstant %u32 0",
494 "{result} = OpRayQueryGetIntersectionInstanceCustomIndexKHR %u32 {ray_query} %intersection",
495 ray_query = in(reg) self,
496 result = out(reg) result,
497 }
498
499 result
500 }
501 }
502
503 #[spirv_std_macros::gpu_only]
511 #[doc(alias = "OpRayQueryGetIntersectionInstanceCustomIndexKHR")]
512 #[inline]
513 pub unsafe fn get_committed_intersection_instance_custom_index(&self) -> u32 {
514 unsafe {
515 let result;
516
517 asm! {
518 "%u32 = OpTypeInt 32 0",
519 "%intersection = OpConstant %u32 1",
520 "{result} = OpRayQueryGetIntersectionInstanceCustomIndexKHR %u32 {ray_query} %intersection",
521 ray_query = in(reg) self,
522 result = out(reg) result,
523 }
524
525 result
526 }
527 }
528
529 #[spirv_std_macros::gpu_only]
534 #[doc(alias = "OpRayQueryGetIntersectionInstanceIdKHR")]
535 #[inline]
536 pub unsafe fn get_candidate_intersection_instance_id(&self) -> u32 {
537 unsafe {
538 let result;
539
540 asm! {
541 "%u32 = OpTypeInt 32 0",
542 "%intersection = OpConstant %u32 0",
543 "{result} = OpRayQueryGetIntersectionInstanceIdKHR %u32 {ray_query} %intersection",
544 ray_query = in(reg) self,
545 result = out(reg) result,
546 }
547
548 result
549 }
550 }
551
552 #[spirv_std_macros::gpu_only]
560 #[doc(alias = "OpRayQueryGetIntersectionInstanceIdKHR")]
561 #[inline]
562 pub unsafe fn get_committed_intersection_instance_id(&self) -> u32 {
563 unsafe {
564 let result;
565
566 asm! {
567 "%u32 = OpTypeInt 32 0",
568 "%intersection = OpConstant %u32 1",
569 "{result} = OpRayQueryGetIntersectionInstanceIdKHR %u32 {ray_query} %intersection",
570 ray_query = in(reg) self,
571 result = out(reg) result,
572 }
573
574 result
575 }
576 }
577
578 #[spirv_std_macros::gpu_only]
583 #[doc(alias = "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR")]
584 #[inline]
585 pub unsafe fn get_candidate_intersection_shader_binding_table_record_offset(&self) -> u32 {
586 unsafe {
587 let result;
588
589 asm! {
590 "%u32 = OpTypeInt 32 0",
591 "%intersection = OpConstant %u32 0",
592 "{result} = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %u32 {ray_query} %intersection",
593 ray_query = in(reg) self,
594 result = out(reg) result,
595 }
596
597 result
598 }
599 }
600
601 #[spirv_std_macros::gpu_only]
609 #[doc(alias = "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR")]
610 #[inline]
611 pub unsafe fn get_committed_intersection_shader_binding_table_record_offset(&self) -> u32 {
612 unsafe {
613 let result;
614
615 asm! {
616 "%u32 = OpTypeInt 32 0",
617 "%intersection = OpConstant %u32 1",
618 "{result} = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %u32 {ray_query} %intersection",
619 ray_query = in(reg) self,
620 result = out(reg) result,
621 }
622
623 result
624 }
625 }
626
627 #[spirv_std_macros::gpu_only]
632 #[doc(alias = "OpRayQueryGetIntersectionGeometryIndexKHR")]
633 #[inline]
634 pub unsafe fn get_candidate_intersection_geometry_index(&self) -> u32 {
635 unsafe {
636 let result;
637
638 asm! {
639 "%u32 = OpTypeInt 32 0",
640 "%intersection = OpConstant %u32 0",
641 "{result} = OpRayQueryGetIntersectionGeometryIndexKHR %u32 {ray_query} %intersection",
642 ray_query = in(reg) self,
643 result = out(reg) result,
644 }
645
646 result
647 }
648 }
649
650 #[spirv_std_macros::gpu_only]
658 #[doc(alias = "OpRayQueryGetIntersectionGeometryIndexKHR")]
659 #[inline]
660 pub unsafe fn get_committed_intersection_geometry_index(&self) -> u32 {
661 unsafe {
662 let result;
663
664 asm! {
665 "%u32 = OpTypeInt 32 0",
666 "%intersection = OpConstant %u32 1",
667 "{result} = OpRayQueryGetIntersectionGeometryIndexKHR %u32 {ray_query} %intersection",
668 ray_query = in(reg) self,
669 result = out(reg) result,
670 }
671
672 result
673 }
674 }
675
676 #[spirv_std_macros::gpu_only]
681 #[doc(alias = "OpRayQueryGetIntersectionPrimitiveIndexKHR")]
682 #[inline]
683 pub unsafe fn get_candidate_intersection_primitive_index(&self) -> u32 {
684 unsafe {
685 let result;
686
687 asm! {
688 "%u32 = OpTypeInt 32 0",
689 "%intersection = OpConstant %u32 0",
690 "{result} = OpRayQueryGetIntersectionPrimitiveIndexKHR %u32 {ray_query} %intersection",
691 ray_query = in(reg) self,
692 result = out(reg) result,
693 }
694
695 result
696 }
697 }
698
699 #[spirv_std_macros::gpu_only]
707 #[doc(alias = "OpRayQueryGetIntersectionPrimitiveIndexKHR")]
708 #[inline]
709 pub unsafe fn get_committed_intersection_primitive_index(&self) -> u32 {
710 unsafe {
711 let result;
712
713 asm! {
714 "%u32 = OpTypeInt 32 0",
715 "%intersection = OpConstant %u32 1",
716 "{result} = OpRayQueryGetIntersectionPrimitiveIndexKHR %u32 {ray_query} %intersection",
717 ray_query = in(reg) self,
718 result = out(reg) result,
719 }
720
721 result
722 }
723 }
724
725 #[spirv_std_macros::gpu_only]
732 #[doc(alias = "OpRayQueryGetIntersectionBarycentricsKHR")]
733 #[inline]
734 pub unsafe fn get_candidate_intersection_barycentrics<V: Vector<f32, 2>>(&self) -> V {
735 unsafe {
736 let mut result = Default::default();
737
738 asm! {
739 "%u32 = OpTypeInt 32 0",
740 "%intersection = OpConstant %u32 0",
741 "%result = OpRayQueryGetIntersectionBarycentricsKHR typeof*{result} {ray_query} %intersection",
742 "OpStore {result} %result",
743 ray_query = in(reg) self,
744 result = in(reg) &mut result,
745 }
746
747 result
748 }
749 }
750
751 #[spirv_std_macros::gpu_only]
760 #[doc(alias = "OpRayQueryGetIntersectionBarycentricsKHR")]
761 #[inline]
762 pub unsafe fn get_committed_intersection_barycentrics<V: Vector<f32, 2>>(&self) -> V {
763 unsafe {
764 let mut result = Default::default();
765
766 asm! {
767 "%u32 = OpTypeInt 32 0",
768 "%intersection = OpConstant %u32 1",
769 "%result = OpRayQueryGetIntersectionBarycentricsKHR typeof*{result} {ray_query} %intersection",
770 "OpStore {result} %result",
771 ray_query = in(reg) self,
772 result = in(reg) &mut result,
773 }
774
775 result
776 }
777 }
778
779 #[spirv_std_macros::gpu_only]
786 #[doc(alias = "OpRayQueryGetIntersectionFrontFaceKHR")]
787 #[inline]
788 pub unsafe fn get_candidate_intersection_front_face(&self) -> bool {
789 unsafe {
790 let mut result = false;
791
792 asm! {
793 "%bool = OpTypeBool",
794 "%u32 = OpTypeInt 32 0",
795 "%intersection = OpConstant %u32 0",
796 "%result = OpRayQueryGetIntersectionFrontFaceKHR %bool {ray_query} %intersection",
797 "OpStore {result} %result",
798 ray_query = in(reg) self,
799 result = in(reg) &mut result,
800 }
801
802 result
803 }
804 }
805
806 #[spirv_std_macros::gpu_only]
815 #[doc(alias = "OpRayQueryGetIntersectionFrontFaceKHR")]
816 #[inline]
817 pub unsafe fn get_committed_intersection_front_face(&self) -> bool {
818 unsafe {
819 let mut result = false;
820
821 asm! {
822 "%bool = OpTypeBool",
823 "%u32 = OpTypeInt 32 0",
824 "%intersection = OpConstant %u32 1",
825 "%result = OpRayQueryGetIntersectionFrontFaceKHR %bool {ray_query} %intersection",
826 "OpStore {result} %result",
827 ray_query = in(reg) self,
828 result = in(reg) &mut result,
829 }
830
831 result
832 }
833 }
834
835 #[spirv_std_macros::gpu_only]
838 #[doc(alias = "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR")]
839 #[inline]
840 pub unsafe fn get_intersection_candidate_aabb_opaque(&self) -> bool {
841 unsafe {
842 let mut result = false;
843
844 asm! {
845 "%bool = OpTypeBool",
846 "%result = OpRayQueryGetIntersectionCandidateAABBOpaqueKHR %bool {ray_query}",
847 "OpStore {result} %result",
848 ray_query = in(reg) self,
849 result = in(reg) &mut result,
850 }
851
852 result
853 }
854 }
855
856 #[spirv_std_macros::gpu_only]
861 #[doc(alias = "OpRayQueryGetIntersectionObjectRayDirectionKHR")]
862 #[inline]
863 pub unsafe fn get_candidate_intersection_object_ray_direction<V: Vector<f32, 3>>(&self) -> V {
864 unsafe {
865 let mut result = Default::default();
866
867 asm! {
868 "%u32 = OpTypeInt 32 0",
869 "%intersection = OpConstant %u32 0",
870 "%result = OpRayQueryGetIntersectionObjectRayDirectionKHR typeof*{result} {ray_query} %intersection",
871 "OpStore {result} %result",
872 ray_query = in(reg) self,
873 result = in(reg) &mut result,
874 }
875
876 result
877 }
878 }
879
880 #[spirv_std_macros::gpu_only]
888 #[doc(alias = "OpRayQueryGetIntersectionObjectRayDirectionKHR")]
889 #[inline]
890 pub unsafe fn get_committed_intersection_object_ray_direction<V: Vector<f32, 3>>(&self) -> V {
891 unsafe {
892 let mut result = Default::default();
893
894 asm! {
895 "%u32 = OpTypeInt 32 0",
896 "%intersection = OpConstant %u32 1",
897 "%result = OpRayQueryGetIntersectionObjectRayDirectionKHR typeof*{result} {ray_query} %intersection",
898 "OpStore {result} %result",
899 ray_query = in(reg) self,
900 result = in(reg) &mut result,
901 }
902
903 result
904 }
905 }
906
907 #[spirv_std_macros::gpu_only]
912 #[doc(alias = "OpRayQueryGetIntersectionObjectRayOriginKHR")]
913 #[inline]
914 pub unsafe fn get_candidate_intersection_object_ray_origin<V: Vector<f32, 3>>(&self) -> V {
915 unsafe {
916 let mut result = Default::default();
917
918 asm! {
919 "%u32 = OpTypeInt 32 0",
920 "%intersection = OpConstant %u32 0",
921 "%result = OpRayQueryGetIntersectionObjectRayOriginKHR typeof*{result} {ray_query} %intersection",
922 "OpStore {result} %result",
923 ray_query = in(reg) self,
924 result = in(reg) &mut result,
925 }
926
927 result
928 }
929 }
930
931 #[spirv_std_macros::gpu_only]
939 #[doc(alias = "OpRayQueryGetIntersectionObjectRayOriginKHR")]
940 #[inline]
941 pub unsafe fn get_committed_intersection_object_ray_origin<V: Vector<f32, 3>>(&self) -> V {
942 unsafe {
943 let mut result = Default::default();
944
945 asm! {
946 "%u32 = OpTypeInt 32 0",
947 "%intersection = OpConstant %u32 1",
948 "%result = OpRayQueryGetIntersectionObjectRayOriginKHR typeof*{result} {ray_query} %intersection",
949 "OpStore {result} %result",
950 ray_query = in(reg) self,
951 result = in(reg) &mut result,
952 }
953
954 result
955 }
956 }
957
958 #[spirv_std_macros::gpu_only]
960 #[doc(alias = "OpRayQueryGetWorldRayDirectionKHR")]
961 #[inline]
962 pub unsafe fn get_world_ray_direction<V: Vector<f32, 3>>(&self) -> V {
963 unsafe {
964 let mut result = Default::default();
965
966 asm! {
967 "%u32 = OpTypeInt 32 0",
968 "%result = OpRayQueryGetWorldRayDirectionKHR typeof*{result} {ray_query}",
969 "OpStore {result} %result",
970 ray_query = in(reg) self,
971 result = in(reg) &mut result,
972 }
973
974 result
975 }
976 }
977
978 #[spirv_std_macros::gpu_only]
980 #[doc(alias = "OpRayQueryGetWorldRayOriginKHR")]
981 #[inline]
982 pub unsafe fn get_world_ray_origin<V: Vector<f32, 3>>(&self) -> V {
983 unsafe {
984 let mut result = Default::default();
985
986 asm! {
987 "%u32 = OpTypeInt 32 0",
988 "%result = OpRayQueryGetWorldRayOriginKHR typeof*{result} {ray_query}",
989 "OpStore {result} %result",
990 ray_query = in(reg) self,
991 result = in(reg) &mut result,
992 }
993
994 result
995 }
996 }
997
998 #[spirv_std_macros::gpu_only]
1003 #[doc(alias = "OpRayQueryGetIntersectionObjectToWorldKHR")]
1004 #[inline]
1005 pub unsafe fn get_candidate_intersection_object_to_world<V: Vector<f32, 3>>(&self) -> [V; 4] {
1006 unsafe {
1007 let mut result = Default::default();
1008
1009 asm! {
1010 "%u32 = OpTypeInt 32 0",
1011 "%f32 = OpTypeFloat 32",
1012 "%f32x3 = OpTypeVector %f32 3",
1013 "%f32x3x4 = OpTypeMatrix %f32x3 4",
1014 "%intersection = OpConstant %u32 0",
1015 "%matrix = OpRayQueryGetIntersectionObjectToWorldKHR %f32x3x4 {ray_query} %intersection",
1016 "%col0 = OpCompositeExtract %f32x3 %matrix 0",
1017 "%col1 = OpCompositeExtract %f32x3 %matrix 1",
1018 "%col2 = OpCompositeExtract %f32x3 %matrix 2",
1019 "%col3 = OpCompositeExtract %f32x3 %matrix 3",
1020 "%result = OpCompositeConstruct typeof*{result} %col0 %col1 %col2 %col3",
1021 "OpStore {result} %result",
1022 ray_query = in(reg) self,
1023 result = in(reg) &mut result,
1024 }
1025
1026 result
1027 }
1028 }
1029
1030 #[spirv_std_macros::gpu_only]
1038 #[doc(alias = "OpRayQueryGetIntersectionObjectToWorldKHR")]
1039 #[inline]
1040 pub unsafe fn get_committed_intersection_object_to_world<V: Vector<f32, 3>>(&self) -> [V; 4] {
1041 unsafe {
1042 let mut result = Default::default();
1043
1044 asm! {
1045 "%u32 = OpTypeInt 32 0",
1046 "%f32 = OpTypeFloat 32",
1047 "%f32x3 = OpTypeVector %f32 3",
1048 "%f32x3x4 = OpTypeMatrix %f32x3 4",
1049 "%intersection = OpConstant %u32 1",
1050 "%matrix = OpRayQueryGetIntersectionObjectToWorldKHR %f32x3x4 {ray_query} %intersection",
1051 "%col0 = OpCompositeExtract %f32x3 %matrix 0",
1052 "%col1 = OpCompositeExtract %f32x3 %matrix 1",
1053 "%col2 = OpCompositeExtract %f32x3 %matrix 2",
1054 "%col3 = OpCompositeExtract %f32x3 %matrix 3",
1055 "%result = OpCompositeConstruct typeof*{result} %col0 %col1 %col2 %col3",
1056 "OpStore {result} %result",
1057 ray_query = in(reg) self,
1058 result = in(reg) &mut result,
1059 }
1060
1061 result
1062 }
1063 }
1064}