mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 14:55:05 +00:00
Check for webgl2 validation errors and catch issues (#3296)
This commit is contained in:
parent
5241633b3a
commit
6b6bc69ba0
@ -329,7 +329,10 @@ fn main() {
|
||||
framework::run::<Example>("boids");
|
||||
}
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn boids() {
|
||||
framework::test::<Example>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/boids/screenshot.png",
|
||||
|
@ -357,7 +357,10 @@ fn main() {
|
||||
framework::run::<Example>("bunnymark");
|
||||
}
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn bunnymark() {
|
||||
framework::test::<Example>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/bunnymark/screenshot.png",
|
||||
|
@ -225,7 +225,10 @@ mod tests {
|
||||
use super::*;
|
||||
use wgpu::BufferView;
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn ensure_generated_data_matches_expected() {
|
||||
assert_generated_data_matches_expected();
|
||||
}
|
||||
|
@ -314,7 +314,10 @@ fn main() {
|
||||
framework::run::<Example>("conservative-raster");
|
||||
}
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn conservative_raster() {
|
||||
framework::test::<Example>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/conservative-raster/screenshot.png",
|
||||
|
@ -406,7 +406,10 @@ fn main() {
|
||||
framework::run::<Example>("cube");
|
||||
}
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn cube() {
|
||||
framework::test::<Example>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/cube/screenshot.png",
|
||||
@ -420,6 +423,7 @@ fn cube() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn cube_lines() {
|
||||
framework::test::<Example>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/cube/screenshot-lines.png",
|
||||
|
@ -6,7 +6,10 @@ use std::sync::Arc;
|
||||
use super::*;
|
||||
use common::{initialize_test, TestParameters};
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn test_compute_1() {
|
||||
initialize_test(
|
||||
TestParameters::default()
|
||||
@ -27,6 +30,7 @@ fn test_compute_1() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn test_compute_2() {
|
||||
initialize_test(
|
||||
TestParameters::default()
|
||||
@ -47,6 +51,7 @@ fn test_compute_2() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn test_compute_overflow() {
|
||||
initialize_test(
|
||||
TestParameters::default()
|
||||
@ -66,6 +71,7 @@ fn test_compute_overflow() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Wasm doesn't support threads
|
||||
fn test_multithreaded_compute() {
|
||||
initialize_test(
|
||||
TestParameters::default()
|
||||
|
@ -487,7 +487,10 @@ fn main() {
|
||||
framework::run::<Example>("mipmap");
|
||||
}
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn mipmap() {
|
||||
framework::test::<Example>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/mipmap/screenshot.png",
|
||||
|
@ -310,7 +310,10 @@ fn main() {
|
||||
framework::run::<Example>("msaa-line");
|
||||
}
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn msaa_line() {
|
||||
framework::test::<Example>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/msaa-line/screenshot.png",
|
||||
|
@ -841,7 +841,10 @@ fn main() {
|
||||
framework::run::<Example>("shadow");
|
||||
}
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn shadow() {
|
||||
framework::test::<Example>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/shadow/screenshot.png",
|
||||
@ -850,6 +853,7 @@ fn shadow() {
|
||||
optional_features: wgpu::Features::default(),
|
||||
base_test_parameters: framework::test_common::TestParameters::default()
|
||||
.downlevel_flags(wgpu::DownlevelFlags::COMPARISON_SAMPLERS)
|
||||
.specific_failure(Some(wgpu::Backends::GL), None, Some("ANGLE"), false)
|
||||
// rpi4 on VK doesn't work: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3916
|
||||
.specific_failure(Some(wgpu::Backends::VULKAN), None, Some("V3D"), false)
|
||||
// llvmpipe versions in CI are flaky: https://github.com/gfx-rs/wgpu/issues/2594
|
||||
|
@ -465,20 +465,29 @@ fn main() {
|
||||
framework::run::<Skybox>("skybox");
|
||||
}
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn skybox() {
|
||||
framework::test::<Skybox>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/skybox/screenshot.png",
|
||||
width: 1024,
|
||||
height: 768,
|
||||
optional_features: wgpu::Features::default(),
|
||||
base_test_parameters: framework::test_common::TestParameters::default(),
|
||||
base_test_parameters: framework::test_common::TestParameters::default().specific_failure(
|
||||
Some(wgpu::Backends::GL),
|
||||
None,
|
||||
Some("ANGLE"),
|
||||
false,
|
||||
),
|
||||
tolerance: 3,
|
||||
max_outliers: 207, // bounded by swiftshader
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn skybox_bc1() {
|
||||
framework::test::<Skybox>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/skybox/screenshot-bc1.png",
|
||||
@ -492,6 +501,7 @@ fn skybox_bc1() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn skybox_etc2() {
|
||||
framework::test::<Skybox>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/skybox/screenshot-etc2.png",
|
||||
@ -505,6 +515,7 @@ fn skybox_etc2() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn skybox_astc() {
|
||||
framework::test::<Skybox>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/skybox/screenshot-astc.png",
|
||||
|
@ -406,7 +406,10 @@ fn main() {
|
||||
framework::run::<Example>("texture-arrays");
|
||||
}
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn texture_arrays_uniform() {
|
||||
framework::test::<Example>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/texture-arrays/screenshot.png",
|
||||
@ -420,6 +423,7 @@ fn texture_arrays_uniform() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn texture_arrays_non_uniform() {
|
||||
framework::test::<Example>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/texture-arrays/screenshot.png",
|
||||
|
@ -818,7 +818,10 @@ fn main() {
|
||||
framework::run::<Example>("water");
|
||||
}
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||
fn water() {
|
||||
framework::test::<Example>(framework::FrameworkRefTest {
|
||||
image_path: "/examples/water/screenshot.png",
|
||||
|
@ -2072,7 +2072,7 @@ impl crate::Context for Context {
|
||||
fn queue_write_buffer(
|
||||
&self,
|
||||
queue: &Self::QueueId,
|
||||
_queue_data: &Self::QueueData,
|
||||
queue_data: &Self::QueueData,
|
||||
buffer: &Self::BufferId,
|
||||
_buffer_data: &Self::BufferData,
|
||||
offset: wgt::BufferAddress,
|
||||
@ -2083,46 +2083,54 @@ impl crate::Context for Context {
|
||||
*queue => global.queue_write_buffer(*queue, *buffer, offset, data)
|
||||
) {
|
||||
Ok(()) => (),
|
||||
Err(err) => self.handle_error_fatal(err, "Queue::write_buffer"),
|
||||
Err(err) => {
|
||||
self.handle_error_nolabel(&queue_data.error_sink, err, "Queue::write_buffer")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn queue_validate_write_buffer(
|
||||
&self,
|
||||
queue: &Self::QueueId,
|
||||
_queue_data: &Self::QueueData,
|
||||
queue_data: &Self::QueueData,
|
||||
buffer: &Self::BufferId,
|
||||
_buffer_data: &Self::BufferData,
|
||||
offset: wgt::BufferAddress,
|
||||
size: wgt::BufferSize,
|
||||
) {
|
||||
) -> Option<()> {
|
||||
let global = &self.0;
|
||||
match wgc::gfx_select!(
|
||||
*queue => global.queue_validate_write_buffer(*queue, *buffer, offset, size.get())
|
||||
) {
|
||||
Ok(()) => (),
|
||||
Err(err) => self.handle_error_fatal(err, "Queue::write_buffer_with"),
|
||||
Ok(()) => Some(()),
|
||||
Err(err) => {
|
||||
self.handle_error_nolabel(&queue_data.error_sink, err, "Queue::write_buffer_with");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn queue_create_staging_buffer(
|
||||
&self,
|
||||
queue: &Self::QueueId,
|
||||
_queue_data: &Self::QueueData,
|
||||
queue_data: &Self::QueueData,
|
||||
size: wgt::BufferSize,
|
||||
) -> Box<dyn crate::context::QueueWriteBuffer> {
|
||||
) -> Option<Box<dyn crate::context::QueueWriteBuffer>> {
|
||||
let global = &self.0;
|
||||
match wgc::gfx_select!(
|
||||
*queue => global.queue_create_staging_buffer(*queue, size, ())
|
||||
) {
|
||||
Ok((buffer_id, ptr)) => Box::new(QueueWriteBuffer {
|
||||
Ok((buffer_id, ptr)) => Some(Box::new(QueueWriteBuffer {
|
||||
buffer_id,
|
||||
mapping: BufferMappedRange {
|
||||
ptr,
|
||||
size: size.get() as usize,
|
||||
},
|
||||
}),
|
||||
Err(err) => self.handle_error_fatal(err, "Queue::write_buffer_with"),
|
||||
})),
|
||||
Err(err) => {
|
||||
self.handle_error_nolabel(&queue_data.error_sink, err, "Queue::write_buffer_with");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2250,27 +2250,33 @@ impl crate::context::Context for Context {
|
||||
_buffer_data: &Self::BufferData,
|
||||
offset: wgt::BufferAddress,
|
||||
size: wgt::BufferSize,
|
||||
) {
|
||||
) -> Option<()> {
|
||||
let usage = wgt::BufferUsages::from_bits_truncate(buffer.0.usage());
|
||||
// TODO: actually send this down the error scope
|
||||
if !usage.contains(wgt::BufferUsages::COPY_DST) {
|
||||
panic!("Destination buffer is missing the `COPY_DST` usage flag");
|
||||
log::error!("Destination buffer is missing the `COPY_DST` usage flag");
|
||||
return None;
|
||||
}
|
||||
let write_size = u64::from(size);
|
||||
if write_size % wgt::COPY_BUFFER_ALIGNMENT != 0 {
|
||||
panic!(
|
||||
log::error!(
|
||||
"Copy size {} does not respect `COPY_BUFFER_ALIGNMENT`",
|
||||
size
|
||||
);
|
||||
return None;
|
||||
}
|
||||
if offset % wgt::COPY_BUFFER_ALIGNMENT != 0 {
|
||||
panic!(
|
||||
log::error!(
|
||||
"Buffer offset {} is not aligned to block size or `COPY_BUFFER_ALIGNMENT`",
|
||||
offset
|
||||
);
|
||||
return None;
|
||||
}
|
||||
if write_size + offset > buffer.0.size() as u64 {
|
||||
panic!("copy of {}..{} would end up overrunning the bounds of the destination buffer of size {}", offset, offset + write_size, buffer.0.size());
|
||||
log::error!("copy of {}..{} would end up overrunning the bounds of the destination buffer of size {}", offset, offset + write_size, buffer.0.size());
|
||||
return None;
|
||||
}
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn queue_create_staging_buffer(
|
||||
@ -2278,10 +2284,10 @@ impl crate::context::Context for Context {
|
||||
_queue: &Self::QueueId,
|
||||
_queue_data: &Self::QueueData,
|
||||
size: wgt::BufferSize,
|
||||
) -> Box<dyn QueueWriteBuffer> {
|
||||
Box::new(WebQueueWriteBuffer(
|
||||
) -> Option<Box<dyn QueueWriteBuffer>> {
|
||||
Some(Box::new(WebQueueWriteBuffer(
|
||||
vec![0; size.get() as usize].into_boxed_slice(),
|
||||
))
|
||||
)))
|
||||
}
|
||||
|
||||
fn queue_write_staging_buffer(
|
||||
|
@ -538,13 +538,13 @@ pub trait Context: Debug + Send + Sized + Sync {
|
||||
buffer_data: &Self::BufferData,
|
||||
offset: wgt::BufferAddress,
|
||||
size: wgt::BufferSize,
|
||||
);
|
||||
) -> Option<()>;
|
||||
fn queue_create_staging_buffer(
|
||||
&self,
|
||||
queue: &Self::QueueId,
|
||||
queue_data: &Self::QueueData,
|
||||
size: BufferSize,
|
||||
) -> Box<dyn QueueWriteBuffer>;
|
||||
) -> Option<Box<dyn QueueWriteBuffer>>;
|
||||
fn queue_write_staging_buffer(
|
||||
&self,
|
||||
queue: &Self::QueueId,
|
||||
@ -1438,13 +1438,13 @@ pub(crate) trait DynContext: Debug + Send + Sync {
|
||||
buffer_data: &crate::Data,
|
||||
offset: wgt::BufferAddress,
|
||||
size: wgt::BufferSize,
|
||||
);
|
||||
) -> Option<()>;
|
||||
fn queue_create_staging_buffer(
|
||||
&self,
|
||||
queue: &ObjectId,
|
||||
queue_data: &crate::Data,
|
||||
size: BufferSize,
|
||||
) -> Box<dyn QueueWriteBuffer>;
|
||||
) -> Option<Box<dyn QueueWriteBuffer>>;
|
||||
fn queue_write_staging_buffer(
|
||||
&self,
|
||||
queue: &ObjectId,
|
||||
@ -2785,7 +2785,7 @@ where
|
||||
buffer_data: &crate::Data,
|
||||
offset: wgt::BufferAddress,
|
||||
size: wgt::BufferSize,
|
||||
) {
|
||||
) -> Option<()> {
|
||||
let queue = <T::QueueId>::from(*queue);
|
||||
let queue_data = downcast_ref(queue_data);
|
||||
let buffer = <T::BufferId>::from(*buffer);
|
||||
@ -2806,7 +2806,7 @@ where
|
||||
queue: &ObjectId,
|
||||
queue_data: &crate::Data,
|
||||
size: BufferSize,
|
||||
) -> Box<dyn QueueWriteBuffer> {
|
||||
) -> Option<Box<dyn QueueWriteBuffer>> {
|
||||
let queue = <T::QueueId>::from(*queue);
|
||||
let queue_data = downcast_ref(queue_data);
|
||||
Context::queue_create_staging_buffer(self, &queue, queue_data, size)
|
||||
|
@ -59,7 +59,7 @@ static_assertions::assert_impl_all!(ErrorFilter: Send, Sync);
|
||||
type C = dyn DynContext;
|
||||
type Data = dyn Any + Send + Sync;
|
||||
|
||||
/// Context for all other wgpu objects. Instance of wgpu.
|
||||
/// Context for all other wgpu objects. Instan ce of wgpu.
|
||||
///
|
||||
/// This is the first thing you create when using wgpu.
|
||||
/// Its primary use is to create [`Adapter`]s and [`Surface`]s.
|
||||
@ -3734,7 +3734,7 @@ impl Queue {
|
||||
buffer: &'a Buffer,
|
||||
offset: BufferAddress,
|
||||
size: BufferSize,
|
||||
) -> QueueWriteBufferView<'a> {
|
||||
) -> Option<QueueWriteBufferView<'a>> {
|
||||
DynContext::queue_validate_write_buffer(
|
||||
&*self.context,
|
||||
&self.id,
|
||||
@ -3743,19 +3743,19 @@ impl Queue {
|
||||
buffer.data.as_ref(),
|
||||
offset,
|
||||
size,
|
||||
);
|
||||
)?;
|
||||
let staging_buffer = DynContext::queue_create_staging_buffer(
|
||||
&*self.context,
|
||||
&self.id,
|
||||
self.data.as_ref(),
|
||||
size,
|
||||
);
|
||||
QueueWriteBufferView {
|
||||
)?;
|
||||
Some(QueueWriteBufferView {
|
||||
queue: self,
|
||||
buffer,
|
||||
offset,
|
||||
inner: staging_buffer,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Schedule a write of some data into a texture.
|
||||
|
@ -1,21 +1,20 @@
|
||||
//! Tests for buffer copy validation.
|
||||
|
||||
use wasm_bindgen_test::wasm_bindgen_test;
|
||||
use wgt::BufferAddress;
|
||||
|
||||
use crate::common::{initialize_test, TestParameters};
|
||||
use crate::common::{fail_if, initialize_test, TestParameters};
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test]
|
||||
fn copy_alignment() {
|
||||
fn try_copy(offset: BufferAddress, size: BufferAddress, should_panic: bool) {
|
||||
let mut parameters = TestParameters::default();
|
||||
if should_panic {
|
||||
parameters = parameters.failure();
|
||||
}
|
||||
|
||||
initialize_test(parameters, |ctx| {
|
||||
fn try_copy(offset: BufferAddress, size: BufferAddress, should_fail: bool) {
|
||||
initialize_test(TestParameters::default(), |ctx| {
|
||||
let buffer = ctx.device.create_buffer(&BUFFER_DESCRIPTOR);
|
||||
let data = vec![255; size as usize];
|
||||
ctx.queue.write_buffer(&buffer, offset, &data);
|
||||
fail_if(&ctx.device, should_fail, || {
|
||||
ctx.queue.write_buffer(&buffer, offset, &data)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -307,9 +307,12 @@ fn clear_texture_tests(
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[wasm_bindgen_test]
|
||||
fn clear_texture_2d_uncompressed() {
|
||||
initialize_test(
|
||||
TestParameters::default().features(wgpu::Features::CLEAR_TEXTURE),
|
||||
TestParameters::default()
|
||||
.webgl2_failure()
|
||||
.features(wgpu::Features::CLEAR_TEXTURE),
|
||||
|ctx| {
|
||||
clear_texture_tests(&ctx, TEXTURE_FORMATS_UNCOMPRESSED, true, true);
|
||||
clear_texture_tests(&ctx, TEXTURE_FORMATS_DEPTH, false, false);
|
||||
|
@ -1,7 +1,6 @@
|
||||
use std::{
|
||||
ffi::{OsStr, OsString},
|
||||
fs::File,
|
||||
io::{BufWriter, Cursor},
|
||||
io,
|
||||
path::Path,
|
||||
str::FromStr,
|
||||
};
|
||||
@ -18,7 +17,7 @@ fn read_png(path: impl AsRef<Path>, width: u32, height: u32) -> Option<Vec<u8>>
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let decoder = png::Decoder::new(Cursor::new(data));
|
||||
let decoder = png::Decoder::new(io::Cursor::new(data));
|
||||
let mut reader = decoder.read_info().ok()?;
|
||||
|
||||
let mut buffer = vec![0; reader.output_buffer_size()];
|
||||
@ -43,6 +42,7 @@ fn read_png(path: impl AsRef<Path>, width: u32, height: u32) -> Option<Vec<u8>>
|
||||
Some(buffer)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn write_png(
|
||||
path: impl AsRef<Path>,
|
||||
width: u32,
|
||||
@ -50,15 +50,18 @@ fn write_png(
|
||||
data: &[u8],
|
||||
compression: png::Compression,
|
||||
) {
|
||||
let file = BufWriter::new(File::create(path).unwrap());
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
let file = io::BufWriter::new(std::fs::File::create(path).unwrap());
|
||||
|
||||
let mut encoder = png::Encoder::new(file, width, height);
|
||||
encoder.set_color(png::ColorType::Rgba);
|
||||
encoder.set_depth(png::BitDepth::Eight);
|
||||
encoder.set_compression(compression);
|
||||
let mut writer = encoder.write_header().unwrap();
|
||||
let mut encoder = png::Encoder::new(file, width, height);
|
||||
encoder.set_color(png::ColorType::Rgba);
|
||||
encoder.set_depth(png::BitDepth::Eight);
|
||||
encoder.set_compression(compression);
|
||||
let mut writer = encoder.write_header().unwrap();
|
||||
|
||||
writer.write_image_data(data).unwrap();
|
||||
writer.write_image_data(data).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn calc_difference(lhs: u8, rhs: u8) -> u8 {
|
||||
|
@ -27,7 +27,10 @@ pub struct OneTestPerProcessGuard(());
|
||||
impl OneTestPerProcessGuard {
|
||||
pub fn new() -> Self {
|
||||
let other_tests_in_flight = TEST_ACTIVE_IN_PROCESS.swap(true, Ordering::SeqCst);
|
||||
if other_tests_in_flight {
|
||||
|
||||
// We never abort if we're on wasm. Wasm tests are inherently single threaded, and panics cannot
|
||||
// unwind the stack and trigger all the guards, so we don't actually need to check.
|
||||
if other_tests_in_flight && !cfg!(target_arch = "wasm32") {
|
||||
log::error!("{}", OTHER_TEST_IN_PROGRESS_ERROR);
|
||||
// Hard exit to call attention to the error
|
||||
std::process::abort();
|
||||
|
@ -145,6 +145,20 @@ impl TestParameters {
|
||||
self
|
||||
}
|
||||
|
||||
/// Mark the test as always failing on WebGL. Because limited ability of wasm to recover from errors, we need to wholesale
|
||||
/// skip the test if it's not supported.
|
||||
pub fn webgl2_failure(mut self) -> Self {
|
||||
let _ = &mut self;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
self.failures.push(FailureCase {
|
||||
backends: Some(wgpu::Backends::GL),
|
||||
vendor: None,
|
||||
adapter: None,
|
||||
skip: true,
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
/// Determines if a test should fail under a particular set of conditions. If any of these are None, that means that it will match anything in that field.
|
||||
///
|
||||
/// ex.
|
||||
@ -178,7 +192,7 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te
|
||||
|
||||
let _test_guard = isolation::OneTestPerProcessGuard::new();
|
||||
|
||||
let (adapter, _) = initialize_adapter();
|
||||
let (adapter, _surface_guard) = initialize_adapter();
|
||||
|
||||
let adapter_info = adapter.get_info();
|
||||
let adapter_lowercase_name = adapter_info.name.to_lowercase();
|
||||
@ -283,7 +297,7 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te
|
||||
if #[cfg(any(not(target_arch = "wasm32"), target_os = "emscripten"))] {
|
||||
let canary_set = hal::VALIDATION_CANARY.get_and_reset();
|
||||
} else {
|
||||
let canary_set = false;
|
||||
let canary_set = _surface_guard.check_for_unreported_errors();
|
||||
}
|
||||
);
|
||||
|
||||
@ -319,10 +333,12 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te
|
||||
fn initialize_adapter() -> (Adapter, SurfaceGuard) {
|
||||
let backend_bits = wgpu::util::backend_bits_from_env().unwrap_or_else(Backends::all);
|
||||
let instance = Instance::new(backend_bits);
|
||||
let surface_guard;
|
||||
let compatible_surface;
|
||||
|
||||
#[cfg(not(all(target_arch = "wasm32", feature = "webgl")))]
|
||||
{
|
||||
surface_guard = SurfaceGuard {};
|
||||
compatible_surface = None;
|
||||
}
|
||||
#[cfg(all(target_arch = "wasm32", feature = "webgl"))]
|
||||
@ -334,6 +350,8 @@ fn initialize_adapter() -> (Adapter, SurfaceGuard) {
|
||||
.create_surface_from_canvas(&canvas)
|
||||
.expect("could not create surface from canvas");
|
||||
|
||||
surface_guard = SurfaceGuard { canvas };
|
||||
|
||||
compatible_surface = Some(surface);
|
||||
}
|
||||
|
||||
@ -345,10 +363,34 @@ fn initialize_adapter() -> (Adapter, SurfaceGuard) {
|
||||
))
|
||||
.expect("could not find suitable adapter on the system");
|
||||
|
||||
(adapter, SurfaceGuard)
|
||||
(adapter, surface_guard)
|
||||
}
|
||||
|
||||
struct SurfaceGuard;
|
||||
struct SurfaceGuard {
|
||||
#[cfg(all(target_arch = "wasm32", feature = "webgl"))]
|
||||
canvas: web_sys::HtmlCanvasElement,
|
||||
}
|
||||
|
||||
impl SurfaceGuard {
|
||||
fn check_for_unreported_errors(&self) -> bool {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(all(target_arch = "wasm32", feature = "webgl"))] {
|
||||
use wasm_bindgen::JsCast;
|
||||
|
||||
self.canvas
|
||||
.get_context("webgl2")
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.dyn_into::<web_sys::WebGl2RenderingContext>()
|
||||
.unwrap()
|
||||
.get_error()
|
||||
!= web_sys::WebGl2RenderingContext::NO_ERROR
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "wasm32", feature = "webgl"))]
|
||||
impl Drop for SurfaceGuard {
|
||||
|
@ -7,7 +7,7 @@ use wasm_bindgen_test::*;
|
||||
#[test]
|
||||
#[wasm_bindgen_test]
|
||||
fn discarding_color_target_resets_texture_init_state_check_visible_on_copy_after_submit() {
|
||||
initialize_test(TestParameters::default(), |ctx| {
|
||||
initialize_test(TestParameters::default().webgl2_failure(), |ctx| {
|
||||
let (texture, readback_buffer) =
|
||||
create_white_texture_and_readback_buffer(&ctx, wgpu::TextureFormat::Rgba8UnormSrgb);
|
||||
{
|
||||
@ -43,7 +43,7 @@ fn discarding_color_target_resets_texture_init_state_check_visible_on_copy_after
|
||||
#[test]
|
||||
#[wasm_bindgen_test]
|
||||
fn discarding_color_target_resets_texture_init_state_check_visible_on_copy_in_same_encoder() {
|
||||
initialize_test(TestParameters::default(), |ctx| {
|
||||
initialize_test(TestParameters::default().webgl2_failure(), |ctx| {
|
||||
let (texture, readback_buffer) =
|
||||
create_white_texture_and_readback_buffer(&ctx, wgpu::TextureFormat::Rgba8UnormSrgb);
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user