Rebuild a suboptimal swapchain after presenting, not before

`Surface::configure` panics while a texture the surface handed out is still
alive, which wgpu says at both `configure` and `get_current_texture`. The
`Suboptimal` arm configured with the texture it was about to draw with in
hand, so the first suboptimal frame -- a resize or a display change on some
drivers -- takes the app down instead of rebuilding the swapchain.

The texture is good for this frame, so it is drawn with and presented, and
the rebuild happens once `present` has consumed it.
This commit is contained in:
iris-ai committed 2026-09-20 01:00:05 -04:00
1 parent d8d51221ee
commit 02048eab77
1 file changed
+9 -6
+9 -6
View File
@@ -22,12 +22,12 @@ impl UiRenderer {
} }
pub fn draw(&mut self) { pub fn draw(&mut self) {
let output = match self.surface.get_current_texture() { let (output, suboptimal) = match self.surface.get_current_texture() {
CurrentSurfaceTexture::Success(texture) => texture, CurrentSurfaceTexture::Success(texture) => (texture, false),
CurrentSurfaceTexture::Suboptimal(texture) => { // Used for this frame, and the swapchain rebuilt after it has
self.surface.configure(&self.device, &self.config); // been presented: configuring the surface while a texture it
texture // handed out is still alive panics.
} CurrentSurfaceTexture::Suboptimal(texture) => (texture, true),
CurrentSurfaceTexture::Outdated | CurrentSurfaceTexture::Lost => { CurrentSurfaceTexture::Outdated | CurrentSurfaceTexture::Lost => {
self.surface.configure(&self.device, &self.config); self.surface.configure(&self.device, &self.config);
return; return;
@@ -60,6 +60,9 @@ impl UiRenderer {
self.queue.submit(std::iter::once(encoder.finish())); self.queue.submit(std::iter::once(encoder.finish()));
self.window.pre_present_notify(); self.window.pre_present_notify();
self.queue.present(output); self.queue.present(output);
if suboptimal {
self.surface.configure(&self.device, &self.config);
}
} }
pub fn resize(&mut self, size: &PhysicalSize<u32>) { pub fn resize(&mut self, size: &PhysicalSize<u32>) {