Skip to content

Commit ae06318

Browse files
committed
WIP: Handle enum-constants via vk-parse
1 parent 96becc8 commit ae06318

File tree

4 files changed

+68
-40
lines changed

4 files changed

+68
-40
lines changed

ash/src/vk/constants.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use super::definitions::*;
22
pub const MAX_PHYSICAL_DEVICE_NAME_SIZE: usize = 256;
33
pub const UUID_SIZE: usize = 16;
44
pub const LUID_SIZE: usize = 8;
5+
pub const LUID_SIZE_KHR: usize = LUID_SIZE;
56
pub const MAX_EXTENSION_NAME_SIZE: usize = 256;
67
pub const MAX_DESCRIPTION_SIZE: usize = 256;
78
pub const MAX_MEMORY_TYPES: usize = 32;
@@ -17,15 +18,20 @@ pub const TRUE: Bool32 = 1;
1718
pub const FALSE: Bool32 = 0;
1819
pub const QUEUE_FAMILY_IGNORED: u32 = !0;
1920
pub const QUEUE_FAMILY_EXTERNAL: u32 = !1;
21+
pub const QUEUE_FAMILY_EXTERNAL_KHR: u32 = QUEUE_FAMILY_EXTERNAL;
2022
pub const QUEUE_FAMILY_FOREIGN_EXT: u32 = !2;
2123
pub const SUBPASS_EXTERNAL: u32 = !0;
2224
pub const MAX_DEVICE_GROUP_SIZE: usize = 32;
25+
pub const MAX_DEVICE_GROUP_SIZE_KHR: usize = MAX_DEVICE_GROUP_SIZE;
2326
pub const MAX_DRIVER_NAME_SIZE: usize = 256;
27+
pub const MAX_DRIVER_NAME_SIZE_KHR: usize = MAX_DRIVER_NAME_SIZE;
2428
pub const MAX_DRIVER_INFO_SIZE: usize = 256;
29+
pub const MAX_DRIVER_INFO_SIZE_KHR: usize = MAX_DRIVER_INFO_SIZE;
2530
pub const SHADER_UNUSED_KHR: u32 = !0;
31+
pub const SHADER_UNUSED_NV: u32 = SHADER_UNUSED_KHR;
2632
pub const MAX_GLOBAL_PRIORITY_SIZE_KHR: usize = 16;
33+
pub const MAX_GLOBAL_PRIORITY_SIZE_EXT: usize = MAX_GLOBAL_PRIORITY_SIZE_KHR;
2734
pub const MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT: usize = 32;
2835
pub const MAX_PIPELINE_BINARY_KEY_SIZE_KHR: usize = 32;
2936
pub const MAX_VIDEO_AV1_REFERENCES_PER_FRAME_KHR: usize = 7;
3037
pub const SHADER_INDEX_UNUSED_AMDX: u32 = !0;
31-
pub const SHADER_UNUSED_NV: u32 = SHADER_UNUSED_KHR;

ash/src/vk/definitions.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ pub const fn version_major(version: u32) -> u32 {
2525
#[deprecated = "This define is deprecated. VK_API_VERSION_MINOR should be used instead."]
2626
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_VERSION_MINOR.html>"]
2727
pub const fn version_minor(version: u32) -> u32 {
28-
((version) >> 12) & 0x3ffu32
28+
((version) >> 12) & 0x3ff
2929
}
3030
#[deprecated = "This define is deprecated. VK_API_VERSION_PATCH should be used instead."]
3131
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_VERSION_PATCH.html>"]
3232
pub const fn version_patch(version: u32) -> u32 {
33-
(version) & 0xfffu32
33+
(version) & 0xfff
3434
}
3535
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_MAKE_API_VERSION.html>"]
3636
pub const fn make_api_version(variant: u32, major: u32, minor: u32, patch: u32) -> u32 {
@@ -42,15 +42,15 @@ pub const fn api_version_variant(version: u32) -> u32 {
4242
}
4343
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_API_VERSION_MAJOR.html>"]
4444
pub const fn api_version_major(version: u32) -> u32 {
45-
((version) >> 22) & 0x7fu32
45+
((version) >> 22) & 0x7f
4646
}
4747
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_API_VERSION_MINOR.html>"]
4848
pub const fn api_version_minor(version: u32) -> u32 {
49-
((version) >> 12) & 0x3ffu32
49+
((version) >> 12) & 0x3ff
5050
}
5151
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_API_VERSION_PATCH.html>"]
5252
pub const fn api_version_patch(version: u32) -> u32 {
53-
(version) & 0xfffu32
53+
(version) & 0xfff
5454
}
5555
#[doc = "<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_API_VERSION_1_0.html>"]
5656
pub const API_VERSION_1_0: u32 = make_api_version(0, 1, 0, 0);

generator/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
[package]
22
name = "generator"
33
version = "0.1.0"
4-
authors = ["Maik Klein <[email protected]>"]
4+
authors = [
5+
"Maik Klein <[email protected]>",
6+
"Benjamin Saunders <[email protected]>",
7+
"Marijn Suijten <[email protected]>",
8+
]
59
edition = "2021"
610
publish = false
711

generator/src/lib.rs

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,20 @@ impl quote::ToTokens for CType {
8484
}
8585

8686
fn parse_ctype(i: &str) -> IResult<&str, CType> {
87-
(alt((value(CType::U64, tag("ULL")), value(CType::U32, tag("U"))))).parse(i)
87+
(alt((
88+
value(CType::U64, tag("ULL")),
89+
value(CType::U32, tag("U")),
90+
// success(CType::U32), // Only for `0x1234` hexadecimals without type-suffix
91+
)))
92+
.parse(i)
8893
}
8994

9095
fn parse_cexpr(i: &str) -> IResult<&str, (CType, String)> {
9196
(alt((
9297
map(parse_cfloat, |f| (CType::Float, format!("{f:.2}"))),
98+
parse_hexadecimal_number,
9399
parse_inverse_number,
94100
parse_decimal_number,
95-
parse_hexadecimal_number,
96101
)))
97102
.parse(i)
98103
}
@@ -156,10 +161,7 @@ fn parse_hexadecimal_number(i: &str) -> IResult<&str, (CType, String)> {
156161
(preceded(
157162
alt((tag("0x"), tag("0X"))),
158163
map(pair(hex_digit1, parse_ctype), |(num, typ)| {
159-
(
160-
typ,
161-
format!("0x{}{}", num.to_ascii_lowercase(), typ.to_string()),
162-
)
164+
(typ, format!("0x{}", num.to_ascii_lowercase()))
163165
}),
164166
))
165167
.parse(i)
@@ -398,7 +400,10 @@ pub enum Constant {
398400
Number(i32),
399401
Hex(String),
400402
BitPos(u32),
401-
CExpr(vkxml::CExpression),
403+
/// A C expression, also used for floating point (`1000.0F`) and some integer representations (`(~0ULL)`).
404+
///
405+
/// Hexadecimals could use this path, but are currently handled separately.
406+
CExpr(String),
402407
Text(String),
403408
Alias(Ident),
404409
}
@@ -417,7 +422,7 @@ impl quote::ToTokens for Constant {
417422
Self::Text(ref text) => text.to_tokens(tokens),
418423
Self::CExpr(ref expr) => {
419424
let (rem, (_, rexpr)) = parse_cexpr(expr).expect("Unable to parse cexpr");
420-
assert!(rem.is_empty());
425+
assert!(rem.is_empty(), "{rem}");
421426
tokens.extend(rexpr.parse::<TokenStream>());
422427
}
423428
Self::BitPos(pos) => {
@@ -426,7 +431,7 @@ impl quote::ToTokens for Constant {
426431
let bit_string = interleave_number('_', 4, &bit_string);
427432
syn::LitInt::new(&format!("0b{bit_string}"), Span::call_site()).to_tokens(tokens);
428433
}
429-
Self::Alias(ref value) => tokens.extend(quote!(Self::#value)),
434+
Self::Alias(ref value) => tokens.extend(quote!(#value)),
430435
}
431436
}
432437
}
@@ -471,10 +476,10 @@ impl Constant {
471476
Self::Number(_) | Self::Hex(_) => CType::USize,
472477
Self::CExpr(expr) => {
473478
let (rem, (ty, _)) = parse_cexpr(expr).expect("Unable to parse cexpr");
474-
assert!(rem.is_empty());
479+
assert!(rem.is_empty(), "{rem}");
475480
ty
476481
}
477-
_ => unimplemented!(),
482+
x => unimplemented!("{x:?}"),
478483
}
479484
}
480485

@@ -528,19 +533,26 @@ impl Constant {
528533
Some((Self::Number(value as i32), Some(extends.clone()), false))
529534
}
530535
EnumSpec::Value { value, extends } => {
531-
let value = value
532-
.strip_prefix("0x")
533-
.map(|hex| Self::Hex(hex.to_owned()))
534-
.or_else(|| value.parse::<i32>().ok().map(Self::Number))?;
536+
let value = if let Ok(value) = value.parse::<i32>() {
537+
Self::Number(value)
538+
} else if let Some(hex) = value.strip_prefix("0x") {
539+
Self::Hex(hex.to_owned())
540+
} else {
541+
Self::CExpr(value.to_owned())
542+
};
543+
535544
Some((value, extends.clone(), false))
536545
}
537546
EnumSpec::Alias { alias, extends } => {
538-
let base_type = extends.as_deref().or(enum_name)?;
539-
let key = variant_ident(base_type, alias);
547+
let base_type = extends.as_deref().or(enum_name);
548+
let key = base_type
549+
.map_or(format_ident!("{}", constant_name(alias)), |base_type| {
550+
variant_ident(base_type, alias)
551+
});
540552
if key == "DISPATCH_BASE" {
541553
None
542554
} else {
543-
Some((Self::Alias(key), Some(base_type.to_owned()), true))
555+
Some((Self::Alias(key), base_type.map(str::to_owned), true))
544556
}
545557
}
546558
_ => None,
@@ -1685,7 +1697,7 @@ pub fn bitflags_impl_block(
16851697
let notation = constant.doc_attribute();
16861698
let constant = constant.constant(enum_name);
16871699
let value = if let Constant::Alias(_) = &constant {
1688-
quote!(#constant)
1700+
quote!(Self::#constant)
16891701
} else {
16901702
quote!(Self(#constant))
16911703
};
@@ -2805,20 +2817,25 @@ pub fn constant_name(name: &str) -> &str {
28052817
}
28062818

28072819
pub fn generate_constant<'a>(
2808-
constant: &'a vkxml::Constant,
2809-
cache: &mut HashSet<&'a str>,
2820+
constant: &'a vk_parse::Enum,
2821+
global_const_cache: &mut HashMap<&'a str, CType>,
28102822
) -> TokenStream {
2811-
cache.insert(constant.name.as_str());
2812-
let c = Constant::from_constant(constant);
2823+
let (c, _, is_alias) = Constant::from_vk_parse_enum(constant, None, None).unwrap();
2824+
// This requires knowing the type of the alias, that is unavailable here. Besides
2825+
// backwards-compatibility, stabilization aliases serve no purpose.
28132826
let name = constant_name(&constant.name);
28142827
let ident = format_ident!("{}", name);
28152828
let notation = constant.doc_attribute();
2816-
2817-
let ty = if name == "TRUE" || name == "FALSE" {
2829+
let ty = if let Constant::Alias(a) = &c {
2830+
// TODO: Drop is_alias over Constant::Alias match
2831+
assert!(is_alias);
2832+
global_const_cache[a.to_string().as_str()]
2833+
} else if name == "TRUE" || name == "FALSE" {
28182834
CType::Bool32
28192835
} else {
28202836
c.ty()
28212837
};
2838+
global_const_cache.insert(name, ty);
28222839
quote! {
28232840
#notation
28242841
pub const #ident: #ty = #c;
@@ -3064,11 +3081,13 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {
30643081
.flat_map(|definitions| &definitions.elements)
30653082
.collect();
30663083

3067-
let constants: Vec<&vkxml::Constant> = spec
3068-
.elements
3084+
let constants: Vec<_> = spec2
3085+
.0
30693086
.iter()
3070-
.filter_map(get_variant!(vkxml::RegistryElement::Constants))
3071-
.flat_map(|constants| &constants.elements)
3087+
.filter_map(get_variant!(vk_parse::RegistryChild::Enums))
3088+
.filter(|enums| enums.kind.as_deref() == Some("constants"))
3089+
.flat_map(|enums| &enums.children)
3090+
.filter_map(get_variant!(vk_parse::EnumsChild::Enum))
30723091
.collect();
30733092

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

3147-
let mut constants_code: Vec<_> = constants
3166+
let mut global_const_cache = HashMap::new();
3167+
let constants_code: Vec<_> = constants
31483168
.iter()
3149-
.map(|constant| generate_constant(constant, &mut const_cache))
3169+
.map(|constant| generate_constant(constant, &mut global_const_cache))
31503170
.collect();
31513171

3152-
constants_code.push(quote! { pub const SHADER_UNUSED_NV : u32 = SHADER_UNUSED_KHR;});
3153-
31543172
let union_types = definitions
31553173
.iter()
31563174
.filter_map(get_variant!(vkxml::DefinitionsElement::Union))

0 commit comments

Comments
 (0)