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.
|
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
|
A frame whose meshes the GPU refuses to stage (device lost or out of memory) is
|
||||||
skipped with a warning instead of panicking (#1469).
|
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
|
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
|
smaller scale, instead of a `Surface::configure` validation panic (#869). The resize path and
|
||||||
an unsupported surface no longer unwrap.
|
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;
|
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 {
|
if surface_state.needs_reconfigure {
|
||||||
Self::configure_surface(surface_state, render_state, &self.config.surface);
|
Self::configure_surface(surface_state, render_state, &self.config.surface);
|
||||||
surface_state.needs_reconfigure = false;
|
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 mut capture_buffer = None;
|
||||||
{
|
{
|
||||||
let renderer = render_state.renderer.read();
|
let renderer = render_state.renderer.read();
|
||||||
|
|||||||
Reference in new issue
Block a user