Skip to content

Commit 948ccfd

Browse files
cwfitzgeralddavnotdev
authored andcommitted
Properly Deal with Timeouts (gfx-rs#7030)
1 parent 8cfa35c commit 948ccfd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+470
-353
lines changed

CHANGELOG.md

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Bottom level categories:
4040

4141
## Unreleased
4242

43-
### Major Changes
43+
### Major Features
4444

4545
#### Hashmaps Removed from APIs
4646

@@ -51,6 +51,66 @@ also allows more easily creating these structures inline.
5151

5252
By @cwfitzgerald in [#7133](https://github.com/gfx-rs/wgpu/pull/7133)
5353

54+
#### `device.poll` Api Reworked
55+
56+
This release reworked the poll api significantly to allow polling to return errors when polling hits internal timeout limits.
57+
58+
`Maintain` was renamed `PollType`. Additionally, `poll` now returns a result containing information about what happened during the poll.
59+
60+
```diff
61+
-pub fn wgpu::Device::poll(&self, maintain: wgpu::Maintain) -> wgpu::MaintainResult
62+
+pub fn wgpu::Device::poll(&self, poll_type: wgpu::PollType) -> Result<wgpu::PollStatus, wgpu::PollError>
63+
64+
-device.poll(wgpu::Maintain::Poll);
65+
+device.poll(wgpu::PollType::Poll).unwrap();
66+
```
67+
68+
```rust
69+
pub enum PollType<T> {
70+
/// On wgpu-core based backends, block until the given submission has
71+
/// completed execution, and any callbacks have been invoked.
72+
///
73+
/// On WebGPU, this has no effect. Callbacks are invoked from the
74+
/// window event loop.
75+
WaitForSubmissionIndex(T),
76+
/// Same as WaitForSubmissionIndex but waits for the most recent submission.
77+
Wait,
78+
/// Check the device for a single time without blocking.
79+
Poll,
80+
}
81+
82+
pub enum PollStatus {
83+
/// There are no active submissions in flight as of the beginning of the poll call.
84+
/// Other submissions may have been queued on other threads during the call.
85+
///
86+
/// This implies that the given Wait was satisfied before the timeout.
87+
QueueEmpty,
88+
89+
/// The requested Wait was satisfied before the timeout.
90+
WaitSucceeded,
91+
92+
/// This was a poll.
93+
Poll,
94+
}
95+
96+
pub enum PollError {
97+
/// The requested Wait timed out before the submission was completed.
98+
Timeout,
99+
}
100+
```
101+
102+
> [!WARNING]
103+
> As part of this change, WebGL's default behavior has changed. Previously `device.poll(Wait)` appeared as though it functioned correctly. This was a quirk caused by the bug that these PRs fixed. Now it will always return `Timeout` if the submission has not already completed. As many people rely on this behavior on WebGL, there is a new options in `BackendOptions`. If you want the old behavior, set the following on instance creation:
104+
>
105+
> ```rust
106+
> instance_desc.backend_options.gl.fence_behavior = wgpu::GlFenceBehavior::AutoFinish;
107+
> ```
108+
>
109+
> You will lose the ability to know exactly when a submission has completed, but `device.poll(Wait)` will behave the same as it does on native.
110+
111+
By @cwfitzgerald in [#6942](https://github.com/gfx-rs/wgpu/pull/6942).
112+
By @cwfitzgerald in [#7030](https://github.com/gfx-rs/wgpu/pull/7030).
113+
54114
### New Features
55115
56116
#### General

Cargo.lock

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

benches/benches/bind_groups.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ fn run_bench(ctx: &mut Criterion) {
152152
duration += start.elapsed();
153153

154154
drop(bind_group);
155-
state.device_state.device.poll(wgpu::Maintain::Wait);
155+
state
156+
.device_state
157+
.device
158+
.poll(wgpu::PollType::Wait)
159+
.unwrap();
156160
}
157161

158162
duration

benches/benches/computepass.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,11 @@ fn run_bench(ctx: &mut Criterion) {
486486
duration += start.elapsed();
487487
}
488488

489-
state.device_state.device.poll(wgpu::Maintain::Wait);
489+
state
490+
.device_state
491+
.device
492+
.poll(wgpu::PollType::Wait)
493+
.unwrap();
490494
}
491495

492496
duration
@@ -531,7 +535,11 @@ fn run_bench(ctx: &mut Criterion) {
531535
duration += start.elapsed();
532536

533537
state.device_state.queue.submit(buffers);
534-
state.device_state.device.poll(wgpu::Maintain::Wait);
538+
state
539+
.device_state
540+
.device
541+
.poll(wgpu::PollType::Wait)
542+
.unwrap();
535543
}
536544

537545
duration
@@ -573,7 +581,11 @@ fn run_bench(ctx: &mut Criterion) {
573581
duration += start.elapsed();
574582

575583
state.device_state.queue.submit([buffer]);
576-
state.device_state.device.poll(wgpu::Maintain::Wait);
584+
state
585+
.device_state
586+
.device
587+
.poll(wgpu::PollType::Wait)
588+
.unwrap();
577589
}
578590

579591
duration

benches/benches/renderpass.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,11 @@ fn run_bench(ctx: &mut Criterion) {
492492
duration += start.elapsed();
493493
}
494494

495-
state.device_state.device.poll(wgpu::Maintain::Wait);
495+
state
496+
.device_state
497+
.device
498+
.poll(wgpu::PollType::Wait)
499+
.unwrap();
496500
}
497501

498502
duration
@@ -535,7 +539,11 @@ fn run_bench(ctx: &mut Criterion) {
535539
duration += start.elapsed();
536540

537541
state.device_state.queue.submit(buffers);
538-
state.device_state.device.poll(wgpu::Maintain::Wait);
542+
state
543+
.device_state
544+
.device
545+
.poll(wgpu::PollType::Wait)
546+
.unwrap();
539547
}
540548

541549
duration
@@ -571,7 +579,11 @@ fn run_bench(ctx: &mut Criterion) {
571579
duration += start.elapsed();
572580

573581
state.device_state.queue.submit([buffer]);
574-
state.device_state.device.poll(wgpu::Maintain::Wait);
582+
state
583+
.device_state
584+
.device
585+
.poll(wgpu::PollType::Wait)
586+
.unwrap();
575587
}
576588

577589
duration

benches/benches/resource_creation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fn run_bench(ctx: &mut Criterion) {
6161
drop(buffers);
6262

6363
state.queue.submit([]);
64-
state.device.poll(wgpu::Maintain::Wait);
64+
state.device.poll(wgpu::PollType::Wait).unwrap();
6565
}
6666

6767
duration

deno_webgpu/buffer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ impl GPUBuffer {
161161
while !*done.borrow() {
162162
{
163163
self.instance
164-
.device_poll(self.device, wgpu_types::Maintain::wait())
164+
.device_poll(self.device, wgpu_types::PollType::wait())
165165
.unwrap();
166166
}
167167
tokio::time::sleep(Duration::from_millis(10)).await;

deno_webgpu/device.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ impl GPUDevice {
615615
#[fast]
616616
fn stop_capture(&self) {
617617
self.instance
618-
.device_poll(self.id, wgpu_types::Maintain::wait())
618+
.device_poll(self.id, wgpu_types::PollType::wait())
619619
.unwrap();
620620
self.instance.device_stop_capture(self.id);
621621
}

examples/features/src/framework.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -592,9 +592,7 @@ impl<E: Example + wgpu::WasmNotSendSync> From<ExampleTestParams<E>>
592592

593593
let dst_buffer_slice = dst_buffer.slice(..);
594594
dst_buffer_slice.map_async(wgpu::MapMode::Read, |_| ());
595-
ctx.async_poll(wgpu::Maintain::wait())
596-
.await
597-
.panic_on_timeout();
595+
ctx.async_poll(wgpu::PollType::wait()).await.unwrap();
598596
let bytes = dst_buffer_slice.get_mapped_range().to_vec();
599597

600598
wgpu_test::image::compare_image_output(

examples/features/src/hello_synchronization/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ async fn get_data<T: bytemuck::Pod>(
183183
let buffer_slice = staging_buffer.slice(..);
184184
let (sender, receiver) = flume::bounded(1);
185185
buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap());
186-
device.poll(wgpu::Maintain::wait()).panic_on_timeout();
186+
device.poll(wgpu::PollType::wait()).unwrap();
187187
receiver.recv_async().await.unwrap().unwrap();
188188
output.copy_from_slice(bytemuck::cast_slice(&buffer_slice.get_mapped_range()[..]));
189189
staging_buffer.unmap();

0 commit comments

Comments
 (0)