-
Notifications
You must be signed in to change notification settings - Fork 978
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
Add buffer debug labels #528
Conversation
Yes, this is what I had in mind.
Correct, they are absent today. Should be a part of gfx-rs/gfx#1508 |
I've added debug labels for the items that hal supports and are exposed. I ran the triangle example in RenderDoc and verified that the A few observations:
|
As far as I'm aware, using nightly rustfmt is not uncommon at all. You just do "cargo +nightly install rustfmt-nightly -f" and the rest is the same.
Sounds good!
I disagree. It's annoying to have your CI failed (and everybody losing time blocked on that) simply because there was a piece of formatting that rustfmt didn't like.
what kind of fatigue did you experience?
Unfortunately, now with the labels there isn't another way. So yes, we'll need to duplicate all the descriptors on the Rust side. |
).unwrap(); | ||
if !desc.label.is_null() { | ||
let label = ffi::CStr::from_ptr(desc.label).to_string_lossy(); | ||
self.raw.set_image_name(&mut image, &label); |
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.
hmm, that seems suboptimal. So we are getting *const char
, then converting to &str
to pass to gfx-rs, and then it probably converts it back to *const char
at some point later on... Hmm.
At the same time, this is object creation, so it's not a big concern. Just that it would affect the API.
One way to address this (I'm not sure that we should, but still) is to have something like this:
enum Stringy<'a> {
Rust(&'a str),
C(&'a CStr),
}
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.
Yep - that's the issue I mentioned in the EDIT above.
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 think gfx-hal
should just take CStr
and be done with it. It's purpose is to be low level.
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.
problem is that not all the backends agree on the strings they want. D3D, GL, and Vulkan do agree, but Metal wants NSString anyway, so it doesn't want CStr.
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.
You can convert a CStr
to a &str
by finding the length and creating the slice. You can't go in the other direction without allocating or having an intermediate buffer.
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.
Ah, okay
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 a copy and convert step, just like one would do to convert &str to NSString, or &str to CStr. In that sense, CStr doesn't have an advantage.
Isn't there a copy with &str
to NSString
anyway?
Wont &str
-> &CStr
-> &str
-> [&CStr or NSString]
always be more copies than
&str
-> [&CStr or NSString]
.
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 don't think anybody proposed &str -> &CStr -> &str -> [&CStr or NSString]
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.
&str
-> &CStr
-> &str
-> [&CStr or NSString]
This is what would currently happen with wgpu-rs
. The label comes in as a &str
from the rust descriptor. Then converted to a *const c_char
to use with wgpu-native
descriptor. Then converted back to &str
to pass to gfx-hal
. Then gfx-hal converts it back to CStr
to use with native API (or NSString in the mac case).
Apologies, I'm using CStr
and *const c_char
interchangeably here to indicate a copy to null-terminated buffer.
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 see, yeah. This isn't intended. As outlined in gfx-rs/wgpu-rs#156 , the main critical paths will be via wgpu-core (which works with &str
) or websys, which needs its own strings anyway. Going via wgpu-native C API is kinda silly, only needed for compatibility with C apps and Dawn.
I would argue that most public projects are not using nightly rustfmt / unstable options due to the friction that it causes. For example,
This is easily overcome by making the format check the first step of the CI job. It fails fast, you run I don't want to run |
It was mostly fumbling with cmake and building |
First of all, with the current flow you do not have to do any formatting at all. Less work for you, less worries about. |
@aloucks we had a conversation about formatting of the project with a Gecko engineer and agreed to format this with an empty configuration on rustfmt stable. Let's not do any formatting in this PR and then follow up with all-format PR once the dust settles with the open PRs, ok? |
cool |
Can we do the same with |
The wgpu-rs doesn't have that requirement of being consistent with Gecko code, so it's still on the table. Let's not rush this just yet. |
- bind group - bind group layout - command encoder - texture
@kvark I'v rebased and fixed merge conflicts. I'd like to tackle the command encoder push/pop labels separately. With that said, merging this will require all of the affected descriptor types to be duplicated in wgpu-rs. |
@aloucks thank you!
Not sure what do do here. One "solution" is to convert gfx-rs to accept *const char for all labels. Another is more involved - having wgpu-core truly work with Rusty structures, and then have something on top for raw pointers in wgpu-native/wgpu-remote. |
As much as I dislike duplication of code, I think it's appropriate in this case. I think all of the
This is what I was arguing for above! :) I don't particularly care if it's |
@kvark IMO multiple string conversions for debug labels isn't too much of an issue so it's mostly just a question of which API we'd like to work with at each level. Although it does seem pretty reasonable to accept |
@grovesNL I'm not worried about object labels (this PR) as much as the markers. I imagine it being useful to just mostly have markers enabled (i.e. both debug and release builds, just not fully optimized shipping ones). And having a few heap allocations on every marker can have a devastating effect during command encoding. |
@kvark I've got an idea with flexible inlined strings. I'll update the PR later this evening. |
Wanted to follow up on that with this little quote from rustfmt itself:
Rustfmt stable is not a valid choice, it's deprecated. |
I'm fairly certain that it's not deprecated. I think you get that error if you installed rustfmt from |
Interesting. I'm currently trying to get it running from rustup component instead. Didn't realize the cargo binary could be outdated. |
|
Silly question: how are you running it from the installed component? I see that the binaries are installed in |
If you look in |
|
Got the binaries after |
@kvark I've pushed a new commit with inlinable labels. This works for now but I think long/medium term this needs to move to gfx-rs. This is the course of action I think we should take:
|
wgpu-core/src/device/mod.rs
Outdated
@@ -321,6 +321,12 @@ impl<B: GfxBackend> Device<B> { | |||
}; | |||
|
|||
let mut buffer = unsafe { self.raw.create_buffer(desc.size, usage).unwrap() }; | |||
let label = conv::label_from_ptr(desc.label); |
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 was just browsing the docs now, and noticed that to_string_lossy
just borrows the existing contents when the string is a valid UTF8. I think that's all we really need here?
Do you think we could remove all the Label
stuff and just call to_string_lossy
on them before passing to gfx-hal?
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.
Or even just to_str
and log::warn
on being unable to get Ok()
from it (ignoring the label in this case)
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 could remove all the Label stuff and just call to_string_lossy on them before passing to gfx-hal?
This is what I had before.
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.
Deeply sorry if I missed that somehow! Could you link to that comment please?
I somehow assumed that all the conversion involve heap allocations before...
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.
Maybe we should just hold off on this until gfx-hal is updated? The inlinable label stuff should be there anyway, as I described above.
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'm not quite feeling comfortable with having Label
in gfx-hal at this point. Maybe I need to grow to it? :)
Also, gfx-hal was just released, and we are updating wgpu to use it (#537). We typically try to stay on the published version of gfx, since otherwise it's harder to patch things up.
Let's proceed with your original code? (I slightly prefer to_str
with warning on failure, but we can change that later)
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.
@kvark I rolled off the last commit and force pushed.
The inlinable label is left here if there's any interest in it later: https://github.com/aloucks/wgpu/tree/buffer_label_with_inline_string
wgpu-types/src/lib.rs
Outdated
|
||
impl Default for CommandEncoderDescriptor { | ||
fn default() -> CommandEncoderDescriptor { | ||
unsafe { std::mem::zeroed() } |
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.
why use zeroed instead of just assigning ptr::null()
safely?
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 can't remember at this point, but mem::zeroed
is safe in this context. All zeros is a valid bit pattern for CommandEncoderDescriptor
as it exists in this PR. However, I could see how someone could accidentally make it UB later (e.g. if for some reason a reference field was added).
I'll change it to use ptr::null
.
bors r+ |
Build succeeded |
Related #404
@kvark Is this what you had in mind? The webgpu headers have labels on all the descriptor structs and I didn't see any specific functions for altering/adding labels after creation. I'll add the rest if this looks good to you.
I also went looking for command buffer marker support in gfx-hal so that I could add group labels and markers. Is this functionality absent in
hal
or did I miss it?