Skip to content

Commit b5dda09

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

File tree

3 files changed

+68
-44
lines changed

3 files changed

+68
-44
lines changed

ash/src/vk/constants.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,3 @@ pub const MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT: usize = 32;
2828
pub const MAX_PIPELINE_BINARY_KEY_SIZE_KHR: usize = 32;
2929
pub const MAX_VIDEO_AV1_REFERENCES_PER_FRAME_KHR: usize = 7;
3030
pub const SHADER_INDEX_UNUSED_AMDX: u32 = !0;
31-
pub const SHADER_UNUSED_NV: u32 = SHADER_UNUSED_KHR;

generator/Cargo.toml

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

812
[dependencies]

generator/src/lib.rs

Lines changed: 62 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use heck::{ToShoutySnakeCase, ToSnakeCase, ToUpperCamelCase};
1212
use itertools::Itertools;
1313
use nom::{
14+
IResult, Parser,
1415
branch::alt,
1516
bytes::complete::{tag, take_until, take_while1},
1617
character::complete::{
@@ -19,7 +20,6 @@ use nom::{
1920
combinator::{map, map_res, opt, value},
2021
multi::{many1, separated_list1},
2122
sequence::{delimited, pair, preceded, separated_pair, terminated},
22-
IResult, Parser,
2323
};
2424
use proc_macro2::{Delimiter, Group, Literal, Span, TokenStream, TokenTree};
2525
use quote::*;
@@ -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
}
@@ -398,7 +403,10 @@ pub enum Constant {
398403
Number(i32),
399404
Hex(String),
400405
BitPos(u32),
401-
CExpr(vkxml::CExpression),
406+
/// A C expression, also used for floating point (`1000.0F`) and some integer representations (`(~0ULL)`).
407+
///
408+
/// Hexadecimals could use this path, but are currently handled separately.
409+
CExpr(String),
402410
Text(String),
403411
Alias(Ident),
404412
}
@@ -417,7 +425,7 @@ impl quote::ToTokens for Constant {
417425
Self::Text(ref text) => text.to_tokens(tokens),
418426
Self::CExpr(ref expr) => {
419427
let (rem, (_, rexpr)) = parse_cexpr(expr).expect("Unable to parse cexpr");
420-
assert!(rem.is_empty());
428+
assert!(rem.is_empty(), "{rem}");
421429
tokens.extend(rexpr.parse::<TokenStream>());
422430
}
423431
Self::BitPos(pos) => {
@@ -471,10 +479,10 @@ impl Constant {
471479
Self::Number(_) | Self::Hex(_) => CType::USize,
472480
Self::CExpr(expr) => {
473481
let (rem, (ty, _)) = parse_cexpr(expr).expect("Unable to parse cexpr");
474-
assert!(rem.is_empty());
482+
assert!(rem.is_empty(), "{rem}");
475483
ty
476484
}
477-
_ => unimplemented!(),
485+
x => unimplemented!("{x:?}"),
478486
}
479487
}
480488

@@ -528,19 +536,25 @@ impl Constant {
528536
Some((Self::Number(value as i32), Some(extends.clone()), false))
529537
}
530538
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))?;
539+
let value = if let Ok(value) = value.parse::<i32>() {
540+
Self::Number(value)
541+
} else if let Some(hex) = value.strip_prefix("0x") {
542+
Self::Hex(hex.to_owned())
543+
} else {
544+
Self::CExpr(value.to_owned())
545+
};
546+
535547
Some((value, extends.clone(), false))
536548
}
537549
EnumSpec::Alias { alias, extends } => {
538-
let base_type = extends.as_deref().or(enum_name)?;
539-
let key = variant_ident(base_type, alias);
550+
let base_type = extends.as_deref().or(enum_name);
551+
let key = base_type.map_or(format_ident!("{}", alias), |base_type| {
552+
variant_ident(base_type, alias)
553+
});
540554
if key == "DISPATCH_BASE" {
541555
None
542556
} else {
543-
Some((Self::Alias(key), Some(base_type.to_owned()), true))
557+
Some((Self::Alias(key), base_type.map(str::to_owned), true))
544558
}
545559
}
546560
_ => None,
@@ -2804,12 +2818,13 @@ pub fn constant_name(name: &str) -> &str {
28042818
name.strip_prefix("VK_").unwrap_or(name)
28052819
}
28062820

2807-
pub fn generate_constant<'a>(
2808-
constant: &'a vkxml::Constant,
2809-
cache: &mut HashSet<&'a str>,
2810-
) -> TokenStream {
2811-
cache.insert(constant.name.as_str());
2812-
let c = Constant::from_constant(constant);
2821+
pub fn generate_constant(constant: &vk_parse::Enum) -> TokenStream {
2822+
let (c, _, is_alias) = Constant::from_vk_parse_enum(constant, None, None).unwrap();
2823+
// This requires knowing the type of the alias, that is unavailable here. Besides
2824+
// backwards-compatibility, stabilization aliases serve no purpose.
2825+
if is_alias {
2826+
return quote!();
2827+
}
28132828
let name = constant_name(&constant.name);
28142829
let ident = format_ident!("{}", name);
28152830
let notation = constant.doc_attribute();
@@ -3064,11 +3079,13 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {
30643079
.flat_map(|definitions| &definitions.elements)
30653080
.collect();
30663081

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

30743091
let features_children = spec2
@@ -3080,23 +3097,29 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {
30803097

30813098
let extension_children = extensions.iter().flat_map(|extension| &extension.children);
30823099

3083-
let (required_types, required_commands) = features_children
3100+
let (required_types, required_commands, required_enums) = features_children
30843101
.chain(extension_children)
30853102
.filter_map(get_variant!(vk_parse::FeatureChild::Require { api, items }))
30863103
.filter(|(api, _items)| matches!(api.as_deref(), None | Some(DESIRED_API)))
30873104
.flat_map(|(_api, items)| items)
3088-
.fold((HashSet::new(), HashSet::new()), |mut acc, elem| {
3089-
match elem {
3090-
vk_parse::InterfaceItem::Type { name, .. } => {
3091-
acc.0.insert(name.as_str());
3092-
}
3093-
vk_parse::InterfaceItem::Command { name, .. } => {
3094-
acc.1.insert(name.as_str());
3095-
}
3096-
_ => {}
3097-
};
3098-
acc
3099-
});
3105+
.fold(
3106+
(HashSet::new(), HashSet::new(), HashSet::new()),
3107+
|mut acc, elem| {
3108+
match elem {
3109+
vk_parse::InterfaceItem::Type { name, .. } => {
3110+
acc.0.insert(name.as_str());
3111+
}
3112+
vk_parse::InterfaceItem::Command { name, .. } => {
3113+
acc.1.insert(name.as_str());
3114+
}
3115+
vk_parse::InterfaceItem::Enum(vk_parse::Enum { name, spec, .. }) => {
3116+
acc.2.insert(name.as_str());
3117+
}
3118+
_ => {}
3119+
};
3120+
acc
3121+
},
3122+
);
31003123

31013124
let commands: CommandMap<'_> = spec2
31023125
.0
@@ -3144,13 +3167,11 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {
31443167
acc
31453168
});
31463169

3147-
let mut constants_code: Vec<_> = constants
3170+
let constants_code: Vec<_> = constants
31483171
.iter()
3149-
.map(|constant| generate_constant(constant, &mut const_cache))
3172+
.map(|constant| generate_constant(constant))
31503173
.collect();
31513174

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

0 commit comments

Comments
 (0)