Skip to content
Open
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
8 changes: 7 additions & 1 deletion ash/src/vk/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::definitions::*;
pub const MAX_PHYSICAL_DEVICE_NAME_SIZE: usize = 256;
pub const UUID_SIZE: usize = 16;
pub const LUID_SIZE: usize = 8;
pub const LUID_SIZE_KHR: usize = LUID_SIZE;
pub const MAX_EXTENSION_NAME_SIZE: usize = 256;
pub const MAX_DESCRIPTION_SIZE: usize = 256;
pub const MAX_MEMORY_TYPES: usize = 32;
Expand All @@ -17,15 +18,20 @@ pub const TRUE: Bool32 = 1;
pub const FALSE: Bool32 = 0;
pub const QUEUE_FAMILY_IGNORED: u32 = !0;
pub const QUEUE_FAMILY_EXTERNAL: u32 = !1;
pub const QUEUE_FAMILY_EXTERNAL_KHR: u32 = QUEUE_FAMILY_EXTERNAL;
pub const QUEUE_FAMILY_FOREIGN_EXT: u32 = !2;
pub const SUBPASS_EXTERNAL: u32 = !0;
pub const MAX_DEVICE_GROUP_SIZE: usize = 32;
pub const MAX_DEVICE_GROUP_SIZE_KHR: usize = MAX_DEVICE_GROUP_SIZE;
pub const MAX_DRIVER_NAME_SIZE: usize = 256;
pub const MAX_DRIVER_NAME_SIZE_KHR: usize = MAX_DRIVER_NAME_SIZE;
pub const MAX_DRIVER_INFO_SIZE: usize = 256;
pub const MAX_DRIVER_INFO_SIZE_KHR: usize = MAX_DRIVER_INFO_SIZE;
pub const SHADER_UNUSED_KHR: u32 = !0;
pub const SHADER_UNUSED_NV: u32 = SHADER_UNUSED_KHR;
pub const MAX_GLOBAL_PRIORITY_SIZE_KHR: usize = 16;
pub const MAX_GLOBAL_PRIORITY_SIZE_EXT: usize = MAX_GLOBAL_PRIORITY_SIZE_KHR;
pub const MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT: usize = 32;
pub const MAX_PIPELINE_BINARY_KEY_SIZE_KHR: usize = 32;
pub const MAX_VIDEO_AV1_REFERENCES_PER_FRAME_KHR: usize = 7;
pub const SHADER_INDEX_UNUSED_AMDX: u32 = !0;
pub const SHADER_UNUSED_NV: u32 = SHADER_UNUSED_KHR;
10 changes: 5 additions & 5 deletions ash/src/vk/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ pub const fn version_major(version: u32) -> u32 {
#[deprecated = "This define is deprecated. VK_API_VERSION_MINOR should be used instead."]
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_VERSION_MINOR.html>"]
pub const fn version_minor(version: u32) -> u32 {
((version) >> 12) & 0x3ffu32
((version) >> 12) & 0x3ff
}
#[deprecated = "This define is deprecated. VK_API_VERSION_PATCH should be used instead."]
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_VERSION_PATCH.html>"]
pub const fn version_patch(version: u32) -> u32 {
(version) & 0xfffu32
(version) & 0xfff
}
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_MAKE_API_VERSION.html>"]
pub const fn make_api_version(variant: u32, major: u32, minor: u32, patch: u32) -> u32 {
Expand All @@ -42,15 +42,15 @@ pub const fn api_version_variant(version: u32) -> u32 {
}
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_API_VERSION_MAJOR.html>"]
pub const fn api_version_major(version: u32) -> u32 {
((version) >> 22) & 0x7fu32
((version) >> 22) & 0x7f
}
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_API_VERSION_MINOR.html>"]
pub const fn api_version_minor(version: u32) -> u32 {
((version) >> 12) & 0x3ffu32
((version) >> 12) & 0x3ff
}
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_API_VERSION_PATCH.html>"]
pub const fn api_version_patch(version: u32) -> u32 {
(version) & 0xfffu32
(version) & 0xfff
}
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_API_VERSION_1_0.html>"]
pub const API_VERSION_1_0: u32 = make_api_version(0, 1, 0, 0);
Expand Down
6 changes: 5 additions & 1 deletion generator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
[package]
name = "generator"
version = "0.1.0"
authors = ["Maik Klein <[email protected]>"]
authors = [
"Maik Klein <[email protected]>",
"Benjamin Saunders <[email protected]>",
"Marijn Suijten <[email protected]>",
]
edition = "2021"
publish = false

Expand Down
84 changes: 51 additions & 33 deletions generator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,20 @@ impl quote::ToTokens for CType {
}

fn parse_ctype(i: &str) -> IResult<&str, CType> {
(alt((value(CType::U64, tag("ULL")), value(CType::U32, tag("U"))))).parse(i)
(alt((
value(CType::U64, tag("ULL")),
value(CType::U32, tag("U")),
// success(CType::U32), // Only for `0x1234` hexadecimals without type-suffix
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Was mainly "experimenting" with removing the Number and Hex variants from enum Constant because this code already handles both, but they'd end up weirdly formatted.

We have logic that doesn't append the type (ctype parsing does it by default) and interleaves the number with _.

EDIT: Though it wouldn't look out of order to just delete the 0x...u32 suffix.

)))
.parse(i)
}

fn parse_cexpr(i: &str) -> IResult<&str, (CType, String)> {
(alt((
map(parse_cfloat, |f| (CType::Float, format!("{f:.2}"))),
parse_hexadecimal_number,
parse_inverse_number,
parse_decimal_number,
parse_hexadecimal_number,
)))
.parse(i)
}
Expand Down Expand Up @@ -156,10 +161,7 @@ fn parse_hexadecimal_number(i: &str) -> IResult<&str, (CType, String)> {
(preceded(
alt((tag("0x"), tag("0X"))),
map(pair(hex_digit1, parse_ctype), |(num, typ)| {
(
typ,
format!("0x{}{}", num.to_ascii_lowercase(), typ.to_string()),
)
(typ, format!("0x{}", num.to_ascii_lowercase()))
}),
))
.parse(i)
Expand Down Expand Up @@ -398,7 +400,10 @@ pub enum Constant {
Number(i32),
Hex(String),
BitPos(u32),
CExpr(vkxml::CExpression),
/// A C expression, also used for floating point (`1000.0F`) and some integer representations (`(~0ULL)`).
///
/// Hexadecimals could use this path, but are currently handled separately.
CExpr(String),
Text(String),
Alias(Ident),
}
Expand All @@ -417,7 +422,7 @@ impl quote::ToTokens for Constant {
Self::Text(ref text) => text.to_tokens(tokens),
Self::CExpr(ref expr) => {
let (rem, (_, rexpr)) = parse_cexpr(expr).expect("Unable to parse cexpr");
assert!(rem.is_empty());
assert!(rem.is_empty(), "{rem}");
tokens.extend(rexpr.parse::<TokenStream>());
}
Self::BitPos(pos) => {
Expand All @@ -426,7 +431,7 @@ impl quote::ToTokens for Constant {
let bit_string = interleave_number('_', 4, &bit_string);
syn::LitInt::new(&format!("0b{bit_string}"), Span::call_site()).to_tokens(tokens);
}
Self::Alias(ref value) => tokens.extend(quote!(Self::#value)),
Self::Alias(ref value) => tokens.extend(quote!(#value)),
}
}
}
Expand Down Expand Up @@ -471,10 +476,10 @@ impl Constant {
Self::Number(_) | Self::Hex(_) => CType::USize,
Self::CExpr(expr) => {
let (rem, (ty, _)) = parse_cexpr(expr).expect("Unable to parse cexpr");
assert!(rem.is_empty());
assert!(rem.is_empty(), "{rem}");
ty
}
_ => unimplemented!(),
x => unimplemented!("{x:?}"),
}
}

Expand Down Expand Up @@ -528,19 +533,26 @@ impl Constant {
Some((Self::Number(value as i32), Some(extends.clone()), false))
}
EnumSpec::Value { value, extends } => {
let value = value
.strip_prefix("0x")
.map(|hex| Self::Hex(hex.to_owned()))
.or_else(|| value.parse::<i32>().ok().map(Self::Number))?;
let value = if let Ok(value) = value.parse::<i32>() {
Self::Number(value)
} else if let Some(hex) = value.strip_prefix("0x") {
Self::Hex(hex.to_owned())
} else {
Self::CExpr(value.to_owned())
};

Some((value, extends.clone(), false))
}
EnumSpec::Alias { alias, extends } => {
let base_type = extends.as_deref().or(enum_name)?;
let key = variant_ident(base_type, alias);
let base_type = extends.as_deref().or(enum_name);
let key = base_type
.map_or(format_ident!("{}", constant_name(alias)), |base_type| {
variant_ident(base_type, alias)
});
if key == "DISPATCH_BASE" {
None
} else {
Some((Self::Alias(key), Some(base_type.to_owned()), true))
Some((Self::Alias(key), base_type.map(str::to_owned), true))
}
}
_ => None,
Expand Down Expand Up @@ -1685,7 +1697,7 @@ pub fn bitflags_impl_block(
let notation = constant.doc_attribute();
let constant = constant.constant(enum_name);
let value = if let Constant::Alias(_) = &constant {
quote!(#constant)
quote!(Self::#constant)
} else {
quote!(Self(#constant))
};
Expand Down Expand Up @@ -2805,20 +2817,25 @@ pub fn constant_name(name: &str) -> &str {
}

pub fn generate_constant<'a>(
constant: &'a vkxml::Constant,
cache: &mut HashSet<&'a str>,
constant: &'a vk_parse::Enum,
global_const_cache: &mut HashMap<&'a str, CType>,
) -> TokenStream {
cache.insert(constant.name.as_str());
let c = Constant::from_constant(constant);
let (c, _, is_alias) = Constant::from_vk_parse_enum(constant, None, None).unwrap();
// This requires knowing the type of the alias, that is unavailable here. Besides
// backwards-compatibility, stabilization aliases serve no purpose.
let name = constant_name(&constant.name);
let ident = format_ident!("{}", name);
let notation = constant.doc_attribute();

let ty = if name == "TRUE" || name == "FALSE" {
let ty = if let Constant::Alias(a) = &c {
// TODO: Drop is_alias over Constant::Alias match
assert!(is_alias);
global_const_cache[a.to_string().as_str()]
} else if name == "TRUE" || name == "FALSE" {
CType::Bool32
} else {
c.ty()
};
global_const_cache.insert(name, ty);
quote! {
#notation
pub const #ident: #ty = #c;
Expand Down Expand Up @@ -3064,11 +3081,13 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {
.flat_map(|definitions| &definitions.elements)
.collect();

let constants: Vec<&vkxml::Constant> = spec
.elements
let constants: Vec<_> = spec2
.0
.iter()
.filter_map(get_variant!(vkxml::RegistryElement::Constants))
.flat_map(|constants| &constants.elements)
.filter_map(get_variant!(vk_parse::RegistryChild::Enums))
.filter(|enums| enums.kind.as_deref() == Some("constants"))
.flat_map(|enums| &enums.children)
.filter_map(get_variant!(vk_parse::EnumsChild::Enum))
.collect();

let features_children = spec2
Expand Down Expand Up @@ -3144,13 +3163,12 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {
acc
});

let mut constants_code: Vec<_> = constants
let mut global_const_cache = HashMap::new();
let constants_code: Vec<_> = constants
.iter()
.map(|constant| generate_constant(constant, &mut const_cache))
.map(|constant| generate_constant(constant, &mut global_const_cache))
.collect();

constants_code.push(quote! { pub const SHADER_UNUSED_NV : u32 = SHADER_UNUSED_KHR;});
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was mainly thinking about autogenerating this - but these are impossible without knowing the type through some additional bookeeping and they feel a bit useless if it isn't for vendor suffixes that might be necessary for extension stabilization going forward.


let union_types = definitions
.iter()
.filter_map(get_variant!(vkxml::DefinitionsElement::Union))
Expand Down