Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 40 additions & 32 deletions vello/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,41 +427,49 @@ impl Renderer for VelloRenderer {
if self.capture {
self.render_capture_image()
} else {
if let Ok(surface_texture) = self.surface.surface.get_current_texture() {
self.renderer
.render_to_texture(
&self.device,
&self.queue,
&self.scene,
&self.surface.target_view,
&vello::RenderParams {
base_color: palette::css::TRANSPARENT, // Background color
width: self.surface.config.width,
height: self.surface.config.height,
antialiasing_method: vello::AaConfig::Msaa16,
},
)
.unwrap();

// Perform the copy
let mut encoder =
self.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Surface Blit"),
});
self.surface.blitter.copy(
let surface_texture = match self.surface.surface.get_current_texture() {
Ok(surface_texture) => surface_texture,
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
self.surface
.surface
.configure(&self.device, &self.surface.config);
return None;
}
_ => return None,
};
self.renderer
.render_to_texture(
&self.device,
&mut encoder,
&self.queue,
&self.scene,
&self.surface.target_view,
&surface_texture
.texture
.create_view(&wgpu::TextureViewDescriptor::default()),
);
self.queue.submit([encoder.finish()]);
&vello::RenderParams {
base_color: palette::css::TRANSPARENT, // Background color
width: self.surface.config.width,
height: self.surface.config.height,
antialiasing_method: vello::AaConfig::Msaa16,
},
)
.unwrap();

// Perform the copy
let mut encoder = self
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Surface Blit"),
});
self.surface.blitter.copy(
&self.device,
&mut encoder,
&self.surface.target_view,
&surface_texture
.texture
.create_view(&wgpu::TextureViewDescriptor::default()),
);
self.queue.submit([encoder.finish()]);

// Queue the texture to be presented on the surface
surface_texture.present();
}
// Queue the texture to be presented on the surface
surface_texture.present();
None
}
}
Expand Down
52 changes: 29 additions & 23 deletions vger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,29 +710,35 @@ impl Renderer for VgerRenderer {
if self.capture {
self.render_image()
} else {
if let Ok(frame) = self.surface.get_current_texture() {
let texture_view = frame
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
let desc = wgpu::RenderPassDescriptor {
label: None,
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &texture_view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
store: StoreOp::Store,
},
depth_slice: None,
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
};

self.vger.encode(&desc);
frame.present();
}
let frame = match self.surface.get_current_texture() {
Ok(frame) => frame,
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {

@0xNULLderef 0xNULLderef May 11, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WebGpu examples also choose to handle wgpu::SurfaceError::Other and wgpu::SurfaceError::OutOfMemory. Not relevant on niri (from my testing), but it might help getting a present instead of a frozen mess in some other specific edge cases

they also choose to attempt a get again but I'm not that thoroughly versed in Vulkan to decide whether this or the other approach is better

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's interesting. In the wgpu docs, it's described a bit differently:

Lost and Outdated are the two variants where wgpu itself explicitly recommends recreating the surface: https://docs.rs/wgpu/27.0.1/wgpu/enum.SurfaceError.html#variants

It seems in their example they opted for a broad "just reconfigure will fix it" catch-all approach, but it might make sense to only handle what's actually a surface configuration issue.

OOM shouldn't really try to recreate the surface if memory is starved (wouldn't be able to create a new frame anway - the comment in their example even says that), and Other would need to be inspected to decide what to do.

self.surface.configure(&self.device, &self.config);
return None;
}
_ => return None,
};
let texture_view = frame
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
let desc = wgpu::RenderPassDescriptor {
label: None,
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &texture_view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
store: StoreOp::Store,
},
depth_slice: None,
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
};

self.vger.encode(&desc);
frame.present();
None
}
}
Expand Down
Loading