mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-25 10:46:50 -06:00
Merge pull request #1164 from Hamza0101/fix/gpu-failed-fallback
Hamza's diagnosis of the forgotten OpenGL failure, with the filter reordered so it covers any backend and does not hold another machine's record against this one, plus a regression test.
No workflow runs on this PR: every one is path-filtered and apps/designcraft/src/gpu/backend.rs matches none. Verified locally on 653f83b8 instead — cargo test --workspace --no-fail-fast: 2847 passed, 0 failed, 5 pre-existing ignores; cargo fmt --check clean.
This commit is contained in:
@@ -138,13 +138,18 @@ pub fn choose(candidates: &[Backend], previous: &Record, version: &str, skipped:
|
||||
let first = *candidates.first()?;
|
||||
let same_version = previous.version == version;
|
||||
let mut failed: Vec<Backend> = if same_version { previous.failed.clone() } else { Vec::new() };
|
||||
// A stored entry that is no candidate here came from another machine and says nothing. The
|
||||
// backend the previous start was still on is added after this and stays, candidate or not:
|
||||
// the instance can load a backend that is no candidate — everywhere but Windows OpenGL rides
|
||||
// along beside the chosen one (`instance_backends`) — and a start that one took down must
|
||||
// keep it out of the next instance.
|
||||
failed.retain(|b| candidates.contains(b));
|
||||
let unfinished = previous.trying.filter(|_| same_version);
|
||||
if let Some(b) = unfinished
|
||||
&& !failed.contains(&b)
|
||||
{
|
||||
failed.push(b);
|
||||
}
|
||||
failed.retain(|b| candidates.contains(b));
|
||||
let pick = |failed: &[Backend]| candidates.iter().copied().find(|b| !failed.contains(b) && !skipped.contains(b));
|
||||
let backend = match pick(&failed) {
|
||||
Some(b) => b,
|
||||
@@ -387,6 +392,23 @@ mod tests {
|
||||
assert_eq!(c.record.failed, &[Backend::Vulkan]);
|
||||
}
|
||||
|
||||
/// The backend the previous start was still on stays in `failed` even where it is no
|
||||
/// candidate: on macOS Metal is the only candidate, but the instance loads OpenGL beside it,
|
||||
/// so a start OpenGL took down has to keep it out of the next one. Only the stored list is
|
||||
/// filtered to this platform's candidates — those entries came from another machine.
|
||||
#[test]
|
||||
fn the_backend_a_start_was_on_counts_as_failed_even_where_it_is_no_candidate() {
|
||||
const MAC: &[Backend] = &[Backend::Metal];
|
||||
let c = choose(MAC, &record(Some(Backend::Gl), &[]), V, &[]).unwrap();
|
||||
assert_eq!(c.backend, Backend::Metal);
|
||||
assert_eq!(c.record.failed, &[Backend::Gl], "OpenGL ran here, so it failed here");
|
||||
assert_eq!(c.switched_from, Some(Backend::Gl));
|
||||
assert!(!instance_backends(c.backend, &c.record.failed).contains(wgpu::Backends::GL));
|
||||
// Stored on another machine, never run here: dropped, and OpenGL may ride along again.
|
||||
let c = choose(MAC, &record(None, &[Backend::Gl]), V, &[]).unwrap();
|
||||
assert_eq!(c.record.failed, &[]);
|
||||
}
|
||||
|
||||
/// A restart that found no adapter of DirectX 12 names the backend in its skip list: that start
|
||||
/// takes the next candidate, with or without a record, and the record doesn't keep it as failed
|
||||
/// (a later launch tries it again).
|
||||
|
||||
Reference in New Issue
Block a user