Skip to content

Commit 83822ad

Browse files
committed
Add support for running tests on the noop backend
1 parent fd7dcac commit 83822ad

File tree

7 files changed

+81
-27
lines changed

7 files changed

+81
-27
lines changed

tests/src/expectations.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use core::fmt;
3636
/// [skip]: super::TestParameters::skip
3737
/// [expect_fail]: super::TestParameters::expect_fail
3838
/// [`AdapterInfo`]: wgpu::AdapterInfo
39-
#[derive(Default, Clone)]
39+
#[derive(Default, Clone, PartialEq)]
4040
pub struct FailureCase {
4141
/// Backends expected to fail, or `None` for any backend.
4242
///
@@ -334,7 +334,7 @@ impl FailureReason {
334334
}
335335
}
336336

337-
#[derive(Default, Clone)]
337+
#[derive(Default, Clone, PartialEq)]
338338
pub enum FailureBehavior {
339339
/// Assert that the test fails for the given reason.
340340
///

tests/src/init.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@ pub fn initialize_instance(backends: wgpu::Backends, params: &TestParameters) ->
6565
..Default::default()
6666
}
6767
.with_env(),
68-
// TODO(https://github.com/gfx-rs/wgpu/issues/7119): Enable noop backend?
69-
noop: wgpu::NoopBackendOptions::default(),
68+
// Allow the noop backend to be used in tests. This will not be used unless
69+
// WGPU_GPU_TESTS_USE_NOOP_BACKEND env var is set, because wgpu-info will not
70+
// enumerate the noop backend.
71+
noop: wgpu::NoopBackendOptions { enable: true },
7072
},
7173
})
7274
}

tests/src/native.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,32 @@ pub fn main() -> MainResult {
8181

8282
use crate::report::GpuReport;
8383

84-
let config_text = {
85-
profiling::scope!("Reading .gpuconfig");
86-
&std::fs::read_to_string(format!("{}/../.gpuconfig", env!("CARGO_MANIFEST_DIR")))
87-
.context("Failed to read .gpuconfig, did you run the tests via `cargo xtask test`?")?
84+
// If this environment variable is set, we will only enumerate the noop backend. The
85+
// main use case is running tests with miri, where we can't even enumerate adapters,
86+
// as we cannot load DLLs or make any external calls.
87+
let use_noop = std::env::var("WGPU_GPU_TESTS_USE_NOOP_BACKEND").as_deref() == Ok("1");
88+
89+
let report = if use_noop {
90+
GpuReport::noop_only()
91+
} else {
92+
let config_text = {
93+
profiling::scope!("Reading .gpuconfig");
94+
&std::fs::read_to_string(format!("{}/../.gpuconfig", env!("CARGO_MANIFEST_DIR")))
95+
.context(
96+
"Failed to read .gpuconfig, did you run the tests via `cargo xtask test`?",
97+
)?
98+
};
99+
let mut report =
100+
GpuReport::from_json(config_text).context("Could not parse .gpuconfig JSON")?;
101+
102+
// Filter out the adapters that are not part of WGPU_BACKEND.
103+
let wgpu_backends = wgpu::Backends::from_env().unwrap_or_default();
104+
report
105+
.devices
106+
.retain(|report| wgpu_backends.contains(wgpu::Backends::from(report.info.backend)));
107+
108+
report
88109
};
89-
let mut report =
90-
GpuReport::from_json(config_text).context("Could not parse .gpuconfig JSON")?;
91-
92-
// Filter out the adapters that are not part of WGPU_BACKEND.
93-
let wgpu_backends = wgpu::Backends::from_env().unwrap_or_default();
94-
report
95-
.devices
96-
.retain(|report| wgpu_backends.contains(wgpu::Backends::from(report.info.backend)));
97110

98111
let mut test_guard = TEST_LIST.lock();
99112
// Iterate through all the tests. Creating a test per adapter.

tests/src/params.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ impl Default for TestParameters {
4141
required_limits: Limits::downlevel_webgl2_defaults(),
4242
required_instance_flags: InstanceFlags::empty(),
4343
force_fxc: false,
44-
skips: Vec::new(),
44+
// By default we skip the noop backend, and enable it if the test
45+
// parameters ask us to remove it.
46+
skips: vec![FailureCase::backend(wgpu::Backends::NOOP)],
4547
failures: Vec::new(),
4648
}
4749
}
@@ -94,6 +96,16 @@ impl TestParameters {
9496
self.skips.push(when);
9597
self
9698
}
99+
100+
/// Enable testing against the noop backend and miri.
101+
///
102+
/// The noop backend does not execute any operations, but allows us to test
103+
/// validation and memory safety.
104+
pub fn enable_noop(mut self) -> Self {
105+
self.skips
106+
.retain(|case| *case != FailureCase::backend(wgpu::Backends::NOOP));
107+
self
108+
}
97109
}
98110

99111
/// Information about a test, including if if it should be skipped.

tests/src/report.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@ pub(crate) struct GpuReport {
1515
}
1616

1717
impl GpuReport {
18+
#[cfg(not(target_arch = "wasm32"))]
19+
/// Creates a new GpuReport with a single noop adapter.
20+
pub(crate) fn noop_only() -> Self {
21+
GpuReport {
22+
devices: vec![AdapterReport {
23+
info: wgpu::hal::noop::adapter_info(),
24+
features: Features::all(),
25+
limits: wgpu::hal::noop::CAPABILITIES.limits,
26+
downlevel_caps: wgpu::hal::noop::CAPABILITIES.downlevel,
27+
texture_format_features: HashMap::new(), // todo
28+
}],
29+
}
30+
}
31+
1832
#[cfg_attr(target_arch = "wasm32", allow(unused))]
1933
pub(crate) fn from_json(file: &str) -> serde_json::Result<Self> {
2034
profiling::scope!("Parsing .gpuconfig");

wgpu-hal/src/noop/mod.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,22 +118,34 @@ impl crate::Instance for Context {
118118
) -> Vec<crate::ExposedAdapter<Api>> {
119119
vec![crate::ExposedAdapter {
120120
adapter: Context,
121-
info: wgt::AdapterInfo {
122-
name: String::from("noop wgpu backend"),
123-
vendor: 0,
124-
device: 0,
125-
device_type: wgt::DeviceType::Cpu,
126-
driver: String::from("wgpu"),
127-
driver_info: String::new(),
128-
backend: wgt::Backend::Noop,
129-
},
121+
info: adapter_info(),
130122
features: wgt::Features::all(),
131123
capabilities: CAPABILITIES,
132124
}]
133125
}
134126
}
135127

136-
const CAPABILITIES: crate::Capabilities = {
128+
/// Returns the adapter info for the noop backend.
129+
///
130+
/// This is used in the test harness to construct info about
131+
/// the noop backend adapter without actually initializing wgpu.
132+
pub fn adapter_info() -> wgt::AdapterInfo {
133+
wgt::AdapterInfo {
134+
name: String::from("noop wgpu backend"),
135+
vendor: 0,
136+
device: 0,
137+
device_type: wgt::DeviceType::Cpu,
138+
driver: String::from("wgpu"),
139+
driver_info: String::new(),
140+
backend: wgt::Backend::Noop,
141+
}
142+
}
143+
144+
/// The capabilities of the noop backend.
145+
///
146+
/// This is used in the test harness to construct capabilities
147+
/// of the noop backend without actually initializing wgpu.
148+
pub const CAPABILITIES: crate::Capabilities = {
137149
/// Guaranteed to be no bigger than isize::MAX which is the maximum size of an allocation,
138150
/// except on 16-bit platforms which we certainly don’t fit in.
139151
const ALLOC_MAX_U32: u32 = i32::MAX as u32;

xtask/src/miri.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub fn run_miri(shell: Shell, mut args: Arguments) -> anyhow::Result<()> {
2020
"MIRIFLAGS",
2121
"-Zmiri-disable-isolation -Zmiri-deterministic-floats",
2222
)
23+
.env("WGPU_GPU_TESTS_USE_NOOP_BACKEND", "1")
2324
.quiet()
2425
.run()?;
2526

0 commit comments

Comments
 (0)