Skip to content

Commit 6b0735d

Browse files
committed
rewrite: Initial codegen
1 parent 8eb9094 commit 6b0735d

File tree

267 files changed

+2412
-18
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

267 files changed

+2412
-18
lines changed

analysis/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ edition = "2021"
66
[dependencies]
77
roxmltree = "0.19"
88
tracing = "0.1"
9+
indexmap = "2"

analysis/src/cdecl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub struct UnsupportedCTok<'a>(&'a str);
3333
impl<'a> CTok<'a> {
3434
pub const SUPPORTED_KEYWORDS: &'static [&'static str] = &["const", "struct", "typedef", "void"];
3535

36-
pub fn lex_into(
36+
pub(crate) fn lex_into(
3737
s: &'a str,
3838
out: &mut impl Extend<CTok<'a>>,
3939
) -> Result<(), UnsupportedCTok<'a>> {
@@ -143,7 +143,7 @@ pub enum CDeclParseErrorKind<'a> {
143143

144144
impl<'a> CDecl<'a> {
145145
// HACK(eddyb) this split is literally just to simplify error tracking.
146-
pub fn parse<'b>(
146+
pub(crate) fn parse<'b>(
147147
mode: CDeclMode,
148148
tokens: &'b [CTok<'a>],
149149
) -> Result<CDecl<'a>, CDeclParseError<'a, 'b>> {

analysis/src/items/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use self::structures::Structure;
2+
use crate::LibraryId;
3+
use indexmap::IndexMap;
4+
5+
pub mod structures;
6+
7+
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
8+
pub struct Origin {
9+
pub library_id: LibraryId,
10+
pub required_by: RequiredBy,
11+
}
12+
13+
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
14+
pub enum RequiredBy {
15+
Feature { major: u32, minor: u32 },
16+
Extension { name: &'static str },
17+
}
18+
19+
#[derive(Default, Debug)]
20+
pub struct Items {
21+
pub structures: IndexMap<&'static str, Structure>,
22+
}

analysis/src/items/structures.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use super::Origin;
2+
use crate::xml::{self, UnwrapBorrowed};
3+
4+
#[derive(Debug)]
5+
pub struct Structure {
6+
pub origin: Origin,
7+
pub name: &'static str,
8+
}
9+
10+
impl Structure {
11+
pub fn new(origin: Origin, xml: &xml::Structure) -> Structure {
12+
Structure {
13+
origin,
14+
name: xml.name.unwrap_borrowed(),
15+
}
16+
}
17+
}

analysis/src/lib.rs

Lines changed: 114 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,139 @@
1-
mod xml;
1+
pub mod cdecl;
2+
pub mod items;
3+
pub mod xml;
24

3-
use std::{fs, path::Path};
5+
use crate::items::Origin;
6+
use items::{structures::Structure, Items, RequiredBy};
7+
use std::{
8+
collections::HashMap,
9+
fmt::{self, Display},
10+
fs,
11+
path::{Path, PathBuf},
12+
};
413
use tracing::{debug, error_span};
14+
use xml::UnwrapBorrowed;
515

616
#[derive(Debug)]
717
pub struct Analysis {
8-
pub vk: Library,
9-
pub video: Library,
18+
vk: Library,
19+
video: Library,
20+
items: Items,
1021
}
1122

1223
impl Analysis {
1324
pub fn new(vulkan_headers_path: impl AsRef<Path>) -> Analysis {
25+
let vk = Library::new(LibraryId::Vk, &vulkan_headers_path);
26+
let video = Library::new(LibraryId::Video, &vulkan_headers_path);
27+
28+
let mut items = Items::default();
29+
vk.collect_into(&mut items);
30+
video.collect_into(&mut items);
31+
32+
Analysis { vk, video, items }
33+
}
34+
35+
pub fn vk_xml(&self) -> &xml::Registry {
36+
&self.vk.xml
37+
}
38+
39+
pub fn video_xml(&self) -> &xml::Registry {
40+
&self.video.xml
41+
}
42+
43+
pub fn items(&self) -> &Items {
44+
&self.items
45+
}
46+
}
47+
48+
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
49+
pub enum LibraryId {
50+
Vk,
51+
Video,
52+
}
53+
54+
impl LibraryId {
55+
fn xml_path(&self, vulkan_headers_path: impl AsRef<Path>) -> PathBuf {
1456
let vulkan_headers_path = vulkan_headers_path.as_ref();
15-
Analysis {
16-
vk: Library::new(vulkan_headers_path.join("registry/vk.xml")),
17-
video: Library::new(vulkan_headers_path.join("registry/video.xml")),
57+
match self {
58+
LibraryId::Vk => vulkan_headers_path.join("registry/vk.xml"),
59+
LibraryId::Video => vulkan_headers_path.join("registry/video.xml"),
1860
}
1961
}
2062
}
2163

64+
impl Display for LibraryId {
65+
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
66+
formatter.write_str(match self {
67+
LibraryId::Vk => "vk",
68+
LibraryId::Video => "video",
69+
})
70+
}
71+
}
72+
2273
#[derive(Debug)]
2374
pub struct Library {
24-
_xml: xml::Registry,
75+
id: LibraryId,
76+
xml: xml::Registry,
2577
}
2678

2779
impl Library {
28-
fn new(xml_path: impl AsRef<Path>) -> Library {
29-
let xml = error_span!("xml", path = %xml_path.as_ref().display()).in_scope(|| {
80+
fn new(id: LibraryId, vulkan_headers_path: impl AsRef<Path>) -> Library {
81+
let xml = error_span!("xml", library_id = %id).in_scope(|| {
82+
let path = id.xml_path(vulkan_headers_path);
3083
// We leak the input string here for convenience, to avoid explicit lifetimes.
31-
let xml_input = Box::leak(fs::read_to_string(xml_path).unwrap().into_boxed_str());
84+
let input = Box::leak(fs::read_to_string(path).unwrap().into_boxed_str());
3285
debug!("parsing xml");
33-
xml::Registry::parse(xml_input, "vulkan")
86+
xml::Registry::parse(input, "vulkan")
3487
});
3588

36-
Library { _xml: xml }
89+
Library { id, xml }
90+
}
91+
92+
pub fn xml(&self) -> &xml::Registry {
93+
&self.xml
94+
}
95+
96+
fn collect_into(&self, items: &mut Items) {
97+
let mut types_required_by = HashMap::new();
98+
99+
for feature in &self.xml.features {
100+
let required_by = RequiredBy::Feature {
101+
major: feature.major,
102+
minor: feature.minor,
103+
};
104+
105+
for require in &feature.requires {
106+
for require_type in &require.types {
107+
types_required_by.insert(require_type.name.unwrap_borrowed(), required_by);
108+
}
109+
}
110+
}
111+
112+
for extension in &self.xml.extensions {
113+
let required_by = RequiredBy::Extension {
114+
name: extension.name.unwrap_borrowed(),
115+
};
116+
117+
for require in &extension.requires {
118+
for require_type in &require.types {
119+
types_required_by.insert(require_type.name.unwrap_borrowed(), required_by);
120+
}
121+
}
122+
}
123+
124+
for structure in &self.xml.structs {
125+
let name = structure.name.unwrap_borrowed();
126+
let Some(&required_by) = types_required_by.get(name) else {
127+
continue;
128+
};
129+
130+
let origin = Origin {
131+
library_id: self.id,
132+
required_by,
133+
};
134+
135+
let structure = Structure::new(origin, structure);
136+
assert!(items.structures.insert(name, structure).is_none());
137+
}
37138
}
38139
}

analysis/src/xml.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,26 @@ type Node<'a> = roxmltree::Node<'a, 'static>;
99
///
1010
/// A `&'static str` is not used directly because sometimes string allocation is
1111
/// needed, for example when replacing `&quot;` with normal quotes.
12-
type XmlStr = Cow<'static, str>;
12+
pub type XmlStr = Cow<'static, str>;
13+
14+
pub trait UnwrapBorrowed<'a, B>
15+
where
16+
B: ToOwned + ?Sized,
17+
{
18+
fn unwrap_borrowed(&self) -> &'a B;
19+
}
20+
21+
impl<'a, B> UnwrapBorrowed<'a, B> for Cow<'a, B>
22+
where
23+
B: ToOwned + ?Sized,
24+
{
25+
fn unwrap_borrowed(&self) -> &'a B {
26+
match self {
27+
Cow::Borrowed(b) => b,
28+
Cow::Owned(_) => panic!("Called `unwrap_borrowed` on `Owned` value"),
29+
}
30+
}
31+
}
1332

1433
/// Retrieves the value of the `node`'s attribute named `name`.
1534
fn attribute(node: Node, name: &str) -> Option<XmlStr> {

ash-rewrite/src/generated/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// DO NOT EDIT: @generated by ash generator-rewrite 2.0.0
2+
pub mod video;
3+
pub mod vk;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// DO NOT EDIT: @generated by ash generator-rewrite 2.0.0
2+
pub struct StdVideoH264SpsVuiFlags;
3+
pub struct StdVideoH264HrdParameters;
4+
pub struct StdVideoH264SequenceParameterSetVui;
5+
pub struct StdVideoH264SpsFlags;
6+
pub struct StdVideoH264ScalingLists;
7+
pub struct StdVideoH264SequenceParameterSet;
8+
pub struct StdVideoH264PpsFlags;
9+
pub struct StdVideoH264PictureParameterSet;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// DO NOT EDIT: @generated by ash generator-rewrite 2.0.0
2+
pub struct StdVideoDecodeH264PictureInfoFlags;
3+
pub struct StdVideoDecodeH264PictureInfo;
4+
pub struct StdVideoDecodeH264ReferenceInfoFlags;
5+
pub struct StdVideoDecodeH264ReferenceInfo;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// DO NOT EDIT: @generated by ash generator-rewrite 2.0.0
2+
pub struct StdVideoEncodeH264WeightTableFlags;
3+
pub struct StdVideoEncodeH264WeightTable;
4+
pub struct StdVideoEncodeH264SliceHeaderFlags;
5+
pub struct StdVideoEncodeH264PictureInfoFlags;
6+
pub struct StdVideoEncodeH264ReferenceInfoFlags;
7+
pub struct StdVideoEncodeH264ReferenceListsInfoFlags;
8+
pub struct StdVideoEncodeH264RefListModEntry;
9+
pub struct StdVideoEncodeH264RefPicMarkingEntry;
10+
pub struct StdVideoEncodeH264ReferenceListsInfo;
11+
pub struct StdVideoEncodeH264PictureInfo;
12+
pub struct StdVideoEncodeH264ReferenceInfo;
13+
pub struct StdVideoEncodeH264SliceHeader;

0 commit comments

Comments
 (0)