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