[WIP] Khr Ray Tracing (#278)
* Fix incorrect generation of commands with aliases * Use alias name instead of the actual cmd name * Generate vulkan ray-tracing bindings * Add ray-tracing khr * High level ray tracing support * Re-enable nv ray tracing extension (this will break the build) * Generate aliases for extension enums * Add missing alias because the parser doesn't provide alias information here * Fix 'unreachable pattern' warnings * Fix clippy warning Co-authored-by: Maik Klein <maikklein@googlemail.com>
This commit is contained in:
parent
af6acb93e5
commit
6bdc403330
6 changed files with 8226 additions and 1886 deletions
|
@ -3,6 +3,7 @@ pub use self::display::Display;
|
||||||
pub use self::display_swapchain::DisplaySwapchain;
|
pub use self::display_swapchain::DisplaySwapchain;
|
||||||
pub use self::external_memory_fd::ExternalMemoryFd;
|
pub use self::external_memory_fd::ExternalMemoryFd;
|
||||||
pub use self::push_descriptor::PushDescriptor;
|
pub use self::push_descriptor::PushDescriptor;
|
||||||
|
pub use self::ray_tracing::RayTracing;
|
||||||
pub use self::surface::Surface;
|
pub use self::surface::Surface;
|
||||||
pub use self::swapchain::Swapchain;
|
pub use self::swapchain::Swapchain;
|
||||||
pub use self::wayland_surface::WaylandSurface;
|
pub use self::wayland_surface::WaylandSurface;
|
||||||
|
@ -15,6 +16,7 @@ mod display;
|
||||||
mod display_swapchain;
|
mod display_swapchain;
|
||||||
mod external_memory_fd;
|
mod external_memory_fd;
|
||||||
mod push_descriptor;
|
mod push_descriptor;
|
||||||
|
mod ray_tracing;
|
||||||
mod surface;
|
mod surface;
|
||||||
mod swapchain;
|
mod swapchain;
|
||||||
mod wayland_surface;
|
mod wayland_surface;
|
||||||
|
|
369
ash/src/extensions/khr/ray_tracing.rs
Normal file
369
ash/src/extensions/khr/ray_tracing.rs
Normal file
|
@ -0,0 +1,369 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
use crate::prelude::*;
|
||||||
|
use crate::version::{DeviceV1_0, InstanceV1_0, InstanceV1_1};
|
||||||
|
use crate::vk;
|
||||||
|
use crate::RawPtr;
|
||||||
|
use std::ffi::CStr;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct RayTracing {
|
||||||
|
handle: vk::Device,
|
||||||
|
ray_tracing_fn: vk::KhrRayTracingFn,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RayTracing {
|
||||||
|
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(instance: &I, device: &D) -> RayTracing {
|
||||||
|
let ray_tracing_fn = vk::KhrRayTracingFn::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::PhysicalDeviceRayTracingPropertiesKHR {
|
||||||
|
let mut props_rt = vk::PhysicalDeviceRayTracingPropertiesKHR::default();
|
||||||
|
{
|
||||||
|
let mut props = vk::PhysicalDeviceProperties2::builder().push_next(&mut props_rt);
|
||||||
|
instance.get_physical_device_properties2(pdevice, &mut props);
|
||||||
|
}
|
||||||
|
props_rt
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCreateAccelerationStructureKHR.html>"]
|
||||||
|
pub unsafe fn create_acceleration_structure(
|
||||||
|
&self,
|
||||||
|
create_info: &vk::AccelerationStructureCreateInfoKHR,
|
||||||
|
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
||||||
|
) -> VkResult<vk::AccelerationStructureKHR> {
|
||||||
|
let mut accel_struct = mem::zeroed();
|
||||||
|
let err_code = self.ray_tracing_fn.create_acceleration_structure_khr(
|
||||||
|
self.handle,
|
||||||
|
create_info,
|
||||||
|
allocation_callbacks.as_raw_ptr(),
|
||||||
|
&mut accel_struct,
|
||||||
|
);
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(accel_struct),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkDestroyAccelerationStructureKHR.html>"]
|
||||||
|
pub unsafe fn destroy_acceleration_structure(
|
||||||
|
&self,
|
||||||
|
accel_struct: vk::AccelerationStructureKHR,
|
||||||
|
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn.destroy_acceleration_structure_khr(
|
||||||
|
self.handle,
|
||||||
|
accel_struct,
|
||||||
|
allocation_callbacks.as_raw_ptr(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetAccelerationStructureMemoryRequirementsKHR.html>"]
|
||||||
|
pub unsafe fn get_acceleration_structure_memory_requirements(
|
||||||
|
&self,
|
||||||
|
info: &vk::AccelerationStructureMemoryRequirementsInfoKHR,
|
||||||
|
) -> vk::MemoryRequirements2KHR {
|
||||||
|
let mut requirements = mem::zeroed();
|
||||||
|
self.ray_tracing_fn
|
||||||
|
.get_acceleration_structure_memory_requirements_khr(
|
||||||
|
self.handle,
|
||||||
|
info,
|
||||||
|
&mut requirements,
|
||||||
|
);
|
||||||
|
requirements
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkBindAccelerationStructureMemoryKHR.html>"]
|
||||||
|
pub unsafe fn bind_acceleration_structure_memory(
|
||||||
|
&self,
|
||||||
|
bind_info: &[vk::BindAccelerationStructureMemoryInfoKHR],
|
||||||
|
) -> VkResult<()> {
|
||||||
|
let err_code = self.ray_tracing_fn.bind_acceleration_structure_memory_khr(
|
||||||
|
self.handle,
|
||||||
|
bind_info.len() as u32,
|
||||||
|
bind_info.as_ptr(),
|
||||||
|
);
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(()),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdBuildAccelerationStructureKHR.html>"]
|
||||||
|
pub unsafe fn cmd_build_acceleration_structure(
|
||||||
|
&self,
|
||||||
|
command_buffer: vk::CommandBuffer,
|
||||||
|
infos: &[vk::AccelerationStructureBuildGeometryInfoKHR],
|
||||||
|
offset_infos: &[&[vk::AccelerationStructureBuildOffsetInfoKHR]],
|
||||||
|
) {
|
||||||
|
let offset_info_ptr = offset_infos
|
||||||
|
.iter()
|
||||||
|
.map(|slice| slice.as_ptr())
|
||||||
|
.collect::<Vec<*const vk::AccelerationStructureBuildOffsetInfoKHR>>();
|
||||||
|
|
||||||
|
self.ray_tracing_fn.cmd_build_acceleration_structure_khr(
|
||||||
|
command_buffer,
|
||||||
|
infos.len() as u32,
|
||||||
|
infos.as_ptr(),
|
||||||
|
offset_info_ptr.as_ptr(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdCopyAccelerationStructureKHR.html>"]
|
||||||
|
pub unsafe fn cmd_copy_acceleration_structure(
|
||||||
|
&self,
|
||||||
|
command_buffer: vk::CommandBuffer,
|
||||||
|
info: &vk::CopyAccelerationStructureInfoKHR,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn
|
||||||
|
.cmd_copy_acceleration_structure_khr(command_buffer, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdTraceRaysKHR.html>"]
|
||||||
|
pub unsafe fn cmd_trace_rays(
|
||||||
|
&self,
|
||||||
|
command_buffer: vk::CommandBuffer,
|
||||||
|
raygen_shader_binding_tables: &[vk::StridedBufferRegionKHR],
|
||||||
|
miss_shader_binding_tables: &[vk::StridedBufferRegionKHR],
|
||||||
|
hit_shader_binding_tables: &[vk::StridedBufferRegionKHR],
|
||||||
|
callable_shader_binding_tables: &[vk::StridedBufferRegionKHR],
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
depth: u32,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn.cmd_trace_rays_khr(
|
||||||
|
command_buffer,
|
||||||
|
raygen_shader_binding_tables.as_ptr(),
|
||||||
|
miss_shader_binding_tables.as_ptr(),
|
||||||
|
hit_shader_binding_tables.as_ptr(),
|
||||||
|
callable_shader_binding_tables.as_ptr(),
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
depth,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCreateRayTracingPipelinesKHR.html>"]
|
||||||
|
pub unsafe fn create_ray_tracing_pipelines(
|
||||||
|
&self,
|
||||||
|
pipeline_cache: vk::PipelineCache,
|
||||||
|
create_info: &[vk::RayTracingPipelineCreateInfoKHR],
|
||||||
|
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
||||||
|
) -> VkResult<Vec<vk::Pipeline>> {
|
||||||
|
let mut pipelines = vec![mem::zeroed(); create_info.len()];
|
||||||
|
let err_code = self.ray_tracing_fn.create_ray_tracing_pipelines_khr(
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetRayTracingShaderGroupHandlesKHR.html>"]
|
||||||
|
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_khr(
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetAccelerationStructureHandleKHR.html>"]
|
||||||
|
pub unsafe fn get_acceleration_structure_device_address(
|
||||||
|
&self,
|
||||||
|
info: &vk::AccelerationStructureDeviceAddressInfoKHR,
|
||||||
|
) -> vk::DeviceAddress {
|
||||||
|
self.ray_tracing_fn
|
||||||
|
.get_acceleration_structure_device_address_khr(self.handle, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdWriteAccelerationStructuresPropertiesKHR.html>"]
|
||||||
|
pub unsafe fn cmd_write_acceleration_structures_properties(
|
||||||
|
&self,
|
||||||
|
command_buffer: vk::CommandBuffer,
|
||||||
|
structures: &[vk::AccelerationStructureKHR],
|
||||||
|
query_type: vk::QueryType,
|
||||||
|
query_pool: vk::QueryPool,
|
||||||
|
first_query: u32,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn
|
||||||
|
.cmd_write_acceleration_structures_properties_khr(
|
||||||
|
command_buffer,
|
||||||
|
structures.len() as u32,
|
||||||
|
structures.as_ptr(),
|
||||||
|
query_type,
|
||||||
|
query_pool,
|
||||||
|
first_query,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn cmd_build_acceleration_structure_indirect(
|
||||||
|
&self,
|
||||||
|
command_buffer: vk::CommandBuffer,
|
||||||
|
info: &vk::AccelerationStructureBuildGeometryInfoKHR,
|
||||||
|
indirect_buffer: vk::Buffer,
|
||||||
|
indirect_offset: vk::DeviceSize,
|
||||||
|
indirect_stride: u32,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn
|
||||||
|
.cmd_build_acceleration_structure_indirect_khr(
|
||||||
|
command_buffer,
|
||||||
|
info,
|
||||||
|
indirect_buffer,
|
||||||
|
indirect_offset,
|
||||||
|
indirect_stride,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn copy_acceleration_structure_to_memory(
|
||||||
|
&self,
|
||||||
|
device: vk::Device,
|
||||||
|
info: &vk::CopyAccelerationStructureToMemoryInfoKHR,
|
||||||
|
) -> VkResult<()> {
|
||||||
|
let err_code = self
|
||||||
|
.ray_tracing_fn
|
||||||
|
.copy_acceleration_structure_to_memory_khr(device, info);
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(()),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn copy_memory_to_acceleration_structure(
|
||||||
|
&self,
|
||||||
|
device: vk::Device,
|
||||||
|
info: &vk::CopyMemoryToAccelerationStructureInfoKHR,
|
||||||
|
) -> VkResult<()> {
|
||||||
|
let err_code = self
|
||||||
|
.ray_tracing_fn
|
||||||
|
.copy_memory_to_acceleration_structure_khr(device, info);
|
||||||
|
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(()),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn cmd_copy_acceleration_structure_to_memory(
|
||||||
|
&self,
|
||||||
|
command_buffer: vk::CommandBuffer,
|
||||||
|
info: &vk::CopyAccelerationStructureToMemoryInfoKHR,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn
|
||||||
|
.cmd_copy_acceleration_structure_to_memory_khr(command_buffer, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn cmd_copy_memory_to_acceleration_structure(
|
||||||
|
&self,
|
||||||
|
command_buffer: vk::CommandBuffer,
|
||||||
|
info: &vk::CopyMemoryToAccelerationStructureInfoKHR,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn
|
||||||
|
.cmd_copy_memory_to_acceleration_structure_khr(command_buffer, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn get_ray_tracing_capture_replay_shader_group_handles(
|
||||||
|
&self,
|
||||||
|
device: vk::Device,
|
||||||
|
pipeline: vk::Pipeline,
|
||||||
|
first_group: u32,
|
||||||
|
group_count: u32,
|
||||||
|
data_size: usize,
|
||||||
|
) -> VkResult<Vec<u8>> {
|
||||||
|
let mut data: Vec<u8> = Vec::with_capacity(data_size);
|
||||||
|
|
||||||
|
let err_code = self
|
||||||
|
.ray_tracing_fn
|
||||||
|
.get_ray_tracing_capture_replay_shader_group_handles_khr(
|
||||||
|
device,
|
||||||
|
pipeline,
|
||||||
|
first_group,
|
||||||
|
group_count,
|
||||||
|
data_size,
|
||||||
|
data.as_mut_ptr() as *mut _,
|
||||||
|
);
|
||||||
|
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(data),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn cmd_trace_rays_indirect(
|
||||||
|
&self,
|
||||||
|
command_buffer: vk::CommandBuffer,
|
||||||
|
raygen_shader_binding_table: &[vk::StridedBufferRegionKHR],
|
||||||
|
miss_shader_binding_table: &[vk::StridedBufferRegionKHR],
|
||||||
|
hit_shader_binding_table: &[vk::StridedBufferRegionKHR],
|
||||||
|
callable_shader_binding_table: &[vk::StridedBufferRegionKHR],
|
||||||
|
buffer: vk::Buffer,
|
||||||
|
offset: vk::DeviceSize,
|
||||||
|
) {
|
||||||
|
self.ray_tracing_fn.cmd_trace_rays_indirect_khr(
|
||||||
|
command_buffer,
|
||||||
|
raygen_shader_binding_table.as_ptr(),
|
||||||
|
miss_shader_binding_table.as_ptr(),
|
||||||
|
hit_shader_binding_table.as_ptr(),
|
||||||
|
callable_shader_binding_table.as_ptr(),
|
||||||
|
buffer,
|
||||||
|
offset,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn get_device_acceleration_structure_compatibility(
|
||||||
|
&self,
|
||||||
|
device: vk::Device,
|
||||||
|
version: &vk::AccelerationStructureVersionKHR,
|
||||||
|
) -> VkResult<()> {
|
||||||
|
let err_code = self
|
||||||
|
.ray_tracing_fn
|
||||||
|
.get_device_acceleration_structure_compatibility_khr(device, version);
|
||||||
|
|
||||||
|
match err_code {
|
||||||
|
vk::Result::SUCCESS => Ok(()),
|
||||||
|
_ => Err(err_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name() -> &'static CStr {
|
||||||
|
vk::KhrRayTracingFn::name()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fp(&self) -> &vk::KhrRayTracingFn {
|
||||||
|
&self.ray_tracing_fn
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn device(&self) -> vk::Device {
|
||||||
|
self.handle
|
||||||
|
}
|
||||||
|
}
|
9588
ash/src/vk.rs
9588
ash/src/vk.rs
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,7 @@ authors = ["Maik Klein <maikklein@googlemail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
vk-parse = "0.3.0"
|
vk-parse = "0.4.0"
|
||||||
vkxml = "0.3"
|
vkxml = "0.3"
|
||||||
nom = "4.0"
|
nom = "4.0"
|
||||||
heck = "0.3"
|
heck = "0.3"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 881bbb347a08d1b5aa77f61a52a30b506de9f2bf
|
Subproject commit fb7f9c9bcd1d1544ea203a1f3d4253d0e90c5a90
|
|
@ -391,7 +391,7 @@ impl ConstVal {
|
||||||
}
|
}
|
||||||
pub trait ConstantExt {
|
pub trait ConstantExt {
|
||||||
fn variant_ident(&self, enum_name: &str) -> Ident;
|
fn variant_ident(&self, enum_name: &str) -> Ident;
|
||||||
fn to_tokens(&self) -> Tokens;
|
fn to_tokens(&self, ident: Option<Ident>) -> Tokens;
|
||||||
fn notation(&self) -> Option<&str>;
|
fn notation(&self) -> Option<&str>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,8 +399,11 @@ impl ConstantExt for vkxml::ExtensionEnum {
|
||||||
fn variant_ident(&self, enum_name: &str) -> Ident {
|
fn variant_ident(&self, enum_name: &str) -> Ident {
|
||||||
variant_ident(enum_name, &self.name)
|
variant_ident(enum_name, &self.name)
|
||||||
}
|
}
|
||||||
fn to_tokens(&self) -> Tokens {
|
fn to_tokens(&self, ident: Option<Ident>) -> Tokens {
|
||||||
Constant::from_extension_enum(self).expect("").to_tokens()
|
let expr = Constant::from_extension_enum(self)
|
||||||
|
.expect("")
|
||||||
|
.to_tokens(ident);
|
||||||
|
quote! { #ident(#expr) }
|
||||||
}
|
}
|
||||||
fn notation(&self) -> Option<&str> {
|
fn notation(&self) -> Option<&str> {
|
||||||
self.notation.as_deref()
|
self.notation.as_deref()
|
||||||
|
@ -411,8 +414,9 @@ impl ConstantExt for vkxml::Constant {
|
||||||
fn variant_ident(&self, enum_name: &str) -> Ident {
|
fn variant_ident(&self, enum_name: &str) -> Ident {
|
||||||
variant_ident(enum_name, &self.name)
|
variant_ident(enum_name, &self.name)
|
||||||
}
|
}
|
||||||
fn to_tokens(&self) -> Tokens {
|
fn to_tokens(&self, ident: Option<Ident>) -> Tokens {
|
||||||
Constant::from_constant(self).to_tokens()
|
let expr = Constant::from_constant(self).to_tokens(ident);
|
||||||
|
quote! { #expr }
|
||||||
}
|
}
|
||||||
fn notation(&self) -> Option<&str> {
|
fn notation(&self) -> Option<&str> {
|
||||||
self.notation.as_deref()
|
self.notation.as_deref()
|
||||||
|
@ -426,7 +430,9 @@ pub enum Constant {
|
||||||
BitPos(u32),
|
BitPos(u32),
|
||||||
CExpr(vkxml::CExpression),
|
CExpr(vkxml::CExpression),
|
||||||
Text(String),
|
Text(String),
|
||||||
|
Alias(Ident, Ident),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl quote::ToTokens for ConstVal {
|
impl quote::ToTokens for ConstVal {
|
||||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||||
match self {
|
match self {
|
||||||
|
@ -473,32 +479,35 @@ impl Constant {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_tokens(&self) -> Tokens {
|
pub fn to_tokens(&self, ident: Option<Ident>) -> Tokens {
|
||||||
match *self {
|
match *self {
|
||||||
Constant::Number(n) => {
|
Constant::Number(n) => {
|
||||||
let number = interleave_number('_', 3, &n.to_string());
|
let number = interleave_number('_', 3, &n.to_string());
|
||||||
let term = Term::intern(&number);
|
let term = Term::intern(&number);
|
||||||
quote! {#term}
|
quote! {#ident(#term)}
|
||||||
}
|
}
|
||||||
Constant::Hex(ref s) => {
|
Constant::Hex(ref s) => {
|
||||||
let number = interleave_number('_', 4, s);
|
let number = interleave_number('_', 4, s);
|
||||||
let term = Term::intern(&format!("0x{}", number));
|
let term = Term::intern(&format!("0x{}", number));
|
||||||
quote! {#term}
|
quote! {#ident(#term)}
|
||||||
}
|
}
|
||||||
Constant::Text(ref text) => {
|
Constant::Text(ref text) => {
|
||||||
quote! {#text}
|
quote! {#ident(#text)}
|
||||||
}
|
}
|
||||||
Constant::CExpr(ref expr) => {
|
Constant::CExpr(ref expr) => {
|
||||||
let (_, (_, rexpr)) = cexpr(expr).expect("Unable to parse cexpr");
|
let (_, (_, rexpr)) = cexpr(expr).expect("Unable to parse cexpr");
|
||||||
let term = Term::intern(rexpr.as_str());
|
let term = Term::intern(rexpr.as_str());
|
||||||
quote! {#term}
|
quote! {#ident(#term)}
|
||||||
}
|
}
|
||||||
Constant::BitPos(pos) => {
|
Constant::BitPos(pos) => {
|
||||||
let value = 1 << pos;
|
let value = 1 << pos;
|
||||||
let bit_string = format!("{:b}", value);
|
let bit_string = format!("{:b}", value);
|
||||||
let bit_string = interleave_number('_', 4, &bit_string);
|
let bit_string = interleave_number('_', 4, &bit_string);
|
||||||
let term = Term::intern(&format!("0b{}", bit_string));
|
let term = Term::intern(&format!("0b{}", bit_string));
|
||||||
quote! {#term}
|
quote! {#ident(#term)}
|
||||||
|
}
|
||||||
|
Constant::Alias(ref base, ref value) => {
|
||||||
|
quote! {#base::#value}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -932,8 +941,8 @@ impl<'a> ConstantExt for ExtensionConstant<'a> {
|
||||||
fn variant_ident(&self, enum_name: &str) -> Ident {
|
fn variant_ident(&self, enum_name: &str) -> Ident {
|
||||||
variant_ident(enum_name, self.name)
|
variant_ident(enum_name, self.name)
|
||||||
}
|
}
|
||||||
fn to_tokens(&self) -> Tokens {
|
fn to_tokens(&self, ident: Option<Ident>) -> Tokens {
|
||||||
self.constant.to_tokens()
|
self.constant.to_tokens(ident)
|
||||||
}
|
}
|
||||||
fn notation(&self) -> Option<&str> {
|
fn notation(&self) -> Option<&str> {
|
||||||
None
|
None
|
||||||
|
@ -945,7 +954,7 @@ pub fn generate_extension_constants<'a>(
|
||||||
extension_number: i64,
|
extension_number: i64,
|
||||||
extension_items: &'a [vk_parse::ExtensionChild],
|
extension_items: &'a [vk_parse::ExtensionChild],
|
||||||
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
||||||
const_values: &mut BTreeMap<Ident, Vec<Ident>>,
|
const_values: &mut BTreeMap<Ident, Vec<ConstantMatchInfo>>,
|
||||||
) -> quote::Tokens {
|
) -> quote::Tokens {
|
||||||
use vk_parse::EnumSpec;
|
use vk_parse::EnumSpec;
|
||||||
let items = extension_items
|
let items = extension_items
|
||||||
|
@ -960,9 +969,9 @@ pub fn generate_extension_constants<'a>(
|
||||||
if const_cache.contains(_enum.name.as_str()) {
|
if const_cache.contains(_enum.name.as_str()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let (constant, extends) = match &_enum.spec {
|
let (constant, extends, is_alias) = match &_enum.spec {
|
||||||
EnumSpec::Bitpos { bitpos, extends } => {
|
EnumSpec::Bitpos { bitpos, extends } => {
|
||||||
Some((Constant::BitPos(*bitpos as u32), extends.clone()))
|
Some((Constant::BitPos(*bitpos as u32), extends.clone(), false))
|
||||||
}
|
}
|
||||||
EnumSpec::Offset {
|
EnumSpec::Offset {
|
||||||
offset,
|
offset,
|
||||||
|
@ -975,11 +984,24 @@ pub fn generate_extension_constants<'a>(
|
||||||
let extnumber = extnumber.unwrap_or_else(|| extension_number);
|
let extnumber = extnumber.unwrap_or_else(|| extension_number);
|
||||||
let value = ext_base + (extnumber - 1) * ext_block_size + offset;
|
let value = ext_base + (extnumber - 1) * ext_block_size + offset;
|
||||||
let value = if *positive { value } else { -value };
|
let value = if *positive { value } else { -value };
|
||||||
Some((Constant::Number(value as i32), Some(extends.clone())))
|
Some((Constant::Number(value as i32), Some(extends.clone()), false))
|
||||||
}
|
}
|
||||||
EnumSpec::Value { value, extends } => {
|
EnumSpec::Value { value, extends } => {
|
||||||
if let (Some(extends), Ok(value)) = (extends, value.parse::<i32>()) {
|
if let (Some(extends), Ok(value)) = (extends, value.parse::<i32>()) {
|
||||||
Some((Constant::Number(value), Some(extends.clone())))
|
Some((Constant::Number(value), Some(extends.clone()), false))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EnumSpec::Alias { alias, extends } => {
|
||||||
|
if let Some(extends) = extends {
|
||||||
|
let ident = name_to_tokens(&extends);
|
||||||
|
let key = variant_ident(&extends, &alias);
|
||||||
|
if key == "DISPATCH_BASE" {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some((Constant::Alias(ident, key), Some(extends.clone()), true))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -995,7 +1017,10 @@ pub fn generate_extension_constants<'a>(
|
||||||
const_values
|
const_values
|
||||||
.get_mut(&ident)
|
.get_mut(&ident)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.push(ext_constant.variant_ident(&extends));
|
.push(ConstantMatchInfo {
|
||||||
|
ident: ext_constant.variant_ident(&extends),
|
||||||
|
is_alias,
|
||||||
|
});
|
||||||
let impl_block = bitflags_impl_block(ident, &extends, &[&ext_constant]);
|
let impl_block = bitflags_impl_block(ident, &extends, &[&ext_constant]);
|
||||||
let doc_string = format!("Generated from '{}'", extension_name);
|
let doc_string = format!("Generated from '{}'", extension_name);
|
||||||
let q = quote! {
|
let q = quote! {
|
||||||
|
@ -1068,7 +1093,7 @@ pub fn generate_extension<'a>(
|
||||||
extension: &'a vk_parse::Extension,
|
extension: &'a vk_parse::Extension,
|
||||||
cmd_map: &CommandMap<'a>,
|
cmd_map: &CommandMap<'a>,
|
||||||
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
||||||
const_values: &mut BTreeMap<Ident, Vec<Ident>>,
|
const_values: &mut BTreeMap<Ident, Vec<ConstantMatchInfo>>,
|
||||||
cmd_aliases: &HashMap<String, String, impl BuildHasher>,
|
cmd_aliases: &HashMap<String, String, impl BuildHasher>,
|
||||||
fn_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
fn_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
||||||
) -> Option<quote::Tokens> {
|
) -> Option<quote::Tokens> {
|
||||||
|
@ -1110,7 +1135,7 @@ pub fn generate_typedef(typedef: &vkxml::Typedef) -> Tokens {
|
||||||
pub fn generate_bitmask(
|
pub fn generate_bitmask(
|
||||||
bitmask: &vkxml::Bitmask,
|
bitmask: &vkxml::Bitmask,
|
||||||
bitflags_cache: &mut HashSet<Ident, impl BuildHasher>,
|
bitflags_cache: &mut HashSet<Ident, impl BuildHasher>,
|
||||||
const_values: &mut BTreeMap<Ident, Vec<Ident>>,
|
const_values: &mut BTreeMap<Ident, Vec<ConstantMatchInfo>>,
|
||||||
) -> Option<Tokens> {
|
) -> Option<Tokens> {
|
||||||
// Workaround for empty bitmask
|
// Workaround for empty bitmask
|
||||||
if bitmask.name.is_empty() {
|
if bitmask.name.is_empty() {
|
||||||
|
@ -1183,7 +1208,7 @@ pub fn bitflags_impl_block(
|
||||||
.iter()
|
.iter()
|
||||||
.map(|constant| {
|
.map(|constant| {
|
||||||
let variant_ident = constant.variant_ident(enum_name);
|
let variant_ident = constant.variant_ident(enum_name);
|
||||||
let tokens = constant.to_tokens();
|
let tokens = constant.to_tokens(Some(ident));
|
||||||
(variant_ident, tokens)
|
(variant_ident, tokens)
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
@ -1203,7 +1228,7 @@ pub fn bitflags_impl_block(
|
||||||
.map(|((variant_ident, value), ref notation)| {
|
.map(|((variant_ident, value), ref notation)| {
|
||||||
quote! {
|
quote! {
|
||||||
#notation
|
#notation
|
||||||
pub const #variant_ident: Self = #ident(#value);
|
pub const #variant_ident: Self = #value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
quote! {
|
quote! {
|
||||||
|
@ -1216,7 +1241,7 @@ pub fn bitflags_impl_block(
|
||||||
pub fn generate_enum<'a>(
|
pub fn generate_enum<'a>(
|
||||||
_enum: &'a vkxml::Enumeration,
|
_enum: &'a vkxml::Enumeration,
|
||||||
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
||||||
const_values: &mut BTreeMap<Ident, Vec<Ident>>,
|
const_values: &mut BTreeMap<Ident, Vec<ConstantMatchInfo>>,
|
||||||
bitflags_cache: &mut HashSet<Ident, impl BuildHasher>,
|
bitflags_cache: &mut HashSet<Ident, impl BuildHasher>,
|
||||||
) -> EnumType {
|
) -> EnumType {
|
||||||
let name = &_enum.name[2..];
|
let name = &_enum.name[2..];
|
||||||
|
@ -1233,7 +1258,10 @@ pub fn generate_enum<'a>(
|
||||||
let mut values = Vec::with_capacity(constants.len());
|
let mut values = Vec::with_capacity(constants.len());
|
||||||
for constant in &constants {
|
for constant in &constants {
|
||||||
const_cache.insert(constant.name.as_str());
|
const_cache.insert(constant.name.as_str());
|
||||||
values.push(constant.variant_ident(&_enum.name));
|
values.push(ConstantMatchInfo {
|
||||||
|
ident: constant.variant_ident(&_enum.name),
|
||||||
|
is_alias: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const_values.insert(ident, values);
|
const_values.insert(ident, values);
|
||||||
|
|
||||||
|
@ -1503,7 +1531,11 @@ pub fn derive_setters(
|
||||||
_struct: &vkxml::Struct,
|
_struct: &vkxml::Struct,
|
||||||
root_struct_names: &HashSet<String, impl BuildHasher>,
|
root_struct_names: &HashSet<String, impl BuildHasher>,
|
||||||
) -> Option<Tokens> {
|
) -> Option<Tokens> {
|
||||||
if &_struct.name == "VkBaseInStructure" || &_struct.name == "VkBaseOutStructure" {
|
if &_struct.name == "VkBaseInStructure"
|
||||||
|
|| &_struct.name == "VkBaseOutStructure"
|
||||||
|
|| &_struct.name == "VkTransformMatrixKHR"
|
||||||
|
|| &_struct.name == "VkAccelerationStructureInstanceKHR"
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1833,6 +1865,29 @@ pub fn generate_struct(
|
||||||
union_types: &HashSet<&str, impl BuildHasher>,
|
union_types: &HashSet<&str, impl BuildHasher>,
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
let name = name_to_tokens(&_struct.name);
|
let name = name_to_tokens(&_struct.name);
|
||||||
|
if &_struct.name == "VkTransformMatrixKHR" {
|
||||||
|
return quote! {
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct TransformMatrixKHR {
|
||||||
|
pub matrix: [f32; 12],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if &_struct.name == "VkAccelerationStructureInstanceKHR" {
|
||||||
|
return quote! {
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct AccelerationStructureInstanceKHR {
|
||||||
|
pub transform: TransformMatrixKHR,
|
||||||
|
pub instance_custom_index_and_mask: u32,
|
||||||
|
pub instance_shader_binding_table_record_offset_and_flags: u32,
|
||||||
|
pub acceleration_structure_reference: u64,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let members = _struct.elements.iter().filter_map(|elem| match *elem {
|
let members = _struct.elements.iter().filter_map(|elem| match *elem {
|
||||||
vkxml::StructElement::Member(ref field) => Some(field),
|
vkxml::StructElement::Member(ref field) => Some(field),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -1960,7 +2015,7 @@ pub fn generate_definition(
|
||||||
union_types: &HashSet<&str, impl BuildHasher>,
|
union_types: &HashSet<&str, impl BuildHasher>,
|
||||||
root_structs: &HashSet<String, impl BuildHasher>,
|
root_structs: &HashSet<String, impl BuildHasher>,
|
||||||
bitflags_cache: &mut HashSet<Ident, impl BuildHasher>,
|
bitflags_cache: &mut HashSet<Ident, impl BuildHasher>,
|
||||||
const_values: &mut BTreeMap<Ident, Vec<Ident>>,
|
const_values: &mut BTreeMap<Ident, Vec<ConstantMatchInfo>>,
|
||||||
) -> Option<Tokens> {
|
) -> Option<Tokens> {
|
||||||
match *definition {
|
match *definition {
|
||||||
vkxml::DefinitionsElement::Typedef(ref typedef) => Some(generate_typedef(typedef)),
|
vkxml::DefinitionsElement::Typedef(ref typedef) => Some(generate_typedef(typedef)),
|
||||||
|
@ -2070,7 +2125,7 @@ pub fn generate_constant<'a>(
|
||||||
let c = Constant::from_constant(constant);
|
let c = Constant::from_constant(constant);
|
||||||
let name = constant_name(&constant.name);
|
let name = constant_name(&constant.name);
|
||||||
let ident = Ident::from(name.as_str());
|
let ident = Ident::from(name.as_str());
|
||||||
let value = c.to_tokens();
|
let value = c.to_tokens(None);
|
||||||
let ty = if name == "TRUE" || name == "FALSE" {
|
let ty = if name == "TRUE" || name == "FALSE" {
|
||||||
CType::Bool32
|
CType::Bool32
|
||||||
} else {
|
} else {
|
||||||
|
@ -2085,7 +2140,7 @@ pub fn generate_constant<'a>(
|
||||||
pub fn generate_feature_extension<'a>(
|
pub fn generate_feature_extension<'a>(
|
||||||
registry: &'a vk_parse::Registry,
|
registry: &'a vk_parse::Registry,
|
||||||
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
||||||
const_values: &mut BTreeMap<Ident, Vec<Ident>>,
|
const_values: &mut BTreeMap<Ident, Vec<ConstantMatchInfo>>,
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
let constants = registry.0.iter().filter_map(|item| match item {
|
let constants = registry.0.iter().filter_map(|item| match item {
|
||||||
vk_parse::RegistryChild::Feature(feature) => Some(generate_extension_constants(
|
vk_parse::RegistryChild::Feature(feature) => Some(generate_extension_constants(
|
||||||
|
@ -2102,12 +2157,22 @@ pub fn generate_feature_extension<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_const_debugs(const_values: &BTreeMap<Ident, Vec<Ident>>) -> Tokens {
|
pub struct ConstantMatchInfo {
|
||||||
|
pub ident: Ident,
|
||||||
|
pub is_alias: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_const_debugs(const_values: &BTreeMap<Ident, Vec<ConstantMatchInfo>>) -> Tokens {
|
||||||
let impls = const_values.iter().map(|(ty, values)| {
|
let impls = const_values.iter().map(|(ty, values)| {
|
||||||
if ty.to_string().contains("Flags") {
|
if ty.to_string().contains("Flags") {
|
||||||
let cases = values.iter().map(|value| {
|
let cases = values.iter().filter_map(|value| {
|
||||||
let name = value.to_string();
|
if value.is_alias {
|
||||||
quote! { (#ty::#value.0, #name) }
|
None
|
||||||
|
} else {
|
||||||
|
let name = value.ident.to_string();
|
||||||
|
let ident = value.ident;
|
||||||
|
Some(quote! { (#ty::#ident.0, #name) })
|
||||||
|
}
|
||||||
});
|
});
|
||||||
quote! {
|
quote! {
|
||||||
impl fmt::Debug for #ty {
|
impl fmt::Debug for #ty {
|
||||||
|
@ -2118,9 +2183,14 @@ pub fn generate_const_debugs(const_values: &BTreeMap<Ident, Vec<Ident>>) -> Toke
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let cases = values.iter().map(|value| {
|
let cases = values.iter().filter_map(|value| {
|
||||||
let name = value.to_string();
|
if value.is_alias {
|
||||||
quote! { Self::#value => Some(#name), }
|
None
|
||||||
|
} else {
|
||||||
|
let name = value.ident.to_string();
|
||||||
|
let ident = value.ident;
|
||||||
|
Some(quote! { Self::#ident => Some(#name), })
|
||||||
|
}
|
||||||
});
|
});
|
||||||
quote! {
|
quote! {
|
||||||
impl fmt::Debug for #ty {
|
impl fmt::Debug for #ty {
|
||||||
|
@ -2291,7 +2361,7 @@ pub fn write_source_code(path: &Path) {
|
||||||
let mut bitflags_cache = HashSet::new();
|
let mut bitflags_cache = HashSet::new();
|
||||||
let mut const_cache = HashSet::new();
|
let mut const_cache = HashSet::new();
|
||||||
|
|
||||||
let mut const_values: BTreeMap<Ident, Vec<Ident>> = BTreeMap::new();
|
let mut const_values: BTreeMap<Ident, Vec<ConstantMatchInfo>> = BTreeMap::new();
|
||||||
|
|
||||||
let (enum_code, bitflags_code) = enums
|
let (enum_code, bitflags_code) = enums
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -2304,10 +2374,13 @@ pub fn write_source_code(path: &Path) {
|
||||||
acc
|
acc
|
||||||
});
|
});
|
||||||
|
|
||||||
let constants_code: Vec<_> = constants
|
let mut constants_code: Vec<_> = constants
|
||||||
.iter()
|
.iter()
|
||||||
.map(|constant| generate_constant(constant, &mut const_cache))
|
.map(|constant| generate_constant(constant, &mut const_cache))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
constants_code.push(quote! { pub const SHADER_UNUSED_NV : u32 = SHADER_UNUSED_KHR;});
|
||||||
|
|
||||||
let extension_code = extensions
|
let extension_code = extensions
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|ext| {
|
.filter_map(|ext| {
|
||||||
|
|
Loading…
Add table
Reference in a new issue