Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to ash 0.38 #2510

Merged
merged 2 commits into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
137 changes: 73 additions & 64 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),
extension_fns_members(&vk_data.commands, &vk_data.extensions, false),
"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),
extension_fns_members(&vk_data.commands, &vk_data.extensions, true),
"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,61 @@ 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 extension_fns_members<'a>(
commands: &'a IndexMap<&str, &Command>,
extensions: &'a IndexMap<&str, &Extension>,
device_functions: bool,
// extension_filter: impl Fn(&str) -> bool,
) -> impl Iterator<Item = FnsMember> + 'a {
let fn_struct_name = if device_functions {
format_ident!("DeviceFn")
} else {
format_ident!("InstanceFn")
};

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| {
.filter(move |ext| {
ext.children.iter().any(move |ch| {
if let ExtensionChild::Require { items, .. } = ch {
items
.iter()
.any(|i| matches!(i, InterfaceItem::Command { .. }))
.any(move |i| matches!(i, InterfaceItem::Command { name, .. } if device_functions == is_device_command(commands, name)))
} else {
false
}
})
})
.map(|ext| {
let base = ext.name.strip_prefix("VK_").unwrap().to_snake_case();
let name = format_ident!("{}", base);
let fn_struct = format_ident!("{}Fn", base.to_upper_camel_case());
FnsMember { name, fn_struct }
})
.collect()
}

fn instance_extension_fns_members(extensions: &IndexMap<&str, &Extension>) -> Vec<FnsMember> {
extensions
.values()
.filter(|ext| {
match ext.ext_type.as_deref().unwrap() {
// Include any instance extensions that have functions.
"instance" => ext.children.iter().any(|ch| {
if let ExtensionChild::Require { items, .. } = ch {
items
.iter()
.any(|i| matches!(i, InterfaceItem::Command { .. }))
} 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();
.map(move |ext| {
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::#fn_struct_name);
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 conjunctive_normal_form;
Expand Down Expand Up @@ -68,7 +68,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 @@ -94,6 +94,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 @@ -107,6 +108,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 @@ -117,6 +119,7 @@ impl<'r> VkRegistryData<'r> {
spirv_capabilities,
spirv_extensions,
types,
commands,
}
}

Expand Down Expand Up @@ -435,6 +438,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
Comment on lines +447 to +460
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts? This would save on the extra code in autogen/fns.rs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I plan to refactor a lot of the autogen stuff, so I will have a look at that as well then.

})
.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 @@ -320,7 +320,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 @@ -345,7 +345,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 @@ -361,7 +361,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
Loading