Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/infra/logging/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ mod tests {
vkd3d_enabled: false,
graphics_backend_policy: crate::models::GraphicsBackendPolicy::WineD3D,
d3d12_policy: crate::models::D3D12ProviderPolicy::Auto,
gpu_selection: crate::models::GpuSelection::Auto,
};

let warnings = check_environment_sanity(&env, "Wine", Some(&config));
Expand Down
46 changes: 27 additions & 19 deletions src/infra/runners/wine_tkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,30 +308,38 @@ impl Runner for WineTkgRunner {
.unwrap_or("wine")
};

// Resolve graphics backend policy
// Resolve graphics backend policy using authoritative pipeline resolutions
match glc.graphics_backend_policy {
crate::models::GraphicsBackendPolicy::Auto => {
let components = crate::utils::detect_runner_components(
&crate::utils::resolve_runner(proton, &library_root),
Some(&game_wineprefix),
);

if components.dxvk.is_some() {
let has_dxvk = ctx.dll_resolutions.iter().any(|r| {
matches!(r.name.as_str(), "d3d11" | "d3d9" | "dxgi") &&
matches!(r.chosen_provider, crate::launch::dll_provider_resolver::DllProvider::Runner | crate::launch::dll_provider_resolver::DllProvider::GameLocal)
});
if has_dxvk {
glc.dxvk_enabled = true;
}
// Respect d3d12_policy when auto-detecting VKD3D variant

match glc.d3d12_policy {
crate::models::D3D12ProviderPolicy::Vkd3dWine => {
if components.vkd3d.is_some() {
let has_vkd3d_wine = ctx.dll_resolutions.iter().any(|r| {
r.name == "d3d12" &&
matches!(r.chosen_provider, crate::launch::dll_provider_resolver::DllProvider::Runner) &&
r.chosen_path.as_ref().map(|p| !p.to_string_lossy().contains("vkd3d-proton")).unwrap_or(false)
});
if has_vkd3d_wine {
glc.vkd3d_enabled = true;
}
}
_ => {
// Auto or Vkd3dProton: prefer proton, fall back to wine VKD3D
if components.vkd3d_proton.is_some() {
glc.vkd3d_proton_enabled = true;
} else if components.vkd3d.is_some() {
glc.vkd3d_enabled = true;
let d3d12_res = ctx.dll_resolutions.iter().find(|r| r.name == "d3d12");
if let Some(res) = d3d12_res {
if matches!(res.chosen_provider, crate::launch::dll_provider_resolver::DllProvider::Runner | crate::launch::dll_provider_resolver::DllProvider::GameLocal) {
if res.chosen_path.as_ref().map(|p| p.to_string_lossy().contains("vkd3d-proton")).unwrap_or(false) {
glc.vkd3d_proton_enabled = true;
} else {
glc.vkd3d_enabled = true;
}
}
}
}
}
Expand All @@ -340,20 +348,17 @@ impl Runner for WineTkgRunner {
glc.dxvk_enabled = false;
glc.vkd3d_proton_enabled = false;
glc.vkd3d_enabled = false;
// force_builtin_d3d handles the rest below
}
crate::models::GraphicsBackendPolicy::DXVK => {
glc.dxvk_enabled = true;
}
crate::models::GraphicsBackendPolicy::VKD3D => {
// Consult d3d12_policy to select the right implementation
match glc.d3d12_policy {
crate::models::D3D12ProviderPolicy::Vkd3dWine => {
glc.vkd3d_enabled = true;
glc.vkd3d_proton_enabled = false;
}
_ => {
// Auto or Vkd3dProton
glc.vkd3d_proton_enabled = true;
}
}
Expand Down Expand Up @@ -453,8 +458,11 @@ impl Runner for WineTkgRunner {
env.insert("XDG_RUNTIME_DIR".to_string(), xdg_runtime);
}

// Auto-inject PRIME/Optimus GPU selection (user env vars can still override below)
for (k, v) in crate::utils::detect_prime_env() {
// Auto-inject GPU selection (user env vars can still override below)
let gpu_selection = ctx.user_config.as_ref()
.map(|c| c.graphics_layers.gpu_selection.clone())
.unwrap_or_default();
for (k, v) in crate::utils::get_gpu_selection_env(&gpu_selection) {
env.entry(k).or_insert(v);
}

Expand Down
7 changes: 7 additions & 0 deletions src/launch/dll_provider_resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,20 @@ impl DllProviderResolver {
let subdirs = [
"files/lib/wine/dxvk",
"files/lib/wine/vkd3d",
"files/lib/wine/vkd3d-proton",
"files/lib64/wine/dxvk",
"files/lib64/wine/vkd3d",
"files/lib64/wine/vkd3d-proton",
"files/lib/vkd3d",
"dist/lib/wine/dxvk",
"dist/lib/wine/vkd3d",
"dist/lib/wine/vkd3d-proton",
"lib/wine/dxvk",
"lib/wine/vkd3d",
"lib/wine/vkd3d-proton",
"lib64/wine/dxvk",
"lib64/wine/vkd3d",
"lib64/wine/vkd3d-proton",
];
for s in subdirs { roots.push(runner_root.join(s)); }
report.scan_roots = roots;
Expand Down Expand Up @@ -391,10 +396,12 @@ mod tests {
components.vkd3d_proton = Some(crate::utils::ComponentInfo {
version: "2.10".into(),
source: crate::utils::ComponentSource::BundledWithRunner,
path: None,
});
components.vkd3d = Some(crate::utils::ComponentInfo {
version: "1.8".into(),
source: crate::utils::ComponentSource::BundledWithRunner,
path: None,
});

let resolver = DllProviderResolver::new();
Expand Down
6 changes: 6 additions & 0 deletions src/launch/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct GraphicsStackInfo {
pub graphics_stack_evidence: Vec<String>, // e.g. ["DXVK: v2.3.1"]
pub graphics_stack_confidence: String, // "low" | "medium" | "high"
pub override_policy: String, // e.g. "Native-only"
pub gpu_selection: String, // e.g. "Manual: AMD (0x1002 0x73ff)"
pub dll_providers: HashMap<String, String>, // e.g. {"d3d11": "Runner", "d3d9": "GameLocal"}
}

Expand Down Expand Up @@ -431,6 +432,11 @@ impl LaunchPipeline {
ctx.graphics_stack.graphics_stack_expected = format!("{} [Policy: {}]", expected.join(", "), policy);
ctx.graphics_stack.override_policy = "Native-preferred".to_string();
}

ctx.graphics_stack.gpu_selection = match &config.graphics_layers.gpu_selection {
crate::models::GpuSelection::Auto => "Auto".to_string(),
crate::models::GpuSelection::Manual { index, name } => format!("Manual: {} (#{})", name, index),
};
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ pub enum D3D12ProviderPolicy {
Vkd3dWine,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub enum GpuSelection {
#[default]
Auto,
Manual {
index: usize,
name: String,
},
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct GraphicsLayerConfig {
#[serde(default)]
Expand All @@ -73,6 +83,8 @@ pub struct GraphicsLayerConfig {
pub graphics_backend_policy: GraphicsBackendPolicy,
#[serde(default)]
pub d3d12_policy: D3D12ProviderPolicy,
#[serde(default)]
pub gpu_selection: GpuSelection,
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
Expand Down
Loading