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
41 changes: 39 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,52 @@ by if the `Feature::MULTI_DRAW_INDIRECT_COUNT` feature is available on the devic

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


#### `wgpu::PollType::Wait` has now an optional timeout

We removed `wgpu::PollType::WaitForSubmissionIndex` and added fields to `wgpu::PollType::Wait` in order to express timeouts.

Before/after for `wgpu::PollType::Wait`:

```diff
-device.poll(wgpu::PollType::Wait).unwrap();
-device.poll(wgpu::PollType::wait_indefinitely()).unwrap();
+device.poll(wgpu::PollType::Wait {
+ submission_index: None, // Wait for most recent submission
+ timeout: Some(std::time::Duration::from_secs(60)), // Previous behavior, but more likely you want `None` instead.
+ })
+ .unwrap();
```

Before/after for `wgpu::PollType::WaitForSubmissionIndex`:

```diff
-device.poll(wgpu::PollType::WaitForSubmissionIndex(index_to_wait_on))
+device.poll(wgpu::PollType::Wait {
+ submission_index: Some(index_to_wait_on),
+ timeout: Some(std::time::Duration::from_secs(60)), // Previous behavior, but more likely you want `None` instead.
+ })
+ .unwrap();
```

⚠️ Previously, both `wgpu::PollType::WaitForSubmissionIndex` and `wgpu::PollType::Wait` had a hard-coded timeout of 60 seconds.


To wait indefinitely on the latest submission, you can also use the `wait_indefinitely` convenience function:
```rust
device.poll(wgpu::PollType::wait_indefinitely());
```

By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282), [#8285](https://github.com/gfx-rs/wgpu/pull/8285)

### New Features

#### General

- Added mesh shader support to `wgpu`, with examples. Requires passthrough. By @SupaMaggie70Incorporated in [#7345](https://github.com/gfx-rs/wgpu/pull/7345).

- Added support for external textures based on WebGPU's [`GPUExternalTexture`](https://www.w3.org/TR/webgpu/#gpuexternaltexture). These allow shaders to transparently operate on potentially multiplanar source texture data in either RGB or YCbCr formats via WGSL's `texture_external` type. This is gated behind the `Features::EXTERNAL_TEXTURE` feature, which is currently only supported on DX12. By @jamienicol in [#4386](https://github.com/gfx-rs/wgpu/issues/4386).
- `wgpu::Device::poll` can now specify a timeout via `wgpu::PollType::WaitWithTimeout`/`wgpu::PollType::WaitForSubmissionIndexWithTimeout`. By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282)
- `wgpu::Device::poll` can now specify a timeout via `wgpu::PollType::Wait`. By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282) & [#8285](https://github.com/gfx-rs/wgpu/pull/8285)

#### naga

Expand Down Expand Up @@ -195,7 +233,6 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162).
- Require new `F16_IN_F32` downlevel flag for `quantizeToF16`, `pack2x16float`, and `unpack2x16float` in WGSL input. By @aleiserson in [#8130](https://github.com/gfx-rs/wgpu/pull/8130).
- The error message for non-copyable depth/stencil formats no longer mentions the aspect when it is not relevant. By @reima in [#8156](https://github.com/gfx-rs/wgpu/pull/8156).
- Track the initialization status of buffer memory correctly when `copy_texture_to_buffer` skips over padding space between rows or layers, or when the start/end of a texture-buffer transfer is not 4B aligned. By @andyleiserson in [#8099](https://github.com/gfx-rs/wgpu/pull/8099).
- `wgpu::PollType::Wait`/`wgpu::PollType::WaitForSubmissionIndex` will no longer timeout after 60 seconds, but instead wait indefinitely or (depending on backend implementation) until an error is encountered. Use `wgpu::PollType::WaitWithTimeout`/`wgpu::PollType::WaitForSubmissionIndexWithTimeout` if you need a timeout. By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282)

#### naga

Expand Down
2 changes: 1 addition & 1 deletion benches/benches/wgpu-benchmark/bind_groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ fn run_bench(ctx: &mut Criterion) {
state
.device_state
.device
.poll(wgpu::PollType::Wait)
.poll(wgpu::PollType::wait_indefinitely())
.unwrap();
}

Expand Down
6 changes: 3 additions & 3 deletions benches/benches/wgpu-benchmark/computepass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ fn run_bench(ctx: &mut Criterion) {
state
.device_state
.device
.poll(wgpu::PollType::Wait)
.poll(wgpu::PollType::wait_indefinitely())
.unwrap();
}

Expand Down Expand Up @@ -538,7 +538,7 @@ fn run_bench(ctx: &mut Criterion) {
state
.device_state
.device
.poll(wgpu::PollType::Wait)
.poll(wgpu::PollType::wait_indefinitely())
.unwrap();
}

Expand Down Expand Up @@ -584,7 +584,7 @@ fn run_bench(ctx: &mut Criterion) {
state
.device_state
.device
.poll(wgpu::PollType::Wait)
.poll(wgpu::PollType::wait_indefinitely())
.unwrap();
}

Expand Down
6 changes: 3 additions & 3 deletions benches/benches/wgpu-benchmark/renderpass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ fn run_bench(ctx: &mut Criterion) {
state
.device_state
.device
.poll(wgpu::PollType::Wait)
.poll(wgpu::PollType::wait_indefinitely())
.unwrap();
}

Expand Down Expand Up @@ -544,7 +544,7 @@ fn run_bench(ctx: &mut Criterion) {
state
.device_state
.device
.poll(wgpu::PollType::Wait)
.poll(wgpu::PollType::wait_indefinitely())
.unwrap();
}

Expand Down Expand Up @@ -584,7 +584,7 @@ fn run_bench(ctx: &mut Criterion) {
state
.device_state
.device
.poll(wgpu::PollType::Wait)
.poll(wgpu::PollType::wait_indefinitely())
.unwrap();
}

Expand Down
5 changes: 4 additions & 1 deletion benches/benches/wgpu-benchmark/resource_creation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ fn run_bench(ctx: &mut Criterion) {
drop(buffers);

state.queue.submit([]);
state.device.poll(wgpu::PollType::Wait).unwrap();
state
.device
.poll(wgpu::PollType::wait_indefinitely())
.unwrap();
}

duration
Expand Down
2 changes: 1 addition & 1 deletion deno_webgpu/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl GPUBuffer {
{
self
.instance
.device_poll(self.device, wgpu_types::PollType::wait())
.device_poll(self.device, wgpu_types::PollType::wait_indefinitely())
.unwrap();
}
tokio::time::sleep(Duration::from_millis(10)).await;
Expand Down
2 changes: 1 addition & 1 deletion deno_webgpu/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ impl GPUDevice {
fn stop_capture(&self) {
self
.instance
.device_poll(self.id, wgpu_types::PollType::wait())
.device_poll(self.id, wgpu_types::PollType::wait_indefinitely())
.unwrap();
unsafe { self.instance.device_stop_graphics_debugger_capture(self.id) };
}
Expand Down
2 changes: 1 addition & 1 deletion deno_webgpu/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl GPUQueue {
{
self
.instance
.device_poll(self.device, wgpu_types::PollType::wait())
.device_poll(self.device, wgpu_types::PollType::wait_indefinitely())
.unwrap();
}
tokio::time::sleep(Duration::from_millis(10)).await;
Expand Down
2 changes: 1 addition & 1 deletion examples/features/src/big_compute_buffers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub async fn execute_gpu_inner(
slice.map_async(wgpu::MapMode::Read, |_| {});
}

device.poll(wgpu::PollType::Wait).unwrap();
device.poll(wgpu::PollType::wait_indefinitely()).unwrap();

let mut data = Vec::new();
for staging_buffer in &staging_buffers {
Expand Down
4 changes: 3 additions & 1 deletion examples/features/src/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,9 @@ impl<E: Example + wgpu::WasmNotSendSync> From<ExampleTestParams<E>>

let dst_buffer_slice = dst_buffer.slice(..);
dst_buffer_slice.map_async(wgpu::MapMode::Read, |_| ());
ctx.async_poll(wgpu::PollType::wait()).await.unwrap();
ctx.async_poll(wgpu::PollType::wait_indefinitely())
.await
.unwrap();
let bytes = dst_buffer_slice.get_mapped_range().to_vec();

wgpu_test::image::compare_image_output(
Expand Down
2 changes: 1 addition & 1 deletion examples/features/src/hello_synchronization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ async fn get_data<T: bytemuck::Pod>(
let buffer_slice = staging_buffer.slice(..);
let (sender, receiver) = flume::bounded(1);
buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap());
device.poll(wgpu::PollType::wait()).unwrap();
device.poll(wgpu::PollType::wait_indefinitely()).unwrap();
receiver.recv_async().await.unwrap().unwrap();
output.copy_from_slice(bytemuck::cast_slice(&buffer_slice.get_mapped_range()[..]));
staging_buffer.unmap();
Expand Down
2 changes: 1 addition & 1 deletion examples/features/src/hello_workgroups/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ async fn get_data<T: bytemuck::Pod>(
let buffer_slice = staging_buffer.slice(..);
let (sender, receiver) = flume::bounded(1);
buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap());
device.poll(wgpu::PollType::wait()).unwrap();
device.poll(wgpu::PollType::wait_indefinitely()).unwrap();
receiver.recv_async().await.unwrap().unwrap();
output.copy_from_slice(bytemuck::cast_slice(&buffer_slice.get_mapped_range()[..]));
staging_buffer.unmap();
Expand Down
2 changes: 1 addition & 1 deletion examples/features/src/mipmap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ impl crate::framework::Example for Example {
.slice(..)
.map_async(wgpu::MapMode::Read, |_| ());
// Wait for device to be done rendering mipmaps
device.poll(wgpu::PollType::wait()).unwrap();
device.poll(wgpu::PollType::wait_indefinitely()).unwrap();
// This is guaranteed to be ready.
let timestamp_view = query_sets
.mapping_buffer
Expand Down
2 changes: 1 addition & 1 deletion examples/features/src/ray_shadows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ impl crate::framework::Example for Example {
rpass.draw_indexed(0..12, 0, 0..1);
}
queue.submit(Some(encoder.finish()));
device.poll(wgpu::PollType::Wait).unwrap();
device.poll(wgpu::PollType::wait_indefinitely()).unwrap();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/features/src/render_to_texture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ async fn run(_path: Option<String>) {
let buffer_slice = output_staging_buffer.slice(..);
let (sender, receiver) = flume::bounded(1);
buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap());
device.poll(wgpu::PollType::wait()).unwrap();
device.poll(wgpu::PollType::wait_indefinitely()).unwrap();
receiver.recv_async().await.unwrap().unwrap();
log::info!("Output buffer mapped.");
{
Expand Down
5 changes: 4 additions & 1 deletion examples/features/src/repeated_compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ async fn compute(local_buffer: &mut [u32], context: &WgpuContext) {
// One of those can be calling `Device::poll`. This isn't necessary on the web as devices
// are polled automatically but natively, we need to make sure this happens manually.
// `PollType::Wait` will cause the thread to wait on native but not on WebGpu.
context.device.poll(wgpu::PollType::wait()).unwrap();
context
.device
.poll(wgpu::PollType::wait_indefinitely())
.unwrap();
log::info!("Device polled.");
// Now we await the receiving and panic if anything went wrong because we're lazy.
receiver.recv_async().await.unwrap().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion examples/features/src/storage_texture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ async fn run(_path: Option<String>) {
let buffer_slice = output_staging_buffer.slice(..);
let (sender, receiver) = flume::bounded(1);
buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap());
device.poll(wgpu::PollType::wait()).unwrap();
device.poll(wgpu::PollType::wait_indefinitely()).unwrap();
receiver.recv_async().await.unwrap().unwrap();
log::info!("Output buffer mapped");
{
Expand Down
2 changes: 1 addition & 1 deletion examples/features/src/timestamp_queries/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ impl Queries {
self.destination_buffer
.slice(..)
.map_async(wgpu::MapMode::Read, |_| ());
device.poll(wgpu::PollType::wait()).unwrap();
device.poll(wgpu::PollType::wait_indefinitely()).unwrap();

let timestamps = {
let timestamp_view = self
Expand Down
2 changes: 1 addition & 1 deletion examples/standalone/01_hello_compute/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ fn main() {

// Wait for the GPU to finish working on the submitted work. This doesn't work on WebGPU, so we would need
// to rely on the callback to know when the buffer is mapped.
device.poll(wgpu::PollType::Wait).unwrap();
device.poll(wgpu::PollType::wait_indefinitely()).unwrap();

// We can now read the data from the buffer.
let data = buffer_slice.get_mapped_range();
Expand Down
8 changes: 6 additions & 2 deletions player/src/bin/play.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ fn main() {
}

unsafe { global.device_stop_graphics_debugger_capture(device) };
global.device_poll(device, wgt::PollType::wait()).unwrap();
global
.device_poll(device, wgt::PollType::wait_indefinitely())
.unwrap();
}
#[cfg(feature = "winit")]
{
Expand Down Expand Up @@ -227,7 +229,9 @@ fn main() {
},
Event::LoopExiting => {
log::info!("Closing");
global.device_poll(device, wgt::PollType::wait()).unwrap();
global
.device_poll(device, wgt::PollType::wait_indefinitely())
.unwrap();
}
_ => {}
}
Expand Down
8 changes: 7 additions & 1 deletion player/tests/player/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,13 @@ impl Test<'_> {

println!("\t\t\tWaiting...");
global
.device_poll(device_id, wgt::PollType::wait())
.device_poll(
device_id,
wgt::PollType::Wait {
submission_index: None,
timeout: Some(std::time::Duration::from_secs(1)), // Tests really shouldn't need longer than that!
},
)
.unwrap();

for expect in self.expectations {
Expand Down
2 changes: 1 addition & 1 deletion tests/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ impl ReadbackBuffers {
) -> Vec<u8> {
let buffer_slice = buffer.slice(..);
buffer_slice.map_async(MapMode::Read, |_| ());
ctx.async_poll(PollType::wait()).await.unwrap();
ctx.async_poll(PollType::wait_indefinitely()).await.unwrap();
let (block_width, block_height) = self.texture_format.block_dimensions();
let expected_bytes_per_row = (self.texture_width / block_width)
* self.texture_format.block_copy_size(aspect).unwrap_or(4);
Expand Down
4 changes: 3 additions & 1 deletion tests/tests/wgpu-gpu/bgra8unorm_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ static BGRA8_UNORM_STORAGE: GpuTestConfiguration = GpuTestConfiguration::new()

let buffer_slice = readback_buffer.slice(..);
buffer_slice.map_async(wgpu::MapMode::Read, Result::unwrap);
ctx.async_poll(wgpu::PollType::wait()).await.unwrap();
ctx.async_poll(wgpu::PollType::wait_indefinitely())
.await
.unwrap();

{
let texels = buffer_slice.get_mapped_range();
Expand Down
2 changes: 1 addition & 1 deletion tests/tests/wgpu-gpu/bind_groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ fn multiple_bindings_with_differing_sizes(ctx: TestingContext) {
ctx.queue.write_buffer(&buffer, 0, &data);
ctx.queue.submit(Some(encoder.finish()));

ctx.device.poll(PollType::Wait).unwrap();
ctx.device.poll(PollType::wait_indefinitely()).unwrap();
}

/// Test `descriptor` against a bind group layout that requires non-filtering sampler.
Expand Down
2 changes: 1 addition & 1 deletion tests/tests/wgpu-gpu/binding_array/buffers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ async fn binding_array_buffers(
let slice = readback_buffer.slice(..);
slice.map_async(MapMode::Read, |_| {});

ctx.device.poll(PollType::Wait).unwrap();
ctx.device.poll(PollType::wait_indefinitely()).unwrap();

let data = slice.get_mapped_range();

Expand Down
2 changes: 1 addition & 1 deletion tests/tests/wgpu-gpu/binding_array/samplers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ async fn binding_array_samplers(ctx: TestingContext, partially_bound: bool) {
ctx.queue.submit(Some(encoder.finish()));

readback_buffer.slice(..).map_async(MapMode::Read, |_| {});
ctx.device.poll(PollType::Wait).unwrap();
ctx.device.poll(PollType::wait_indefinitely()).unwrap();

let readback_buffer_slice = readback_buffer.slice(..).get_mapped_range();

Expand Down
Loading