Build bodies on the CPU on AMD FirePro under Metal (GPU hang on Mac Pro 2013) (#1171)

The AMD FirePro D300/D500/D700 Metal driver hangs on the tessellation compute shader and macOS resets the GPU, freezing the desktop. Bodies are built on the CPU on that device, and SOLIDCRAFT_CPU_TESS=1 forces the CPU path on any GPU. The check is a tested predicate, and the troubleshooting guide documents the variable.
This commit is contained in:
devrosx authored and GitHub committed 2026-10-14 18:25:31 -04:00
1 parent 01b1b70586
commit 78079587ad
2 files changed
+30 -1

No files matched your search

+23 -1
View File
@@ -834,6 +834,10 @@ fn tessellation(adapter: &wgpu::Adapter, device: &wgpu::Device, queue: &wgpu::Qu
return None;
}
let info = adapter.get_info();
if hangs_on_gpu_tessellation(info.backend, &info.name) || std::env::var_os("SOLIDCRAFT_CPU_TESS").is_some() {
log::warn!("bodies are built on the CPU on {} ({:?})", info.name, info.backend);
return None;
}
match solidcraft_gpu::TessGpu::with_shader(info.name.clone(), device.clone(), queue.clone(), shader) {
Ok(t) => Some(t),
Err(e) => {
@@ -843,6 +847,13 @@ fn tessellation(adapter: &wgpu::Adapter, device: &wgpu::Device, queue: &wgpu::Qu
}
}
/// A device whose driver hangs on the evaluation shader, so bodies are built on the CPU there:
/// the AMD FirePro D300/D500/D700 (Mac Pro 2013, Tahiti) under Metal, where macOS resets the GPU
/// and the whole desktop freezes. `SOLIDCRAFT_CPU_TESS=1` forces CPU evaluation on any device.
fn hangs_on_gpu_tessellation(backend: wgpu::Backend, name: &str) -> bool {
backend == wgpu::Backend::Metal && name.contains("FirePro")
}
/// Create the pipelines. Call once with the app's render state and its depth/stencil/MSAA
/// settings. Without a stencil the section cap does not hide the inside of cut bodies. Without
/// `gpu_meshing` (safe mode) bodies are meshed on the CPU.
@@ -1182,7 +1193,18 @@ pub fn analysis_colors(c: &crate::theme::AnalysisColors) -> [f32; 36] {
#[cfg(test)]
mod tests {
use egui_wgpu::wgpu::naga;
use egui_wgpu::wgpu::{self, naga};
/// Only the FirePro under Metal skips GPU evaluation; the same card under another backend
/// and other Metal GPUs keep it.
#[test]
fn firepro_under_metal_builds_bodies_on_the_cpu() {
assert!(super::hangs_on_gpu_tessellation(wgpu::Backend::Metal, "AMD FirePro D500"));
assert!(super::hangs_on_gpu_tessellation(wgpu::Backend::Metal, "AMD FirePro D700"));
assert!(!super::hangs_on_gpu_tessellation(wgpu::Backend::Metal, "Apple M2"));
assert!(!super::hangs_on_gpu_tessellation(wgpu::Backend::Metal, "AMD Radeon Pro 560X"));
assert!(!super::hangs_on_gpu_tessellation(wgpu::Backend::Vulkan, "AMD FirePro W5100"));
}
/// The viewport shader parses and validates (a bad shader would only fail at run time).
#[test]
+7
View File
@@ -62,6 +62,13 @@ saying what failed (earlier versions closed without a word). Things to try:
- Run `solidcraft --crash-log` to list recent crash reports, and attach the newest one to an
issue.
## The desktop stutters or freezes while SolidCraft builds bodies
Some graphics drivers hang on the shader SolidCraft uses to build bodies on the GPU, and the
system then resets the GPU. SolidCraft already builds bodies on the CPU on the AMD FirePro
D300/D500/D700 (Mac Pro 2013). On another GPU that does this, start SolidCraft with
`SOLIDCRAFT_CPU_TESS=1` set to build bodies on the CPU, and open an issue with the GPU's name.
## SolidCraft closes right away on Windows
A graphics driver can crash the app while it starts, before SolidCraft can show anything (an