Skip to content

Commit

Permalink
Upgrade to ash 0.38
Browse files Browse the repository at this point in the history
  • Loading branch information
MarijnS95 committed Apr 2, 2024
1 parent 55556bb commit 4546591
Show file tree
Hide file tree
Showing 27 changed files with 212 additions and 162 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ ahash = "0.8"
# When updating Ash, also update vk.xml to the same Vulkan patch version that Ash uses.
# All versions of vk.xml can be found at:
# https://github.com/KhronosGroup/Vulkan-Headers/commits/main/registry/vk.xml
ash = "0.37.3"
ash = "0.38.0"
bytemuck = "1.9"
core-graphics-types = "0.1"
crossbeam-queue = "0.3"
Expand Down
8 changes: 4 additions & 4 deletions vulkano/autogen/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ struct FeaturesFfiMember {

fn features_ffi_output(members: &[FeaturesFfiMember]) -> TokenStream {
let struct_items = members.iter().map(|FeaturesFfiMember { name, ty, .. }| {
quote! { #name: Option<ash::vk::#ty>, }
quote! { #name: Option<ash::vk::#ty<'static>>, }
});

let make_chain_items = members.iter().map(
Expand All @@ -640,7 +640,7 @@ fn features_ffi_output(members: &[FeaturesFfiMember]) -> TokenStream {
quote! {
#[derive(Default)]
pub(crate) struct DeviceFeaturesFfi {
features_vulkan10: ash::vk::PhysicalDeviceFeatures2KHR,
features_vulkan10: ash::vk::PhysicalDeviceFeatures2KHR<'static>,
#(#struct_items)*
}

Expand All @@ -656,11 +656,11 @@ fn features_ffi_output(members: &[FeaturesFfiMember]) -> TokenStream {
#(#make_chain_items)*
}

pub(crate) fn head_as_ref(&self) -> &ash::vk::PhysicalDeviceFeatures2KHR {
pub(crate) fn head_as_ref(&self) -> &ash::vk::PhysicalDeviceFeatures2KHR<'static> {
&self.features_vulkan10
}

pub(crate) fn head_as_mut(&mut self) -> &mut ash::vk::PhysicalDeviceFeatures2KHR {
pub(crate) fn head_as_mut(&mut self) -> &mut ash::vk::PhysicalDeviceFeatures2KHR<'static> {
&mut self.features_vulkan10
}
}
Expand Down
120 changes: 75 additions & 45 deletions vulkano/autogen/fns.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
use super::{write_file, IndexMap, VkRegistryData};
use heck::{ToSnakeCase, ToUpperCamelCase};
use proc_macro2::{Ident, TokenStream};
use proc_macro2::{Ident, Span, TokenStream};
use quote::{format_ident, quote};
use vk_parse::{Extension, ExtensionChild, InterfaceItem};
use vk_parse::{Command, Extension, ExtensionChild, InterfaceItem};

pub fn write(vk_data: &VkRegistryData<'_>) {
// TODO: Long strings break rustfmt

let entry_fns_output = fns_output(
&[],
std::iter::empty(),
"Entry",
&["1_0", "1_1" /*, "1_2", "1_3"*/],
"Raw Vulkan global entry point-level functions.\n\nTo use these, you need to include the Ash crate, using the same version Vulkano uses.",
);
let instance_fns_output = fns_output(
&instance_extension_fns_members(&vk_data.extensions),
instance_extension_fns_members(&vk_data.commands, &vk_data.extensions),
"Instance",
&["1_0", "1_1" /*, "1_2"*/, "1_3"],
"Raw Vulkan instance-level functions.\n\nTo use these, you need to include the Ash crate, using the same version Vulkano uses.",
);
let device_fns_output = fns_output(
&device_extension_fns_members(&vk_data.extensions),
device_extension_fns_members(&vk_data.commands, &vk_data.extensions),
"Device",
&["1_0", "1_1", "1_2", "1_3"],
"Raw Vulkan device-level functions.\n\nTo use these, you need to include the Ash crate, using the same version Vulkano uses.",
);
write_file(
Expand All @@ -37,26 +41,35 @@ pub fn write(vk_data: &VkRegistryData<'_>) {
#[derive(Clone, Debug)]
struct FnsMember {
name: Ident,
fn_struct: Ident,
/// Path to the struct
fn_struct: TokenStream,
}

fn fns_output(extension_members: &[FnsMember], fns_level: &str, doc: &str) -> TokenStream {
fn fns_output(
extension_members: impl Iterator<Item = FnsMember>,
fns_level: &str,
fns_versions: &[&str], // TODO: Parse from vk.xml?
doc: &str,
) -> TokenStream {
let struct_name = format_ident!("{}Functions", fns_level);
let members = ["1_0", "1_1", "1_2", "1_3"]
.into_iter()
.map(|version| FnsMember {
name: format_ident!("v{}", version),
fn_struct: format_ident!("{}FnV{}", fns_level, version),
let members = fns_versions
.iter()
.map(|version| {
let fn_struct = format_ident!("{}FnV{}", fns_level, version);
FnsMember {
name: format_ident!("v{}", version),
fn_struct: quote!(#fn_struct),
}
})
.chain(extension_members.iter().cloned())
.chain(extension_members)
.collect::<Vec<_>>();

let struct_items = members.iter().map(|FnsMember { name, fn_struct }| {
quote! { pub #name: ash::vk::#fn_struct, }
quote! { pub #name: ash::#fn_struct, }
});

let load_items = members.iter().map(|FnsMember { name, fn_struct }| {
quote! { #name: ash::vk::#fn_struct::load(&mut load_fn), }
quote! { #name: ash::#fn_struct::load(&mut load_fn), }
});

quote! {
Expand Down Expand Up @@ -87,65 +100,82 @@ fn fns_output(extension_members: &[FnsMember], fns_level: &str, doc: &str) -> To
}
}

fn device_extension_fns_members(extensions: &IndexMap<&str, &Extension>) -> Vec<FnsMember> {
/// Returns [`false`] when this is an `instance` or `entry` command
fn is_device_command(commands: &IndexMap<&str, &Command>, name: &str) -> bool {
// Based on
// https://github.com/ash-rs/ash/blob/b724b78dac8d83879ed7a1aad2b91bb9f2beb5cf/generator/src/lib.rs#L568-L586

let mut name = name;
loop {
let command = commands[name];
match command {
Command::Alias { alias, .. } => name = alias.as_str(),
Command::Definition(command) => {
break command.params.first().map_or(false, |field| {
matches!(
field.definition.type_name.as_deref(),
Some("VkDevice" | "VkCommandBuffer" | "VkQueue")
)
})
}
_ => todo!(),
}
}
}

fn device_extension_fns_members<'a>(
commands: &'a IndexMap<&str, &Command>,
extensions: &'a IndexMap<&str, &Extension>,
) -> impl Iterator<Item = FnsMember> + 'a {
extensions
.values()
// Include any device extensions that have functions.
.filter(|ext| ext.ext_type.as_ref().unwrap() == "device")
.filter(|ext| {
ext.children.iter().any(|ch| {
if let ExtensionChild::Require { items, .. } = ch {
items
.iter()
.any(|i| matches!(i, InterfaceItem::Command { .. }))
.any(|i| matches!(i, InterfaceItem::Command { name, .. } if is_device_command(commands, name)))
} else {
false
}
})
})
.map(|ext| {
let base = ext.name.strip_prefix("VK_").unwrap().to_snake_case();
// TODO: Dedup at call site?
let base = ext.name.strip_prefix("VK_").unwrap().to_lowercase();
let (vendor, extension) = base.split_once('_').unwrap();
let vendor = Ident::new(vendor, Span::call_site());
let extension = Ident::new(extension, Span::call_site());
let name = format_ident!("{}", base);
let fn_struct = format_ident!("{}Fn", base.to_upper_camel_case());
let fn_struct = quote!(#vendor::#extension::DeviceFn);
FnsMember { name, fn_struct }
})
.collect()
}

fn instance_extension_fns_members(extensions: &IndexMap<&str, &Extension>) -> Vec<FnsMember> {
fn instance_extension_fns_members<'a>(
commands: &'a IndexMap<&str, &Command>,
extensions: &'a IndexMap<&str, &Extension>,
) -> impl Iterator<Item = FnsMember> + 'a {
extensions
.values()
.filter(|ext| {
match ext.ext_type.as_deref().unwrap() {
// Include any instance extensions that have functions.
"instance" => ext.children.iter().any(|ch| {
ext.children.iter().any(|ch| {
if let ExtensionChild::Require { items, .. } = ch {
items
.iter()
.any(|i| matches!(i, InterfaceItem::Command { .. }))
.any(|i| matches!(i, InterfaceItem::Command { name, .. } if !is_device_command(commands, name)))
} else {
false
}
}),
// Include device extensions that have functions containing "PhysicalDevice".
// Note: this test might not be sufficient in the long run...
"device" => ext.children.iter().any(|ch| {
if let ExtensionChild::Require { items, .. } = ch {
items
.iter()
.any(|i| matches!(i, InterfaceItem::Command { name, .. } if name.contains("PhysicalDevice")))
} else {
false
}
}),
_ => unreachable!(),
}
})
})
.map(|ext| {
let base = ext.name.strip_prefix("VK_").unwrap().to_snake_case();
let base = ext.name.strip_prefix("VK_").unwrap().to_lowercase();
let (vendor, extension) = base.split_once('_').unwrap();
let vendor = Ident::new(vendor, Span::call_site());
let extension = Ident::new(extension, Span::call_site());
let name = format_ident!("{}", base);
let fn_struct = format_ident!("{}Fn", base.to_upper_camel_case());
let fn_struct = quote!(#vendor::#extension::InstanceFn);
FnsMember { name, fn_struct }
})
.collect()
}
35 changes: 31 additions & 4 deletions vulkano/autogen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ use std::{
io::{BufWriter, Write},
ops::BitOrAssign,
path::Path,
process::Command,
process,
};
use vk_parse::{
Enum, EnumSpec, Enums, EnumsChild, Extension, ExtensionChild, Feature, Format, InterfaceItem,
Registry, RegistryChild, SpirvExtOrCap, Type, TypeSpec, TypesChild,
Command, Enum, EnumSpec, Enums, EnumsChild, Extension, ExtensionChild, Feature, Format,
InterfaceItem, Registry, RegistryChild, SpirvExtOrCap, Type, TypeSpec, TypesChild,
};

mod errors;
Expand Down Expand Up @@ -67,7 +67,7 @@ fn write_file(file: impl AsRef<Path>, source: impl AsRef<str>, content: impl Dis
.unwrap();

drop(writer); // Ensure that the file is fully written
Command::new("rustfmt").arg(&path).status().ok();
process::Command::new("rustfmt").arg(&path).status().ok();
}

fn get_vk_registry<P: AsRef<Path> + ?Sized>(path: &P) -> Registry {
Expand All @@ -93,6 +93,7 @@ pub struct VkRegistryData<'r> {
pub spirv_capabilities: Vec<&'r SpirvExtOrCap>,
pub spirv_extensions: Vec<&'r SpirvExtOrCap>,
pub types: HashMap<&'r str, (&'r Type, Vec<&'r str>)>,
pub commands: IndexMap<&'r str, &'r Command>,
}

impl<'r> VkRegistryData<'r> {
Expand All @@ -106,6 +107,7 @@ impl<'r> VkRegistryData<'r> {
let errors = Self::get_errors(registry, &features, &extensions);
let types = Self::get_types(registry, &aliases, &features, &extensions);
let header_version = Self::get_header_version(registry);
let commands = Self::get_commands(registry);

VkRegistryData {
header_version,
Expand All @@ -116,6 +118,7 @@ impl<'r> VkRegistryData<'r> {
spirv_capabilities,
spirv_extensions,
types,
commands,
}
}

Expand Down Expand Up @@ -434,6 +437,30 @@ impl<'r> VkRegistryData<'r> {
.filter(|(_key, val)| !val.1.is_empty())
.collect()
}

fn get_commands(registry: &Registry) -> IndexMap<&str, &Command> {
registry
.0
.iter()
.filter_map(|child| {
// TODO: resolve aliases into CommandDefinition immediately?
if let RegistryChild::Commands(commands) = child {
return Some(commands.children.iter().map(|c| {
(
match c {
Command::Alias { name, .. } => name.as_str(),
Command::Definition(d) => d.proto.name.as_str(),
_ => todo!(),
},
c,
)
}));
}
None
})
.flatten()
.collect()
}
}

pub fn get_spirv_grammar<P: AsRef<Path> + ?Sized>(path: &P) -> SpirvGrammar {
Expand Down
6 changes: 3 additions & 3 deletions vulkano/autogen/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ struct PropertiesFfiMember {

fn properties_ffi_output(members: &[PropertiesFfiMember]) -> TokenStream {
let struct_items = members.iter().map(|PropertiesFfiMember { name, ty, .. }| {
quote! { #name: Option<ash::vk::#ty>, }
quote! { #name: Option<ash::vk::#ty<'static>>, }
});

let make_chain_items = members.iter().map(
Expand All @@ -286,7 +286,7 @@ fn properties_ffi_output(members: &[PropertiesFfiMember]) -> TokenStream {
quote! {
#[derive(Default)]
pub(crate) struct DevicePropertiesFfi {
properties_vulkan10: ash::vk::PhysicalDeviceProperties2KHR,
properties_vulkan10: ash::vk::PhysicalDeviceProperties2KHR<'static>,
#(#struct_items)*
}

Expand All @@ -302,7 +302,7 @@ fn properties_ffi_output(members: &[PropertiesFfiMember]) -> TokenStream {
#(#make_chain_items)*
}

pub(crate) fn head_as_mut(&mut self) -> &mut ash::vk::PhysicalDeviceProperties2KHR {
pub(crate) fn head_as_mut(&mut self) -> &mut ash::vk::PhysicalDeviceProperties2KHR<'static> {
&mut self.properties_vulkan10
}
}
Expand Down
4 changes: 2 additions & 2 deletions vulkano/src/acceleration_structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,8 +596,8 @@ impl AccelerationStructureBuildGeometryInfo {
pub(crate) fn to_vulkan(
&self,
) -> (
ash::vk::AccelerationStructureBuildGeometryInfoKHR,
Vec<ash::vk::AccelerationStructureGeometryKHR>,
ash::vk::AccelerationStructureBuildGeometryInfoKHR<'static>,
Vec<ash::vk::AccelerationStructureGeometryKHR<'static>>,
) {
let &Self {
flags,
Expand Down
4 changes: 2 additions & 2 deletions vulkano/src/command_buffer/commands/bind_push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1311,8 +1311,8 @@ impl RawRecordingCommandBuffer {

struct PerDescriptorWrite {
write_info: DescriptorWriteInfo,
acceleration_structures: ash::vk::WriteDescriptorSetAccelerationStructureKHR,
inline_uniform_block: ash::vk::WriteDescriptorSetInlineUniformBlock,
acceleration_structures: ash::vk::WriteDescriptorSetAccelerationStructureKHR<'static>,
inline_uniform_block: ash::vk::WriteDescriptorSetInlineUniformBlock<'static>,
}

let mut writes_vk: SmallVec<[_; 8]> = SmallVec::with_capacity(descriptor_writes.len());
Expand Down
Loading

0 comments on commit 4546591

Please sign in to comment.