Generate function pointer raw type definitions
This commit is contained in:
parent
424ebbad20
commit
cd20cc4e37
1 changed files with 184 additions and 94 deletions
|
@ -1,11 +1,11 @@
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
extern crate heck;
|
||||||
|
extern crate itertools;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate nom;
|
extern crate nom;
|
||||||
extern crate heck;
|
|
||||||
extern crate proc_macro2;
|
extern crate proc_macro2;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate quote;
|
extern crate quote;
|
||||||
extern crate itertools;
|
|
||||||
extern crate syn;
|
extern crate syn;
|
||||||
pub extern crate vk_parse;
|
pub extern crate vk_parse;
|
||||||
pub extern crate vkxml;
|
pub extern crate vkxml;
|
||||||
|
@ -531,13 +531,13 @@ impl CommandExt for vkxml::Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn function_type(&self) -> FunctionType {
|
fn function_type(&self) -> FunctionType {
|
||||||
let is_first_param_device = self
|
let is_first_param_device = self.param
|
||||||
.param
|
|
||||||
.get(0)
|
.get(0)
|
||||||
.map(|field| match field.basetype.as_str() {
|
.map(|field| match field.basetype.as_str() {
|
||||||
"VkDevice" | "VkCommandBuffer" | "VkQueue" => true,
|
"VkDevice" | "VkCommandBuffer" | "VkQueue" => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}).unwrap_or(false);
|
})
|
||||||
|
.unwrap_or(false);
|
||||||
match self.name.as_str() {
|
match self.name.as_str() {
|
||||||
"vkGetInstanceProcAddr" => FunctionType::Static,
|
"vkGetInstanceProcAddr" => FunctionType::Static,
|
||||||
"vkCreateInstance"
|
"vkCreateInstance"
|
||||||
|
@ -643,8 +643,7 @@ impl FieldExt for vkxml::Field {
|
||||||
|
|
||||||
fn type_tokens(&self) -> Tokens {
|
fn type_tokens(&self) -> Tokens {
|
||||||
let ty = name_to_tokens(&self.basetype);
|
let ty = name_to_tokens(&self.basetype);
|
||||||
let pointer = self
|
let pointer = self.reference
|
||||||
.reference
|
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|r| r.to_tokens(self.is_const))
|
.map(|r| r.to_tokens(self.is_const))
|
||||||
.unwrap_or(quote!{});
|
.unwrap_or(quote!{});
|
||||||
|
@ -653,8 +652,7 @@ impl FieldExt for vkxml::Field {
|
||||||
};
|
};
|
||||||
let array = self.array.as_ref().and_then(|arraytype| match arraytype {
|
let array = self.array.as_ref().and_then(|arraytype| match arraytype {
|
||||||
vkxml::ArrayType::Static => {
|
vkxml::ArrayType::Static => {
|
||||||
let size = self
|
let size = self.size
|
||||||
.size
|
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.or_else(|| self.size_enumref.as_ref())
|
.or_else(|| self.size_enumref.as_ref())
|
||||||
.expect("Should have size");
|
.expect("Should have size");
|
||||||
|
@ -674,7 +672,11 @@ impl FieldExt for vkxml::Field {
|
||||||
|
|
||||||
pub type CommandMap<'a> = HashMap<vkxml::Identifier, &'a vkxml::Command>;
|
pub type CommandMap<'a> = HashMap<vkxml::Identifier, &'a vkxml::Command>;
|
||||||
|
|
||||||
fn generate_function_pointers(ident: Ident, commands: &[&vkxml::Command]) -> quote::Tokens {
|
fn generate_function_pointers<'a>(
|
||||||
|
ident: Ident,
|
||||||
|
commands: &[&'a vkxml::Command],
|
||||||
|
fn_cache: &mut HashSet<&'a str>,
|
||||||
|
) -> quote::Tokens {
|
||||||
let names: Vec<_> = commands.iter().map(|cmd| cmd.command_ident()).collect();
|
let names: Vec<_> = commands.iter().map(|cmd| cmd.command_ident()).collect();
|
||||||
let names_ref = &names;
|
let names_ref = &names;
|
||||||
let names_ref1 = &names;
|
let names_ref1 = &names;
|
||||||
|
@ -688,19 +690,33 @@ fn generate_function_pointers(ident: Ident, commands: &[&vkxml::Command]) -> quo
|
||||||
let names_left = &names;
|
let names_left = &names;
|
||||||
let names_right = &names;
|
let names_right = &names;
|
||||||
|
|
||||||
|
let pfn_commands: Vec<_> = commands
|
||||||
|
.iter()
|
||||||
|
.filter(|cmd| {
|
||||||
|
let ident = cmd.name.as_str();
|
||||||
|
if !fn_cache.contains(ident) {
|
||||||
|
fn_cache.insert(ident);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let params: Vec<Vec<(Ident, Tokens)>> = commands
|
let params: Vec<Vec<(Ident, Tokens)>> = commands
|
||||||
.iter()
|
.iter()
|
||||||
.map(|cmd| {
|
.map(|cmd| {
|
||||||
let params: Vec<_> = cmd
|
let params: Vec<_> = cmd.param
|
||||||
.param
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
let name = field.param_ident();
|
let name = field.param_ident();
|
||||||
let ty = field.type_tokens();
|
let ty = field.type_tokens();
|
||||||
(name, ty)
|
(name, ty)
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
params
|
params
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let params_names: Vec<Vec<_>> = params
|
let params_names: Vec<Vec<_>> = params
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -709,7 +725,8 @@ fn generate_function_pointers(ident: Ident, commands: &[&vkxml::Command]) -> quo
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(param_name, _)| param_name)
|
.map(|&(param_name, _)| param_name)
|
||||||
.collect()
|
.collect()
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
let param_names_ref = ¶ms_names;
|
let param_names_ref = ¶ms_names;
|
||||||
let expanded_params: Vec<_> = params
|
let expanded_params: Vec<_> = params
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -720,7 +737,8 @@ fn generate_function_pointers(ident: Ident, commands: &[&vkxml::Command]) -> quo
|
||||||
quote!{
|
quote!{
|
||||||
#(#inner_params_iter,)*
|
#(#inner_params_iter,)*
|
||||||
}
|
}
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
let expanded_params_unused: Vec<_> = params
|
let expanded_params_unused: Vec<_> = params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|inner_params| {
|
.map(|inner_params| {
|
||||||
|
@ -731,7 +749,8 @@ fn generate_function_pointers(ident: Ident, commands: &[&vkxml::Command]) -> quo
|
||||||
quote!{
|
quote!{
|
||||||
#(#inner_params_iter,)*
|
#(#inner_params_iter,)*
|
||||||
}
|
}
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
let expanded_params_ref = &expanded_params;
|
let expanded_params_ref = &expanded_params;
|
||||||
|
|
||||||
let return_types: Vec<_> = commands
|
let return_types: Vec<_> = commands
|
||||||
|
@ -739,7 +758,41 @@ fn generate_function_pointers(ident: Ident, commands: &[&vkxml::Command]) -> quo
|
||||||
.map(|cmd| cmd.return_type.type_tokens())
|
.map(|cmd| cmd.return_type.type_tokens())
|
||||||
.collect();
|
.collect();
|
||||||
let return_types_ref = &return_types;
|
let return_types_ref = &return_types;
|
||||||
|
|
||||||
|
let pfn_names: Vec<_> = pfn_commands
|
||||||
|
.iter()
|
||||||
|
.map(|cmd| Ident::from(format!("PFN_{}", cmd.name.as_str())))
|
||||||
|
.collect();
|
||||||
|
let pfn_names_ref = &pfn_names;
|
||||||
|
|
||||||
|
let signature_params: Vec<Vec<_>> = pfn_commands
|
||||||
|
.iter()
|
||||||
|
.map(|cmd| {
|
||||||
|
let params: Vec<_> = cmd.param
|
||||||
|
.iter()
|
||||||
|
.map(|field| {
|
||||||
|
let name = field.param_ident();
|
||||||
|
let ty = field.type_tokens();
|
||||||
|
quote! { #name: #ty }
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
params
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let signature_params_ref = &signature_params;
|
||||||
|
|
||||||
|
let pfn_return_types: Vec<_> = pfn_commands
|
||||||
|
.iter()
|
||||||
|
.map(|cmd| cmd.return_type.type_tokens())
|
||||||
|
.collect();
|
||||||
|
let pfn_return_types_ref = &pfn_return_types;
|
||||||
|
|
||||||
quote!{
|
quote!{
|
||||||
|
#(
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub type #pfn_names_ref = extern "system" fn(#(#signature_params_ref),*) -> #pfn_return_types_ref;
|
||||||
|
)*
|
||||||
|
|
||||||
pub struct #ident {
|
pub struct #ident {
|
||||||
#(
|
#(
|
||||||
#names_ref: extern "system" fn(#expanded_params_ref) -> #return_types_ref,
|
#names_ref: extern "system" fn(#expanded_params_ref) -> #return_types_ref,
|
||||||
|
@ -816,7 +869,8 @@ pub fn generate_extension_constants<'a>(
|
||||||
.filter_map(|item| match item {
|
.filter_map(|item| match item {
|
||||||
vk_parse::ExtensionItem::Require { items, .. } => Some(items.iter()),
|
vk_parse::ExtensionItem::Require { items, .. } => Some(items.iter()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).flat_map(|iter| iter);
|
})
|
||||||
|
.flat_map(|iter| iter);
|
||||||
let enum_tokens = items.filter_map(|item| match item {
|
let enum_tokens = items.filter_map(|item| match item {
|
||||||
vk_parse::InterfaceItem::Enum(_enum) => {
|
vk_parse::InterfaceItem::Enum(_enum) => {
|
||||||
use vk_parse::EnumSpec;
|
use vk_parse::EnumSpec;
|
||||||
|
@ -850,7 +904,9 @@ pub fn generate_extension_constants<'a>(
|
||||||
constant,
|
constant,
|
||||||
};
|
};
|
||||||
let ident = name_to_tokens(&extends);
|
let ident = name_to_tokens(&extends);
|
||||||
const_values.entry(ident.clone()).or_insert_with(Vec::new)
|
const_values
|
||||||
|
.entry(ident.clone())
|
||||||
|
.or_insert_with(Vec::new)
|
||||||
.push(ext_constant.variant_ident(&extends));
|
.push(ext_constant.variant_ident(&extends));
|
||||||
let impl_block = bitflags_impl_block(ident, &extends, &[&ext_constant]);
|
let impl_block = bitflags_impl_block(ident, &extends, &[&ext_constant]);
|
||||||
let doc_string = format!("Generated from '{}'", extension_name);
|
let doc_string = format!("Generated from '{}'", extension_name);
|
||||||
|
@ -868,10 +924,11 @@ pub fn generate_extension_constants<'a>(
|
||||||
#(#enum_tokens)*
|
#(#enum_tokens)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn generate_extension_commands(
|
pub fn generate_extension_commands<'a>(
|
||||||
extension_name: &str,
|
extension_name: &str,
|
||||||
items: &[vk_parse::ExtensionItem],
|
items: &[vk_parse::ExtensionItem],
|
||||||
cmd_map: &CommandMap,
|
cmd_map: &CommandMap<'a>,
|
||||||
|
fn_cache: &mut HashSet<&'a str>,
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
let commands = items
|
let commands = items
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -883,17 +940,19 @@ pub fn generate_extension_commands(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}).flat_map(|iter| iter)
|
})
|
||||||
|
.flat_map(|iter| iter)
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
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..]);
|
||||||
generate_function_pointers(ident, &commands)
|
generate_function_pointers(ident, &commands, fn_cache)
|
||||||
}
|
}
|
||||||
pub fn generate_extension<'a>(
|
pub fn generate_extension<'a>(
|
||||||
extension: &'a vk_parse::Extension,
|
extension: &'a vk_parse::Extension,
|
||||||
cmd_map: &CommandMap,
|
cmd_map: &CommandMap<'a>,
|
||||||
const_cache: &mut HashSet<&'a str>,
|
const_cache: &mut HashSet<&'a str>,
|
||||||
const_values: &mut HashMap<Ident, Vec<Ident>>
|
const_values: &mut HashMap<Ident, Vec<Ident>>,
|
||||||
|
fn_cache: &mut HashSet<&'a str>,
|
||||||
) -> 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,
|
||||||
// because otherwise some StructureTypes won't get generated. But we don't generate extensions
|
// because otherwise some StructureTypes won't get generated. But we don't generate extensions
|
||||||
|
@ -908,7 +967,7 @@ pub fn generate_extension<'a>(
|
||||||
const_cache,
|
const_cache,
|
||||||
const_values,
|
const_values,
|
||||||
);
|
);
|
||||||
let fp = generate_extension_commands(&extension.name, &extension.items, cmd_map);
|
let fp = generate_extension_commands(&extension.name, &extension.items, cmd_map, fn_cache);
|
||||||
let q = quote!{
|
let q = quote!{
|
||||||
#fp
|
#fp
|
||||||
#extension_tokens
|
#extension_tokens
|
||||||
|
@ -989,7 +1048,8 @@ pub fn bitflags_impl_block(
|
||||||
let variant_ident = constant.variant_ident(enum_name);
|
let variant_ident = constant.variant_ident(enum_name);
|
||||||
let tokens = constant.to_tokens();
|
let tokens = constant.to_tokens();
|
||||||
(variant_ident, tokens)
|
(variant_ident, tokens)
|
||||||
}).collect_vec();
|
})
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
let notations = constants.iter().map(|constant| {
|
let notations = constants.iter().map(|constant| {
|
||||||
constant.notation().map(|n| {
|
constant.notation().map(|n| {
|
||||||
|
@ -999,16 +1059,14 @@ pub fn bitflags_impl_block(
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let variants =
|
let variants = variants.iter().zip(notations.clone()).map(
|
||||||
variants
|
|((variant_ident, value), ref notation)| {
|
||||||
.iter()
|
quote!{
|
||||||
.zip(notations.clone())
|
#notation
|
||||||
.map(|((variant_ident, value), ref notation)| {
|
pub const #variant_ident: Self = #ident(#value);
|
||||||
quote!{
|
}
|
||||||
#notation
|
},
|
||||||
pub const #variant_ident: Self = #ident(#value);
|
);
|
||||||
}
|
|
||||||
});
|
|
||||||
quote!{
|
quote!{
|
||||||
impl #ident {
|
impl #ident {
|
||||||
#(#variants)*
|
#(#variants)*
|
||||||
|
@ -1019,7 +1077,7 @@ pub fn bitflags_impl_block(
|
||||||
pub fn generate_enum<'a>(
|
pub fn generate_enum<'a>(
|
||||||
_enum: &'a vkxml::Enumeration,
|
_enum: &'a vkxml::Enumeration,
|
||||||
const_cache: &mut HashSet<&'a str>,
|
const_cache: &mut HashSet<&'a str>,
|
||||||
const_values: &mut HashMap<Ident, Vec<Ident>>
|
const_values: &mut HashMap<Ident, Vec<Ident>>,
|
||||||
) -> EnumType {
|
) -> EnumType {
|
||||||
let name = &_enum.name[2..];
|
let name = &_enum.name[2..];
|
||||||
let _name = name.replace("FlagBits", "Flags");
|
let _name = name.replace("FlagBits", "Flags");
|
||||||
|
@ -1030,7 +1088,8 @@ pub fn generate_enum<'a>(
|
||||||
.filter_map(|elem| match *elem {
|
.filter_map(|elem| match *elem {
|
||||||
vkxml::EnumerationElement::Enum(ref constant) => Some(constant),
|
vkxml::EnumerationElement::Enum(ref constant) => Some(constant),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).collect_vec();
|
})
|
||||||
|
.collect_vec();
|
||||||
let values = const_values.entry(ident.clone()).or_insert_with(Vec::new);
|
let values = const_values.entry(ident.clone()).or_insert_with(Vec::new);
|
||||||
for constant in &constants {
|
for constant in &constants {
|
||||||
const_cache.insert(constant.name.as_str());
|
const_cache.insert(constant.name.as_str());
|
||||||
|
@ -1134,7 +1193,8 @@ fn is_static_array(field: &vkxml::Field) -> bool {
|
||||||
.map(|ty| match ty {
|
.map(|ty| match ty {
|
||||||
vkxml::ArrayType::Static => true,
|
vkxml::ArrayType::Static => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}).unwrap_or(false)
|
})
|
||||||
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
pub fn derive_default(_struct: &vkxml::Struct) -> Option<Tokens> {
|
pub fn derive_default(_struct: &vkxml::Struct) -> Option<Tokens> {
|
||||||
let name = name_to_tokens(&_struct.name);
|
let name = name_to_tokens(&_struct.name);
|
||||||
|
@ -1201,9 +1261,7 @@ pub fn derive_default(_struct: &vkxml::Struct) -> Option<Tokens> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if is_static_array(field)
|
} else if is_static_array(field) || handles.contains(&field.basetype.as_str()) {
|
||||||
|| handles.contains(&field.basetype.as_str())
|
|
||||||
{
|
|
||||||
quote!{
|
quote!{
|
||||||
#param_ident: unsafe { ::std::mem::zeroed() }
|
#param_ident: unsafe { ::std::mem::zeroed() }
|
||||||
}
|
}
|
||||||
|
@ -1240,7 +1298,9 @@ pub fn derive_debug(_struct: &vkxml::Struct, union_types: &HashSet<&str>) -> Opt
|
||||||
.map(|n| n.contains("pfn"))
|
.map(|n| n.contains("pfn"))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
});
|
});
|
||||||
let contains_static_array = members.clone().any(|x| is_static_array(x) && x.basetype == "char");
|
let contains_static_array = members
|
||||||
|
.clone()
|
||||||
|
.any(|x| is_static_array(x) && x.basetype == "char");
|
||||||
let contains_union = members
|
let contains_union = members
|
||||||
.clone()
|
.clone()
|
||||||
.any(|field| union_types.contains(field.basetype.as_str()));
|
.any(|field| union_types.contains(field.basetype.as_str()));
|
||||||
|
@ -1298,26 +1358,32 @@ pub fn derive_setters(_struct: &vkxml::Struct) -> Option<Tokens> {
|
||||||
"VkPipelineViewportStateCreateInfo.pScissors",
|
"VkPipelineViewportStateCreateInfo.pScissors",
|
||||||
"VkDescriptorSetLayoutBinding.pImmutableSamplers",
|
"VkDescriptorSetLayoutBinding.pImmutableSamplers",
|
||||||
];
|
];
|
||||||
let filter_members: Vec<String> = members.clone().filter_map(|field| {
|
let filter_members: Vec<String> = members
|
||||||
let field_name = field.name.as_ref().unwrap();
|
.clone()
|
||||||
|
.filter_map(|field| {
|
||||||
|
let field_name = field.name.as_ref().unwrap();
|
||||||
|
|
||||||
// Associated _count members
|
// Associated _count members
|
||||||
if field.array.is_some() {
|
if field.array.is_some() {
|
||||||
if let Some(ref array_size) = field.size {
|
if let Some(ref array_size) = field.size {
|
||||||
if !array_size.starts_with("latexmath")
|
if !array_size.starts_with("latexmath")
|
||||||
&& !nofilter_count_members.iter().any(|n| *n == &(_struct.name.clone() + "." + field_name)) {
|
&& !nofilter_count_members
|
||||||
return Some((*array_size).clone());
|
.iter()
|
||||||
|
.any(|n| *n == &(_struct.name.clone() + "." + field_name))
|
||||||
|
{
|
||||||
|
return Some((*array_size).clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// VkShaderModuleCreateInfo requiers a custom setter
|
// VkShaderModuleCreateInfo requiers a custom setter
|
||||||
if field_name == "codeSize" {
|
if field_name == "codeSize" {
|
||||||
return Some(field_name.clone());
|
return Some(field_name.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let setters = members.clone().filter_map(|field| {
|
let setters = members.clone().filter_map(|field| {
|
||||||
let param_ident = field.param_ident();
|
let param_ident = field.param_ident();
|
||||||
|
@ -1400,7 +1466,8 @@ pub fn derive_setters(_struct: &vkxml::Struct) -> Option<Tokens> {
|
||||||
let slice_param_ty_tokens;
|
let slice_param_ty_tokens;
|
||||||
let ptr_mutability;
|
let ptr_mutability;
|
||||||
if param_ty_string.starts_with("*const ") {
|
if param_ty_string.starts_with("*const ") {
|
||||||
slice_param_ty_tokens = "&'a [".to_string() + ¶m_ty_string[7..] + "]";
|
slice_param_ty_tokens =
|
||||||
|
"&'a [".to_string() + ¶m_ty_string[7..] + "]";
|
||||||
ptr_mutability = ".as_ptr()";
|
ptr_mutability = ".as_ptr()";
|
||||||
} else {
|
} else {
|
||||||
// *mut
|
// *mut
|
||||||
|
@ -1411,7 +1478,6 @@ pub fn derive_setters(_struct: &vkxml::Struct) -> Option<Tokens> {
|
||||||
let slice_param_ty_tokens = Term::intern(&slice_param_ty_tokens);
|
let slice_param_ty_tokens = Term::intern(&slice_param_ty_tokens);
|
||||||
let ptr_mutability = Term::intern(ptr_mutability);
|
let ptr_mutability = Term::intern(ptr_mutability);
|
||||||
|
|
||||||
|
|
||||||
match array_type {
|
match array_type {
|
||||||
vkxml::ArrayType::Dynamic => {
|
vkxml::ArrayType::Dynamic => {
|
||||||
return Some(quote!{
|
return Some(quote!{
|
||||||
|
@ -1619,7 +1685,11 @@ pub fn generate_definition(
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn generate_feature(feature: &vkxml::Feature, commands: &CommandMap) -> quote::Tokens {
|
pub fn generate_feature<'a>(
|
||||||
|
feature: &vkxml::Feature,
|
||||||
|
commands: &CommandMap<'a>,
|
||||||
|
fn_cache: &mut HashSet<&'a str>,
|
||||||
|
) -> quote::Tokens {
|
||||||
let (static_commands, entry_commands, device_commands, instance_commands) = feature
|
let (static_commands, entry_commands, device_commands, instance_commands) = feature
|
||||||
.elements
|
.elements
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1634,11 +1704,13 @@ pub fn generate_feature(feature: &vkxml::Feature, commands: &CommandMap) -> quot
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}).collect()
|
})
|
||||||
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
}).filter_map(|cmd_ref| commands.get(&cmd_ref.name))
|
})
|
||||||
|
.filter_map(|cmd_ref| commands.get(&cmd_ref.name))
|
||||||
.fold(
|
.fold(
|
||||||
(Vec::new(), Vec::new(), Vec::new(), Vec::new()),
|
(Vec::new(), Vec::new(), Vec::new(), Vec::new()),
|
||||||
|mut acc, &cmd_ref| {
|
|mut acc, &cmd_ref| {
|
||||||
|
@ -1661,21 +1733,24 @@ pub fn generate_feature(feature: &vkxml::Feature, commands: &CommandMap) -> quot
|
||||||
);
|
);
|
||||||
let version = feature.version_string();
|
let version = feature.version_string();
|
||||||
let static_fn = if feature.version == 1.0 {
|
let static_fn = if feature.version == 1.0 {
|
||||||
generate_function_pointers(Ident::from("StaticFn"), &static_commands)
|
generate_function_pointers(Ident::from("StaticFn"), &static_commands, 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,
|
||||||
|
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,
|
||||||
|
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,
|
||||||
|
fn_cache,
|
||||||
);
|
);
|
||||||
quote! {
|
quote! {
|
||||||
#static_fn
|
#static_fn
|
||||||
|
@ -1711,21 +1786,23 @@ pub fn generate_constant<'a>(
|
||||||
pub fn generate_feature_extension<'a>(
|
pub fn generate_feature_extension<'a>(
|
||||||
registry: &'a vk_parse::Registry,
|
registry: &'a vk_parse::Registry,
|
||||||
const_cache: &mut HashSet<&'a str>,
|
const_cache: &mut HashSet<&'a str>,
|
||||||
const_values: &mut HashMap<Ident, Vec<Ident>>
|
const_values: &mut HashMap<Ident, Vec<Ident>>,
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
let constants = registry.0.iter().filter_map(|item| match item {
|
let constants =
|
||||||
vk_parse::RegistryItem::Feature { name, items, .. } => {
|
registry.0.iter().filter_map(|item| match item {
|
||||||
Some(generate_extension_constants(name, 0, items, const_cache, const_values))
|
vk_parse::RegistryItem::Feature { name, items, .. } => Some(
|
||||||
}
|
generate_extension_constants(name, 0, items, const_cache, const_values),
|
||||||
_ => None,
|
),
|
||||||
});
|
_ => None,
|
||||||
|
});
|
||||||
quote!{
|
quote!{
|
||||||
#(#constants)*
|
#(#constants)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_const_displays<'a>(const_values: &HashMap<Ident, Vec<Ident>>) -> Tokens {
|
pub fn generate_const_displays<'a>(const_values: &HashMap<Ident, Vec<Ident>>) -> Tokens {
|
||||||
let impls = const_values.iter()
|
let impls = const_values
|
||||||
|
.iter()
|
||||||
.filter(|(ty, _)| *ty != "Result")
|
.filter(|(ty, _)| *ty != "Result")
|
||||||
.map(|(ty, values)| {
|
.map(|(ty, values)| {
|
||||||
if ty.to_string().contains("Flags") {
|
if ty.to_string().contains("Flags") {
|
||||||
|
@ -1796,59 +1873,62 @@ pub fn write_source_code(path: &Path) {
|
||||||
.filter_map(|item| match item {
|
.filter_map(|item| match item {
|
||||||
vk_parse::RegistryItem::Extensions { items: ext, .. } => Some(ext),
|
vk_parse::RegistryItem::Extensions { items: ext, .. } => Some(ext),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).nth(0)
|
})
|
||||||
|
.nth(0)
|
||||||
.expect("extension");
|
.expect("extension");
|
||||||
|
|
||||||
let spec = vk_parse::parse_file_as_vkxml(path);
|
let spec = vk_parse::parse_file_as_vkxml(path);
|
||||||
let commands: HashMap<vkxml::Identifier, &vkxml::Command> = spec
|
let commands: HashMap<vkxml::Identifier, &vkxml::Command> = spec.elements
|
||||||
.elements
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|elem| match elem {
|
.filter_map(|elem| match elem {
|
||||||
vkxml::RegistryElement::Commands(ref cmds) => Some(cmds),
|
vkxml::RegistryElement::Commands(ref cmds) => Some(cmds),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).flat_map(|cmds| cmds.elements.iter().map(|cmd| (cmd.name.clone(), cmd)))
|
})
|
||||||
|
.flat_map(|cmds| cmds.elements.iter().map(|cmd| (cmd.name.clone(), cmd)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let features: Vec<&vkxml::Feature> = spec
|
let features: Vec<&vkxml::Feature> = spec.elements
|
||||||
.elements
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|elem| match elem {
|
.filter_map(|elem| match elem {
|
||||||
vkxml::RegistryElement::Features(ref features) => Some(features),
|
vkxml::RegistryElement::Features(ref features) => Some(features),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).flat_map(|features| features.elements.iter())
|
})
|
||||||
|
.flat_map(|features| features.elements.iter())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let definitions: Vec<&vkxml::DefinitionsElement> = spec
|
let definitions: Vec<&vkxml::DefinitionsElement> = spec.elements
|
||||||
.elements
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|elem| match elem {
|
.filter_map(|elem| match elem {
|
||||||
vkxml::RegistryElement::Definitions(ref definitions) => Some(definitions),
|
vkxml::RegistryElement::Definitions(ref definitions) => Some(definitions),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).flat_map(|definitions| definitions.elements.iter())
|
})
|
||||||
|
.flat_map(|definitions| definitions.elements.iter())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let enums: Vec<&vkxml::Enumeration> = spec
|
let enums: Vec<&vkxml::Enumeration> = spec.elements
|
||||||
.elements
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|elem| match elem {
|
.filter_map(|elem| match elem {
|
||||||
vkxml::RegistryElement::Enums(ref enums) => Some(enums),
|
vkxml::RegistryElement::Enums(ref enums) => Some(enums),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).flat_map(|enums| {
|
})
|
||||||
|
.flat_map(|enums| {
|
||||||
enums.elements.iter().filter_map(|_enum| match *_enum {
|
enums.elements.iter().filter_map(|_enum| match *_enum {
|
||||||
vkxml::EnumsElement::Enumeration(ref e) => Some(e),
|
vkxml::EnumsElement::Enumeration(ref e) => Some(e),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let constants: Vec<&vkxml::Constant> = spec
|
let constants: Vec<&vkxml::Constant> = spec.elements
|
||||||
.elements
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|elem| match elem {
|
.filter_map(|elem| match elem {
|
||||||
vkxml::RegistryElement::Constants(ref constants) => Some(constants),
|
vkxml::RegistryElement::Constants(ref constants) => Some(constants),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).flat_map(|constants| constants.elements.iter())
|
})
|
||||||
|
.flat_map(|constants| constants.elements.iter())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let mut fn_cache = HashSet::new();
|
||||||
let mut const_cache = HashSet::new();
|
let mut const_cache = HashSet::new();
|
||||||
|
|
||||||
let mut const_values: HashMap<Ident, Vec<Ident>> = HashMap::new();
|
let mut const_values: HashMap<Ident, Vec<Ident>> = HashMap::new();
|
||||||
|
@ -1870,7 +1950,15 @@ pub fn write_source_code(path: &Path) {
|
||||||
.collect();
|
.collect();
|
||||||
let extension_code = extensions
|
let extension_code = extensions
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|ext| generate_extension(ext, &commands, &mut const_cache, &mut const_values))
|
.filter_map(|ext| {
|
||||||
|
generate_extension(
|
||||||
|
ext,
|
||||||
|
&commands,
|
||||||
|
&mut const_cache,
|
||||||
|
&mut const_values,
|
||||||
|
&mut fn_cache,
|
||||||
|
)
|
||||||
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
let union_types = definitions
|
let union_types = definitions
|
||||||
|
@ -1878,7 +1966,8 @@ pub fn write_source_code(path: &Path) {
|
||||||
.filter_map(|def| match def {
|
.filter_map(|def| match def {
|
||||||
vkxml::DefinitionsElement::Union(ref union) => Some(union.name.as_str()),
|
vkxml::DefinitionsElement::Union(ref union) => Some(union.name.as_str()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).collect::<HashSet<&str>>();
|
})
|
||||||
|
.collect::<HashSet<&str>>();
|
||||||
|
|
||||||
let definition_code: Vec<_> = definitions
|
let definition_code: Vec<_> = definitions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -1887,9 +1976,10 @@ pub fn write_source_code(path: &Path) {
|
||||||
|
|
||||||
let feature_code: Vec<_> = features
|
let feature_code: Vec<_> = features
|
||||||
.iter()
|
.iter()
|
||||||
.map(|feature| generate_feature(feature, &commands))
|
.map(|feature| generate_feature(feature, &commands, &mut fn_cache))
|
||||||
.collect();
|
.collect();
|
||||||
let feature_extensions_code = generate_feature_extension(&spec2, &mut const_cache, &mut const_values);
|
let feature_extensions_code =
|
||||||
|
generate_feature_extension(&spec2, &mut const_cache, &mut const_values);
|
||||||
|
|
||||||
let const_displays = generate_const_displays(&const_values);
|
let const_displays = generate_const_displays(&const_values);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue