1 use crate::prelude::*;
2 use crate::vk;
3 use crate::RawPtr;
4 use crate::{Device, Instance};
5 use std::ffi::CStr;
6 use std::mem;
7 
8 #[derive(Clone)]
9 pub struct RayTracing {
10     handle: vk::Device,
11     fp: vk::NvRayTracingFn,
12 }
13 
14 impl RayTracing {
new(instance: &Instance, device: &Device) -> Self15     pub fn new(instance: &Instance, device: &Device) -> Self {
16         let handle = device.handle();
17         let fp = vk::NvRayTracingFn::load(|name| unsafe {
18             mem::transmute(instance.get_device_proc_addr(handle, name.as_ptr()))
19         });
20         Self { handle, fp }
21     }
22 
23     #[inline]
get_properties( instance: &Instance, pdevice: vk::PhysicalDevice, ) -> vk::PhysicalDeviceRayTracingPropertiesNV24     pub unsafe fn get_properties(
25         instance: &Instance,
26         pdevice: vk::PhysicalDevice,
27     ) -> vk::PhysicalDeviceRayTracingPropertiesNV {
28         let mut props_rt = vk::PhysicalDeviceRayTracingPropertiesNV::default();
29         {
30             let mut props = vk::PhysicalDeviceProperties2::builder().push_next(&mut props_rt);
31             instance.get_physical_device_properties2(pdevice, &mut props);
32         }
33         props_rt
34     }
35 
36     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateAccelerationStructureNV.html>
37     #[inline]
create_acceleration_structure( &self, create_info: &vk::AccelerationStructureCreateInfoNV, allocation_callbacks: Option<&vk::AllocationCallbacks>, ) -> VkResult<vk::AccelerationStructureNV>38     pub unsafe fn create_acceleration_structure(
39         &self,
40         create_info: &vk::AccelerationStructureCreateInfoNV,
41         allocation_callbacks: Option<&vk::AllocationCallbacks>,
42     ) -> VkResult<vk::AccelerationStructureNV> {
43         let mut accel_struct = mem::zeroed();
44         (self.fp.create_acceleration_structure_nv)(
45             self.handle,
46             create_info,
47             allocation_callbacks.as_raw_ptr(),
48             &mut accel_struct,
49         )
50         .result_with_success(accel_struct)
51     }
52 
53     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkDestroyAccelerationStructureNV.html>
54     #[inline]
destroy_acceleration_structure( &self, accel_struct: vk::AccelerationStructureNV, allocation_callbacks: Option<&vk::AllocationCallbacks>, )55     pub unsafe fn destroy_acceleration_structure(
56         &self,
57         accel_struct: vk::AccelerationStructureNV,
58         allocation_callbacks: Option<&vk::AllocationCallbacks>,
59     ) {
60         (self.fp.destroy_acceleration_structure_nv)(
61             self.handle,
62             accel_struct,
63             allocation_callbacks.as_raw_ptr(),
64         );
65     }
66 
67     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetAccelerationStructureMemoryRequirementsNV.html>
68     #[inline]
get_acceleration_structure_memory_requirements( &self, info: &vk::AccelerationStructureMemoryRequirementsInfoNV, ) -> vk::MemoryRequirements2KHR69     pub unsafe fn get_acceleration_structure_memory_requirements(
70         &self,
71         info: &vk::AccelerationStructureMemoryRequirementsInfoNV,
72     ) -> vk::MemoryRequirements2KHR {
73         let mut requirements = mem::zeroed();
74         (self.fp.get_acceleration_structure_memory_requirements_nv)(
75             self.handle,
76             info,
77             &mut requirements,
78         );
79         requirements
80     }
81 
82     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkBindAccelerationStructureMemoryNV.html>
83     #[inline]
bind_acceleration_structure_memory( &self, bind_info: &[vk::BindAccelerationStructureMemoryInfoNV], ) -> VkResult<()>84     pub unsafe fn bind_acceleration_structure_memory(
85         &self,
86         bind_info: &[vk::BindAccelerationStructureMemoryInfoNV],
87     ) -> VkResult<()> {
88         (self.fp.bind_acceleration_structure_memory_nv)(
89             self.handle,
90             bind_info.len() as u32,
91             bind_info.as_ptr(),
92         )
93         .result()
94     }
95 
96     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdBuildAccelerationStructureNV.html>
97     #[inline]
cmd_build_acceleration_structure( &self, command_buffer: vk::CommandBuffer, info: &vk::AccelerationStructureInfoNV, instance_data: vk::Buffer, instance_offset: vk::DeviceSize, update: bool, dst: vk::AccelerationStructureNV, src: vk::AccelerationStructureNV, scratch: vk::Buffer, scratch_offset: vk::DeviceSize, )98     pub unsafe fn cmd_build_acceleration_structure(
99         &self,
100         command_buffer: vk::CommandBuffer,
101         info: &vk::AccelerationStructureInfoNV,
102         instance_data: vk::Buffer,
103         instance_offset: vk::DeviceSize,
104         update: bool,
105         dst: vk::AccelerationStructureNV,
106         src: vk::AccelerationStructureNV,
107         scratch: vk::Buffer,
108         scratch_offset: vk::DeviceSize,
109     ) {
110         (self.fp.cmd_build_acceleration_structure_nv)(
111             command_buffer,
112             info,
113             instance_data,
114             instance_offset,
115             if update { vk::TRUE } else { vk::FALSE },
116             dst,
117             src,
118             scratch,
119             scratch_offset,
120         );
121     }
122 
123     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdCopyAccelerationStructureNV.html>
124     #[inline]
cmd_copy_acceleration_structure( &self, command_buffer: vk::CommandBuffer, dst: vk::AccelerationStructureNV, src: vk::AccelerationStructureNV, mode: vk::CopyAccelerationStructureModeNV, )125     pub unsafe fn cmd_copy_acceleration_structure(
126         &self,
127         command_buffer: vk::CommandBuffer,
128         dst: vk::AccelerationStructureNV,
129         src: vk::AccelerationStructureNV,
130         mode: vk::CopyAccelerationStructureModeNV,
131     ) {
132         (self.fp.cmd_copy_acceleration_structure_nv)(command_buffer, dst, src, mode);
133     }
134 
135     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdTraceRaysNV.html>
136     #[inline]
cmd_trace_rays( &self, command_buffer: vk::CommandBuffer, raygen_shader_binding_table_buffer: vk::Buffer, raygen_shader_binding_offset: vk::DeviceSize, miss_shader_binding_table_buffer: vk::Buffer, miss_shader_binding_offset: vk::DeviceSize, miss_shader_binding_stride: vk::DeviceSize, hit_shader_binding_table_buffer: vk::Buffer, hit_shader_binding_offset: vk::DeviceSize, hit_shader_binding_stride: vk::DeviceSize, callable_shader_binding_table_buffer: vk::Buffer, callable_shader_binding_offset: vk::DeviceSize, callable_shader_binding_stride: vk::DeviceSize, width: u32, height: u32, depth: u32, )137     pub unsafe fn cmd_trace_rays(
138         &self,
139         command_buffer: vk::CommandBuffer,
140         raygen_shader_binding_table_buffer: vk::Buffer,
141         raygen_shader_binding_offset: vk::DeviceSize,
142         miss_shader_binding_table_buffer: vk::Buffer,
143         miss_shader_binding_offset: vk::DeviceSize,
144         miss_shader_binding_stride: vk::DeviceSize,
145         hit_shader_binding_table_buffer: vk::Buffer,
146         hit_shader_binding_offset: vk::DeviceSize,
147         hit_shader_binding_stride: vk::DeviceSize,
148         callable_shader_binding_table_buffer: vk::Buffer,
149         callable_shader_binding_offset: vk::DeviceSize,
150         callable_shader_binding_stride: vk::DeviceSize,
151         width: u32,
152         height: u32,
153         depth: u32,
154     ) {
155         (self.fp.cmd_trace_rays_nv)(
156             command_buffer,
157             raygen_shader_binding_table_buffer,
158             raygen_shader_binding_offset,
159             miss_shader_binding_table_buffer,
160             miss_shader_binding_offset,
161             miss_shader_binding_stride,
162             hit_shader_binding_table_buffer,
163             hit_shader_binding_offset,
164             hit_shader_binding_stride,
165             callable_shader_binding_table_buffer,
166             callable_shader_binding_offset,
167             callable_shader_binding_stride,
168             width,
169             height,
170             depth,
171         );
172     }
173 
174     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateRayTracingPipelinesNV.html>
175     #[inline]
create_ray_tracing_pipelines( &self, pipeline_cache: vk::PipelineCache, create_info: &[vk::RayTracingPipelineCreateInfoNV], allocation_callbacks: Option<&vk::AllocationCallbacks>, ) -> VkResult<Vec<vk::Pipeline>>176     pub unsafe fn create_ray_tracing_pipelines(
177         &self,
178         pipeline_cache: vk::PipelineCache,
179         create_info: &[vk::RayTracingPipelineCreateInfoNV],
180         allocation_callbacks: Option<&vk::AllocationCallbacks>,
181     ) -> VkResult<Vec<vk::Pipeline>> {
182         let mut pipelines = vec![mem::zeroed(); create_info.len()];
183         (self.fp.create_ray_tracing_pipelines_nv)(
184             self.handle,
185             pipeline_cache,
186             create_info.len() as u32,
187             create_info.as_ptr(),
188             allocation_callbacks.as_raw_ptr(),
189             pipelines.as_mut_ptr(),
190         )
191         .result_with_success(pipelines)
192     }
193 
194     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetRayTracingShaderGroupHandlesNV.html>
195     #[inline]
get_ray_tracing_shader_group_handles( &self, pipeline: vk::Pipeline, first_group: u32, group_count: u32, data: &mut [u8], ) -> VkResult<()>196     pub unsafe fn get_ray_tracing_shader_group_handles(
197         &self,
198         pipeline: vk::Pipeline,
199         first_group: u32,
200         group_count: u32,
201         data: &mut [u8],
202     ) -> VkResult<()> {
203         (self.fp.get_ray_tracing_shader_group_handles_nv)(
204             self.handle,
205             pipeline,
206             first_group,
207             group_count,
208             data.len(),
209             data.as_mut_ptr().cast(),
210         )
211         .result()
212     }
213 
214     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetAccelerationStructureHandleNV.html>
215     #[inline]
get_acceleration_structure_handle( &self, accel_struct: vk::AccelerationStructureNV, ) -> VkResult<u64>216     pub unsafe fn get_acceleration_structure_handle(
217         &self,
218         accel_struct: vk::AccelerationStructureNV,
219     ) -> VkResult<u64> {
220         let mut handle: u64 = 0;
221         let handle_ptr: *mut u64 = &mut handle;
222         (self.fp.get_acceleration_structure_handle_nv)(
223             self.handle,
224             accel_struct,
225             std::mem::size_of::<u64>(),
226             handle_ptr.cast(),
227         )
228         .result_with_success(handle)
229     }
230 
231     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdWriteAccelerationStructuresPropertiesNV.html>
232     #[inline]
cmd_write_acceleration_structures_properties( &self, command_buffer: vk::CommandBuffer, structures: &[vk::AccelerationStructureNV], query_type: vk::QueryType, query_pool: vk::QueryPool, first_query: u32, )233     pub unsafe fn cmd_write_acceleration_structures_properties(
234         &self,
235         command_buffer: vk::CommandBuffer,
236         structures: &[vk::AccelerationStructureNV],
237         query_type: vk::QueryType,
238         query_pool: vk::QueryPool,
239         first_query: u32,
240     ) {
241         (self.fp.cmd_write_acceleration_structures_properties_nv)(
242             command_buffer,
243             structures.len() as u32,
244             structures.as_ptr(),
245             query_type,
246             query_pool,
247             first_query,
248         );
249     }
250 
251     /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCompileDeferredNV.html>
252     #[inline]
compile_deferred(&self, pipeline: vk::Pipeline, shader: u32) -> VkResult<()>253     pub unsafe fn compile_deferred(&self, pipeline: vk::Pipeline, shader: u32) -> VkResult<()> {
254         (self.fp.compile_deferred_nv)(self.handle, pipeline, shader).result()
255     }
256 
257     #[inline]
name() -> &'static CStr258     pub const fn name() -> &'static CStr {
259         vk::NvRayTracingFn::name()
260     }
261 
262     #[inline]
fp(&self) -> &vk::NvRayTracingFn263     pub fn fp(&self) -> &vk::NvRayTracingFn {
264         &self.fp
265     }
266 
267     #[inline]
device(&self) -> vk::Device268     pub fn device(&self) -> vk::Device {
269         self.handle
270     }
271 }
272