-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
analysis: Introduce Vulkan XML parser #745
base: master
Are you sure you want to change the base?
Conversation
@Friz64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking very clean and simple, I really like it thus far!
Curious to see how much processing we're going to have to do on top and how sane we can make it (consider e.g. recent issues about multiple features/extensions depending on and providing the same functions and types, etc).
analysis/src/xml.rs
Outdated
Some("struct") => { | ||
registry.struct_aliases.push(Alias::from_node(type_node)); | ||
} | ||
_ => (), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Warn about new/unhandled items? Same below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I designed this parser around it only filtering out data WE want, and ignoring everything else. If new nodes with an unknown category get added, and we want to use that data, we can easily expand this. It's not often that there are new types of data points which are of use to our generator, and adding checks everywhere throughout the code to look for these feels unnecessary in my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is true, it's not like we provide just the parser and need to be alerted whenever new elements / attributes are added; instead we might notice when updating to a newer vk.xml
and implement it from the get-go, or need to implement it to be able to generate the right code for a new pattern.
Will consider this resolved now, though a debug!()
stating all the features that we haven't implemented (for sensible reasons) might still be nice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
though a
debug!()
stating all the features that we haven't implemented (for sensible reasons) might still be nice
Implemented this. I have also set up env_logger
to go along with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented this. I have also set up
env_logger
to go along with this.
Hm, CI fails because env_logger
0.11, which came out just hours ago, has an MSRV of 1.71. It's probably not worth bumping our MSRV over this? So, is it fine depending on env_logger
0.10? Or maybe use another logging library?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Switched to tracing
now, which is more modern.
node.attribute("supported") | ||
.map(|values| values.split(',').any(|support| support == api)) | ||
.unwrap_or(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deduplicate with api_matches
? Only the attribute name is different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only place in the code where we have to filter for the string "supported" instead of the much more common "api", so I decided not to disturb the api_matches
function and just have a special case here. We could also have api_matches
call another function attribute_matches
with this code, and then use that here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Do we remember what the difference was between api
and supported
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not exactly the same as api
, because it's value can also be disabled
.
Side note, this also means that we automatically skip all disabled extensions as a consequence of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also have
api_matches
call another functionattribute_matches
with this code, and then use that here.
So, to be clear, did you suggest that this should be done?
analysis/src/xml.rs
Outdated
fn child_text(node: Node, name: &str) -> Option<XmlStr> { | ||
let child = node.children().find(|node| node.has_tag_name(name)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think we need more StringStorage
-> Cow
conversions, and should we factor it out into a function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There probably won't be any more conversions. We could factor it out, but I don't think it's really worth it currently.
@Friz64 looks like we have a few comments left after which we should be ready to merge this and build the next layer on top.
Seems fine to me as it is, every struct and field name corresponds to the XML element / attribute name AFAIR. I wonder if this crate should be renamed to |
Trying to get back into working on this. Sorry for the silence. Life is hard.
The intention was for this crate to contain the |
330a9dd
to
8035d4d
Compare
The next layer on top of this should take care of all remaining parsing. For this, I was reading back on the conversation in #662, and the conclusion we seemingly came to for C parsing was to use a parsing library, not on the whole spec at once, but on small chunks, lifted from the XML. One idea was to leverage the Today, I again searched for other C parsing libraries we could use, and one stuck out to me: |
Sorry if this was discussed before (I couldn't easily find this specific point brought up), but: <member><type>uint8_t</type> <name>pipelineIdentifier</name>[<enum>VK_UUID_SIZE</enum>]</member> The actual XML has Even without the (if you'll excuse my shorthand - If there are counter-examples to that idea, I'd love to see them, because it's the direction I would've went in, for my own coincidental I'm really tempted to try to at least categorize the shapes of child nodes (and text between them), which are currently flattened in this PR's (disclaimer: back in the C11 days, I wrote a C declaration parser/compiler on top of someone else's yacc grammar, so the quirks of the syntax, like order independence of specifiers and the inside-out mode when the "declaree" is parenthesized, are "burned-in", making custom C parsers more appealing than they should be - my only hope is Khronos having been sensible enough, really) EDIT: this went smoother than expected (except for the hard part of 11 function pointer template<typename T> using Id = T;
#define _(X) Id<X>
_(_(_(R(A, B, C))*)[3]) *f; C++ lets us add a crude form of parentheses, which then lets us force the a much more intuitive nesting, and if removing those parentheses was viable, we'd be left with |
Looks like custom parsing was 100% viable. By far most of the effort was spent making it powerful enough to handle the 11 function pointer Outside of that, the only 2D array is in
|
Finally dug enough into the old generator to see how the C parsing works there: Lines 86 to 272 in 92084df
I would agree with anyone who would want to replace that, and here's my first impressions:
With some of these aspects I feel a bit out of my depth, especially when it comes to "what other efforts are out there and am I at risk of duplicating work?", but nothing else I've seen so far seems principled enough (at most there's a lot of reliance on the limited set of possible patterns which is somewhat reasonable I suppose). |
We use both. With this approach from @Friz64 we should no longer need to rely on A little warning: this PR sat stale since June 2023, and right as activity is picking back up now, I'll be away from computers all of February. I hope no-one is affected by my absence and feel free to keep working/discussing on a generator rewrite, but it'll have to do without my input for a while 👍 |
This is not really true anymore with Friz64#1. Other than that, I've come around to saying simple parsing doesn't hurt. |
I've added support for the
|
d610c44
to
c64ea2e
Compare
I tried playing around with this and it's pretty good already, much nicer to use then vk-parse / vkxml. I'm using it for a small codgen task that would live outside of Two small bits of feedback
|
Hey, thanks for taking a look! It's good to have feedback from real world use cases.
This PR doesn't really try to expose a public API for the
C parsing is what Friz64#1 aims to accomplish. I recall that it's in a usable state already, just not 100% finished. This PR is currently marked as draft because the intention is that it gets merged into here first. |
This adds a parser for Vulkan XML registries, namely
vk.xml
andvideo.xml
. It doesn't have a 100% coverage of all possible attributes, and doesn't aim to do so, though it can be easily expanded when necessary. Any additional attributes that are not extracted will simply be ignored.It doesn't try to process the XML in any way at all, even for simple things such as parsing a number.TODO