Fix missing viewport surfaces after a skipped startup frame (#1791)
Thanks @allisonChilton.
This commit is contained in:
1 parent
44732f8b40
commit
8c58efdecf
3 files changed
+45
-37
No files matched your search
@@ -466,3 +466,5 @@ and shares that effective count with the surface attachments and CAD callbacks.
|
||||
Vulkan, DirectX 12, Metal and WebGPU retain their requested multisampling.
|
||||
A frame whose meshes the GPU refuses to stage (device lost or out of memory) is
|
||||
skipped with a warning instead of panicking (#1469).
|
||||
Paint callbacks are prepared only after a drawable is acquired, so a skipped
|
||||
surface frame cannot strand cached meshes without their GPU initialization.
|
||||
Vendored
+2
@@ -210,3 +210,5 @@ SolidCraft changes:
|
||||
clamped to it (`clamp_surface_extent`, aspect ratio kept) and egui is drawn at the matching
|
||||
smaller scale, instead of a `Surface::configure` validation panic (#869). The resize path and
|
||||
an unsupported surface no longer unwrap.
|
||||
- `src/winit.rs`: acquire a drawable before preparing paint callbacks, so a skipped
|
||||
surface frame cannot discard initialization commands for cached viewport meshes.
|
||||
Vendored
+41
-37
@@ -588,43 +588,6 @@ impl Painter {
|
||||
return vsync_sec;
|
||||
};
|
||||
|
||||
let mut encoder =
|
||||
render_state
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: Some("encoder"),
|
||||
});
|
||||
|
||||
// Upload all resources for the GPU.
|
||||
// SolidCraft: a clamped surface draws the whole window at a smaller scale.
|
||||
let screen_descriptor = renderer::ScreenDescriptor {
|
||||
size_in_pixels: [surface_state.width, surface_state.height],
|
||||
pixels_per_point: pixels_per_point * surface_state.scale,
|
||||
};
|
||||
|
||||
let user_cmd_bufs = {
|
||||
let mut renderer = render_state.renderer.write();
|
||||
#[expect(clippy::iter_over_hash_type)] // Order doesn't matter here
|
||||
for (id, image_deltas) in textures_delta.set.drain() {
|
||||
for image_delta in image_deltas {
|
||||
renderer.update_texture(
|
||||
&render_state.device,
|
||||
&render_state.queue,
|
||||
id,
|
||||
&image_delta,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
renderer.update_buffers(
|
||||
&render_state.device,
|
||||
&render_state.queue,
|
||||
&mut encoder,
|
||||
clipped_primitives,
|
||||
&screen_descriptor,
|
||||
)
|
||||
};
|
||||
|
||||
if surface_state.needs_reconfigure {
|
||||
Self::configure_surface(surface_state, render_state, &self.config.surface);
|
||||
surface_state.needs_reconfigure = false;
|
||||
@@ -670,6 +633,47 @@ impl Painter {
|
||||
}
|
||||
};
|
||||
|
||||
// SolidCraft: acquire the drawable before preparing callbacks. Preparation can
|
||||
// cache GPU resources whose initialization is recorded into `encoder` (such as
|
||||
// the viewport's tessellated vertices). If acquisition skips this frame, dropping
|
||||
// that encoder leaves the cached resources uninitialized on every later frame.
|
||||
let mut encoder =
|
||||
render_state
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: Some("encoder"),
|
||||
});
|
||||
|
||||
// Upload all resources for the GPU.
|
||||
// SolidCraft: a clamped surface draws the whole window at a smaller scale.
|
||||
let screen_descriptor = renderer::ScreenDescriptor {
|
||||
size_in_pixels: [surface_state.width, surface_state.height],
|
||||
pixels_per_point: pixels_per_point * surface_state.scale,
|
||||
};
|
||||
|
||||
let user_cmd_bufs = {
|
||||
let mut renderer = render_state.renderer.write();
|
||||
#[expect(clippy::iter_over_hash_type)] // Order doesn't matter here
|
||||
for (id, image_deltas) in textures_delta.set.drain() {
|
||||
for image_delta in image_deltas {
|
||||
renderer.update_texture(
|
||||
&render_state.device,
|
||||
&render_state.queue,
|
||||
id,
|
||||
&image_delta,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
renderer.update_buffers(
|
||||
&render_state.device,
|
||||
&render_state.queue,
|
||||
&mut encoder,
|
||||
clipped_primitives,
|
||||
&screen_descriptor,
|
||||
)
|
||||
};
|
||||
|
||||
let mut capture_buffer = None;
|
||||
{
|
||||
let renderer = render_state.renderer.read();
|
||||
|
||||
Reference in new issue
Block a user