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