[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:
Jasper Bekkers 2020-03-22 16:05:30 +01:00 committed by GitHub
parent af6acb93e5
commit 6bdc403330
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 8226 additions and 1886 deletions

View file

@ -3,6 +3,7 @@ pub use self::display::Display;
pub use self::display_swapchain::DisplaySwapchain;
pub use self::external_memory_fd::ExternalMemoryFd;
pub use self::push_descriptor::PushDescriptor;
pub use self::ray_tracing::RayTracing;
pub use self::surface::Surface;
pub use self::swapchain::Swapchain;
pub use self::wayland_surface::WaylandSurface;
@ -15,6 +16,7 @@ mod display;
mod display_swapchain;
mod external_memory_fd;
mod push_descriptor;
mod ray_tracing;
mod surface;
mod swapchain;
mod wayland_surface;

View 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
}
}

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@ authors = ["Maik Klein <maikklein@googlemail.com>"]
edition = "2018"
[dependencies]
vk-parse = "0.3.0"
vk-parse = "0.4.0"
vkxml = "0.3"
nom = "4.0"
heck = "0.3"

@ -1 +1 @@
Subproject commit 881bbb347a08d1b5aa77f61a52a30b506de9f2bf
Subproject commit fb7f9c9bcd1d1544ea203a1f3d4253d0e90c5a90

View file

@ -391,7 +391,7 @@ impl ConstVal {
}
pub trait ConstantExt {
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>;
}
@ -399,8 +399,11 @@ impl ConstantExt for vkxml::ExtensionEnum {
fn variant_ident(&self, enum_name: &str) -> Ident {
variant_ident(enum_name, &self.name)
}
fn to_tokens(&self) -> Tokens {
Constant::from_extension_enum(self).expect("").to_tokens()
fn to_tokens(&self, ident: Option<Ident>) -> Tokens {
let expr = Constant::from_extension_enum(self)
.expect("")
.to_tokens(ident);
quote! { #ident(#expr) }
}
fn notation(&self) -> Option<&str> {
self.notation.as_deref()
@ -411,8 +414,9 @@ impl ConstantExt for vkxml::Constant {
fn variant_ident(&self, enum_name: &str) -> Ident {
variant_ident(enum_name, &self.name)
}
fn to_tokens(&self) -> Tokens {
Constant::from_constant(self).to_tokens()
fn to_tokens(&self, ident: Option<Ident>) -> Tokens {
let expr = Constant::from_constant(self).to_tokens(ident);
quote! { #expr }
}
fn notation(&self) -> Option<&str> {
self.notation.as_deref()
@ -426,7 +430,9 @@ pub enum Constant {
BitPos(u32),
CExpr(vkxml::CExpression),
Text(String),
Alias(Ident, Ident),
}
impl quote::ToTokens for ConstVal {
fn to_tokens(&self, tokens: &mut Tokens) {
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 {
Constant::Number(n) => {
let number = interleave_number('_', 3, &n.to_string());
let term = Term::intern(&number);
quote! {#term}
quote! {#ident(#term)}
}
Constant::Hex(ref s) => {
let number = interleave_number('_', 4, s);
let term = Term::intern(&format!("0x{}", number));
quote! {#term}
quote! {#ident(#term)}
}
Constant::Text(ref text) => {
quote! {#text}
quote! {#ident(#text)}
}
Constant::CExpr(ref expr) => {
let (_, (_, rexpr)) = cexpr(expr).expect("Unable to parse cexpr");
let term = Term::intern(rexpr.as_str());
quote! {#term}
quote! {#ident(#term)}
}
Constant::BitPos(pos) => {
let value = 1 << pos;
let bit_string = format!("{:b}", value);
let bit_string = interleave_number('_', 4, &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 {
variant_ident(enum_name, self.name)
}
fn to_tokens(&self) -> Tokens {
self.constant.to_tokens()
fn to_tokens(&self, ident: Option<Ident>) -> Tokens {
self.constant.to_tokens(ident)
}
fn notation(&self) -> Option<&str> {
None
@ -945,7 +954,7 @@ pub fn generate_extension_constants<'a>(
extension_number: i64,
extension_items: &'a [vk_parse::ExtensionChild],
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
const_values: &mut BTreeMap<Ident, Vec<Ident>>,
const_values: &mut BTreeMap<Ident, Vec<ConstantMatchInfo>>,
) -> quote::Tokens {
use vk_parse::EnumSpec;
let items = extension_items
@ -960,9 +969,9 @@ pub fn generate_extension_constants<'a>(
if const_cache.contains(_enum.name.as_str()) {
return None;
}
let (constant, extends) = match &_enum.spec {
let (constant, extends, is_alias) = match &_enum.spec {
EnumSpec::Bitpos { bitpos, extends } => {
Some((Constant::BitPos(*bitpos as u32), extends.clone()))
Some((Constant::BitPos(*bitpos as u32), extends.clone(), false))
}
EnumSpec::Offset {
offset,
@ -975,11 +984,24 @@ pub fn generate_extension_constants<'a>(
let extnumber = extnumber.unwrap_or_else(|| extension_number);
let value = ext_base + (extnumber - 1) * ext_block_size + offset;
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 } => {
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 {
None
}
@ -995,7 +1017,10 @@ pub fn generate_extension_constants<'a>(
const_values
.get_mut(&ident)
.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 doc_string = format!("Generated from '{}'", extension_name);
let q = quote! {
@ -1068,7 +1093,7 @@ pub fn generate_extension<'a>(
extension: &'a vk_parse::Extension,
cmd_map: &CommandMap<'a>,
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>,
fn_cache: &mut HashSet<&'a str, impl BuildHasher>,
) -> Option<quote::Tokens> {
@ -1110,7 +1135,7 @@ pub fn generate_typedef(typedef: &vkxml::Typedef) -> Tokens {
pub fn generate_bitmask(
bitmask: &vkxml::Bitmask,
bitflags_cache: &mut HashSet<Ident, impl BuildHasher>,
const_values: &mut BTreeMap<Ident, Vec<Ident>>,
const_values: &mut BTreeMap<Ident, Vec<ConstantMatchInfo>>,
) -> Option<Tokens> {
// Workaround for empty bitmask
if bitmask.name.is_empty() {
@ -1183,7 +1208,7 @@ pub fn bitflags_impl_block(
.iter()
.map(|constant| {
let variant_ident = constant.variant_ident(enum_name);
let tokens = constant.to_tokens();
let tokens = constant.to_tokens(Some(ident));
(variant_ident, tokens)
})
.collect_vec();
@ -1203,7 +1228,7 @@ pub fn bitflags_impl_block(
.map(|((variant_ident, value), ref notation)| {
quote! {
#notation
pub const #variant_ident: Self = #ident(#value);
pub const #variant_ident: Self = #value;
}
});
quote! {
@ -1216,7 +1241,7 @@ pub fn bitflags_impl_block(
pub fn generate_enum<'a>(
_enum: &'a vkxml::Enumeration,
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>,
) -> EnumType {
let name = &_enum.name[2..];
@ -1233,7 +1258,10 @@ pub fn generate_enum<'a>(
let mut values = Vec::with_capacity(constants.len());
for constant in &constants {
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);
@ -1503,7 +1531,11 @@ pub fn derive_setters(
_struct: &vkxml::Struct,
root_struct_names: &HashSet<String, impl BuildHasher>,
) -> Option<Tokens> {
if &_struct.name == "VkBaseInStructure" || &_struct.name == "VkBaseOutStructure" {
if &_struct.name == "VkBaseInStructure"
|| &_struct.name == "VkBaseOutStructure"
|| &_struct.name == "VkTransformMatrixKHR"
|| &_struct.name == "VkAccelerationStructureInstanceKHR"
{
return None;
}
@ -1833,6 +1865,29 @@ pub fn generate_struct(
union_types: &HashSet<&str, impl BuildHasher>,
) -> Tokens {
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 {
vkxml::StructElement::Member(ref field) => Some(field),
_ => None,
@ -1960,7 +2015,7 @@ pub fn generate_definition(
union_types: &HashSet<&str, impl BuildHasher>,
root_structs: &HashSet<String, 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> {
match *definition {
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 name = constant_name(&constant.name);
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" {
CType::Bool32
} else {
@ -2085,7 +2140,7 @@ pub fn generate_constant<'a>(
pub fn generate_feature_extension<'a>(
registry: &'a vk_parse::Registry,
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
const_values: &mut BTreeMap<Ident, Vec<Ident>>,
const_values: &mut BTreeMap<Ident, Vec<ConstantMatchInfo>>,
) -> Tokens {
let constants = registry.0.iter().filter_map(|item| match item {
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)| {
if ty.to_string().contains("Flags") {
let cases = values.iter().map(|value| {
let name = value.to_string();
quote! { (#ty::#value.0, #name) }
let cases = values.iter().filter_map(|value| {
if value.is_alias {
None
} else {
let name = value.ident.to_string();
let ident = value.ident;
Some(quote! { (#ty::#ident.0, #name) })
}
});
quote! {
impl fmt::Debug for #ty {
@ -2118,9 +2183,14 @@ pub fn generate_const_debugs(const_values: &BTreeMap<Ident, Vec<Ident>>) -> Toke
}
}
} else {
let cases = values.iter().map(|value| {
let name = value.to_string();
quote! { Self::#value => Some(#name), }
let cases = values.iter().filter_map(|value| {
if value.is_alias {
None
} else {
let name = value.ident.to_string();
let ident = value.ident;
Some(quote! { Self::#ident => Some(#name), })
}
});
quote! {
impl fmt::Debug for #ty {
@ -2291,7 +2361,7 @@ pub fn write_source_code(path: &Path) {
let mut bitflags_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
.into_iter()
@ -2304,10 +2374,13 @@ pub fn write_source_code(path: &Path) {
acc
});
let constants_code: Vec<_> = constants
let mut constants_code: Vec<_> = constants
.iter()
.map(|constant| generate_constant(constant, &mut const_cache))
.collect();
constants_code.push(quote! { pub const SHADER_UNUSED_NV : u32 = SHADER_UNUSED_KHR;});
let extension_code = extensions
.iter()
.filter_map(|ext| {