Fix incorrect generation of commands with aliases (#279)
* Fix incorrect generation of commands with aliases * Use alias name instead of the actual cmd name
This commit is contained in:
parent
c32f0dd739
commit
af6acb93e5
3 changed files with 2203 additions and 304 deletions
2402
ash/src/vk.rs
2402
ash/src/vk.rs
File diff suppressed because it is too large
Load diff
|
@ -10,7 +10,7 @@ vkxml = "0.3"
|
||||||
nom = "4.0"
|
nom = "4.0"
|
||||||
heck = "0.3"
|
heck = "0.3"
|
||||||
proc-macro2 = "0.2"
|
proc-macro2 = "0.2"
|
||||||
itertools = "0.7"
|
itertools = "0.9"
|
||||||
|
|
||||||
[dependencies.quote]
|
[dependencies.quote]
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
|
|
@ -723,10 +723,26 @@ pub type CommandMap<'a> = HashMap<vkxml::Identifier, &'a vkxml::Command>;
|
||||||
fn generate_function_pointers<'a>(
|
fn generate_function_pointers<'a>(
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
commands: &[&'a vkxml::Command],
|
commands: &[&'a vkxml::Command],
|
||||||
|
aliases: &HashMap<String, String, impl BuildHasher>,
|
||||||
fn_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
fn_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
||||||
) -> quote::Tokens {
|
) -> quote::Tokens {
|
||||||
// We filter commands so that we don't have duplicates
|
// Commands can have duplicates inside them because they are declared per features. But we only
|
||||||
let commands: Vec<_> = commands
|
// really want to generate one function pointer.
|
||||||
|
let commands = {
|
||||||
|
let mut cache = HashSet::new();
|
||||||
|
let mut cmd_vec: Vec<&vkxml::Command> = Vec::new();
|
||||||
|
for cmd in commands {
|
||||||
|
let name = cmd.name.as_str();
|
||||||
|
if !cache.contains(name) {
|
||||||
|
cmd_vec.push(cmd);
|
||||||
|
cache.insert(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cmd_vec
|
||||||
|
};
|
||||||
|
// PFN function pointers are global and can not have duplicates. This can happen because there
|
||||||
|
// are aliases to commands
|
||||||
|
let commands_pfn: Vec<_> = commands
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|cmd| {
|
.filter(|cmd| {
|
||||||
let ident = cmd.name.as_str();
|
let ident = cmd.name.as_str();
|
||||||
|
@ -738,14 +754,29 @@ fn generate_function_pointers<'a>(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let names: Vec<_> = commands.iter().map(|cmd| cmd.command_ident()).collect();
|
|
||||||
|
let function_name_raw = |name: &str| -> String {
|
||||||
|
if let Some(alias_name) = aliases.get(name) {
|
||||||
|
alias_name.to_string()
|
||||||
|
} else {
|
||||||
|
name.to_string()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let function_name = |name: &str| -> Ident {
|
||||||
|
let fn_name = function_name_raw(&name);
|
||||||
|
Ident::from(fn_name[2..].to_snake_case().as_str())
|
||||||
|
};
|
||||||
|
let names: Vec<_> = commands
|
||||||
|
.iter()
|
||||||
|
.map(|cmd| function_name(&cmd.name))
|
||||||
|
.collect();
|
||||||
let names_ref = &names;
|
let names_ref = &names;
|
||||||
let names_ref1 = &names;
|
let names_ref1 = &names;
|
||||||
let names_ref2 = &names;
|
let names_ref2 = &names;
|
||||||
let names_ref3 = &names;
|
let names_ref3 = &names;
|
||||||
let raw_names: Vec<_> = commands
|
let raw_names: Vec<_> = commands
|
||||||
.iter()
|
.iter()
|
||||||
.map(|cmd| Ident::from(cmd.name.as_str()))
|
.map(|cmd| Ident::from(function_name_raw(cmd.name.as_str()).as_str()))
|
||||||
.collect();
|
.collect();
|
||||||
let raw_names_ref = &raw_names;
|
let raw_names_ref = &raw_names;
|
||||||
let names_left = &names;
|
let names_left = &names;
|
||||||
|
@ -809,7 +840,7 @@ fn generate_function_pointers<'a>(
|
||||||
.collect();
|
.collect();
|
||||||
let return_types_ref = &return_types;
|
let return_types_ref = &return_types;
|
||||||
|
|
||||||
let pfn_names: Vec<_> = commands
|
let pfn_names: Vec<_> = commands_pfn
|
||||||
.iter()
|
.iter()
|
||||||
.map(|cmd| Ident::from(format!("PFN_{}", cmd.name.as_str())))
|
.map(|cmd| Ident::from(format!("PFN_{}", cmd.name.as_str())))
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -985,24 +1016,38 @@ pub fn generate_extension_commands<'a>(
|
||||||
extension_name: &str,
|
extension_name: &str,
|
||||||
items: &[vk_parse::ExtensionChild],
|
items: &[vk_parse::ExtensionChild],
|
||||||
cmd_map: &CommandMap<'a>,
|
cmd_map: &CommandMap<'a>,
|
||||||
|
cmd_aliases: &HashMap<String, String, impl BuildHasher>,
|
||||||
fn_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
fn_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
let commands = items
|
let mut commands = Vec::new();
|
||||||
|
let mut aliases = HashMap::new();
|
||||||
|
items
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|ext_item| match ext_item {
|
.filter_map(|ext_item| match ext_item {
|
||||||
vk_parse::ExtensionChild::Require { items, .. } => {
|
vk_parse::ExtensionChild::Require { items, .. } => {
|
||||||
Some(items.iter().filter_map(|item| match item {
|
Some(items.iter().filter_map(|item| match item {
|
||||||
vk_parse::InterfaceItem::Command { ref name, .. } => cmd_map.get(name).copied(),
|
vk_parse::InterfaceItem::Command { ref name, .. } => Some(name),
|
||||||
_ => None,
|
_ => None,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.flat_map(|iter| iter)
|
.flatten()
|
||||||
.collect_vec();
|
.for_each(|name| {
|
||||||
|
if let Some(cmd) = cmd_map.get(name).copied() {
|
||||||
|
commands.push(cmd);
|
||||||
|
} else if let Some(cmd) = cmd_aliases
|
||||||
|
.get(name)
|
||||||
|
.and_then(|alias_name| cmd_map.get(alias_name).copied())
|
||||||
|
{
|
||||||
|
aliases.insert(cmd.name.clone(), name.to_string());
|
||||||
|
commands.push(cmd);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let name = format!("{}Fn", extension_name.to_camel_case());
|
let name = format!("{}Fn", extension_name.to_camel_case());
|
||||||
let ident = Ident::from(&name[2..]);
|
let ident = Ident::from(&name[2..]);
|
||||||
let fp = generate_function_pointers(ident, &commands, fn_cache);
|
let fp = generate_function_pointers(ident, &commands, &aliases, fn_cache);
|
||||||
let byte_name = format!("{}\0", extension_name);
|
let byte_name = format!("{}\0", extension_name);
|
||||||
|
|
||||||
let byte_name_ident =
|
let byte_name_ident =
|
||||||
|
@ -1024,6 +1069,7 @@ pub fn generate_extension<'a>(
|
||||||
cmd_map: &CommandMap<'a>,
|
cmd_map: &CommandMap<'a>,
|
||||||
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
const_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
||||||
const_values: &mut BTreeMap<Ident, Vec<Ident>>,
|
const_values: &mut BTreeMap<Ident, Vec<Ident>>,
|
||||||
|
cmd_aliases: &HashMap<String, String, impl BuildHasher>,
|
||||||
fn_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
fn_cache: &mut HashSet<&'a str, impl BuildHasher>,
|
||||||
) -> Option<quote::Tokens> {
|
) -> Option<quote::Tokens> {
|
||||||
// Okay this is a little bit odd. We need to generate all extensions, even disabled ones,
|
// Okay this is a little bit odd. We need to generate all extensions, even disabled ones,
|
||||||
|
@ -1039,7 +1085,13 @@ pub fn generate_extension<'a>(
|
||||||
const_cache,
|
const_cache,
|
||||||
const_values,
|
const_values,
|
||||||
);
|
);
|
||||||
let fp = generate_extension_commands(&extension.name, &extension.children, cmd_map, fn_cache);
|
let fp = generate_extension_commands(
|
||||||
|
&extension.name,
|
||||||
|
&extension.children,
|
||||||
|
cmd_map,
|
||||||
|
cmd_aliases,
|
||||||
|
fn_cache,
|
||||||
|
);
|
||||||
let q = quote! {
|
let q = quote! {
|
||||||
#fp
|
#fp
|
||||||
#extension_tokens
|
#extension_tokens
|
||||||
|
@ -1972,23 +2024,31 @@ pub fn generate_feature<'a>(
|
||||||
);
|
);
|
||||||
let version = feature.version_string();
|
let version = feature.version_string();
|
||||||
let static_fn = if feature.is_version(1, 0) {
|
let static_fn = if feature.is_version(1, 0) {
|
||||||
generate_function_pointers(Ident::from("StaticFn"), &static_commands, fn_cache)
|
generate_function_pointers(
|
||||||
|
Ident::from("StaticFn"),
|
||||||
|
&static_commands,
|
||||||
|
&HashMap::new(),
|
||||||
|
fn_cache,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
quote! {}
|
quote! {}
|
||||||
};
|
};
|
||||||
let entry = generate_function_pointers(
|
let entry = generate_function_pointers(
|
||||||
Ident::from(format!("EntryFnV{}", version).as_str()),
|
Ident::from(format!("EntryFnV{}", version).as_str()),
|
||||||
&entry_commands,
|
&entry_commands,
|
||||||
|
&HashMap::new(),
|
||||||
fn_cache,
|
fn_cache,
|
||||||
);
|
);
|
||||||
let instance = generate_function_pointers(
|
let instance = generate_function_pointers(
|
||||||
Ident::from(format!("InstanceFnV{}", version).as_str()),
|
Ident::from(format!("InstanceFnV{}", version).as_str()),
|
||||||
&instance_commands,
|
&instance_commands,
|
||||||
|
&HashMap::new(),
|
||||||
fn_cache,
|
fn_cache,
|
||||||
);
|
);
|
||||||
let device = generate_function_pointers(
|
let device = generate_function_pointers(
|
||||||
Ident::from(format!("DeviceFnV{}", version).as_str()),
|
Ident::from(format!("DeviceFnV{}", version).as_str()),
|
||||||
&device_commands,
|
&device_commands,
|
||||||
|
&HashMap::new(),
|
||||||
fn_cache,
|
fn_cache,
|
||||||
);
|
);
|
||||||
quote! {
|
quote! {
|
||||||
|
@ -2154,6 +2214,24 @@ pub fn write_source_code(path: &Path) {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let spec = vk_parse::parse_file_as_vkxml(path);
|
let spec = vk_parse::parse_file_as_vkxml(path);
|
||||||
|
let cmd_aliases: HashMap<String, String> = spec2
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
.filter_map(|item| match item {
|
||||||
|
vk_parse::RegistryChild::Commands(cmds) => {
|
||||||
|
let cmd_tuple_iter = cmds.children.iter().filter_map(|cmd| match cmd {
|
||||||
|
vk_parse::Command::Alias { name, alias } => {
|
||||||
|
Some((name.to_string(), alias.to_string()))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
});
|
||||||
|
Some(cmd_tuple_iter)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.collect();
|
||||||
|
|
||||||
let commands: HashMap<vkxml::Identifier, &vkxml::Command> = spec
|
let commands: HashMap<vkxml::Identifier, &vkxml::Command> = spec
|
||||||
.elements
|
.elements
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -2238,6 +2316,7 @@ pub fn write_source_code(path: &Path) {
|
||||||
&commands,
|
&commands,
|
||||||
&mut const_cache,
|
&mut const_cache,
|
||||||
&mut const_values,
|
&mut const_values,
|
||||||
|
&cmd_aliases,
|
||||||
&mut fn_cache,
|
&mut fn_cache,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue