commit
071fe412c1
3257
ash/src/vk.rs
3257
ash/src/vk.rs
File diff suppressed because it is too large
Load diff
12
ash/tests/display.rs
Normal file
12
ash/tests/display.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
extern crate ash;
|
||||||
|
use ash::vk;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn display_flags() {
|
||||||
|
assert_eq!((vk::AccessFlags::INDIRECT_COMMAND_READ | vk::AccessFlags::VERTEX_ATTRIBUTE_READ).to_string(), "INDIRECT_COMMAND_READ | VERTEX_ATTRIBUTE_READ");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn display_enum() {
|
||||||
|
assert_eq!(vk::ChromaLocation::MIDPOINT.to_string(), "MIDPOINT");
|
||||||
|
}
|
|
@ -786,6 +786,7 @@ pub fn generate_extension_constants<'a>(
|
||||||
extension_number: i64,
|
extension_number: i64,
|
||||||
extension_items: &'a [vk_parse::ExtensionItem],
|
extension_items: &'a [vk_parse::ExtensionItem],
|
||||||
const_cache: &mut HashSet<&'a str>,
|
const_cache: &mut HashSet<&'a str>,
|
||||||
|
const_values: &mut HashMap<Ident, Vec<Ident>>,
|
||||||
) -> quote::Tokens {
|
) -> quote::Tokens {
|
||||||
let items = extension_items
|
let items = extension_items
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -819,13 +820,14 @@ pub fn generate_extension_constants<'a>(
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
let extends = extends?;
|
let extends = extends?;
|
||||||
let ext_constant = ExtensionConstant {
|
let ext_constant = ExtensionConstant {
|
||||||
name: &_enum.name,
|
name: &_enum.name,
|
||||||
constant,
|
constant,
|
||||||
};
|
};
|
||||||
let ident = name_to_tokens(&extends);
|
let ident = name_to_tokens(&extends);
|
||||||
|
const_values.entry(ident.clone()).or_insert_with(Vec::new)
|
||||||
|
.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);
|
||||||
let q = quote!{
|
let q = quote!{
|
||||||
|
@ -867,6 +869,7 @@ pub fn generate_extension<'a>(
|
||||||
extension: &'a vk_parse::Extension,
|
extension: &'a vk_parse::Extension,
|
||||||
cmd_map: &CommandMap,
|
cmd_map: &CommandMap,
|
||||||
const_cache: &mut HashSet<&'a str>,
|
const_cache: &mut HashSet<&'a str>,
|
||||||
|
const_values: &mut HashMap<Ident, Vec<Ident>>
|
||||||
) -> 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
|
||||||
|
@ -879,6 +882,7 @@ pub fn generate_extension<'a>(
|
||||||
extension.number.unwrap_or(0),
|
extension.number.unwrap_or(0),
|
||||||
&extension.items,
|
&extension.items,
|
||||||
const_cache,
|
const_cache,
|
||||||
|
const_values,
|
||||||
);
|
);
|
||||||
let fp = generate_extension_commands(&extension.name, &extension.items, cmd_map);
|
let fp = generate_extension_commands(&extension.name, &extension.items, cmd_map);
|
||||||
let q = quote!{
|
let q = quote!{
|
||||||
|
@ -991,6 +995,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>>
|
||||||
) -> EnumType {
|
) -> EnumType {
|
||||||
let name = &_enum.name[2..];
|
let name = &_enum.name[2..];
|
||||||
let _name = name.replace("FlagBits", "Flags");
|
let _name = name.replace("FlagBits", "Flags");
|
||||||
|
@ -1002,8 +1007,10 @@ pub fn generate_enum<'a>(
|
||||||
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);
|
||||||
for constant in &constants {
|
for constant in &constants {
|
||||||
const_cache.insert(constant.name.as_str());
|
const_cache.insert(constant.name.as_str());
|
||||||
|
values.push(constant.variant_ident(&_enum.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
if name.contains("Bit") {
|
if name.contains("Bit") {
|
||||||
|
@ -1061,22 +1068,31 @@ pub fn generate_result(ident: Ident, _enum: &vkxml::Enumeration) -> Tokens {
|
||||||
|
|
||||||
let variant_ident = variant_ident(&_enum.name, variant_name);
|
let variant_ident = variant_ident(&_enum.name, variant_name);
|
||||||
Some(quote!{
|
Some(quote!{
|
||||||
#ident::#variant_ident => write!(fmt, #notation)
|
#ident::#variant_ident => Some(#notation)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let notation2 = notation.clone();
|
||||||
quote!{
|
quote!{
|
||||||
impl ::std::error::Error for #ident {
|
impl ::std::error::Error for #ident {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
"vk::Result"
|
let name = match *self {
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ::std::fmt::Display for #ident {
|
|
||||||
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
|
||||||
writeln!(fmt, "vk::Result::{:?}", self)?;
|
|
||||||
match *self {
|
|
||||||
#(#notation),*,
|
#(#notation),*,
|
||||||
_ => write!(fmt, "Unknown variant")
|
_ => None,
|
||||||
|
};
|
||||||
|
name.unwrap_or("unknown error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl fmt::Display for #ident {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let name = match *self {
|
||||||
|
#(#notation2),*,
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
if let Some(x) = name {
|
||||||
|
fmt.write_str(x)
|
||||||
|
} else {
|
||||||
|
write!(fmt, "{}", self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1447,10 +1463,11 @@ 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>>
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
let constants = registry.0.iter().filter_map(|item| match item {
|
let constants = registry.0.iter().filter_map(|item| match item {
|
||||||
vk_parse::RegistryItem::Feature { name, items, .. } => {
|
vk_parse::RegistryItem::Feature { name, items, .. } => {
|
||||||
Some(generate_extension_constants(name, 0, items, const_cache))
|
Some(generate_extension_constants(name, 0, items, const_cache, const_values))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
|
@ -1459,6 +1476,68 @@ pub fn generate_feature_extension<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate_const_displays<'a>(const_values: &HashMap<Ident, Vec<Ident>>) -> Tokens {
|
||||||
|
let impls = const_values.iter()
|
||||||
|
.filter(|(ty, _)| *ty != "Result")
|
||||||
|
.map(|(ty, values)| {
|
||||||
|
if ty.to_string().contains("Flags") {
|
||||||
|
let cases = values.iter().map(|value| {
|
||||||
|
let name = value.to_string();
|
||||||
|
quote!{ (#ty::#value.0, #name) }
|
||||||
|
});
|
||||||
|
quote!{
|
||||||
|
impl fmt::Display for #ty {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
const KNOWN: &[(Flags, &str)] = &[#(#cases),*];
|
||||||
|
display_flags(f, KNOWN, self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let cases = values.iter().map(|value| {
|
||||||
|
let name = value.to_string();
|
||||||
|
quote!{ Self::#value => Some(#name), }
|
||||||
|
});
|
||||||
|
quote!{
|
||||||
|
impl fmt::Display for #ty {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let name = match *self {
|
||||||
|
#(#cases)*
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
if let Some(x) = name {
|
||||||
|
f.write_str(x)
|
||||||
|
} else {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
quote!{
|
||||||
|
fn display_flags(f: &mut fmt::Formatter, known: &[(Flags, &'static str)], value: Flags) -> fmt::Result {
|
||||||
|
let mut first = true;
|
||||||
|
let mut accum = value;
|
||||||
|
for (bit, name) in known {
|
||||||
|
if accum & bit != 0 {
|
||||||
|
if !first { f.write_str(" | ")?; }
|
||||||
|
f.write_str(name)?;
|
||||||
|
first = false;
|
||||||
|
accum &= !bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if accum != 0 {
|
||||||
|
if !first { f.write_str(" | ")?; }
|
||||||
|
write!(f, "{:b}", accum)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#(#impls)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write_source_code(path: &Path) {
|
pub fn write_source_code(path: &Path) {
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
@ -1523,9 +1602,12 @@ pub fn write_source_code(path: &Path) {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut const_cache = HashSet::new();
|
let mut const_cache = HashSet::new();
|
||||||
|
|
||||||
|
let mut const_values: HashMap<Ident, Vec<Ident>> = HashMap::new();
|
||||||
|
|
||||||
let (enum_code, bitflags_code) = enums
|
let (enum_code, bitflags_code) = enums
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|e| generate_enum(e, &mut const_cache))
|
.map(|e| generate_enum(e, &mut const_cache, &mut const_values))
|
||||||
.fold((Vec::new(), Vec::new()), |mut acc, elem| {
|
.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),
|
||||||
|
@ -1533,13 +1615,14 @@ pub fn write_source_code(path: &Path) {
|
||||||
};
|
};
|
||||||
acc
|
acc
|
||||||
});
|
});
|
||||||
|
|
||||||
let constants_code: Vec<_> = constants
|
let constants_code: Vec<_> = constants
|
||||||
.iter()
|
.iter()
|
||||||
.map(|constant| generate_constant(constant, &mut const_cache))
|
.map(|constant| generate_constant(constant, &mut const_cache))
|
||||||
.collect();
|
.collect();
|
||||||
let extension_code = extensions
|
let extension_code = extensions
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|ext| generate_extension(ext, &commands, &mut const_cache))
|
.filter_map(|ext| generate_extension(ext, &commands, &mut const_cache, &mut const_values))
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
let union_types = definitions
|
let union_types = definitions
|
||||||
|
@ -1558,7 +1641,9 @@ pub fn write_source_code(path: &Path) {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|feature| generate_feature(feature, &commands))
|
.map(|feature| generate_feature(feature, &commands))
|
||||||
.collect();
|
.collect();
|
||||||
let feature_extensions_code = generate_feature_extension(&spec2, &mut const_cache);
|
let feature_extensions_code = generate_feature_extension(&spec2, &mut const_cache, &mut const_values);
|
||||||
|
|
||||||
|
let const_displays = generate_const_displays(&const_values);
|
||||||
|
|
||||||
let mut file = File::create("../ash/src/vk.rs").expect("vk");
|
let mut file = File::create("../ash/src/vk.rs").expect("vk");
|
||||||
let bitflags_macro = vk_bitflags_wrapped_macro();
|
let bitflags_macro = vk_bitflags_wrapped_macro();
|
||||||
|
@ -1567,6 +1652,7 @@ pub fn write_source_code(path: &Path) {
|
||||||
let version_macros = vk_version_macros();
|
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!{
|
||||||
|
use std::fmt;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use libc::*;
|
pub use libc::*;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -1598,6 +1684,7 @@ pub fn write_source_code(path: &Path) {
|
||||||
#(#extension_code)*
|
#(#extension_code)*
|
||||||
#feature_extensions_code
|
#feature_extensions_code
|
||||||
}
|
}
|
||||||
|
#const_displays
|
||||||
};
|
};
|
||||||
write!(&mut file, "{}", source_code).expect("Unable to write to file");
|
write!(&mut file, "{}", source_code).expect("Unable to write to file");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue