mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 00:03:29 +00:00
Convert Tests to Use Async Poll (#5053)
* Convert Tests to Use Async Poll * Update examples/src/repeated_compute/mod.rs Co-authored-by: Andreas Reich <r_andreas2@web.de> --------- Co-authored-by: Andreas Reich <r_andreas2@web.de>
This commit is contained in:
parent
5fd7d228ad
commit
ad625f433f
@ -123,7 +123,7 @@ pub async fn op_webgpu_buffer_get_map_async(
|
||||
{
|
||||
let state = state.borrow();
|
||||
let instance = state.borrow::<super::Instance>();
|
||||
gfx_select!(device => instance.device_poll(device, wgpu_types::Maintain::Wait))
|
||||
gfx_select!(device => instance.device_poll(device, wgpu_types::Maintain::wait()))
|
||||
.unwrap();
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(10)).await;
|
||||
|
@ -612,7 +612,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.device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
let bytes = dst_buffer_slice.get_mapped_range().to_vec();
|
||||
|
||||
wgpu_test::image::compare_image_output(
|
||||
|
@ -152,7 +152,7 @@ async fn execute_gpu_inner(
|
||||
// Poll the device in a blocking manner so that our future resolves.
|
||||
// In an actual application, `device.poll(...)` should
|
||||
// be called in an event loop or on another thread.
|
||||
device.poll(wgpu::Maintain::Wait);
|
||||
device.poll(wgpu::Maintain::wait()).panic_on_timeout();
|
||||
|
||||
// Awaits until `buffer_future` can be read from
|
||||
if let Ok(Ok(())) = receiver.recv_async().await {
|
||||
|
@ -183,7 +183,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::Maintain::Wait);
|
||||
device.poll(wgpu::Maintain::wait()).panic_on_timeout();
|
||||
receiver.recv_async().await.unwrap().unwrap();
|
||||
output.copy_from_slice(bytemuck::cast_slice(&buffer_slice.get_mapped_range()[..]));
|
||||
staging_buffer.unmap();
|
||||
|
@ -172,7 +172,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::Maintain::Wait);
|
||||
device.poll(wgpu::Maintain::wait()).panic_on_timeout();
|
||||
receiver.recv_async().await.unwrap().unwrap();
|
||||
output.copy_from_slice(bytemuck::cast_slice(&buffer_slice.get_mapped_range()[..]));
|
||||
staging_buffer.unmap();
|
||||
|
@ -410,7 +410,7 @@ impl crate::framework::Example for Example {
|
||||
.slice(..)
|
||||
.map_async(wgpu::MapMode::Read, |_| ());
|
||||
// Wait for device to be done rendering mipmaps
|
||||
device.poll(wgpu::Maintain::Wait);
|
||||
device.poll(wgpu::Maintain::wait()).panic_on_timeout();
|
||||
// This is guaranteed to be ready.
|
||||
let timestamp_view = query_sets
|
||||
.mapping_buffer
|
||||
|
@ -131,7 +131,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::Maintain::Wait);
|
||||
device.poll(wgpu::Maintain::wait()).panic_on_timeout();
|
||||
receiver.recv_async().await.unwrap().unwrap();
|
||||
log::info!("Output buffer mapped.");
|
||||
{
|
||||
|
@ -108,8 +108,11 @@ async fn compute(local_buffer: &mut [u32], context: &WgpuContext) {
|
||||
// In order for the mapping to be completed, one of three things must happen.
|
||||
// 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.
|
||||
// `Maintain::Wait` will cause the thread to wait on native but not the web.
|
||||
context.device.poll(wgpu::Maintain::Wait);
|
||||
// `Maintain::Wait` will cause the thread to wait on native but not on WebGpu.
|
||||
context
|
||||
.device
|
||||
.poll(wgpu::Maintain::wait())
|
||||
.panic_on_timeout();
|
||||
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();
|
||||
|
@ -143,7 +143,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::Maintain::Wait);
|
||||
device.poll(wgpu::Maintain::wait()).panic_on_timeout();
|
||||
receiver.recv_async().await.unwrap().unwrap();
|
||||
log::info!("Output buffer mapped");
|
||||
{
|
||||
|
@ -159,7 +159,7 @@ impl Queries {
|
||||
self.destination_buffer
|
||||
.slice(..)
|
||||
.map_async(wgpu::MapMode::Read, |_| ());
|
||||
device.poll(wgpu::Maintain::Wait);
|
||||
device.poll(wgpu::Maintain::wait()).panic_on_timeout();
|
||||
|
||||
let timestamps = {
|
||||
let timestamp_view = self
|
||||
|
@ -114,7 +114,7 @@ fn main() {
|
||||
}
|
||||
|
||||
gfx_select!(device => global.device_stop_capture(device));
|
||||
gfx_select!(device => global.device_poll(device, wgt::Maintain::Wait)).unwrap();
|
||||
gfx_select!(device => global.device_poll(device, wgt::Maintain::wait())).unwrap();
|
||||
}
|
||||
#[cfg(feature = "winit")]
|
||||
{
|
||||
@ -196,7 +196,7 @@ fn main() {
|
||||
},
|
||||
Event::LoopExiting => {
|
||||
log::info!("Closing");
|
||||
gfx_select!(device => global.device_poll(device, wgt::Maintain::Wait)).unwrap();
|
||||
gfx_select!(device => global.device_poll(device, wgt::Maintain::wait())).unwrap();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -121,7 +121,8 @@ impl Test<'_> {
|
||||
}
|
||||
|
||||
println!("\t\t\tWaiting...");
|
||||
wgc::gfx_select!(device_id => global.device_poll(device_id, wgt::Maintain::Wait)).unwrap();
|
||||
wgc::gfx_select!(device_id => global.device_poll(device_id, wgt::Maintain::wait()))
|
||||
.unwrap();
|
||||
|
||||
for expect in self.expectations {
|
||||
println!("\t\t\tChecking {}", expect.name);
|
||||
|
@ -5,6 +5,8 @@ use std::{borrow::Cow, ffi::OsStr, path::Path};
|
||||
use wgpu::util::{align_to, DeviceExt};
|
||||
use wgpu::*;
|
||||
|
||||
use crate::TestingContext;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
async fn read_png(path: impl AsRef<Path>, width: u32, height: u32) -> Option<Vec<u8>> {
|
||||
let data = match std::fs::read(&path) {
|
||||
@ -563,15 +565,15 @@ impl ReadbackBuffers {
|
||||
copy_texture_to_buffer(device, encoder, texture, &self.buffer, &self.buffer_stencil);
|
||||
}
|
||||
|
||||
fn retrieve_buffer(
|
||||
async fn retrieve_buffer(
|
||||
&self,
|
||||
device: &Device,
|
||||
ctx: &TestingContext,
|
||||
buffer: &Buffer,
|
||||
aspect: Option<TextureAspect>,
|
||||
) -> Vec<u8> {
|
||||
let buffer_slice = buffer.slice(..);
|
||||
buffer_slice.map_async(MapMode::Read, |_| ());
|
||||
device.poll(Maintain::Wait);
|
||||
ctx.async_poll(Maintain::wait()).await.panic_on_timeout();
|
||||
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);
|
||||
@ -600,26 +602,36 @@ impl ReadbackBuffers {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn are_zero(&self, device: &Device) -> bool {
|
||||
let is_zero = |device: &Device, buffer: &Buffer, aspect: Option<TextureAspect>| -> bool {
|
||||
let is_zero = self
|
||||
.retrieve_buffer(device, buffer, aspect)
|
||||
.iter()
|
||||
.all(|b| *b == 0);
|
||||
buffer.unmap();
|
||||
is_zero
|
||||
};
|
||||
async fn is_zero(
|
||||
&self,
|
||||
ctx: &TestingContext,
|
||||
buffer: &Buffer,
|
||||
aspect: Option<TextureAspect>,
|
||||
) -> bool {
|
||||
let is_zero = self
|
||||
.retrieve_buffer(ctx, buffer, aspect)
|
||||
.await
|
||||
.iter()
|
||||
.all(|b| *b == 0);
|
||||
buffer.unmap();
|
||||
is_zero
|
||||
}
|
||||
|
||||
let buffer_zero = is_zero(device, &self.buffer, self.buffer_aspect());
|
||||
pub async fn are_zero(&self, ctx: &TestingContext) -> bool {
|
||||
let buffer_zero = self.is_zero(ctx, &self.buffer, self.buffer_aspect()).await;
|
||||
let mut stencil_buffer_zero = true;
|
||||
if let Some(buffer) = &self.buffer_stencil {
|
||||
stencil_buffer_zero = is_zero(device, buffer, Some(TextureAspect::StencilOnly));
|
||||
stencil_buffer_zero = self
|
||||
.is_zero(ctx, buffer, Some(TextureAspect::StencilOnly))
|
||||
.await;
|
||||
};
|
||||
buffer_zero && stencil_buffer_zero
|
||||
}
|
||||
|
||||
pub fn assert_buffer_contents(&self, device: &Device, expected_data: &[u8]) {
|
||||
let result_buffer = self.retrieve_buffer(device, &self.buffer, self.buffer_aspect());
|
||||
pub async fn assert_buffer_contents(&self, ctx: &TestingContext, expected_data: &[u8]) {
|
||||
let result_buffer = self
|
||||
.retrieve_buffer(ctx, &self.buffer, self.buffer_aspect())
|
||||
.await;
|
||||
assert!(
|
||||
result_buffer.len() >= expected_data.len(),
|
||||
"Result buffer ({}) smaller than expected buffer ({})",
|
||||
|
@ -7,6 +7,7 @@ mod init;
|
||||
mod isolation;
|
||||
pub mod native;
|
||||
mod params;
|
||||
mod poll;
|
||||
mod report;
|
||||
mod run;
|
||||
|
||||
|
8
tests/src/poll.rs
Normal file
8
tests/src/poll.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use crate::TestingContext;
|
||||
|
||||
impl TestingContext {
|
||||
/// Utility to allow future asynchronous polling.
|
||||
pub async fn async_poll(&self, maintain: wgpu::Maintain) -> wgpu::MaintainResult {
|
||||
self.device.poll(maintain)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use std::panic::AssertUnwindSafe;
|
||||
use std::{panic::AssertUnwindSafe, sync::Arc};
|
||||
|
||||
use futures_lite::FutureExt;
|
||||
use wgpu::{Adapter, Device, Instance, Queue};
|
||||
@ -18,7 +18,7 @@ pub struct TestingContext {
|
||||
pub adapter: Adapter,
|
||||
pub adapter_info: wgpu::AdapterInfo,
|
||||
pub adapter_downlevel_capabilities: wgpu::DownlevelCapabilities,
|
||||
pub device: Device,
|
||||
pub device: Arc<Device>,
|
||||
pub device_features: wgpu::Features,
|
||||
pub device_limits: wgpu::Limits,
|
||||
pub queue: Queue,
|
||||
@ -58,6 +58,9 @@ pub async fn execute_test(
|
||||
return;
|
||||
}
|
||||
|
||||
// Print the name of the test.
|
||||
log::info!("TEST: {}", config.name);
|
||||
|
||||
let (device, queue) = pollster::block_on(initialize_device(
|
||||
&adapter,
|
||||
config.params.required_features,
|
||||
@ -69,7 +72,7 @@ pub async fn execute_test(
|
||||
adapter,
|
||||
adapter_info,
|
||||
adapter_downlevel_capabilities,
|
||||
device,
|
||||
device: Arc::new(device),
|
||||
device_features: config.params.required_features,
|
||||
device_limits: config.params.required_limits.clone(),
|
||||
queue,
|
||||
@ -109,4 +112,6 @@ pub async fn execute_test(
|
||||
if expectations_match_failures(&test_info.failures, failures) == ExpectationMatchResult::Panic {
|
||||
panic!();
|
||||
}
|
||||
// Print the name of the test.
|
||||
log::info!("TEST FINISHED: {}", config.name);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ static BGRA8_UNORM_STORAGE: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
})
|
||||
.features(wgpu::Features::BGRA8UNORM_STORAGE),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| async move {
|
||||
let device = &ctx.device;
|
||||
let texture = ctx.device.create_texture(&wgpu::TextureDescriptor {
|
||||
label: None,
|
||||
@ -139,7 +139,9 @@ static BGRA8_UNORM_STORAGE: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
|
||||
let buffer_slice = readback_buffer.slice(..);
|
||||
buffer_slice.map_async(wgpu::MapMode::Read, Result::unwrap);
|
||||
device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
{
|
||||
let texels = buffer_slice.get_mapped_range();
|
||||
|
@ -31,9 +31,9 @@ const ENTRY: wgpu::BindGroupLayoutEntry = wgpu::BindGroupLayoutEntry {
|
||||
#[gpu_test]
|
||||
static BIND_GROUP_LAYOUT_DEDUPLICATION: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(TestParameters::default().test_features_limits())
|
||||
.run_sync(bgl_dedupe);
|
||||
.run_async(bgl_dedupe);
|
||||
|
||||
fn bgl_dedupe(ctx: TestingContext) {
|
||||
async fn bgl_dedupe(ctx: TestingContext) {
|
||||
let entries_1 = &[];
|
||||
|
||||
let entries_2 = &[ENTRY];
|
||||
@ -126,7 +126,9 @@ fn bgl_dedupe(ctx: TestingContext) {
|
||||
}
|
||||
}
|
||||
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
if ctx.adapter_info.backend != wgt::Backend::BrowserWebGpu {
|
||||
// Now all of the BGL ids should be dead, so we should get the same ids again.
|
||||
|
@ -1,6 +1,6 @@
|
||||
use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext};
|
||||
|
||||
fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: &str) {
|
||||
async fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: &str) {
|
||||
let r = wgpu::BufferUsages::MAP_READ;
|
||||
let rw = wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::MAP_WRITE;
|
||||
for usage in [r, rw] {
|
||||
@ -14,7 +14,9 @@ fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: &str)
|
||||
b0.slice(0..0)
|
||||
.map_async(wgpu::MapMode::Read, Result::unwrap);
|
||||
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
{
|
||||
let view = b0.slice(0..0).get_mapped_range();
|
||||
@ -48,7 +50,9 @@ fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: &str)
|
||||
b0.slice(0..0)
|
||||
.map_async(wgpu::MapMode::Write, Result::unwrap);
|
||||
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
//{
|
||||
// let view = b0.slice(0..0).get_mapped_range_mut();
|
||||
@ -77,19 +81,21 @@ fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: &str)
|
||||
|
||||
b1.unmap();
|
||||
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
}
|
||||
|
||||
#[gpu_test]
|
||||
static EMPTY_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(TestParameters::default().expect_fail(FailureCase::always()))
|
||||
.run_sync(|ctx| {
|
||||
test_empty_buffer_range(&ctx, 2048, "regular buffer");
|
||||
test_empty_buffer_range(&ctx, 0, "zero-sized buffer");
|
||||
.run_async(|ctx| async move {
|
||||
test_empty_buffer_range(&ctx, 2048, "regular buffer").await;
|
||||
test_empty_buffer_range(&ctx, 0, "zero-sized buffer").await;
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static MAP_OFFSET: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
static MAP_OFFSET: GpuTestConfiguration = GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
// This test writes 16 bytes at the beginning of buffer mapped mapped with
|
||||
// an offset of 32 bytes. Then the buffer is copied into another buffer that
|
||||
// is read back and we check that the written bytes are correctly placed at
|
||||
@ -116,7 +122,9 @@ static MAP_OFFSET: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|
|
||||
result.unwrap();
|
||||
});
|
||||
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
{
|
||||
let slice = write_buf.slice(32..48);
|
||||
@ -140,7 +148,9 @@ static MAP_OFFSET: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|
|
||||
.slice(..)
|
||||
.map_async(wgpu::MapMode::Read, Result::unwrap);
|
||||
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
let slice = read_buf.slice(..);
|
||||
let view = slice.get_mapped_range();
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Tests for buffer usages validation.
|
||||
|
||||
use wgpu::{BufferUsages as Bu, MapMode as Ma};
|
||||
use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration, TestParameters};
|
||||
use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration, TestParameters, TestingContext};
|
||||
use wgt::BufferAddress;
|
||||
|
||||
const BUFFER_SIZE: BufferAddress = 1234;
|
||||
@ -26,7 +26,7 @@ const NEEDS_MAPPABLE_PRIMARY_BUFFERS: &[Bu; 7] = &[
|
||||
const INVALID_BITS: Bu = Bu::from_bits_retain(0b1111111111111);
|
||||
const ALWAYS_FAIL: &[Bu; 2] = &[Bu::empty(), INVALID_BITS];
|
||||
|
||||
fn try_create(ctx: wgpu_test::TestingContext, usages: &[(bool, &[wgpu::BufferUsages])]) {
|
||||
fn try_create(ctx: TestingContext, usages: &[(bool, &[wgpu::BufferUsages])]) {
|
||||
for (expect_validation_error, usage) in usages
|
||||
.iter()
|
||||
.flat_map(|&(expect_error, usages)| usages.iter().copied().map(move |u| (expect_error, u)))
|
||||
@ -69,7 +69,7 @@ static BUFFER_USAGE_MAPPABLE_PRIMARY_BUFFERS: GpuTestConfiguration = GpuTestConf
|
||||
});
|
||||
|
||||
async fn map_test(
|
||||
device: &wgpu::Device,
|
||||
ctx: &TestingContext,
|
||||
usage_type: &str,
|
||||
map_mode_type: Ma,
|
||||
before_unmap: bool,
|
||||
@ -89,8 +89,8 @@ async fn map_test(
|
||||
|
||||
let mut buffer = None;
|
||||
|
||||
fail_if(device, buffer_creation_validation_error, || {
|
||||
buffer = Some(device.create_buffer(&wgpu::BufferDescriptor {
|
||||
fail_if(&ctx.device, buffer_creation_validation_error, || {
|
||||
buffer = Some(ctx.device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
size,
|
||||
usage,
|
||||
@ -107,7 +107,7 @@ async fn map_test(
|
||||
|| (map_mode_type == Ma::Read && !usage.contains(Bu::MAP_READ))
|
||||
|| (map_mode_type == Ma::Write && !usage.contains(Bu::MAP_WRITE));
|
||||
|
||||
fail_if(device, map_async_validation_error, || {
|
||||
fail_if(&ctx.device, map_async_validation_error, || {
|
||||
buffer.slice(0..size).map_async(map_mode_type, |_| {});
|
||||
});
|
||||
|
||||
@ -123,7 +123,9 @@ async fn map_test(
|
||||
buffer.destroy();
|
||||
}
|
||||
|
||||
device.poll(wgpu::MaintainBase::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
if !before_unmap && !before_destroy {
|
||||
{
|
||||
@ -152,7 +154,7 @@ static BUFFER_MAP_ASYNC_MAP_STATE: GpuTestConfiguration = GpuTestConfiguration::
|
||||
for after_unmap in [false, true] {
|
||||
for after_destroy in [false, true] {
|
||||
map_test(
|
||||
&ctx.device,
|
||||
&ctx,
|
||||
usage_type,
|
||||
map_mode_type,
|
||||
before_unmap,
|
||||
|
@ -203,7 +203,7 @@ static TEXTURE_FORMATS_ASTC: &[wgpu::TextureFormat] = &[
|
||||
},
|
||||
];
|
||||
|
||||
fn single_texture_clear_test(
|
||||
async fn single_texture_clear_test(
|
||||
ctx: &TestingContext,
|
||||
format: wgpu::TextureFormat,
|
||||
size: wgpu::Extent3d,
|
||||
@ -259,12 +259,12 @@ fn single_texture_clear_test(
|
||||
ctx.queue.submit([encoder.finish()]);
|
||||
|
||||
assert!(
|
||||
readback_buffers.are_zero(&ctx.device),
|
||||
readback_buffers.are_zero(ctx).await,
|
||||
"texture with format {format:?} was not fully cleared"
|
||||
);
|
||||
}
|
||||
|
||||
fn clear_texture_tests(ctx: &TestingContext, formats: &[wgpu::TextureFormat]) {
|
||||
async fn clear_texture_tests(ctx: TestingContext, formats: &'static [wgpu::TextureFormat]) {
|
||||
for &format in formats {
|
||||
let (block_width, block_height) = format.block_dimensions();
|
||||
let rounded_width = block_width * wgpu::COPY_BYTES_PER_ROW_ALIGNMENT;
|
||||
@ -278,7 +278,7 @@ fn clear_texture_tests(ctx: &TestingContext, formats: &[wgpu::TextureFormat]) {
|
||||
// 1D texture
|
||||
if supports_1d {
|
||||
single_texture_clear_test(
|
||||
ctx,
|
||||
&ctx,
|
||||
format,
|
||||
wgpu::Extent3d {
|
||||
width: rounded_width,
|
||||
@ -286,11 +286,12 @@ fn clear_texture_tests(ctx: &TestingContext, formats: &[wgpu::TextureFormat]) {
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
wgpu::TextureDimension::D1,
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
// 2D texture
|
||||
single_texture_clear_test(
|
||||
ctx,
|
||||
&ctx,
|
||||
format,
|
||||
wgpu::Extent3d {
|
||||
width: rounded_width,
|
||||
@ -298,10 +299,11 @@ fn clear_texture_tests(ctx: &TestingContext, formats: &[wgpu::TextureFormat]) {
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
wgpu::TextureDimension::D2,
|
||||
);
|
||||
)
|
||||
.await;
|
||||
// 2D array texture
|
||||
single_texture_clear_test(
|
||||
ctx,
|
||||
&ctx,
|
||||
format,
|
||||
wgpu::Extent3d {
|
||||
width: rounded_width,
|
||||
@ -309,11 +311,12 @@ fn clear_texture_tests(ctx: &TestingContext, formats: &[wgpu::TextureFormat]) {
|
||||
depth_or_array_layers: 4,
|
||||
},
|
||||
wgpu::TextureDimension::D2,
|
||||
);
|
||||
)
|
||||
.await;
|
||||
if supports_3d {
|
||||
// volume texture
|
||||
single_texture_clear_test(
|
||||
ctx,
|
||||
&ctx,
|
||||
format,
|
||||
wgpu::Extent3d {
|
||||
width: rounded_width,
|
||||
@ -321,7 +324,8 @@ fn clear_texture_tests(ctx: &TestingContext, formats: &[wgpu::TextureFormat]) {
|
||||
depth_or_array_layers: 16,
|
||||
},
|
||||
wgpu::TextureDimension::D3,
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -333,9 +337,7 @@ static CLEAR_TEXTURE_UNCOMPRESSED_GLES: GpuTestConfiguration = GpuTestConfigurat
|
||||
.features(wgpu::Features::CLEAR_TEXTURE)
|
||||
.skip(FailureCase::webgl2()),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
clear_texture_tests(&ctx, TEXTURE_FORMATS_UNCOMPRESSED_GLES_COMPAT);
|
||||
});
|
||||
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_UNCOMPRESSED_GLES_COMPAT));
|
||||
|
||||
#[gpu_test]
|
||||
static CLEAR_TEXTURE_UNCOMPRESSED: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
@ -350,9 +352,7 @@ static CLEAR_TEXTURE_UNCOMPRESSED: GpuTestConfiguration = GpuTestConfiguration::
|
||||
)
|
||||
.features(wgpu::Features::CLEAR_TEXTURE),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
clear_texture_tests(&ctx, TEXTURE_FORMATS_UNCOMPRESSED);
|
||||
});
|
||||
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_UNCOMPRESSED));
|
||||
|
||||
#[gpu_test]
|
||||
static CLEAR_TEXTURE_DEPTH: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
@ -368,9 +368,7 @@ static CLEAR_TEXTURE_DEPTH: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.limits(wgpu::Limits::downlevel_defaults())
|
||||
.features(wgpu::Features::CLEAR_TEXTURE),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
clear_texture_tests(&ctx, TEXTURE_FORMATS_DEPTH);
|
||||
});
|
||||
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_DEPTH));
|
||||
|
||||
#[gpu_test]
|
||||
static CLEAR_TEXTURE_DEPTH32_STENCIL8: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
@ -380,9 +378,7 @@ static CLEAR_TEXTURE_DEPTH32_STENCIL8: GpuTestConfiguration = GpuTestConfigurati
|
||||
// https://github.com/gfx-rs/wgpu/issues/5016
|
||||
.skip(FailureCase::adapter("Apple Paravirtual device")),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
clear_texture_tests(&ctx, &[wgpu::TextureFormat::Depth32FloatStencil8]);
|
||||
});
|
||||
.run_async(|ctx| clear_texture_tests(ctx, &[wgpu::TextureFormat::Depth32FloatStencil8]));
|
||||
|
||||
#[gpu_test]
|
||||
static CLEAR_TEXTURE_COMPRESSED_BCN: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
@ -394,9 +390,7 @@ static CLEAR_TEXTURE_COMPRESSED_BCN: GpuTestConfiguration = GpuTestConfiguration
|
||||
// compressed texture copy to buffer not yet implemented
|
||||
.expect_fail(FailureCase::backend(wgpu::Backends::GL)),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
clear_texture_tests(&ctx, TEXTURE_FORMATS_BC);
|
||||
});
|
||||
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_BC));
|
||||
|
||||
#[gpu_test]
|
||||
static CLEAR_TEXTURE_COMPRESSED_ASTC: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
@ -412,9 +406,7 @@ static CLEAR_TEXTURE_COMPRESSED_ASTC: GpuTestConfiguration = GpuTestConfiguratio
|
||||
// compressed texture copy to buffer not yet implemented
|
||||
.expect_fail(FailureCase::backend(wgpu::Backends::GL)),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
clear_texture_tests(&ctx, TEXTURE_FORMATS_ASTC);
|
||||
});
|
||||
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_ASTC));
|
||||
|
||||
#[gpu_test]
|
||||
static CLEAR_TEXTURE_COMPRESSED_ETC2: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
@ -426,6 +418,4 @@ static CLEAR_TEXTURE_COMPRESSED_ETC2: GpuTestConfiguration = GpuTestConfiguratio
|
||||
// compressed texture copy to buffer not yet implemented
|
||||
.expect_fail(FailureCase::backend(wgpu::Backends::GL)),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
clear_texture_tests(&ctx, TEXTURE_FORMATS_ETC2);
|
||||
});
|
||||
.run_async(|ctx| clear_texture_tests(ctx, TEXTURE_FORMATS_ETC2));
|
||||
|
@ -3,7 +3,7 @@ use wgpu_test::{fail, gpu_test, FailureCase, GpuTestConfiguration, TestParameter
|
||||
#[gpu_test]
|
||||
static CROSS_DEVICE_BIND_GROUP_USAGE: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(TestParameters::default().expect_fail(FailureCase::always()))
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| async move {
|
||||
// Create a bind group uisng a layout from another device. This should be a validation
|
||||
// error but currently crashes.
|
||||
let (device2, _) =
|
||||
@ -23,7 +23,9 @@ static CROSS_DEVICE_BIND_GROUP_USAGE: GpuTestConfiguration = GpuTestConfiguratio
|
||||
});
|
||||
}
|
||||
|
||||
ctx.device.poll(wgpu::Maintain::Poll);
|
||||
ctx.async_poll(wgpu::Maintain::Poll)
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
});
|
||||
|
||||
#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
|
||||
@ -483,7 +485,7 @@ static DEVICE_DESTROY_THEN_MORE: GpuTestConfiguration = GpuTestConfiguration::ne
|
||||
#[gpu_test]
|
||||
static DEVICE_DESTROY_THEN_LOST: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(TestParameters::default())
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| async move {
|
||||
// This test checks that when device.destroy is called, the provided
|
||||
// DeviceLostClosure is called with reason DeviceLostReason::Destroyed.
|
||||
let was_called = std::sync::Arc::<std::sync::atomic::AtomicBool>::new(false.into());
|
||||
@ -504,7 +506,10 @@ static DEVICE_DESTROY_THEN_LOST: GpuTestConfiguration = GpuTestConfiguration::ne
|
||||
|
||||
// Make sure the device queues are empty, which ensures that the closure
|
||||
// has been called.
|
||||
assert!(ctx.device.poll(wgpu::Maintain::Wait));
|
||||
assert!(ctx
|
||||
.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.is_queue_empty());
|
||||
|
||||
assert!(
|
||||
was_called.load(std::sync::atomic::Ordering::SeqCst),
|
||||
|
@ -323,7 +323,9 @@ static IMAGE_BITMAP_IMPORT: GpuTestConfiguration =
|
||||
readback_buffer
|
||||
.slice(..)
|
||||
.map_async(wgpu::MapMode::Read, |_| ());
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
let buffer = readback_buffer.slice(..).get_mapped_range();
|
||||
|
||||
|
@ -1,95 +1,111 @@
|
||||
use wgpu_test::{fail, gpu_test, GpuTestConfiguration};
|
||||
|
||||
#[gpu_test]
|
||||
static BUFFER_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
let buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
size: 256,
|
||||
usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC,
|
||||
mapped_at_creation: false,
|
||||
static BUFFER_DESTROY: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
let buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
size: 256,
|
||||
usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
buffer.destroy();
|
||||
|
||||
buffer.destroy();
|
||||
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
fail(&ctx.device, || {
|
||||
buffer
|
||||
.slice(..)
|
||||
.map_async(wgpu::MapMode::Write, move |_| {});
|
||||
});
|
||||
|
||||
buffer.destroy();
|
||||
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
buffer.destroy();
|
||||
|
||||
buffer.destroy();
|
||||
|
||||
let descriptor = wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
size: 256,
|
||||
usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC,
|
||||
mapped_at_creation: false,
|
||||
};
|
||||
|
||||
// Scopes to mix up the drop/poll ordering.
|
||||
{
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
}
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
{
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
buffer.destroy();
|
||||
}
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
});
|
||||
|
||||
buffer.destroy();
|
||||
|
||||
buffer.destroy();
|
||||
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
|
||||
fail(&ctx.device, || {
|
||||
buffer
|
||||
.slice(..)
|
||||
.map_async(wgpu::MapMode::Write, move |_| {});
|
||||
});
|
||||
|
||||
buffer.destroy();
|
||||
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
|
||||
buffer.destroy();
|
||||
|
||||
buffer.destroy();
|
||||
|
||||
let descriptor = wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
size: 256,
|
||||
usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC,
|
||||
mapped_at_creation: false,
|
||||
};
|
||||
|
||||
// Scopes to mix up the drop/poll ordering.
|
||||
{
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
}
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
{
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
buffer.destroy();
|
||||
}
|
||||
let buffer = ctx.device.create_buffer(&descriptor);
|
||||
buffer.destroy();
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static TEXTURE_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
let texture = ctx.device.create_texture(&wgpu::TextureDescriptor {
|
||||
label: None,
|
||||
size: wgpu::Extent3d {
|
||||
width: 128,
|
||||
height: 128,
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
mip_level_count: 1,
|
||||
sample_count: 1, // multisampling is not supported for clear
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8Snorm,
|
||||
usage: wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::TEXTURE_BINDING,
|
||||
view_formats: &[],
|
||||
static TEXTURE_DESTROY: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
let texture = ctx.device.create_texture(&wgpu::TextureDescriptor {
|
||||
label: None,
|
||||
size: wgpu::Extent3d {
|
||||
width: 128,
|
||||
height: 128,
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
mip_level_count: 1,
|
||||
sample_count: 1, // multisampling is not supported for clear
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8Snorm,
|
||||
usage: wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::TEXTURE_BINDING,
|
||||
view_formats: &[],
|
||||
});
|
||||
|
||||
texture.destroy();
|
||||
|
||||
texture.destroy();
|
||||
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
texture.destroy();
|
||||
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
texture.destroy();
|
||||
|
||||
texture.destroy();
|
||||
});
|
||||
|
||||
texture.destroy();
|
||||
|
||||
texture.destroy();
|
||||
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
|
||||
texture.destroy();
|
||||
|
||||
ctx.device.poll(wgpu::MaintainBase::Wait);
|
||||
|
||||
texture.destroy();
|
||||
|
||||
texture.destroy();
|
||||
});
|
||||
|
@ -3,7 +3,7 @@
|
||||
target_os = "emscripten",
|
||||
feature = "webgl"
|
||||
))]
|
||||
fn draw_test_with_reports(
|
||||
async fn draw_test_with_reports(
|
||||
ctx: wgpu_test::TestingContext,
|
||||
expected: &[u32],
|
||||
function: impl FnOnce(&mut wgpu::RenderPass<'_>),
|
||||
@ -241,8 +241,9 @@ fn draw_test_with_reports(
|
||||
let report = global_report.hub_report(ctx.adapter_info.backend);
|
||||
assert_eq!(report.command_buffers.num_allocated, 0);
|
||||
|
||||
ctx.device
|
||||
.poll(wgpu::Maintain::WaitForSubmissionIndex(submit_index));
|
||||
ctx.async_poll(wgpu::Maintain::wait_for(submit_index))
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
let global_report = ctx.instance.generate_report();
|
||||
let report = global_report.hub_report(ctx.adapter_info.backend);
|
||||
@ -285,7 +286,7 @@ static SIMPLE_DRAW_CHECK_MEM_LEAKS: wgpu_test::GpuTestConfiguration =
|
||||
.test_features_limits()
|
||||
.features(wgpu::Features::VERTEX_WRITABLE_STORAGE),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| {
|
||||
draw_test_with_reports(ctx, &[0, 1, 2, 3, 4, 5], |cmb| {
|
||||
cmb.draw(0..6, 0..1);
|
||||
})
|
||||
|
@ -4,7 +4,7 @@ use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters};
|
||||
#[gpu_test]
|
||||
static OCCLUSION_QUERY: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(TestParameters::default().expect_fail(FailureCase::webgl2()))
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| async move {
|
||||
// Create depth texture
|
||||
let depth_texture = ctx.device.create_texture(&wgpu::TextureDescriptor {
|
||||
label: Some("Depth texture"),
|
||||
@ -117,7 +117,9 @@ static OCCLUSION_QUERY: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
mapping_buffer
|
||||
.slice(..)
|
||||
.map_async(wgpu::MapMode::Read, |_| ());
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
let query_buffer_view = mapping_buffer.slice(..).get_mapped_range();
|
||||
let query_data: &[u64; 3] = bytemuck::from_bytes(&query_buffer_view);
|
||||
|
||||
|
@ -14,7 +14,7 @@ static PARTIALLY_BOUNDED_ARRAY: GpuTestConfiguration = GpuTestConfiguration::new
|
||||
)
|
||||
.limits(wgpu::Limits::downlevel_defaults()),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| async move {
|
||||
let device = &ctx.device;
|
||||
|
||||
let texture_extent = wgpu::Extent3d {
|
||||
@ -98,5 +98,6 @@ static PARTIALLY_BOUNDED_ARRAY: GpuTestConfiguration = GpuTestConfiguration::new
|
||||
ctx.queue.submit(Some(encoder.finish()));
|
||||
|
||||
readback_buffers
|
||||
.assert_buffer_contents(device, bytemuck::bytes_of(&[4.0f32, 3.0, 2.0, 1.0]));
|
||||
.assert_buffer_contents(&ctx, bytemuck::bytes_of(&[4.0f32, 3.0, 2.0, 1.0]))
|
||||
.await;
|
||||
});
|
||||
|
@ -68,48 +68,60 @@ impl DummyWorkData {
|
||||
}
|
||||
|
||||
#[gpu_test]
|
||||
static WAIT: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
static WAIT: GpuTestConfiguration = GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
let data = DummyWorkData::new(&ctx);
|
||||
|
||||
ctx.queue.submit(Some(data.cmd_buf));
|
||||
ctx.device.poll(Maintain::Wait);
|
||||
ctx.async_poll(Maintain::wait()).await.panic_on_timeout();
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static DOUBLE_WAIT: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
let data = DummyWorkData::new(&ctx);
|
||||
|
||||
ctx.queue.submit(Some(data.cmd_buf));
|
||||
ctx.device.poll(Maintain::Wait);
|
||||
ctx.device.poll(Maintain::Wait);
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static WAIT_ON_SUBMISSION: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
let data = DummyWorkData::new(&ctx);
|
||||
|
||||
let index = ctx.queue.submit(Some(data.cmd_buf));
|
||||
ctx.device.poll(Maintain::WaitForSubmissionIndex(index));
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static DOUBLE_WAIT_ON_SUBMISSION: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
static DOUBLE_WAIT: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
let data = DummyWorkData::new(&ctx);
|
||||
|
||||
let index = ctx.queue.submit(Some(data.cmd_buf));
|
||||
ctx.device
|
||||
.poll(Maintain::WaitForSubmissionIndex(index.clone()));
|
||||
ctx.device.poll(Maintain::WaitForSubmissionIndex(index));
|
||||
ctx.queue.submit(Some(data.cmd_buf));
|
||||
ctx.async_poll(Maintain::wait()).await.panic_on_timeout();
|
||||
ctx.async_poll(Maintain::wait()).await.panic_on_timeout();
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static WAIT_OUT_OF_ORDER: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
let data1 = DummyWorkData::new(&ctx);
|
||||
let data2 = DummyWorkData::new(&ctx);
|
||||
static WAIT_ON_SUBMISSION: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
let data = DummyWorkData::new(&ctx);
|
||||
|
||||
let index1 = ctx.queue.submit(Some(data1.cmd_buf));
|
||||
let index2 = ctx.queue.submit(Some(data2.cmd_buf));
|
||||
ctx.device.poll(Maintain::WaitForSubmissionIndex(index2));
|
||||
ctx.device.poll(Maintain::WaitForSubmissionIndex(index1));
|
||||
});
|
||||
let index = ctx.queue.submit(Some(data.cmd_buf));
|
||||
ctx.async_poll(Maintain::wait_for(index))
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static DOUBLE_WAIT_ON_SUBMISSION: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
let data = DummyWorkData::new(&ctx);
|
||||
|
||||
let index = ctx.queue.submit(Some(data.cmd_buf));
|
||||
ctx.async_poll(Maintain::wait_for(index.clone()))
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
ctx.async_poll(Maintain::wait_for(index))
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static WAIT_OUT_OF_ORDER: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
let data1 = DummyWorkData::new(&ctx);
|
||||
let data2 = DummyWorkData::new(&ctx);
|
||||
|
||||
let index1 = ctx.queue.submit(Some(data1.cmd_buf));
|
||||
let index2 = ctx.queue.submit(Some(data2.cmd_buf));
|
||||
ctx.async_poll(Maintain::wait_for(index2))
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
ctx.async_poll(Maintain::wait_for(index1))
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
});
|
||||
|
@ -19,7 +19,7 @@ static PARTIAL_UPDATE: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
..Default::default()
|
||||
}),
|
||||
)
|
||||
.run_sync(partial_update_test);
|
||||
.run_async(partial_update_test);
|
||||
|
||||
const SHADER: &str = r#"
|
||||
struct Pc {
|
||||
@ -38,7 +38,7 @@ const SHADER: &str = r#"
|
||||
}
|
||||
"#;
|
||||
|
||||
fn partial_update_test(ctx: TestingContext) {
|
||||
async fn partial_update_test(ctx: TestingContext) {
|
||||
let sm = ctx
|
||||
.device
|
||||
.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||
@ -139,7 +139,9 @@ fn partial_update_test(ctx: TestingContext) {
|
||||
encoder.copy_buffer_to_buffer(&gpu_buffer, 0, &cpu_buffer, 0, 32);
|
||||
ctx.queue.submit([encoder.finish()]);
|
||||
cpu_buffer.slice(..).map_async(wgpu::MapMode::Read, |_| ());
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
let data = cpu_buffer.slice(..).get_mapped_range();
|
||||
|
||||
|
@ -32,9 +32,9 @@ static MULTI_STAGE_DATA_BINDING: GpuTestConfiguration = GpuTestConfiguration::ne
|
||||
..Default::default()
|
||||
}),
|
||||
)
|
||||
.run_sync(multi_stage_data_binding_test);
|
||||
.run_async(multi_stage_data_binding_test);
|
||||
|
||||
fn multi_stage_data_binding_test(ctx: TestingContext) {
|
||||
async fn multi_stage_data_binding_test(ctx: TestingContext) {
|
||||
// We use different shader modules to allow us to use different
|
||||
// types for the uniform and push constant blocks between stages.
|
||||
let vs_sm = ctx
|
||||
@ -174,5 +174,5 @@ fn multi_stage_data_binding_test(ctx: TestingContext) {
|
||||
ctx.queue.submit([encoder.finish()]);
|
||||
|
||||
let result = input_as_unorm.repeat(4);
|
||||
buffers.assert_buffer_contents(&ctx.device, &result);
|
||||
buffers.assert_buffer_contents(&ctx, &result).await;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use wgpu::*;
|
||||
/// that we unset the correct locations (see PR #3706).
|
||||
#[gpu_test]
|
||||
static PASS_RESET_VERTEX_BUFFER: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
let module = ctx
|
||||
.device
|
||||
.create_shader_module(include_wgsl!("issue_3457.wgsl"));
|
||||
@ -160,7 +160,7 @@ static PASS_RESET_VERTEX_BUFFER: GpuTestConfiguration =
|
||||
drop(vertex_buffer2);
|
||||
|
||||
// Make sure the buffers are actually deleted.
|
||||
ctx.device.poll(Maintain::Wait);
|
||||
ctx.async_poll(Maintain::wait()).await.panic_on_timeout();
|
||||
|
||||
let mut encoder2 = ctx
|
||||
.device
|
||||
|
@ -14,7 +14,7 @@ use wgpu::*;
|
||||
/// to add them to. This is incorrect, as we do not immediatley invoke map_async callbacks.
|
||||
#[gpu_test]
|
||||
static QUEUE_SUBMITTED_CALLBACK_ORDERING: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| async move {
|
||||
// Create a mappable buffer
|
||||
let buffer = ctx.device.create_buffer(&BufferDescriptor {
|
||||
label: Some("mappable buffer"),
|
||||
@ -36,7 +36,7 @@ static QUEUE_SUBMITTED_CALLBACK_ORDERING: GpuTestConfiguration = GpuTestConfigur
|
||||
// Submit the work.
|
||||
ctx.queue.submit(Some(encoder.finish()));
|
||||
// Ensure the work is finished.
|
||||
ctx.device.poll(MaintainBase::Wait);
|
||||
ctx.async_poll(Maintain::wait()).await.panic_on_timeout();
|
||||
|
||||
#[derive(Debug)]
|
||||
struct OrderingContext {
|
||||
@ -74,7 +74,7 @@ static QUEUE_SUBMITTED_CALLBACK_ORDERING: GpuTestConfiguration = GpuTestConfigur
|
||||
});
|
||||
|
||||
// No GPU work is happening at this point, but we want to process callbacks.
|
||||
ctx.device.poll(MaintainBase::Poll);
|
||||
ctx.async_poll(MaintainBase::Poll).await.panic_on_timeout();
|
||||
|
||||
// Extract the ordering out of the arc.
|
||||
let ordering = Arc::into_inner(ordering).unwrap().into_inner();
|
||||
|
@ -1,8 +1,8 @@
|
||||
use std::ops::Range;
|
||||
|
||||
use wgpu_test::{gpu_test, GpuTestConfiguration, TestingContext};
|
||||
use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext};
|
||||
|
||||
fn fill_test(ctx: &TestingContext, range: Range<u64>, size: u64) -> bool {
|
||||
async fn fill_test(ctx: &TestingContext, range: Range<u64>, size: u64) -> bool {
|
||||
let gpu_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("gpu_buffer"),
|
||||
size,
|
||||
@ -32,7 +32,9 @@ fn fill_test(ctx: &TestingContext, range: Range<u64>, size: u64) -> bool {
|
||||
|
||||
ctx.queue.submit(Some(encoder.finish()));
|
||||
cpu_buffer.slice(..).map_async(wgpu::MapMode::Read, |_| ());
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
let buffer_slice = cpu_buffer.slice(..);
|
||||
let buffer_data = buffer_slice.get_mapped_range();
|
||||
@ -84,8 +86,9 @@ fn fill_test(ctx: &TestingContext, range: Range<u64>, size: u64) -> bool {
|
||||
///
|
||||
/// This test will fail on nvidia if the bug is not properly worked around.
|
||||
#[gpu_test]
|
||||
static CLEAR_BUFFER_RANGE_RESPECTED: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
static CLEAR_BUFFER_RANGE_RESPECTED: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(TestParameters::default())
|
||||
.run_async(|ctx| async move {
|
||||
// This hits most of the cases in nvidia's clear buffer bug
|
||||
let mut succeeded = true;
|
||||
for power in 4..14 {
|
||||
@ -93,7 +96,7 @@ static CLEAR_BUFFER_RANGE_RESPECTED: GpuTestConfiguration =
|
||||
for start_offset in (0..=36).step_by(4) {
|
||||
for size_offset in (0..=36).step_by(4) {
|
||||
let range = start_offset..size + size_offset + start_offset;
|
||||
let result = fill_test(&ctx, range, 1 << 16);
|
||||
let result = fill_test(&ctx, range, 1 << 16).await;
|
||||
|
||||
succeeded &= result;
|
||||
}
|
||||
|
@ -11,7 +11,11 @@ const TEXTURE_HEIGHT: u32 = 2;
|
||||
const TEXTURE_WIDTH: u32 = 2;
|
||||
const BUFFER_SIZE: usize = (TEXTURE_WIDTH * TEXTURE_HEIGHT * 4) as usize;
|
||||
|
||||
fn scissor_test_impl(ctx: &TestingContext, scissor_rect: Rect, expected_data: [u8; BUFFER_SIZE]) {
|
||||
async fn scissor_test_impl(
|
||||
ctx: &TestingContext,
|
||||
scissor_rect: Rect,
|
||||
expected_data: [u8; BUFFER_SIZE],
|
||||
) {
|
||||
let texture = ctx.device.create_texture(&wgpu::TextureDescriptor {
|
||||
label: Some("Offscreen texture"),
|
||||
size: wgpu::Extent3d {
|
||||
@ -94,26 +98,30 @@ fn scissor_test_impl(ctx: &TestingContext, scissor_rect: Rect, expected_data: [u
|
||||
readback_buffer.copy_from(&ctx.device, &mut encoder, &texture);
|
||||
ctx.queue.submit(Some(encoder.finish()));
|
||||
}
|
||||
readback_buffer.assert_buffer_contents(&ctx.device, &expected_data);
|
||||
readback_buffer
|
||||
.assert_buffer_contents(ctx, &expected_data)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[gpu_test]
|
||||
static SCISSOR_TEST_FULL_RECT: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
scissor_test_impl(
|
||||
&ctx,
|
||||
Rect {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: TEXTURE_WIDTH,
|
||||
height: TEXTURE_HEIGHT,
|
||||
},
|
||||
[255; BUFFER_SIZE],
|
||||
);
|
||||
});
|
||||
static SCISSOR_TEST_FULL_RECT: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
scissor_test_impl(
|
||||
&ctx,
|
||||
Rect {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: TEXTURE_WIDTH,
|
||||
height: TEXTURE_HEIGHT,
|
||||
},
|
||||
[255; BUFFER_SIZE],
|
||||
)
|
||||
.await
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static SCISSOR_TEST_EMPTY_RECT: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
scissor_test_impl(
|
||||
&ctx,
|
||||
Rect {
|
||||
@ -123,12 +131,13 @@ static SCISSOR_TEST_EMPTY_RECT: GpuTestConfiguration =
|
||||
height: 0,
|
||||
},
|
||||
[0; BUFFER_SIZE],
|
||||
);
|
||||
)
|
||||
.await;
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static SCISSOR_TEST_EMPTY_RECT_WITH_OFFSET: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| async move {
|
||||
scissor_test_impl(
|
||||
&ctx,
|
||||
Rect {
|
||||
@ -138,12 +147,13 @@ static SCISSOR_TEST_EMPTY_RECT_WITH_OFFSET: GpuTestConfiguration = GpuTestConfig
|
||||
height: 0,
|
||||
},
|
||||
[0; BUFFER_SIZE],
|
||||
);
|
||||
)
|
||||
.await
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static SCISSOR_TEST_CUSTOM_RECT: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
let mut expected_result = [0; BUFFER_SIZE];
|
||||
expected_result[((3 * BUFFER_SIZE) / 4)..][..BUFFER_SIZE / 4]
|
||||
.copy_from_slice(&[255; BUFFER_SIZE / 4]);
|
||||
@ -157,5 +167,6 @@ static SCISSOR_TEST_CUSTOM_RECT: GpuTestConfiguration =
|
||||
height: TEXTURE_HEIGHT / 2,
|
||||
},
|
||||
expected_result,
|
||||
);
|
||||
)
|
||||
.await;
|
||||
});
|
||||
|
@ -177,7 +177,7 @@ impl ShaderTest {
|
||||
const MAX_BUFFER_SIZE: u64 = 128;
|
||||
|
||||
/// Runs the given shader tests with the given storage_type for the input_buffer.
|
||||
fn shader_input_output_test(
|
||||
async fn shader_input_output_test(
|
||||
ctx: TestingContext,
|
||||
storage_type: InputStorageType,
|
||||
tests: Vec<ShaderTest>,
|
||||
@ -355,7 +355,7 @@ fn shader_input_output_test(
|
||||
ctx.queue.submit(Some(encoder.finish()));
|
||||
|
||||
mapping_buffer.slice(..).map_async(MapMode::Read, |_| ());
|
||||
ctx.device.poll(Maintain::Wait);
|
||||
ctx.async_poll(Maintain::wait()).await.panic_on_timeout();
|
||||
|
||||
let mapped = mapping_buffer.slice(..).get_mapped_range();
|
||||
|
||||
|
@ -44,10 +44,10 @@ static NUMERIC_BUILTINS: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.downlevel_flags(DownlevelFlags::COMPUTE_SHADERS)
|
||||
.limits(Limits::downlevel_defaults()),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| {
|
||||
shader_input_output_test(
|
||||
ctx,
|
||||
InputStorageType::Storage,
|
||||
create_numeric_builtin_test(),
|
||||
);
|
||||
)
|
||||
});
|
||||
|
@ -231,12 +231,12 @@ static UNIFORM_INPUT: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
)
|
||||
.limits(Limits::downlevel_defaults()),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| {
|
||||
shader_input_output_test(
|
||||
ctx,
|
||||
InputStorageType::Uniform,
|
||||
create_struct_layout_tests(InputStorageType::Uniform),
|
||||
);
|
||||
)
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
@ -246,12 +246,12 @@ static STORAGE_INPUT: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.downlevel_flags(DownlevelFlags::COMPUTE_SHADERS)
|
||||
.limits(Limits::downlevel_defaults()),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| {
|
||||
shader_input_output_test(
|
||||
ctx,
|
||||
InputStorageType::Storage,
|
||||
create_struct_layout_tests(InputStorageType::Storage),
|
||||
);
|
||||
)
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
@ -265,10 +265,10 @@ static PUSH_CONSTANT_INPUT: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
..Limits::downlevel_defaults()
|
||||
}),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| {
|
||||
shader_input_output_test(
|
||||
ctx,
|
||||
InputStorageType::PushConstant,
|
||||
create_struct_layout_tests(InputStorageType::PushConstant),
|
||||
);
|
||||
)
|
||||
});
|
||||
|
@ -24,7 +24,7 @@ static ZERO_INIT_WORKGROUP_MEMORY: GpuTestConfiguration = GpuTestConfiguration::
|
||||
..FailureCase::default()
|
||||
}),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| async move {
|
||||
let bgl = ctx
|
||||
.device
|
||||
.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||
@ -134,7 +134,7 @@ static ZERO_INIT_WORKGROUP_MEMORY: GpuTestConfiguration = GpuTestConfiguration::
|
||||
ctx.queue.submit(Some(encoder.finish()));
|
||||
|
||||
mapping_buffer.slice(..).map_async(MapMode::Read, |_| ());
|
||||
ctx.device.poll(Maintain::Wait);
|
||||
ctx.async_poll(Maintain::wait()).await.panic_on_timeout();
|
||||
|
||||
let mapped = mapping_buffer.slice(..).get_mapped_range();
|
||||
|
||||
|
@ -43,7 +43,7 @@ static DRAW: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.test_features_limits()
|
||||
.features(wgpu::Features::SHADER_PRIMITIVE_INDEX),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| async move {
|
||||
//
|
||||
// +-----+-----+
|
||||
// |white|blue |
|
||||
@ -57,6 +57,7 @@ static DRAW: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
pulling_common(ctx, &expected, |rpass| {
|
||||
rpass.draw(0..6, 0..1);
|
||||
})
|
||||
.await;
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
@ -66,7 +67,7 @@ static DRAW_INDEXED: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.test_features_limits()
|
||||
.features(wgpu::Features::SHADER_PRIMITIVE_INDEX),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| async move {
|
||||
//
|
||||
// +-----+-----+
|
||||
// |white| red |
|
||||
@ -80,9 +81,10 @@ static DRAW_INDEXED: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
pulling_common(ctx, &expected, |rpass| {
|
||||
rpass.draw_indexed(0..6, 0, 0..1);
|
||||
})
|
||||
.await;
|
||||
});
|
||||
|
||||
fn pulling_common(
|
||||
async fn pulling_common(
|
||||
ctx: TestingContext,
|
||||
expected: &[u8],
|
||||
draw_command: impl FnOnce(&mut wgpu::RenderPass<'_>),
|
||||
@ -192,5 +194,5 @@ fn pulling_common(
|
||||
}
|
||||
readback_buffer.copy_from(&ctx.device, &mut encoder, &color_texture);
|
||||
ctx.queue.submit(Some(encoder.finish()));
|
||||
readback_buffer.assert_buffer_contents(&ctx.device, expected);
|
||||
readback_buffer.assert_buffer_contents(&ctx, expected).await;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ static REINTERPRET_SRGB: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.downlevel_flags(DownlevelFlags::VIEW_FORMATS)
|
||||
.limits(Limits::downlevel_defaults()),
|
||||
)
|
||||
.run_sync(|ctx| {
|
||||
.run_async(|ctx| async move {
|
||||
let unorm_data: [[u8; 4]; 4] = [
|
||||
[180, 0, 0, 255],
|
||||
[0, 84, 0, 127],
|
||||
@ -41,7 +41,8 @@ static REINTERPRET_SRGB: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
TextureFormat::Rgba8UnormSrgb,
|
||||
&unorm_data,
|
||||
&srgb_data,
|
||||
);
|
||||
)
|
||||
.await;
|
||||
|
||||
// Reinterpret Rgba8UnormSrgb back to Rgba8Unorm
|
||||
reinterpret(
|
||||
@ -52,10 +53,11 @@ static REINTERPRET_SRGB: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
TextureFormat::Rgba8Unorm,
|
||||
&srgb_data,
|
||||
&unorm_data,
|
||||
);
|
||||
)
|
||||
.await;
|
||||
});
|
||||
|
||||
fn reinterpret(
|
||||
async fn reinterpret(
|
||||
ctx: &TestingContext,
|
||||
shader: &wgpu::ShaderModule,
|
||||
size: wgpu::Extent3d,
|
||||
@ -178,7 +180,9 @@ fn reinterpret(
|
||||
|
||||
let slice = read_buffer.slice(..);
|
||||
slice.map_async(wgpu::MapMode::Read, |_| ());
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
|
||||
let data: Vec<u8> = slice.get_mapped_range().to_vec();
|
||||
let tolerance_data: [[u8; 4]; 4] = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [1, 1, 1, 0]];
|
||||
|
@ -225,7 +225,7 @@ impl Test {
|
||||
}
|
||||
}
|
||||
|
||||
fn vertex_index_common(ctx: TestingContext) {
|
||||
async fn vertex_index_common(ctx: TestingContext) {
|
||||
let identity_buffer = ctx.device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: Some("identity buffer"),
|
||||
contents: bytemuck::cast_slice(&[0u32, 1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
@ -428,11 +428,15 @@ fn vertex_index_common(ctx: TestingContext) {
|
||||
// See https://github.com/gfx-rs/wgpu/issues/4732 for why this is split between two submissions
|
||||
// with a hard wait in between.
|
||||
ctx.queue.submit([encoder1.finish()]);
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
ctx.queue.submit([encoder2.finish()]);
|
||||
let slice = cpu_buffer.slice(..);
|
||||
slice.map_async(wgpu::MapMode::Read, |_| ());
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
let data: Vec<u32> = bytemuck::cast_slice(&slice.get_mapped_range()).to_vec();
|
||||
|
||||
if data != expected {
|
||||
@ -463,4 +467,4 @@ static VERTEX_INDICES: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.test_features_limits()
|
||||
.features(wgpu::Features::VERTEX_WRITABLE_STORAGE),
|
||||
)
|
||||
.run_sync(vertex_index_common);
|
||||
.run_async(vertex_index_common);
|
||||
|
@ -4,7 +4,7 @@ use wgpu_test::{gpu_test, GpuTestConfiguration};
|
||||
|
||||
#[gpu_test]
|
||||
static WRITE_TEXTURE_SUBSET_2D: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
let size = 256;
|
||||
|
||||
let tex = ctx.device.create_texture(&wgpu::TextureDescriptor {
|
||||
@ -84,7 +84,9 @@ static WRITE_TEXTURE_SUBSET_2D: GpuTestConfiguration =
|
||||
|
||||
let slice = read_buffer.slice(..);
|
||||
slice.map_async(wgpu::MapMode::Read, |_| ());
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
let data: Vec<u8> = slice.get_mapped_range().to_vec();
|
||||
|
||||
for byte in &data[..(size as usize * 2)] {
|
||||
@ -97,7 +99,7 @@ static WRITE_TEXTURE_SUBSET_2D: GpuTestConfiguration =
|
||||
|
||||
#[gpu_test]
|
||||
static WRITE_TEXTURE_SUBSET_3D: GpuTestConfiguration =
|
||||
GpuTestConfiguration::new().run_sync(|ctx| {
|
||||
GpuTestConfiguration::new().run_async(|ctx| async move {
|
||||
let size = 256;
|
||||
let depth = 4;
|
||||
let tex = ctx.device.create_texture(&wgpu::TextureDescriptor {
|
||||
@ -177,7 +179,9 @@ static WRITE_TEXTURE_SUBSET_3D: GpuTestConfiguration =
|
||||
|
||||
let slice = read_buffer.slice(..);
|
||||
slice.map_async(wgpu::MapMode::Read, |_| ());
|
||||
ctx.device.poll(wgpu::Maintain::Wait);
|
||||
ctx.async_poll(wgpu::Maintain::wait())
|
||||
.await
|
||||
.panic_on_timeout();
|
||||
let data: Vec<u8> = slice.get_mapped_range().to_vec();
|
||||
|
||||
for byte in &data[..((size * size) as usize * 2)] {
|
||||
|
@ -9,7 +9,7 @@ use wgpu_test::{
|
||||
static DISCARDING_COLOR_TARGET_RESETS_TEXTURE_INIT_STATE_CHECK_VISIBLE_ON_COPY_AFTER_SUBMIT:
|
||||
GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(TestParameters::default().expect_fail(FailureCase::webgl2()))
|
||||
.run_sync(|mut ctx| {
|
||||
.run_async(|mut ctx| async move {
|
||||
let mut case = TestCase::new(&mut ctx, TextureFormat::Rgba8UnormSrgb);
|
||||
case.create_command_encoder();
|
||||
case.discard();
|
||||
@ -19,21 +19,21 @@ static DISCARDING_COLOR_TARGET_RESETS_TEXTURE_INIT_STATE_CHECK_VISIBLE_ON_COPY_A
|
||||
case.copy_texture_to_buffer();
|
||||
case.submit_command_encoder();
|
||||
|
||||
case.assert_buffers_are_zero();
|
||||
case.assert_buffers_are_zero().await;
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
static DISCARDING_COLOR_TARGET_RESETS_TEXTURE_INIT_STATE_CHECK_VISIBLE_ON_COPY_IN_SAME_ENCODER:
|
||||
GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(TestParameters::default().expect_fail(FailureCase::webgl2()))
|
||||
.run_sync(|mut ctx| {
|
||||
.run_async(|mut ctx| async move {
|
||||
let mut case = TestCase::new(&mut ctx, TextureFormat::Rgba8UnormSrgb);
|
||||
case.create_command_encoder();
|
||||
case.discard();
|
||||
case.copy_texture_to_buffer();
|
||||
case.submit_command_encoder();
|
||||
|
||||
case.assert_buffers_are_zero();
|
||||
case.assert_buffers_are_zero().await;
|
||||
});
|
||||
|
||||
#[gpu_test]
|
||||
@ -46,7 +46,7 @@ static DISCARDING_DEPTH_TARGET_RESETS_TEXTURE_INIT_STATE_CHECK_VISIBLE_ON_COPY_I
|
||||
)
|
||||
.limits(Limits::downlevel_defaults()),
|
||||
)
|
||||
.run_sync(|mut ctx| {
|
||||
.run_async(|mut ctx| async move {
|
||||
for format in [
|
||||
TextureFormat::Stencil8,
|
||||
TextureFormat::Depth16Unorm,
|
||||
@ -60,7 +60,7 @@ static DISCARDING_DEPTH_TARGET_RESETS_TEXTURE_INIT_STATE_CHECK_VISIBLE_ON_COPY_I
|
||||
case.copy_texture_to_buffer();
|
||||
case.submit_command_encoder();
|
||||
|
||||
case.assert_buffers_are_zero();
|
||||
case.assert_buffers_are_zero().await;
|
||||
}
|
||||
});
|
||||
|
||||
@ -75,7 +75,7 @@ static DISCARDING_EITHER_DEPTH_OR_STENCIL_ASPECT_TEST: GpuTestConfiguration =
|
||||
)
|
||||
.limits(Limits::downlevel_defaults()),
|
||||
)
|
||||
.run_sync(|mut ctx| {
|
||||
.run_async(|mut ctx| async move {
|
||||
for format in [
|
||||
TextureFormat::Stencil8,
|
||||
TextureFormat::Depth16Unorm,
|
||||
@ -96,7 +96,7 @@ static DISCARDING_EITHER_DEPTH_OR_STENCIL_ASPECT_TEST: GpuTestConfiguration =
|
||||
case.copy_texture_to_buffer();
|
||||
case.submit_command_encoder();
|
||||
|
||||
case.assert_buffers_are_zero();
|
||||
case.assert_buffers_are_zero().await;
|
||||
}
|
||||
});
|
||||
|
||||
@ -310,9 +310,9 @@ impl<'ctx> TestCase<'ctx> {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn assert_buffers_are_zero(&mut self) {
|
||||
pub async fn assert_buffers_are_zero(&mut self) {
|
||||
assert!(
|
||||
self.readback_buffers.are_zero(&self.ctx.device),
|
||||
self.readback_buffers.are_zero(self.ctx).await,
|
||||
"texture was not fully cleared"
|
||||
);
|
||||
}
|
||||
|
@ -4280,10 +4280,10 @@ impl Default for ColorWrites {
|
||||
/// Passed to `Device::poll` to control how and if it should block.
|
||||
#[derive(Clone)]
|
||||
pub enum Maintain<T> {
|
||||
/// On native backends, block until the given submission has
|
||||
/// On wgpu-core based backends, block until the given submission has
|
||||
/// completed execution, and any callbacks have been invoked.
|
||||
///
|
||||
/// On the web, this has no effect. Callbacks are invoked from the
|
||||
/// On WebGPU, this has no effect. Callbacks are invoked from the
|
||||
/// window event loop.
|
||||
WaitForSubmissionIndex(T),
|
||||
/// Same as WaitForSubmissionIndex but waits for the most recent submission.
|
||||
@ -4293,6 +4293,22 @@ pub enum Maintain<T> {
|
||||
}
|
||||
|
||||
impl<T> Maintain<T> {
|
||||
/// Construct a wait variant
|
||||
pub fn wait() -> Self {
|
||||
// This function seems a little silly, but it is useful to allow
|
||||
// <https://github.com/gfx-rs/wgpu/pull/5012> to be split up, as
|
||||
// it has meaning in that PR.
|
||||
Self::Wait
|
||||
}
|
||||
|
||||
/// Construct a WaitForSubmissionIndex variant
|
||||
pub fn wait_for(submission_index: T) -> Self {
|
||||
// This function seems a little silly, but it is useful to allow
|
||||
// <https://github.com/gfx-rs/wgpu/pull/5012> to be split up, as
|
||||
// it has meaning in that PR.
|
||||
Self::WaitForSubmissionIndex(submission_index)
|
||||
}
|
||||
|
||||
/// This maintain represents a wait of some kind.
|
||||
pub fn is_wait(&self) -> bool {
|
||||
match *self {
|
||||
@ -4314,6 +4330,29 @@ impl<T> Maintain<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Result of a maintain operation.
|
||||
pub enum MaintainResult {
|
||||
/// There are no active submissions in flight as of the beginning of the poll call.
|
||||
/// Other submissions may have been queued on other threads at the same time.
|
||||
///
|
||||
/// This implies that the given poll is complete.
|
||||
SubmissionQueueEmpty,
|
||||
/// More information coming soon <https://github.com/gfx-rs/wgpu/pull/5012>
|
||||
Ok,
|
||||
}
|
||||
|
||||
impl MaintainResult {
|
||||
/// Returns true if the result is [`Self::SubmissionQueueEmpty`]`.
|
||||
pub fn is_queue_empty(&self) -> bool {
|
||||
matches!(self, Self::SubmissionQueueEmpty)
|
||||
}
|
||||
|
||||
/// Panics if the MaintainResult is not Ok.
|
||||
pub fn panic_on_timeout(self) {
|
||||
let _ = self;
|
||||
}
|
||||
}
|
||||
|
||||
/// State of the stencil operation (fixed-pipeline stage).
|
||||
///
|
||||
/// For use in [`DepthStencilState`].
|
||||
|
@ -1403,8 +1403,8 @@ impl crate::Context for Context {
|
||||
#[cfg(any(native, emscripten))]
|
||||
{
|
||||
let global = &self.0;
|
||||
match wgc::gfx_select!(device => global.device_poll(*device, wgt::Maintain::Wait)) {
|
||||
Ok(_) => (),
|
||||
match wgc::gfx_select!(device => global.device_poll(*device, wgt::Maintain::wait())) {
|
||||
Ok(_) => {}
|
||||
Err(err) => self.handle_error_fatal(err, "Device::drop"),
|
||||
}
|
||||
wgc::gfx_select!(device => global.device_drop(*device));
|
||||
@ -1445,14 +1445,17 @@ impl crate::Context for Context {
|
||||
device: &Self::DeviceId,
|
||||
_device_data: &Self::DeviceData,
|
||||
maintain: crate::Maintain,
|
||||
) -> bool {
|
||||
) -> wgt::MaintainResult {
|
||||
let global = &self.0;
|
||||
let maintain_inner = maintain.map_index(|i| *i.1.as_ref().downcast_ref().unwrap());
|
||||
match wgc::gfx_select!(device => global.device_poll(
|
||||
*device,
|
||||
maintain_inner
|
||||
)) {
|
||||
Ok(queue_empty) => queue_empty,
|
||||
Ok(done) => match done {
|
||||
true => wgt::MaintainResult::SubmissionQueueEmpty,
|
||||
false => wgt::MaintainResult::Ok,
|
||||
},
|
||||
Err(err) => self.handle_error_fatal(err, "Device::poll"),
|
||||
}
|
||||
}
|
||||
|
@ -1950,9 +1950,9 @@ impl crate::context::Context for Context {
|
||||
_device: &Self::DeviceId,
|
||||
_device_data: &Self::DeviceData,
|
||||
_maintain: crate::Maintain,
|
||||
) -> bool {
|
||||
) -> crate::MaintainResult {
|
||||
// Device is polled automatically
|
||||
true
|
||||
crate::MaintainResult::SubmissionQueueEmpty
|
||||
}
|
||||
|
||||
fn device_on_uncaptured_error(
|
||||
|
@ -10,8 +10,8 @@ use wgt::{
|
||||
use crate::{
|
||||
AnyWasmNotSendSync, BindGroupDescriptor, BindGroupLayoutDescriptor, Buffer, BufferAsyncError,
|
||||
BufferDescriptor, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor,
|
||||
DeviceDescriptor, Error, ErrorFilter, ImageCopyBuffer, ImageCopyTexture, Maintain, MapMode,
|
||||
PipelineLayoutDescriptor, QuerySetDescriptor, RenderBundleDescriptor,
|
||||
DeviceDescriptor, Error, ErrorFilter, ImageCopyBuffer, ImageCopyTexture, Maintain,
|
||||
MaintainResult, MapMode, PipelineLayoutDescriptor, QuerySetDescriptor, RenderBundleDescriptor,
|
||||
RenderBundleEncoderDescriptor, RenderPassDescriptor, RenderPipelineDescriptor,
|
||||
RequestAdapterOptions, RequestDeviceError, SamplerDescriptor, ShaderModuleDescriptor,
|
||||
ShaderModuleDescriptorSpirV, SurfaceTargetUnsafe, Texture, TextureDescriptor,
|
||||
@ -287,7 +287,7 @@ pub trait Context: Debug + WasmNotSendSync + Sized {
|
||||
device: &Self::DeviceId,
|
||||
device_data: &Self::DeviceData,
|
||||
maintain: Maintain,
|
||||
) -> bool;
|
||||
) -> MaintainResult;
|
||||
fn device_on_uncaptured_error(
|
||||
&self,
|
||||
device: &Self::DeviceId,
|
||||
@ -1309,8 +1309,12 @@ pub(crate) trait DynContext: Debug + WasmNotSendSync {
|
||||
fn device_destroy(&self, device: &ObjectId, device_data: &crate::Data);
|
||||
fn device_mark_lost(&self, device: &ObjectId, device_data: &crate::Data, message: &str);
|
||||
fn queue_drop(&self, queue: &ObjectId, queue_data: &crate::Data);
|
||||
fn device_poll(&self, device: &ObjectId, device_data: &crate::Data, maintain: Maintain)
|
||||
-> bool;
|
||||
fn device_poll(
|
||||
&self,
|
||||
device: &ObjectId,
|
||||
device_data: &crate::Data,
|
||||
maintain: Maintain,
|
||||
) -> MaintainResult;
|
||||
fn device_on_uncaptured_error(
|
||||
&self,
|
||||
device: &ObjectId,
|
||||
@ -2399,7 +2403,7 @@ where
|
||||
device: &ObjectId,
|
||||
device_data: &crate::Data,
|
||||
maintain: Maintain,
|
||||
) -> bool {
|
||||
) -> MaintainResult {
|
||||
let device = <T::DeviceId>::from(*device);
|
||||
let device_data = downcast_ref(device_data);
|
||||
Context::device_poll(self, &device, device_data, maintain)
|
||||
|
@ -85,16 +85,17 @@ pub use wgt::{
|
||||
DepthStencilState, DeviceLostReason, DeviceType, DownlevelCapabilities, DownlevelFlags,
|
||||
Dx12Compiler, DynamicOffset, Extent3d, Face, Features, FilterMode, FrontFace,
|
||||
Gles3MinorVersion, ImageDataLayout, ImageSubresourceRange, IndexFormat, InstanceDescriptor,
|
||||
InstanceFlags, Limits, MultisampleState, Origin2d, Origin3d, PipelineStatisticsTypes,
|
||||
PolygonMode, PowerPreference, PredefinedColorSpace, PresentMode, PresentationTimestamp,
|
||||
PrimitiveState, PrimitiveTopology, PushConstantRange, QueryType, RenderBundleDepthStencil,
|
||||
SamplerBindingType, SamplerBorderColor, ShaderLocation, ShaderModel, ShaderStages,
|
||||
StencilFaceState, StencilOperation, StencilState, StorageTextureAccess, SurfaceCapabilities,
|
||||
SurfaceStatus, TextureAspect, TextureDimension, TextureFormat, TextureFormatFeatureFlags,
|
||||
TextureFormatFeatures, TextureSampleType, TextureUsages, TextureViewDimension, VertexAttribute,
|
||||
VertexFormat, VertexStepMode, WasmNotSend, WasmNotSendSync, WasmNotSync, COPY_BUFFER_ALIGNMENT,
|
||||
COPY_BYTES_PER_ROW_ALIGNMENT, MAP_ALIGNMENT, PUSH_CONSTANT_ALIGNMENT,
|
||||
QUERY_RESOLVE_BUFFER_ALIGNMENT, QUERY_SET_MAX_QUERIES, QUERY_SIZE, VERTEX_STRIDE_ALIGNMENT,
|
||||
InstanceFlags, Limits, MaintainResult, MultisampleState, Origin2d, Origin3d,
|
||||
PipelineStatisticsTypes, PolygonMode, PowerPreference, PredefinedColorSpace, PresentMode,
|
||||
PresentationTimestamp, PrimitiveState, PrimitiveTopology, PushConstantRange, QueryType,
|
||||
RenderBundleDepthStencil, SamplerBindingType, SamplerBorderColor, ShaderLocation, ShaderModel,
|
||||
ShaderStages, StencilFaceState, StencilOperation, StencilState, StorageTextureAccess,
|
||||
SurfaceCapabilities, SurfaceStatus, TextureAspect, TextureDimension, TextureFormat,
|
||||
TextureFormatFeatureFlags, TextureFormatFeatures, TextureSampleType, TextureUsages,
|
||||
TextureViewDimension, VertexAttribute, VertexFormat, VertexStepMode, WasmNotSend,
|
||||
WasmNotSendSync, WasmNotSync, COPY_BUFFER_ALIGNMENT, COPY_BYTES_PER_ROW_ALIGNMENT,
|
||||
MAP_ALIGNMENT, PUSH_CONSTANT_ALIGNMENT, QUERY_RESOLVE_BUFFER_ALIGNMENT, QUERY_SET_MAX_QUERIES,
|
||||
QUERY_SIZE, VERTEX_STRIDE_ALIGNMENT,
|
||||
};
|
||||
|
||||
#[cfg(not(webgpu))]
|
||||
@ -2205,7 +2206,7 @@ impl Adapter {
|
||||
}
|
||||
|
||||
impl Device {
|
||||
/// Check for resource cleanups and mapping callbacks.
|
||||
/// Check for resource cleanups and mapping callbacks. Will block if [`Maintain::Wait`] is passed.
|
||||
///
|
||||
/// Return `true` if the queue is empty, or `false` if there are more queue
|
||||
/// submissions still in flight. (Note that, unless access to the [`Queue`] is
|
||||
@ -2213,8 +2214,8 @@ impl Device {
|
||||
/// the caller receives it. `Queue`s can be shared between threads, so
|
||||
/// other threads could submit new work at any time.)
|
||||
///
|
||||
/// On the web, this is a no-op. `Device`s are automatically polled.
|
||||
pub fn poll(&self, maintain: Maintain) -> bool {
|
||||
/// When running on WebGPU, this is a no-op. `Device`s are automatically polled.
|
||||
pub fn poll(&self, maintain: Maintain) -> MaintainResult {
|
||||
DynContext::device_poll(&*self.context, &self.id, self.data.as_ref(), maintain)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user