-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Update sampler along with texture on wgpu backend #5122
Conversation
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.
thanks for finding and fixing this!
Not sure whether removing and reinserting the texture from and into the textures map, or creating a new bind group, has much of a performance impact.
I'm not worried about removing and inserting the texture as this is a fairly fast operation. But re-creating the bind-group every time is indeed a bit worrisome to me since this is an extra resource that has to be taken care of by wgpu and the driver. (On the web this even needs to wait garbage collection if the old one isn't explicitly destroyed).
I figure solving this shouldn't be too hard: We just store something like this on the hashmap
struct Texture {
/// The texture may be None if the `TextureId` is just a handle to a user-provided sampler.
texture: Option<wgpu::Texture>,
/// Bindgroup for the texture + sampler.
bind_group: wgpu::BindGroup,
/// Options describing the sampler used in the bind group.
options: epaint::textures::TextureOptions,
}
and recreate/fetch sampler & recreate bindgroup only if the options have a mismatch.
Oh and while you're on it: let's call destroy
if we discard a bind_group.
It doesn't make a difference on native, but right now wgpu doesn't call that for you on object death when being on WebGPU. This is relevant because all WebGPU objects live in Javascript land and thus get only destroyed once the garbage collector runs over them.
Same on free_texture
for the texture and bindgroup. (calling destroy invalidates every wgpu object that uses the resource at that point and hasn't submitted its operations yet, but free_texture
is &mut
and render
is &self
, so we should be good!)
I've updated the code to store the
I've also made it so that |
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.
oh, interesting! Wasn't aware that BindGroup
has no destroy
.
Small nit on doc string otherwise good to go imho. Thanks for taking care of everything!
<!-- Please read the "Making a PR" section of [`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/CONTRIBUTING.md) before opening a Pull Request! * Keep your PR:s small and focused. * The PR title is what ends up in the changelog, so make it descriptive! * If applicable, add a screenshot or gif. * If it is a non-trivial addition, consider adding a demo for it to `egui_demo_lib`, or a new example. * Do NOT open PR:s from your `master` branch, as that makes it hard for maintainers to test and add commits to your PR. * Remember to run `cargo fmt` and `cargo clippy`. * Open the PR as a draft until you have self-reviewed it and run `./scripts/check.sh`. * When you have addressed a PR comment, mark it as resolved. Please be patient! I will review your PR, but my time is limited! --> * Closes emilk#5121 * [x] I have followed the instructions in the PR template This unifies the code paths in `update_texture` somewhat, so that the texture sampler and bind group are always replaced. Not sure whether removing and reinserting the texture from and into the `textures` map, or creating a new bind group, has much of a performance impact. An alternative, as described in emilk#5121, would be to split the functionality for updating a texture's data from updating its options, so that we don't have to unconditionally update the bind group (or do something like store the options to check if they're changed).
egui_glow
but notegui_wgpu
#5121This unifies the code paths in
update_texture
somewhat, so that the texture sampler and bind group are always replaced.Not sure whether removing and reinserting the texture from and into the
textures
map, or creating a new bind group, has much of a performance impact. An alternative, as described in #5121, would be to split the functionality for updating a texture's data from updating its options, so that we don't have to unconditionally update the bind group (or do something like store the options to check if they're changed).