Merge #186
186: Ray tracing support r=MaikKlein a=gwihlidal This PR adds support for VK_NV_ray_tracing! (and initial support for VK_EXT_descriptor_indexing, but more support coming for that). One piece I'm unsure if you have a more suggested approach is what I added to ext/mod.rs for names (both of those extensions are very commonly used, and also required for ray tracing). Maybe there should be a names.rs or something which can implement a static string function for all names that don't warrant their own extension struct? I have a local example I've been working on that has been testing against this code, as well as support for descriptor indexing. Originally, I was adding an nv_ray_tracing.rs example alongside triangle and texture, but ray tracing requires some specific extensions and also it doesn't need frame bindings, render states, etc. Additionally, this example only works on NV and with a Turing-class GPU, so I'm unsure if it should co-exist with the basic examples? Because of this, I'm going to first start with a fresh example and just get working to show everything needed - we can chat about merging it in after if desired. These changes + my upcoming ones should take care of both VK_NV_ray_tracing and VK_EXT_descriptor_indexing from https://github.com/MaikKlein/ash/issues/178 Co-authored-by: Graham Wihlidal <graham@wihlidal.ca>
This commit is contained in:
commit
337278042a
|
@ -21,7 +21,7 @@ impl DebugMarker {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_EXT_debug_marker\0").expect("Wrong extension string")
|
vk::ExtDebugMarkerFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn debug_marker_set_object_name(
|
pub unsafe fn debug_marker_set_object_name(
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl DebugReport {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_EXT_debug_report\0").expect("Wrong extension string")
|
vk::ExtDebugReportFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn destroy_debug_report_callback(
|
pub unsafe fn destroy_debug_report_callback(
|
||||||
|
|
|
@ -23,7 +23,7 @@ impl DebugUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_EXT_debug_utils\0").expect("Wrong extension string")
|
vk::ExtDebugUtilsFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn debug_utils_set_object_name(
|
pub unsafe fn debug_utils_set_object_name(
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl AndroidSurface {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_KHR_android_surface\0").expect("Wrong extension string")
|
vk::KhrAndroidSurfaceFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn create_android_surface(
|
pub unsafe fn create_android_surface(
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl DisplaySwapchain {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_KHR_display_swapchain\0").expect("Wrong extension string")
|
vk::KhrDisplaySwapchainFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn create_shared_swapchains(
|
pub unsafe fn create_shared_swapchains(
|
||||||
|
|
|
@ -25,7 +25,7 @@ impl Surface {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_KHR_surface\0").expect("Wrong extension string")
|
vk::KhrSurfaceFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn get_physical_device_surface_support(
|
pub unsafe fn get_physical_device_surface_support(
|
||||||
|
|
|
@ -25,7 +25,7 @@ impl Swapchain {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_KHR_swapchain\0").expect("Wrong extension string")
|
vk::KhrSwapchainFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn destroy_swapchain(
|
pub unsafe fn destroy_swapchain(
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl WaylandSurface {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_KHR_wayland_surface\0").expect("Wrong extension string")
|
vk::KhrWaylandSurfaceFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn create_wayland_surface(
|
pub unsafe fn create_wayland_surface(
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl Win32Surface {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_KHR_win32_surface\0").expect("Wrong extension string")
|
vk::KhrWin32SurfaceFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn create_win32_surface(
|
pub unsafe fn create_win32_surface(
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl XcbSurface {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_KHR_xcb_surface\0").expect("Wrong extension string")
|
vk::KhrXcbSurfaceFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn create_xcb_surface(
|
pub unsafe fn create_xcb_surface(
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl XlibSurface {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_KHR_xlib_surface\0").expect("Wrong extension string")
|
vk::KhrXlibSurfaceFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn create_xlib_surface(
|
pub unsafe fn create_xlib_surface(
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl IOSSurface {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_MVK_IOS_surface\0").expect("Wrong extension string")
|
vk::MvkIosSurfaceFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn create_ios_surface_mvk(
|
pub unsafe fn create_ios_surface_mvk(
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl MacOSSurface {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_MVK_macos_surface\0").expect("Wrong extension string")
|
vk::MvkMacosSurfaceFn::name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn create_mac_os_surface_mvk(
|
pub unsafe fn create_mac_os_surface_mvk(
|
||||||
|
|
|
@ -62,6 +62,6 @@ impl MeshShader {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_NV_mesh_shader\0").expect("Wrong extension string")
|
vk::NvMeshShaderFn::name()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
pub use self::mesh_shader::MeshShader;
|
pub use self::mesh_shader::MeshShader;
|
||||||
|
pub use self::ray_tracing::RayTracing;
|
||||||
|
|
||||||
mod mesh_shader;
|
mod mesh_shader;
|
||||||
|
mod ray_tracing;
|
||||||
|
|
263
ash/src/extensions/nv/ray_tracing.rs
Normal file
263
ash/src/extensions/nv/ray_tracing.rs
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
use prelude::*;
|
||||||
|
use std::ffi::CStr;
|
||||||
|
use std::mem;
|
||||||
|
use version::{DeviceV1_0, InstanceV1_0, InstanceV1_1};
|
||||||
|
use vk;
|
||||||
|
use RawPtr;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct RayTracing {
|
||||||
|
handle: vk::Device,
|
||||||
|
ray_tracing_fn: vk::NvRayTracingFn,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RayTracing {
|
||||||
|
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(instance: &I, device: &D) -> RayTracing {
|
||||||
|
let ray_tracing_fn = vk::NvRayTracingFn::load(|name| unsafe {
|
||||||
|
mem::transmute(instance.get_device_proc_addr(device.handle(), name.as_ptr()))
|
||||||
|
});
|
||||||
|
RayTracing {
|
||||||
|
handle: device.handle(),
|
||||||
|
ray_tracing_fn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn get_properties<I: InstanceV1_1>(
|
||||||
|
instance: &I,
|
||||||
|
pdevice: vk::PhysicalDevice,
|
||||||
|
) -> vk::PhysicalDeviceRayTracingPropertiesNV {
|
||||||
|
let mut props_rt = vk::PhysicalDeviceRayTracingPropertiesNV::default();
|
||||||
|
let mut props = vk::PhysicalDeviceProperties2::builder()
|
||||||
|
.next(&mut props_rt)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
instance.get_physical_device_properties2(pdevice, &mut props);
|
||||||
|
props_rt
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn create_acceleration_structure(
|
||||||
|
&self,
|
||||||
|
create_info: &vk::AccelerationStructureCreateInfoNV,
|
||||||
|
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
||||||
|
) -> VkResult<vk::AccelerationStructureNV> {
|
||||||
|
let mut accel_struct = mem::uninitialized();
|
||||||
|
let err_code = self.ray_tracing_fn.create_acceleration_structure_nv(
|
||||||
|
self.handle,
|
||||||
|
create_info,
|
||||||
|
allocation_callbacks.as_raw_ptr(),
|
||||||
|
&mut accel_struct,
|
||||||
|
);
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(accel_struct),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn destroy_acceleration_structure(
|
||||||
|
&self,
|
||||||
|
accel_struct: vk::AccelerationStructureNV,
|
||||||
|
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn.destroy_acceleration_structure_nv(
|
||||||
|
self.handle,
|
||||||
|
accel_struct,
|
||||||
|
allocation_callbacks.as_raw_ptr(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn get_acceleration_structure_memory_requirements(
|
||||||
|
&self,
|
||||||
|
info: &vk::AccelerationStructureMemoryRequirementsInfoNV,
|
||||||
|
) -> vk::MemoryRequirements2KHR {
|
||||||
|
let mut requirements = mem::uninitialized();
|
||||||
|
self.ray_tracing_fn
|
||||||
|
.get_acceleration_structure_memory_requirements_nv(
|
||||||
|
self.handle,
|
||||||
|
info,
|
||||||
|
&mut requirements,
|
||||||
|
);
|
||||||
|
requirements
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn bind_acceleration_structure_memory(
|
||||||
|
&self,
|
||||||
|
bind_info: &[vk::BindAccelerationStructureMemoryInfoNV],
|
||||||
|
) -> VkResult<()> {
|
||||||
|
let err_code = self.ray_tracing_fn.bind_acceleration_structure_memory_nv(
|
||||||
|
self.handle,
|
||||||
|
bind_info.len() as u32,
|
||||||
|
bind_info.as_ptr(),
|
||||||
|
);
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(()),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn 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,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn.cmd_build_acceleration_structure_nv(
|
||||||
|
command_buffer,
|
||||||
|
info,
|
||||||
|
instance_data,
|
||||||
|
instance_offset,
|
||||||
|
if update { vk::TRUE } else { vk::FALSE },
|
||||||
|
dst,
|
||||||
|
src,
|
||||||
|
scratch,
|
||||||
|
scratch_offset,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn cmd_copy_acceleration_structure(
|
||||||
|
&self,
|
||||||
|
command_buffer: vk::CommandBuffer,
|
||||||
|
dst: vk::AccelerationStructureNV,
|
||||||
|
src: vk::AccelerationStructureNV,
|
||||||
|
mode: vk::CopyAccelerationStructureModeNV,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn
|
||||||
|
.cmd_copy_acceleration_structure_nv(command_buffer, dst, src, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn 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,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn.cmd_trace_rays_nv(
|
||||||
|
command_buffer,
|
||||||
|
raygen_shader_binding_table_buffer,
|
||||||
|
raygen_shader_binding_offset,
|
||||||
|
miss_shader_binding_table_buffer,
|
||||||
|
miss_shader_binding_offset,
|
||||||
|
miss_shader_binding_stride,
|
||||||
|
hit_shader_binding_table_buffer,
|
||||||
|
hit_shader_binding_offset,
|
||||||
|
hit_shader_binding_stride,
|
||||||
|
callable_shader_binding_table_buffer,
|
||||||
|
callable_shader_binding_offset,
|
||||||
|
callable_shader_binding_stride,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
depth,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn create_ray_tracing_pipelines(
|
||||||
|
&self,
|
||||||
|
pipeline_cache: vk::PipelineCache,
|
||||||
|
create_info: &[vk::RayTracingPipelineCreateInfoNV],
|
||||||
|
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
||||||
|
) -> VkResult<Vec<vk::Pipeline>> {
|
||||||
|
let mut pipelines = vec![mem::uninitialized(); create_info.len()];
|
||||||
|
let err_code = self.ray_tracing_fn.create_ray_tracing_pipelines_nv(
|
||||||
|
self.handle,
|
||||||
|
pipeline_cache,
|
||||||
|
create_info.len() as u32,
|
||||||
|
create_info.as_ptr(),
|
||||||
|
allocation_callbacks.as_raw_ptr(),
|
||||||
|
pipelines.as_mut_ptr(),
|
||||||
|
);
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(pipelines),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn get_ray_tracing_shader_group_handles(
|
||||||
|
&self,
|
||||||
|
pipeline: vk::Pipeline,
|
||||||
|
first_group: u32,
|
||||||
|
group_count: u32,
|
||||||
|
data: &mut [u8],
|
||||||
|
) -> VkResult<()> {
|
||||||
|
let err_code = self.ray_tracing_fn.get_ray_tracing_shader_group_handles_nv(
|
||||||
|
self.handle,
|
||||||
|
pipeline,
|
||||||
|
first_group,
|
||||||
|
group_count,
|
||||||
|
data.len(),
|
||||||
|
data.as_mut_ptr() as *mut std::ffi::c_void,
|
||||||
|
);
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(()),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn get_acceleration_structure_handle(
|
||||||
|
&self,
|
||||||
|
accel_struct: vk::AccelerationStructureNV,
|
||||||
|
) -> VkResult<u64> {
|
||||||
|
let mut handle: u64 = 0;
|
||||||
|
let handle_ptr: *mut u64 = &mut handle;
|
||||||
|
let err_code = self.ray_tracing_fn.get_acceleration_structure_handle_nv(
|
||||||
|
self.handle,
|
||||||
|
accel_struct,
|
||||||
|
std::mem::size_of::<u64>(),
|
||||||
|
handle_ptr as *mut std::ffi::c_void,
|
||||||
|
);
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(handle),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn cmd_write_acceleration_structures_properties(
|
||||||
|
&self,
|
||||||
|
command_buffer: vk::CommandBuffer,
|
||||||
|
structures: &[vk::AccelerationStructureNV],
|
||||||
|
query_type: vk::QueryType,
|
||||||
|
query_pool: vk::QueryPool,
|
||||||
|
first_query: u32,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn
|
||||||
|
.cmd_write_acceleration_structures_properties_nv(
|
||||||
|
command_buffer,
|
||||||
|
structures.len() as u32,
|
||||||
|
structures.as_ptr(),
|
||||||
|
query_type,
|
||||||
|
query_pool,
|
||||||
|
first_query,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn compile_deferred(&self, pipeline: vk::Pipeline, shader: u32) -> VkResult<()> {
|
||||||
|
let err_code = self
|
||||||
|
.ray_tracing_fn
|
||||||
|
.compile_deferred_nv(self.handle, pipeline, shader);
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(()),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name() -> &'static CStr {
|
||||||
|
vk::NvRayTracingFn::name()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue