Skip to content

Commit 0d474c3

Browse files
zhaojisengsisyphus-dev-aizerx-lab
authored
fix(gpu): 避免 Windows 独显错误使用 DX12 (#230)
* fix(gpu): 避免 Windows 独显错误使用 DX12 Windows hybrid-GPU machines can select the NVIDIA discrete adapter through DX12 and then crash while creating the Rect render pipeline with a wgpu shader translation error. Request high-performance GPUs at the PE export level, default Windows rendering to Vulkan, and keep high-performance NVIDIA Vulkan adapters ahead of integrated GPUs. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix(gpu): 灰度 Windows 高性能 GPU 默认值 将 Windows 默认高性能 GPU + Vulkan 后端放到 WindowsHighPerformanceGpuDefault flag 后,默认用户继续走集显/未指定后端路径。 同时限制 PE 导出链接参数只用于 MSVC,并抑制驱动查表符号必须保留原名导致的命名警告。 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix(gpu): gate high-perf GPU exports behind feature flag --------- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> Co-authored-by: zero <1603852@qq.com>
1 parent 83793b4 commit 0d474c3

8 files changed

Lines changed: 69 additions & 20 deletions

File tree

app/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ ai_resume_button = []
409409
autoupdate = []
410410
figma_detection = []
411411
bundled_skills = []
412+
windows_high_performance_gpu_default = []
412413
agent_mode = []
413414
agent_mode_computer_use = []
414415
agent_mode_debug = []

app/build.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ fn main() -> Result<()> {
2828

2929
let target_os = env::var("CARGO_CFG_TARGET_OS")?;
3030
let target_family = env::var("CARGO_CFG_TARGET_FAMILY")?;
31+
let target_env = env::var("CARGO_CFG_TARGET_ENV")?;
3132

3233
add_features(&target_family, &target_os);
3334

@@ -115,6 +116,15 @@ fn main() -> Result<()> {
115116
}
116117

117118
if target_os == "windows" {
119+
if target_env == "msvc"
120+
&& env::var("CARGO_FEATURE_WINDOWS_HIGH_PERFORMANCE_GPU_DEFAULT").is_ok()
121+
{
122+
println!("cargo:rustc-link-arg-bin=zap-oss=/EXPORT:NvOptimusEnablement,DATA");
123+
println!(
124+
"cargo:rustc-link-arg-bin=zap-oss=/EXPORT:AmdPowerXpressRequestHighPerformance,DATA"
125+
);
126+
}
127+
118128
// Retrieve the Cargo profile name so that we can put a copy of ConPTY in
119129
// the correct target subdirectory.
120130
//

app/src/bin/generate_settings_schema.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ fn active_flags_for_channel(channel: &str) -> HashSet<FeatureFlag> {
104104
}
105105
}
106106

107+
#[cfg(feature = "windows_high_performance_gpu_default")]
108+
flags.insert(FeatureFlag::WindowsHighPerformanceGpuDefault);
109+
107110
flags
108111
}
109112

@@ -168,6 +171,11 @@ fn main() {
168171
}
169172

170173
let active_flags = active_flags_for_channel(channel);
174+
for flag in &active_flags {
175+
flag.set_enabled(true);
176+
}
177+
warp_core::features::mark_initialized();
178+
171179
let mut generator = SchemaGenerator::default();
172180
let mut root_properties = Map::new();
173181
let mut entry_count = 0;

app/src/bin/zap_oss.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@ use warp_core::{
99
AppId,
1010
};
1111

12+
#[cfg(all(target_os = "windows", feature = "windows_high_performance_gpu_default"))]
13+
#[allow(non_upper_case_globals)]
14+
#[no_mangle]
15+
#[used]
16+
pub static NvOptimusEnablement: u32 = 1;
17+
18+
#[cfg(all(target_os = "windows", feature = "windows_high_performance_gpu_default"))]
19+
#[allow(non_upper_case_globals)]
20+
#[no_mangle]
21+
#[used]
22+
pub static AmdPowerXpressRequestHighPerformance: u32 = 1;
23+
1224
// Zap OSS 构建的入口,简单包一层 warp::run()。
1325
fn main() -> Result<()> {
1426
let mut state = ChannelState::new(

app/src/lib.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,6 +2297,8 @@ pub fn enabled_features() -> HashSet<FeatureFlag> {
22972297
FeatureFlag::InBandGeneratorsForSSH,
22982298
#[cfg(feature = "run_generators_with_cmd_exe")]
22992299
FeatureFlag::RunGeneratorsWithCmdExe,
2300+
#[cfg(feature = "windows_high_performance_gpu_default")]
2301+
FeatureFlag::WindowsHighPerformanceGpuDefault,
23002302
#[cfg(feature = "ligatures")]
23012303
FeatureFlag::Ligatures,
23022304
#[cfg(feature = "selectable_prompt")]
@@ -2683,5 +2685,10 @@ pub fn enabled_features() -> HashSet<FeatureFlag> {
26832685
/// `ZAP_UNSTABLE_FEATURES` 接受的不稳定功能名 -> FeatureFlag 映射。
26842686
/// 这里登记的功能在 release 构建下默认隐藏,设置对应 token 后才会出现;
26852687
/// dev 构建走 debug_assertions 分支默认启用,无需该变量。
2686-
const UNSTABLE_FEATURES: &[(&str, FeatureFlag)] =
2687-
&[("server_file_browser", FeatureFlag::ServerFileBrowser)];
2688+
const UNSTABLE_FEATURES: &[(&str, FeatureFlag)] = &[
2689+
("server_file_browser", FeatureFlag::ServerFileBrowser),
2690+
(
2691+
"windows_high_performance_gpu_default",
2692+
FeatureFlag::WindowsHighPerformanceGpuDefault,
2693+
),
2694+
];

app/src/settings/gpu.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
use settings::{macros::define_settings_group, SupportedPlatforms, SyncToCloud};
2+
use warp_core::features::FeatureFlag;
23
use warpui::platform::GraphicsBackend;
34

5+
fn default_to_windows_high_performance_gpu() -> bool {
6+
cfg!(windows) && FeatureFlag::WindowsHighPerformanceGpuDefault.is_enabled()
7+
}
8+
49
define_settings_group!(GPUSettings, settings: [
5-
prefer_low_power_gpu: PreferLowPowerGPU {
6-
type: bool,
7-
// Opt for the low power (integrated) GPU on Windows / Linux since discrete GPUs tend to be
8-
// more unstable.
9-
default: cfg!(any(target_os = "linux", target_os = "freebsd", windows)),
10-
supported_platforms: SupportedPlatforms::ALL,
11-
sync_to_cloud: SyncToCloud::Never,
12-
private: false,
13-
toml_path: "system.prefer_low_power_gpu",
14-
description: "Whether to prefer the integrated (low-power) GPU.",
15-
},
16-
preferred_backend: PreferredGraphicsBackend {
17-
type: Option<GraphicsBackend>,
18-
default: None,
19-
supported_platforms: SupportedPlatforms::WINDOWS,
20-
sync_to_cloud: SyncToCloud::Never,
21-
private: false,
10+
prefer_low_power_gpu: PreferLowPowerGPU {
11+
type: bool,
12+
default: cfg!(any(target_os = "linux", target_os = "freebsd"))
13+
|| (cfg!(windows) && !default_to_windows_high_performance_gpu()),
14+
supported_platforms: SupportedPlatforms::ALL,
15+
sync_to_cloud: SyncToCloud::Never,
16+
private: false,
17+
toml_path: "system.prefer_low_power_gpu",
18+
description: "Whether to prefer the integrated (low-power) GPU.",
19+
},
20+
preferred_backend: PreferredGraphicsBackend {
21+
type: Option<GraphicsBackend>,
22+
default: default_to_windows_high_performance_gpu().then_some(GraphicsBackend::Vulkan),
23+
supported_platforms: SupportedPlatforms::WINDOWS,
24+
sync_to_cloud: SyncToCloud::Never,
25+
private: false,
2226
toml_path: "system.preferred_graphics_backend",
2327
description: "The preferred graphics backend on Windows.",
2428
},

crates/warp_features/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ pub enum FeatureFlag {
5959
/// discrete GPU.
6060
IntegratedGPU,
6161

62+
/// Defaults Windows builds to the high-performance GPU with Vulkan as the preferred backend.
63+
WindowsHighPerformanceGpuDefault,
64+
6265
/// Zap Agent Mode.
6366
AgentMode,
6467

crates/warpui/src/rendering/wgpu/resources.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ pub(super) fn sort_adapters(
342342
.sorted_by_cached_key(|adapter| {
343343
adapter_stability_sort_func(
344344
adapter,
345+
gpu_power_preference,
345346
windowing_system,
346347
downrank_non_nvidia_vulkan_adapters,
347348
)
@@ -697,6 +698,7 @@ fn adapter_backend_sort_func(
697698
/// us to attempt to use it than for us to give up without trying.
698699
fn adapter_stability_sort_func(
699700
adapter: &wgpu::Adapter,
701+
gpu_power_preference: &GPUPowerPreference,
700702
windowing_system: Option<windowing::System>,
701703
downrank_non_nvidia_vulkan_adapters: bool,
702704
) -> AdapterSupport {
@@ -741,7 +743,9 @@ fn adapter_stability_sort_func(
741743
*MIN_SUPPORTED_NVIDIA_VERSION
742744
);
743745
AdapterSupport::Unsupported
744-
} else if is_newer_nondx12_nvidia_adapter_on_windows(&adapter_info) {
746+
} else if is_newer_nondx12_nvidia_adapter_on_windows(&adapter_info)
747+
&& !matches!(gpu_power_preference, GPUPowerPreference::HighPerformance)
748+
{
745749
log::warn!(
746750
"Deprioritizing non DX12 Nvidia adapter due to version > {} (unsupported). Newer NVIDIA \
747751
drivers can crash if multiple windows are created if the `Vulkan / OpenGL Present Method\

0 commit comments

Comments
 (0)