Skip to content

Commit 34745e8

Browse files
committed
Single squashed commit to fix present bugs & rework api
1 parent 81eca17 commit 34745e8

File tree

33 files changed

+732
-183
lines changed

33 files changed

+732
-183
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Bottom level categories:
5353
#### General
5454

5555
- `Features::CLIP_DISTANCE`, `naga::Capabilities::CLIP_DISTANCE`, and `naga::BuiltIn::ClipDistance` have been renamed to `CLIP_DISTANCES` and `ClipDistances` (viz., pluralized) as appropriate, to match the WebGPU spec. By @ErichDonGubler in [#9267](https://github.com/gfx-rs/wgpu/pull/9267).
56+
- `Surface::present` has been moved to `Queue::present`. By @inner-daemons in [#9222](https://github.com/gfx-rs/wgpu/pull/9222).
5657

5758
#### Validation
5859

@@ -63,6 +64,7 @@ Bottom level categories:
6364
#### General
6465

6566
- Fix limit comparison logic for `max_inter_stage_shader_variables` By @ErichDonGubler in [9264](https://github.com/gfx-rs/wgpu/pull/9264).
67+
- Fix several bugs related to surface presentation, including presenting without rendering and dropping queue after presenting. By @inner-daemons in [#9222](https://github.com/gfx-rs/wgpu/pull/9222).
6668

6769
#### naga
6870

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/bug-repro/01_texture_atomic_bug/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ publish = false
77
[dependencies]
88
env_logger = "0.11"
99
pollster = "0.4"
10-
wgpu = "29.0.0"
10+
wgpu.workspace = true
1111
winit = "0.30.8"

examples/bug-repro/01_texture_atomic_bug/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,6 @@ impl State {
335335
}
336336

337337
self.queue.submit([enc.finish()]);
338-
frame.present();
338+
self.queue.present(frame);
339339
}
340340
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "wgpu-bug-repro-02-present-bugs"
3+
edition = "2021"
4+
rust-version = "1.87"
5+
publish = false
6+
7+
[dependencies]
8+
env_logger = "0.11"
9+
pollster = "0.4"
10+
wgpu.workspace = true
11+
winit = "0.30.8"
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
//! Repro for various issues with queue presentation
2+
//!
3+
//! The 2 current bugs being tested are presentation after no usage of surface texture
4+
//! and queue destruction immediately after present
5+
6+
use std::sync::Arc;
7+
8+
use winit::application::ApplicationHandler;
9+
use winit::event::WindowEvent;
10+
use winit::event_loop::{ActiveEventLoop, EventLoop};
11+
use winit::window::{Window, WindowId};
12+
13+
fn main() {
14+
env_logger::init();
15+
let event_loop = EventLoop::new().unwrap();
16+
event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
17+
let mut app = App::default();
18+
event_loop.run_app(&mut app).unwrap();
19+
}
20+
21+
#[derive(Default)]
22+
struct App {
23+
state: Option<State>,
24+
}
25+
26+
struct State {
27+
window: Arc<Window>,
28+
instance: wgpu::Instance,
29+
device: wgpu::Device,
30+
queue: Option<wgpu::Queue>,
31+
surface: wgpu::Surface<'static>,
32+
surface_config: wgpu::SurfaceConfiguration,
33+
}
34+
35+
impl ApplicationHandler for App {
36+
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
37+
if self.state.is_some() {
38+
return;
39+
}
40+
let window = Arc::new(
41+
event_loop
42+
.create_window(Window::default_attributes().with_title("Presentation bugs"))
43+
.unwrap(),
44+
);
45+
self.state = Some(State::new(window));
46+
}
47+
48+
fn window_event(
49+
&mut self,
50+
event_loop: &ActiveEventLoop,
51+
_window_id: WindowId,
52+
event: WindowEvent,
53+
) {
54+
let Some(state) = &mut self.state else { return };
55+
match event {
56+
WindowEvent::CloseRequested => event_loop.exit(),
57+
WindowEvent::Resized(size) if size.width > 0 && size.height > 0 => {
58+
state.surface_config.width = size.width;
59+
state.surface_config.height = size.height;
60+
state
61+
.surface
62+
.configure(&state.device, &state.surface_config);
63+
}
64+
WindowEvent::RedrawRequested => {
65+
let frame = match state.surface.get_current_texture() {
66+
wgpu::CurrentSurfaceTexture::Success(f) => f,
67+
wgpu::CurrentSurfaceTexture::Suboptimal(_)
68+
| wgpu::CurrentSurfaceTexture::Outdated => {
69+
state
70+
.surface
71+
.configure(&state.device, &state.surface_config);
72+
return;
73+
}
74+
wgpu::CurrentSurfaceTexture::Lost => {
75+
state.surface =
76+
state.instance.create_surface(state.window.clone()).unwrap();
77+
state
78+
.surface
79+
.configure(&state.device, &state.surface_config);
80+
return;
81+
}
82+
_ => return,
83+
};
84+
let Some(queue) = state.queue.take() else {
85+
return;
86+
};
87+
// Immediately present the surface texture (with nothing on it) and then drop the queue, which should cause a full wait.
88+
queue.present(frame);
89+
event_loop.exit();
90+
}
91+
_ => {}
92+
}
93+
}
94+
95+
fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) {
96+
if let Some(state) = &self.state {
97+
state.window.request_redraw();
98+
}
99+
}
100+
}
101+
102+
impl State {
103+
fn new(window: Arc<Window>) -> Self {
104+
let size = window.inner_size();
105+
let width = size.width.max(1);
106+
let height = size.height.max(1);
107+
108+
let mut instance_desc = wgpu::InstanceDescriptor::new_without_display_handle_from_env();
109+
instance_desc.flags |= wgpu::InstanceFlags::advanced_debugging();
110+
let instance = wgpu::Instance::new(instance_desc);
111+
let surface = instance.create_surface(window.clone()).unwrap();
112+
let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions {
113+
compatible_surface: Some(&surface),
114+
..Default::default()
115+
}))
116+
.expect("No adapter");
117+
118+
println!("Adapter: {:?}", adapter.get_info().name);
119+
120+
let (device, queue) =
121+
pollster::block_on(adapter.request_device(&Default::default())).unwrap();
122+
123+
let surface_format = surface.get_capabilities(&adapter).formats[0];
124+
let surface_config = wgpu::SurfaceConfiguration {
125+
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
126+
format: surface_format,
127+
width,
128+
height,
129+
present_mode: wgpu::PresentMode::AutoVsync,
130+
alpha_mode: wgpu::CompositeAlphaMode::Auto,
131+
view_formats: vec![],
132+
desired_maximum_frame_latency: 2,
133+
};
134+
surface.configure(&device, &surface_config);
135+
136+
State {
137+
window,
138+
instance,
139+
device,
140+
queue: Some(queue),
141+
surface,
142+
surface_config,
143+
}
144+
}
145+
}

examples/features/src/framework.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ impl<E: Example> ApplicationHandler<AppAction> for App<E> {
548548
if let Some(window) = &self.window {
549549
window.pre_present_notify();
550550
}
551-
frame.present();
551+
context.queue.present(frame);
552552
}
553553

554554
if let Some(window) = &self.window {

examples/features/src/hello_triangle/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ impl ApplicationHandler<TriangleAction> for App {
289289
if let Some(window) = &self.window {
290290
window.pre_present_notify();
291291
}
292-
frame.present();
292+
wgpu_state.queue.present(frame);
293293
}
294294
WindowEvent::Occluded(is_occluded) => {
295295
if !is_occluded {

examples/features/src/hello_windows/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ impl ApplicationHandler for App {
249249

250250
queue.submit(Some(encoder.finish()));
251251
viewport.desc.window.pre_present_notify();
252-
frame.present();
252+
queue.present(frame);
253253
}
254254
}
255255
WindowEvent::Occluded(is_occluded) => {

examples/features/src/uniform_values/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ impl ApplicationHandler<UniformAction> for App {
470470
if let Some(window) = &self.window {
471471
window.pre_present_notify();
472472
}
473-
frame.present();
473+
wgpu_ctx.queue.present(frame);
474474
}
475475
WindowEvent::Occluded(is_occluded) => {
476476
if !is_occluded {

0 commit comments

Comments
 (0)