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 RayTracingPipeline { 10 handle: vk::Device, 11 fp: vk::KhrRayTracingPipelineFn, 12 } 13 14 impl RayTracingPipeline { new(instance: &Instance, device: &Device) -> Self15 pub fn new(instance: &Instance, device: &Device) -> Self { 16 let handle = device.handle(); 17 let fp = vk::KhrRayTracingPipelineFn::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::PhysicalDeviceRayTracingPipelinePropertiesKHR24 pub unsafe fn get_properties( 25 instance: &Instance, 26 pdevice: vk::PhysicalDevice, 27 ) -> vk::PhysicalDeviceRayTracingPipelinePropertiesKHR { 28 let mut props_rt = vk::PhysicalDeviceRayTracingPipelinePropertiesKHR::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/vkCmdTraceRaysKHR.html> 37 #[inline] cmd_trace_rays( &self, command_buffer: vk::CommandBuffer, raygen_shader_binding_tables: &vk::StridedDeviceAddressRegionKHR, miss_shader_binding_tables: &vk::StridedDeviceAddressRegionKHR, hit_shader_binding_tables: &vk::StridedDeviceAddressRegionKHR, callable_shader_binding_tables: &vk::StridedDeviceAddressRegionKHR, width: u32, height: u32, depth: u32, )38 pub unsafe fn cmd_trace_rays( 39 &self, 40 command_buffer: vk::CommandBuffer, 41 raygen_shader_binding_tables: &vk::StridedDeviceAddressRegionKHR, 42 miss_shader_binding_tables: &vk::StridedDeviceAddressRegionKHR, 43 hit_shader_binding_tables: &vk::StridedDeviceAddressRegionKHR, 44 callable_shader_binding_tables: &vk::StridedDeviceAddressRegionKHR, 45 width: u32, 46 height: u32, 47 depth: u32, 48 ) { 49 (self.fp.cmd_trace_rays_khr)( 50 command_buffer, 51 raygen_shader_binding_tables, 52 miss_shader_binding_tables, 53 hit_shader_binding_tables, 54 callable_shader_binding_tables, 55 width, 56 height, 57 depth, 58 ); 59 } 60 61 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateRayTracingPipelinesKHR.html> 62 #[inline] create_ray_tracing_pipelines( &self, deferred_operation: vk::DeferredOperationKHR, pipeline_cache: vk::PipelineCache, create_info: &[vk::RayTracingPipelineCreateInfoKHR], allocation_callbacks: Option<&vk::AllocationCallbacks>, ) -> VkResult<Vec<vk::Pipeline>>63 pub unsafe fn create_ray_tracing_pipelines( 64 &self, 65 deferred_operation: vk::DeferredOperationKHR, 66 pipeline_cache: vk::PipelineCache, 67 create_info: &[vk::RayTracingPipelineCreateInfoKHR], 68 allocation_callbacks: Option<&vk::AllocationCallbacks>, 69 ) -> VkResult<Vec<vk::Pipeline>> { 70 let mut pipelines = vec![mem::zeroed(); create_info.len()]; 71 (self.fp.create_ray_tracing_pipelines_khr)( 72 self.handle, 73 deferred_operation, 74 pipeline_cache, 75 create_info.len() as u32, 76 create_info.as_ptr(), 77 allocation_callbacks.as_raw_ptr(), 78 pipelines.as_mut_ptr(), 79 ) 80 .result_with_success(pipelines) 81 } 82 83 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetRayTracingShaderGroupHandlesKHR.html> 84 #[inline] get_ray_tracing_shader_group_handles( &self, pipeline: vk::Pipeline, first_group: u32, group_count: u32, data_size: usize, ) -> VkResult<Vec<u8>>85 pub unsafe fn get_ray_tracing_shader_group_handles( 86 &self, 87 pipeline: vk::Pipeline, 88 first_group: u32, 89 group_count: u32, 90 data_size: usize, 91 ) -> VkResult<Vec<u8>> { 92 let mut data = Vec::<u8>::with_capacity(data_size); 93 (self.fp.get_ray_tracing_shader_group_handles_khr)( 94 self.handle, 95 pipeline, 96 first_group, 97 group_count, 98 data_size, 99 data.as_mut_ptr().cast(), 100 ) 101 .result()?; 102 data.set_len(data_size); 103 Ok(data) 104 } 105 106 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetRayTracingCaptureReplayShaderGroupHandlesKHR.html> 107 #[inline] get_ray_tracing_capture_replay_shader_group_handles( &self, pipeline: vk::Pipeline, first_group: u32, group_count: u32, data_size: usize, ) -> VkResult<Vec<u8>>108 pub unsafe fn get_ray_tracing_capture_replay_shader_group_handles( 109 &self, 110 pipeline: vk::Pipeline, 111 first_group: u32, 112 group_count: u32, 113 data_size: usize, 114 ) -> VkResult<Vec<u8>> { 115 let mut data = Vec::<u8>::with_capacity(data_size); 116 (self 117 .fp 118 .get_ray_tracing_capture_replay_shader_group_handles_khr)( 119 self.handle, 120 pipeline, 121 first_group, 122 group_count, 123 data_size, 124 data.as_mut_ptr().cast(), 125 ) 126 .result()?; 127 data.set_len(data_size); 128 Ok(data) 129 } 130 131 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdTraceRaysIndirectKHR.html> 132 /// 133 /// `indirect_device_address` is a buffer device address which is a pointer to a [`vk::TraceRaysIndirectCommandKHR`] structure containing the trace ray parameters. 134 #[inline] cmd_trace_rays_indirect( &self, command_buffer: vk::CommandBuffer, raygen_shader_binding_table: &[vk::StridedDeviceAddressRegionKHR], miss_shader_binding_table: &[vk::StridedDeviceAddressRegionKHR], hit_shader_binding_table: &[vk::StridedDeviceAddressRegionKHR], callable_shader_binding_table: &[vk::StridedDeviceAddressRegionKHR], indirect_device_address: vk::DeviceAddress, )135 pub unsafe fn cmd_trace_rays_indirect( 136 &self, 137 command_buffer: vk::CommandBuffer, 138 raygen_shader_binding_table: &[vk::StridedDeviceAddressRegionKHR], 139 miss_shader_binding_table: &[vk::StridedDeviceAddressRegionKHR], 140 hit_shader_binding_table: &[vk::StridedDeviceAddressRegionKHR], 141 callable_shader_binding_table: &[vk::StridedDeviceAddressRegionKHR], 142 indirect_device_address: vk::DeviceAddress, 143 ) { 144 (self.fp.cmd_trace_rays_indirect_khr)( 145 command_buffer, 146 raygen_shader_binding_table.as_ptr(), 147 miss_shader_binding_table.as_ptr(), 148 hit_shader_binding_table.as_ptr(), 149 callable_shader_binding_table.as_ptr(), 150 indirect_device_address, 151 ); 152 } 153 154 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetRayTracingShaderGroupStackSizeKHR.html> 155 #[inline] get_ray_tracing_shader_group_stack_size( &self, pipeline: vk::Pipeline, group: u32, group_shader: vk::ShaderGroupShaderKHR, ) -> vk::DeviceSize156 pub unsafe fn get_ray_tracing_shader_group_stack_size( 157 &self, 158 pipeline: vk::Pipeline, 159 group: u32, 160 group_shader: vk::ShaderGroupShaderKHR, 161 ) -> vk::DeviceSize { 162 (self.fp.get_ray_tracing_shader_group_stack_size_khr)( 163 self.handle, 164 pipeline, 165 group, 166 group_shader, 167 ) 168 } 169 170 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdSetRayTracingPipelineStackSizeKHR.html> 171 #[inline] cmd_set_ray_tracing_pipeline_stack_size( &self, command_buffer: vk::CommandBuffer, pipeline_stack_size: u32, )172 pub unsafe fn cmd_set_ray_tracing_pipeline_stack_size( 173 &self, 174 command_buffer: vk::CommandBuffer, 175 pipeline_stack_size: u32, 176 ) { 177 (self.fp.cmd_set_ray_tracing_pipeline_stack_size_khr)(command_buffer, pipeline_stack_size); 178 } 179 180 #[inline] name() -> &'static CStr181 pub const fn name() -> &'static CStr { 182 vk::KhrRayTracingPipelineFn::name() 183 } 184 185 #[inline] fp(&self) -> &vk::KhrRayTracingPipelineFn186 pub fn fp(&self) -> &vk::KhrRayTracingPipelineFn { 187 &self.fp 188 } 189 190 #[inline] device(&self) -> vk::Device191 pub fn device(&self) -> vk::Device { 192 self.handle 193 } 194 } 195