Add extension structure type constants to StructureType

This commit is contained in:
Maik Klein 2018-07-07 14:49:17 +02:00
parent e6e8bbd91b
commit fb13cc402e
3 changed files with 121 additions and 16 deletions

View file

@ -1,4 +1,28 @@
pub use libc::*; pub use libc::*;
#[macro_export]
macro_rules! vk_make_version {
($major:expr, $minor:expr, $patch:expr) => {
(($major as u32) << 22) | (($minor as u32) << 12) | $patch as u32
};
}
#[macro_export]
macro_rules! vk_version_major {
($major:expr) => {
($major as uint32_t) >> 22
};
}
#[macro_export]
macro_rules! vk_version_minor {
($minor:expr) => {
(($minor as uint32_t) >> 12) & 0x3ff
};
}
#[macro_export]
macro_rules! vk_version_patch {
($minor:expr) => {
($minor as uint32_t) & 0xfff
};
}
pub type RROutput = c_ulong; pub type RROutput = c_ulong;
pub type VisualID = c_uint; pub type VisualID = c_uint;
pub type Display = *const c_void; pub type Display = *const c_void;

View file

@ -10,6 +10,7 @@ vkxml = {git = "https://github.com/terrybrashaw/vkxml"}
nom = "4.0" nom = "4.0"
heck = "0.3" heck = "0.3"
proc-macro2 = "0.2" proc-macro2 = "0.2"
itertools = "0.7"
[dependencies.quote] [dependencies.quote]
version = "0.4.2" version = "0.4.2"

View file

@ -8,11 +8,13 @@ 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;
use heck::{CamelCase, ShoutySnakeCase, SnakeCase}; use heck::{CamelCase, ShoutySnakeCase, SnakeCase};
use itertools::Itertools;
use proc_macro2::{Term, TokenTree}; use proc_macro2::{Term, TokenTree};
use quote::Tokens; use quote::Tokens;
use std::collections::HashMap; use std::collections::HashMap;
@ -135,6 +137,37 @@ pub fn handle_nondispatchable_macro() -> Tokens {
} }
} }
} }
pub fn vk_version_macros() -> Tokens {
quote!{
#[macro_export]
macro_rules! vk_make_version {
($major:expr, $minor:expr, $patch:expr) => {
(($major as u32) << 22) | (($minor as u32) << 12) | $patch as u32
};
}
#[macro_export]
macro_rules! vk_version_major {
($major:expr) => {
($major as uint32_t) >> 22
};
}
#[macro_export]
macro_rules! vk_version_minor {
($minor:expr) => {
(($minor as uint32_t) >> 12) & 0x3ff
};
}
#[macro_export]
macro_rules! vk_version_patch {
($minor:expr) => {
($minor as uint32_t) & 0xfff
};
}
}
}
pub fn vk_bitflags_wrapped_macro() -> Tokens { pub fn vk_bitflags_wrapped_macro() -> Tokens {
quote!{ quote!{
macro_rules! vk_bitflags_wrapped { macro_rules! vk_bitflags_wrapped {
@ -697,15 +730,15 @@ pub fn generate_extension(extension: &vkxml::Extension, commands: &CommandMap) -
if let &vkxml::ExtensionElement::Require(ref spec) = extension { if let &vkxml::ExtensionElement::Require(ref spec) = extension {
spec.elements spec.elements
.iter() .iter()
.filter_map(|extension_spec| { .filter_map(|extension_spec| match extension_spec {
if let &vkxml::ExtensionSpecificationElement::CommandReference( vkxml::ExtensionSpecificationElement::CommandReference(ref cmd_ref) => {
ref cmd_ref,
) = extension_spec
{
Some(cmd_ref) Some(cmd_ref)
} else { }
vkxml::ExtensionSpecificationElement::DefinitionReference(ref field) => {
println!("EXT {:?}", field);
None None
} }
_ => None,
}) })
.collect() .collect()
} else { } else {
@ -778,7 +811,10 @@ pub enum EnumType {
Enum(Tokens), Enum(Tokens),
} }
pub fn generate_enum(_enum: &vkxml::Enumeration) -> EnumType { pub fn generate_enum(
_enum: &vkxml::Enumeration,
create_info_constants: &[&vkxml::Constant],
) -> EnumType {
let name = &_enum.name[2..]; let name = &_enum.name[2..];
let _name = name.replace("FlagBits", "Flags"); let _name = name.replace("FlagBits", "Flags");
if name.contains("Bit") { if name.contains("Bit") {
@ -822,6 +858,7 @@ pub fn generate_enum(_enum: &vkxml::Enumeration) -> EnumType {
EnumType::Bitflags(q) EnumType::Bitflags(q)
} else { } else {
let q = match _name.as_str() { let q = match _name.as_str() {
"StructureType" => generate_structure_type(&_name, _enum, create_info_constants),
"Result" => generate_result(&_name, _enum), "Result" => generate_result(&_name, _enum),
_ => { _ => {
let ident = Ident::from(_name.as_str()); let ident = Ident::from(_name.as_str());
@ -854,6 +891,38 @@ pub fn generate_enum(_enum: &vkxml::Enumeration) -> EnumType {
EnumType::Enum(q) EnumType::Enum(q)
} }
} }
pub fn generate_structure_type(
name: &str,
_enum: &vkxml::Enumeration,
create_info_constants: &[&vkxml::Constant],
) -> Tokens {
let ident = Ident::from(name);
let constants: Vec<_> = _enum
.elements
.iter()
.filter_map(|elem| match elem {
vkxml::EnumerationElement::Enum(constant) => Some(constant),
_ => None,
})
.collect();
let variants = constants
.iter()
.chain(create_info_constants.into_iter())
.map(|constant| {
let value_tokens = Constant::from_constant(constant).to_tokens();
let variant_ident = to_variant_ident(&name, &constant.name);
quote!{
#variant_ident = #value_tokens
}
});
quote!{
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C)]
pub enum #ident {
#(#variants,)*
}
}
}
pub fn generate_result(name: &str, _enum: &vkxml::Enumeration) -> Tokens { pub fn generate_result(name: &str, _enum: &vkxml::Enumeration) -> Tokens {
let ident = Ident::from(name); let ident = Ident::from(name);
let variants = _enum.elements.iter().filter_map(|elem| { let variants = _enum.elements.iter().filter_map(|elem| {
@ -1157,16 +1226,29 @@ pub fn write_source_code(spec: &vkxml::Registry) {
.flat_map(|constants| constants.elements.iter()) .flat_map(|constants| constants.elements.iter())
.collect(); .collect();
let (enum_code, bitflags_code) = enums.into_iter().map(generate_enum).fold( let (create_info_constants, constants): (Vec<_>, Vec<_>) =
(Vec::new(), Vec::new()), constants.iter().partition_map(|&c| {
|mut acc, elem| { if c.name.contains("CreateInfo") {
itertools::Either::Left(c)
} else {
itertools::Either::Right(c)
}
});
let (enum_code, bitflags_code) = enums
.into_iter()
.map(|e| generate_enum(e, &create_info_constants))
.fold((Vec::new(), Vec::new()), |mut acc, elem| {
match elem { match elem {
EnumType::Enum(token) => acc.0.push(token), EnumType::Enum(token) => acc.0.push(token),
EnumType::Bitflags(token) => acc.1.push(token), EnumType::Bitflags(token) => acc.1.push(token),
}; };
acc acc
}, });
); let constants_code: Vec<_> = constants
.iter()
.map(|constant| generate_constant(constant))
.collect();
let definition_code: Vec<_> = definitions let definition_code: Vec<_> = definitions
.into_iter() .into_iter()
@ -1182,17 +1264,15 @@ pub fn write_source_code(spec: &vkxml::Registry) {
.iter() .iter()
.map(|ext| generate_extension(ext, &commands)) .map(|ext| generate_extension(ext, &commands))
.collect(); .collect();
let constants_code: Vec<_> = constants
.iter()
.map(|constant| generate_constant(constant))
.collect();
let mut file = File::create("../ash/src/vk_test.rs").expect("vk"); let mut file = File::create("../ash/src/vk_test.rs").expect("vk");
let bitflags_macro = vk_bitflags_wrapped_macro(); let bitflags_macro = vk_bitflags_wrapped_macro();
let handle_nondispatchable_macro = handle_nondispatchable_macro(); let handle_nondispatchable_macro = handle_nondispatchable_macro();
let define_handle_macro = define_handle_macro(); let define_handle_macro = define_handle_macro();
let version_macros = vk_version_macros();
let platform_specific_types = platform_specific_types(); let platform_specific_types = platform_specific_types();
let source_code = quote!{ let source_code = quote!{
pub use libc::*; pub use libc::*;
#version_macros
#platform_specific_types #platform_specific_types
#bitflags_macro #bitflags_macro
#handle_nondispatchable_macro #handle_nondispatchable_macro