Build on wgpu 30

Two majors, and the renderer is under everything else that is left to
extract, so it goes before the slices that would otherwise be written twice.
`image` 0.25.6 -> 0.25.10 rides along; `winit` stays on 0.30.12, since 0.31
is only a prerelease.

What the API asked for:

- An instance now takes the display it will present on, and GLES on Wayland
  needs it -- so the window the surface is made from is handed over with it.
- `get_current_texture` returns a `CurrentSurfaceTexture` rather than a
  `Result`, which replaces an `unwrap` that would have panicked on a resize
  or an occluded window: reconfigure when the surface is outdated, lost or
  suboptimal, and skip the frame when there is nothing to draw into.
- Presenting moved to the queue, after `pre_present_notify` as before.
- Bind group layouts and vertex buffer layouts are sparse now, so a pipeline
  states `Some(layout)` per slot.

Verified with the three render checks and `tests/draw_cost.rs`: identical
pictures, and 33.6/167/587/2855 us per frame at 8/64/256/1024 layers against
33.3/161/588/2903 on wgpu 28.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-13 18:57:52 -04:00
1 parent b234497d21
commit 0a5eb2d984
5 files changed
+237 -241

No files matched your search

+25 -4
View File
@@ -22,7 +22,23 @@ impl UiRenderer {
}
pub fn draw(&mut self) {
let output = self.surface.get_current_texture().unwrap();
let output = match self.surface.get_current_texture() {
CurrentSurfaceTexture::Success(texture) => texture,
// Still drawable; the surface has just changed under us, and
// reconfiguring is what the next frame wants rather than this one.
CurrentSurfaceTexture::Suboptimal(texture) => {
self.surface.configure(&self.device, &self.config);
texture
}
CurrentSurfaceTexture::Outdated | CurrentSurfaceTexture::Lost => {
self.surface.configure(&self.device, &self.config);
return;
}
// Nothing to draw into this frame.
CurrentSurfaceTexture::Timeout
| CurrentSurfaceTexture::Occluded
| CurrentSurfaceTexture::Validation => return,
};
let view = output
.texture
.create_view(&TextureViewDescriptor::default());
@@ -46,7 +62,7 @@ impl UiRenderer {
self.queue.submit(std::iter::once(encoder.finish()));
self.window.pre_present_notify();
output.present();
self.queue.present(output);
}
pub fn resize(&mut self, size: &PhysicalSize<u32>) {
@@ -65,9 +81,12 @@ impl UiRenderer {
pub fn new(window: Arc<Window>) -> Self {
let size = window.inner_size();
let instance = Instance::new(&InstanceDescriptor {
// The display handle is what GLES needs to present on Wayland, and it
// has to be the one the surface is made from.
let instance = Instance::new(InstanceDescriptor {
backends: Backends::PRIMARY,
..Default::default()
display: Some(Box::new(window.clone())),
..InstanceDescriptor::new_without_display_handle()
});
let surface = instance
@@ -79,6 +98,7 @@ impl UiRenderer {
power_preference: PowerPreference::default(),
compatible_surface: Some(&surface),
force_fallback_adapter: false,
apply_limit_buckets: false,
})
.block_on()
.expect("Could not get adapter!");
@@ -105,6 +125,7 @@ impl UiRenderer {
let config = SurfaceConfiguration {
usage: TextureUsages::RENDER_ATTACHMENT,
format: surface_format,
color_space: SurfaceColorSpace::Auto,
width: size.width,
height: size.height,
present_mode: PresentMode::AutoVsync,