Skip to content

Commit 859dd88

Browse files
authored
Only Initialize a Single Backend in Tests (#6315)
* Only Initialize a Single Backend in Tests * Update tests/tests/create_surface_error.rs
1 parent 23fa0ae commit 859dd88

File tree

7 files changed

+57
-29
lines changed

7 files changed

+57
-29
lines changed

tests/src/init.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use wgpu::{Adapter, Device, Instance, Queue};
22
use wgt::{Backends, Features, Limits};
33

4+
use crate::report::AdapterReport;
5+
46
/// Initialize the logger for the test runner.
57
pub fn init_logger() {
68
// We don't actually care if it fails
@@ -11,7 +13,7 @@ pub fn init_logger() {
1113
}
1214

1315
/// Initialize a wgpu instance with the options from the environment.
14-
pub fn initialize_instance(force_fxc: bool) -> Instance {
16+
pub fn initialize_instance(backends: wgpu::Backends, force_fxc: bool) -> Instance {
1517
// We ignore `WGPU_BACKEND` for now, merely using test filtering to only run a single backend's tests.
1618
//
1719
// We can potentially work support back into the test runner in the future, but as the adapters are matched up
@@ -23,9 +25,9 @@ pub fn initialize_instance(force_fxc: bool) -> Instance {
2325
// To "disable" webgpu regardless, we do this by removing the webgpu backend whenever we see
2426
// the webgl feature.
2527
let backends = if cfg!(feature = "webgl") {
26-
Backends::all() - Backends::BROWSER_WEBGPU
28+
backends - wgpu::Backends::BROWSER_WEBGPU
2729
} else {
28-
Backends::all()
30+
backends
2931
};
3032
// Some tests need to be able to force demote to FXC, to specifically test workarounds for FXC
3133
// behavior.
@@ -43,12 +45,16 @@ pub fn initialize_instance(force_fxc: bool) -> Instance {
4345
})
4446
}
4547

46-
/// Initialize a wgpu adapter, taking the `n`th adapter from the instance.
48+
/// Initialize a wgpu adapter, using the given adapter report to match the adapter.
4749
pub async fn initialize_adapter(
48-
adapter_index: usize,
50+
adapter_report: Option<&AdapterReport>,
4951
force_fxc: bool,
5052
) -> (Instance, Adapter, Option<SurfaceGuard>) {
51-
let instance = initialize_instance(force_fxc);
53+
let backends = adapter_report
54+
.map(|report| Backends::from(report.info.backend))
55+
.unwrap_or_default();
56+
57+
let instance = initialize_instance(backends, force_fxc);
5258
#[allow(unused_variables)]
5359
let surface: Option<wgpu::Surface>;
5460
let surface_guard: Option<SurfaceGuard>;
@@ -82,13 +88,24 @@ pub async fn initialize_adapter(
8288

8389
cfg_if::cfg_if! {
8490
if #[cfg(not(target_arch = "wasm32"))] {
85-
let adapter_iter = instance.enumerate_adapters(wgpu::Backends::all());
86-
let adapter_count = adapter_iter.len();
91+
let adapter_iter = instance.enumerate_adapters(backends);
8792
let adapter = adapter_iter.into_iter()
88-
.nth(adapter_index)
89-
.unwrap_or_else(|| panic!("Tried to get index {adapter_index} adapter, but adapter list was only {adapter_count} long. Is .gpuconfig out of date?"));
93+
// If we have a report, we only want to match the adapter with the same info.
94+
//
95+
// If we don't have a report, we just take the first adapter.
96+
.find(|adapter| if let Some(adapter_report) = adapter_report {
97+
adapter.get_info() == adapter_report.info
98+
} else {
99+
true
100+
});
101+
let Some(adapter) = adapter else {
102+
panic!(
103+
"Could not find adapter with info {:#?} in {:#?}",
104+
adapter_report.map(|r| &r.info),
105+
instance.enumerate_adapters(backends).into_iter().map(|a| a.get_info()).collect::<Vec<_>>(),
106+
);
107+
};
90108
} else {
91-
assert_eq!(adapter_index, 0);
92109
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions {
93110
compatible_surface: surface.as_ref(),
94111
..Default::default()

tests/src/native.rs

+21-10
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@ struct NativeTest {
1919
}
2020

2121
impl NativeTest {
22+
/// Adapter index is only used for naming the test, the adapters are matched based on the adapter info.
2223
fn from_configuration(
2324
config: GpuTestConfiguration,
24-
adapter: &AdapterReport,
25+
adapter_report: AdapterReport,
2526
adapter_index: usize,
2627
) -> Self {
27-
let backend = adapter.info.backend;
28-
let device_name = &adapter.info.name;
28+
let backend = adapter_report.info.backend;
29+
let device_name = &adapter_report.info.name;
2930

30-
let test_info = TestInfo::from_configuration(&config, adapter);
31+
let test_info = TestInfo::from_configuration(&config, &adapter_report);
3132

3233
let full_name = format!(
3334
"[{running_msg}] [{backend:?}/{device_name}/{adapter_index}] {base_name}",
@@ -50,10 +51,12 @@ impl NativeTest {
5051

5152
let env_value = if metal_validation { "1" } else { "0" };
5253
std::env::set_var("MTL_DEBUG_LAYER", env_value);
53-
// Metal Shader Validation is entirely broken in the paravirtualized CI environment.
54-
// std::env::set_var("MTL_SHADER_VALIDATION", env_value);
54+
if std::env::var("GITHUB_ACTIONS").as_deref() != Ok("true") {
55+
// Metal Shader Validation is entirely broken in the paravirtualized CI environment.
56+
std::env::set_var("MTL_SHADER_VALIDATION", env_value);
57+
}
5558

56-
execute_test(config, Some(test_info), adapter_index).await;
59+
execute_test(Some(&adapter_report), config, Some(test_info)).await;
5760
}),
5861
}
5962
}
@@ -83,16 +86,24 @@ pub fn main() -> MainResult {
8386
&std::fs::read_to_string(format!("{}/../.gpuconfig", env!("CARGO_MANIFEST_DIR")))
8487
.context("Failed to read .gpuconfig, did you run the tests via `cargo xtask test`?")?
8588
};
86-
let report = GpuReport::from_json(config_text).context("Could not parse .gpuconfig JSON")?;
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::util::backend_bits_from_env().unwrap_or(wgpu::Backends::all());
94+
report
95+
.devices
96+
.retain(|report| wgpu_backends.contains(wgpu::Backends::from(report.info.backend)));
8797

8898
let mut test_guard = TEST_LIST.lock();
99+
// Iterate through all the tests. Creating a test per adapter.
89100
execute_native(test_guard.drain(..).flat_map(|test| {
90101
report
91102
.devices
92103
.iter()
93104
.enumerate()
94-
.map(move |(adapter_index, adapter)| {
95-
NativeTest::from_configuration(test.clone(), adapter, adapter_index)
105+
.map(move |(adapter_index, adapter_report)| {
106+
NativeTest::from_configuration(test.clone(), adapter_report.clone(), adapter_index)
96107
})
97108
}));
98109

tests/src/report.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ impl GpuReport {
2525
/// A single report of the capabilities of an Adapter.
2626
///
2727
/// Must be synchronized with the definition on wgpu-info/src/report.rs.
28-
#[derive(Deserialize)]
29-
pub(crate) struct AdapterReport {
28+
#[derive(Deserialize, Clone)]
29+
pub struct AdapterReport {
3030
pub info: AdapterInfo,
3131
pub features: Features,
3232
pub limits: Limits,

tests/src/run.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ pub struct TestingContext {
2424
pub queue: Queue,
2525
}
2626

27-
/// Execute the given test configuration with the given adapter index.
27+
/// Execute the given test configuration with the given adapter report.
2828
///
2929
/// If test_info is specified, will use the information whether to skip the test.
3030
/// If it is not, we'll create the test info from the adapter itself.
3131
pub async fn execute_test(
32+
adapter_report: Option<&AdapterReport>,
3233
config: GpuTestConfiguration,
3334
test_info: Option<TestInfo>,
34-
adapter_index: usize,
3535
) {
3636
// If we get information externally, skip based on that information before we do anything.
3737
if let Some(TestInfo { skip: true, .. }) = test_info {
@@ -43,7 +43,7 @@ pub async fn execute_test(
4343
let _test_guard = isolation::OneTestPerProcessGuard::new();
4444

4545
let (instance, adapter, _surface_guard) =
46-
initialize_adapter(adapter_index, config.params.force_fxc).await;
46+
initialize_adapter(adapter_report, config.params.force_fxc).await;
4747

4848
let adapter_info = adapter.get_info();
4949
let adapter_downlevel_capabilities = adapter.get_downlevel_capabilities();

tests/tests/create_surface_error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#[wasm_bindgen_test::wasm_bindgen_test]
77
fn canvas_get_context_returned_null() {
88
// Not using the normal testing infrastructure because that goes straight to creating the canvas for us.
9-
let instance = wgpu_test::initialize_instance(false);
9+
let instance = wgpu_test::initialize_instance(wgpu::Backends::all(), false);
1010
// Create canvas
1111
let canvas = wgpu_test::initialize_html_canvas();
1212

tests/tests/device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static REQUEST_DEVICE_ERROR_MESSAGE_NATIVE: GpuTestConfiguration =
8787
async fn request_device_error_message() {
8888
// Not using initialize_test() because that doesn't let us catch the error
8989
// nor .await anything
90-
let (_instance, adapter, _surface_guard) = wgpu_test::initialize_adapter(0, false).await;
90+
let (_instance, adapter, _surface_guard) = wgpu_test::initialize_adapter(None, false).await;
9191

9292
let device_error = adapter
9393
.request_device(

wgpu-macros/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub fn gpu_test(_attr: TokenStream, item: TokenStream) -> TokenStream {
3737
// Allow any type that can be converted to a GpuTestConfiguration
3838
let test_config = ::wgpu_test::GpuTestConfiguration::from(#expr).name_from_init_function_typename::<S>(#ident_lower);
3939

40-
::wgpu_test::execute_test(test_config, None, 0).await;
40+
::wgpu_test::execute_test(None, test_config, None).await;
4141
}
4242
}
4343
.into()

0 commit comments

Comments
 (0)