Skip to content

Conversation

@phobos665
Copy link
Contributor

@phobos665 phobos665 commented Dec 13, 2025

Added D7VK Support

This PR adds support for D7VK as a graphics wrapper option alongside DXVK and VKD3D.

What is D7VK?

D7VK is a Vulkan-based translation layer for DirectX 7/8/9, designed to improve compatibility and performance for older Windows games on ARM devices. Unlike DXVK (which focuses on DirectX 10/11), D7VK specifically targets legacy DirectX APIs commonly used by games from the late 1990s to mid-2000s.

Benefits (According to D7VK Repository):

  • Better performance for older DirectX 7/8/9 games compared to native Wine translation
  • Reduced CPU overhead by leveraging modern Vulkan drivers
  • Improved compatibility with legacy rendering techniques
  • Lower memory usage for games using older graphics API

Changes:

  • Added D7VK 1.1 asset (d7vk-1.0.tzst) to assets/dxwrapper/
  • Added D7VK as a selectable wrapper in container configuration UI
  • Implemented version normalization (d7vk → d7vk-1.0) before extraction
  • Added DefaultVersion.D7VK constant for version validation

Note: D7VK is still in a decently early stage of development, so games will still be a while before in a good state.

Summary by CodeRabbit

  • New Features

    • Added D7VK as a selectable wrapper with its own version list and UI control; version choices load alongside existing wrappers and are applied when selected.
    • Extraction and setup flows now recognize and handle D7VK variants alongside DXVK/D8VK/VKD3D.
  • Bug Fixes

    • Improved validation and syncing of per-wrapper versions: mismatched or missing wrapper versions are corrected on load and when switching wrappers.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 13, 2025

📝 Walkthrough

Walkthrough

Adds first-class D7VK support across UI, setup/extraction, container core, enums/constants, and resources: version lists, per-wrapper state, validation/defaulting, extraction logging, and unconditional config updates when wrapper/version changes.

Changes

Cohort / File(s) Summary
UI: ContainerConfigDialog
app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt
Adds D7VK version lists (d7vkVersionsBase, d7vkVersionsAll) and d7vkVersionIndex; validates/reset per-wrapper indices on load/save; updates wrapper selection flow to reset/init per-wrapper defaults (dxvk, d7vk, VKD3D) and update dxwrapperConfig unconditionally; adds D7VK dropdown and selection handling.
Setup & Extraction: XServerScreen
app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
Reads/ensures d7vk config version (defaults to DefaultVersion.D7VK), persists composed d7vk-* dxwrapper value; updates extraction logging and user-profile messaging to reference DXVK/D7VK/D8VK.
Container core eligibility
app/src/main/java/com/winlator/container/Container.java
Extends dxwrapper eligibility checks to accept d7vk- prefixed dxwrapper names alongside dxvk- and d8vk-.
Content types & defaults
app/src/main/java/com/winlator/contents/ContentProfile.java, app/src/main/java/com/winlator/core/DefaultVersion.java
Adds CONTENT_TYPE_D7VK enum entry and DefaultVersion.D7VK = "1.1".
Resources
app/src/main/res/values/arrays.xml, app/src/main/res/values/strings.xml
Adds d7vk_version_entries array with "1.1", inserts D7VK into dxwrapper_entries, and adds d7vk_version string resource.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant UI as ContainerConfigDialog (UI)
  participant Config as dxwrapperConfig
  participant Setup as XServerScreen
  participant Container as Container core
  participant FS as Filesystem/Extraction

  Note over UI,Config: User selects wrapper and per-wrapper version
  UI->>Config: set dxwrapper (e.g., "d7vk-1.1"), set version indices
  Config-->>UI: confirm selection/state

  alt selected wrapper starts with "d7vk-"
    UI->>Setup: trigger setupWineSystemFiles(dxwrapper)
    Setup->>Config: read/validate version (default to DefaultVersion.D7VK if missing)
    Setup->>Container: request extraction for dxwrapper (d7vk-*)
    Container->>FS: extract DXVK/D7VK/D8VK DLLs
    FS-->>Container: extraction result
    Container-->>Setup: extraction applied
  else other dx wrapper variants
    UI->>Setup: trigger setupWineSystemFiles(dxwrapper=...)
    Setup->>Container: request extraction for dxwrapper
  end

  Note over UI,Config: UI keeps per-wrapper version indices synchronized with config
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped into code with a curious click,
D7VK now dances, nimble and quick.
Versions set right, dropdowns in tune,
Extraction hums under a bright full moon. 🎮✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'D7vk support' is clear and directly related to the main change: adding D7VK as a new graphics wrapper option throughout the codebase.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor Author

@phobos665 phobos665 Dec 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in the option to choose D7VK versions (and 1.1). Added some logic to fix an issue where it was auto-forcing the D7VK to an invalid version (2.4.1) which is due to the VK3D having a DXVK version shipped with it.

@phobos665
Copy link
Contributor Author

Going to update this PR tomorrow to add the 1.1 instead as that has large improvements over 1.0

@phobos665 phobos665 marked this pull request as ready for review January 2, 2026 22:21
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt (1)

41-47: Duplicate import of TextButton.

TextButton is imported twice (lines 41 and 47). Remove one of the duplicates.

🔎 Proposed fix
 import androidx.compose.material3.TextButton
 import androidx.compose.material3.OutlinedTextField
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.Slider
 import androidx.compose.material3.CircularProgressIndicator
 import androidx.compose.material3.Text
-import androidx.compose.material3.TextButton
🧹 Nitpick comments (1)
app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt (1)

482-516: Consider using DefaultVersion constants instead of hardcoded index 0.

When resetting to a default version, using DefaultVersion.D7VK and DefaultVersion.DXVK would be more robust and consistent with how defaults are handled elsewhere in the codebase (e.g., line 709 uses DefaultVersion.DXVK).

🔎 Proposed fix
             when (config.dxwrapper) {
                 "d7vk" -> {
                     // Check if version is valid for D7VK
                     val isValidD7VKVersion = d7vkVersionsAll.any {
                         StringUtils.parseIdentifier(it) == savedVersion
                     }
                     if (!isValidD7VKVersion && d7vkVersionsAll.isNotEmpty()) {
-                        // Reset to first D7VK version
-                        val defaultVersion = StringUtils.parseIdentifier(d7vkVersionsAll[0])
+                        // Reset to default D7VK version
+                        val defaultIdx = d7vkVersionsAll.indexOfFirst { 
+                            StringUtils.parseIdentifier(it) == DefaultVersion.D7VK 
+                        }.coerceAtLeast(0)
+                        val defaultVersion = StringUtils.parseIdentifier(d7vkVersionsAll[defaultIdx])
                         currentConfig.put("version", defaultVersion)
                         config = config.copy(dxwrapperConfig = currentConfig.toString())
-                        d7vkVersionIndex = 0
+                        d7vkVersionIndex = defaultIdx
                     }
                 }
                 "dxvk" -> {
                     // Check if version is valid for DXVK
                     val isValidDXVKVersion = dxvkVersionsAll.any {
                         StringUtils.parseIdentifier(it) == savedVersion
                     }
                     if (!isValidDXVKVersion && dxvkVersionsAll.isNotEmpty()) {
-                        // Reset to first DXVK version
-                        val defaultVersion = StringUtils.parseIdentifier(dxvkVersionsAll[0])
+                        // Reset to default DXVK version
+                        val defaultIdx = dxvkVersionsAll.indexOfFirst { 
+                            StringUtils.parseIdentifier(it) == DefaultVersion.DXVK 
+                        }.coerceAtLeast(0)
+                        val defaultVersion = StringUtils.parseIdentifier(dxvkVersionsAll[defaultIdx])
                         currentConfig.put("version", version)
                         config = config.copy(dxwrapperConfig = currentConfig.toString())
-                        dxvkVersionIndex = 0
+                        dxvkVersionIndex = defaultIdx
                     }
                 }
             }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1774b56 and 907fb3a.

📒 Files selected for processing (7)
  • app/src/main/assets/dxwrapper/d7vk-1.1.tzst
  • app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
  • app/src/main/java/com/winlator/container/Container.java
  • app/src/main/java/com/winlator/contents/ContentProfile.java
  • app/src/main/java/com/winlator/core/DefaultVersion.java
  • app/src/main/res/values/arrays.xml
🧰 Additional context used
🧬 Code graph analysis (1)
app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt (3)
app/src/main/java/com/winlator/core/KeyValueSet.java (1)
  • KeyValueSet (7-169)
app/src/main/java/app/gamenative/ui/component/settings/SettingsListDropdown.kt (1)
  • SettingsListDropdown (40-125)
app/src/main/java/app/gamenative/ui/theme/Color.kt (1)
  • settingsTileColors (27-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (8)
app/src/main/java/com/winlator/core/DefaultVersion.java (1)

18-18: LGTM!

The D7VK version constant follows the established pattern and is consistent with other wrapper version constants in the class.

app/src/main/java/com/winlator/contents/ContentProfile.java (1)

28-28: LGTM!

The D7VK content type enum addition is properly placed alongside other DirectX wrapper types and follows the established naming convention.

app/src/main/java/com/winlator/container/Container.java (1)

850-850: LGTM!

The extension of the dxwrapper eligibility check to include d7vk-* prefixes is consistent with the existing handling of d8vk-* and dxvk-* variants.

app/src/main/res/values/arrays.xml (1)

79-79: LGTM!

The D7VK resource entries are properly integrated:

  • "D7VK" added to wrapper selection list
  • Version array initialized with "1.1" (matching DefaultVersion.D7VK)
  • Logical placement alongside other wrapper options

Also applies to: 83-85

app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt (2)

2145-2155: Verify the intentional version enforcement for D7VK.

The D7VK version normalization logic differs from the DXVK implementation:

  • D7VK (lines 2145-2155): Forces DefaultVersion.D7VK ("1.1") when the version is null or doesn't match the default
  • DXVK (lines 2140-2144): Simply appends the version from config without validation

This inconsistency means:

  1. Users cannot select custom D7VK versions (e.g., future 1.2 or custom builds)
  2. Any existing D7VK 1.0 configurations will be automatically upgraded to 1.1

If this forced versioning is intentional (e.g., to ensure users benefit from 1.1 improvements mentioned in the PR), consider:

  • Adding a comment explaining why D7VK differs from DXVK
  • Evaluating whether DXVK should have similar validation

If unintentional, align with DXVK behavior by removing the version != DefaultVersion.D7VK condition.

🔎 Suggested refactor to align with DXVK behavior
 if (xServerState.value.dxwrapper == "d7vk") {
-    // Set version for d7vk or use default if not found.
-    var version = xServerState.value.dxwrapperConfig?.get("version")
-    if (version == null || version != DefaultVersion.D7VK) {
-        version = DefaultVersion.D7VK
-        xServerState.value.dxwrapperConfig?.put("version", version)
-    }
     xServerState.value = xServerState.value.copy(
-        dxwrapper = "d7vk-" + version,
+        dxwrapper = "d7vk-" + xServerState.value.dxwrapperConfig?.get("version"),
     )
 }

2335-2341: LGTM!

The updated comments and log messages appropriately reflect the expanded support for D7VK alongside DXVK and D8VK wrappers.

app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt (2)

149-149: LGTM!

The D7VK version list initialization follows the established pattern used for DXVK and VKD3D, correctly initializing base versions from resources, creating mutable state, and augmenting with installed content profiles.

Also applies to: 191-191, 231-231


714-742: LGTM!

Good addition of the guard clause to ensure this DXVK-specific async version handling only runs when the DXVK wrapper is selected, preventing unintended side effects when D7VK or other wrappers are active.

@phobos665
Copy link
Contributor Author

Will do some final tests to ensure that everything is working correctly.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In
@app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt:
- Around line 591-597: Remove the composition-time mutation of config: delete
the else-if block that checks isVKD3D and writes version into
config.dxwrapperConfig (the block that constructs
KeyValueSet(config.dxwrapperConfig), puts "version", and assigns config =
config.copy(...)). This logic is already handled in
LaunchedEffect(graphicsDriverIndex, dxWrapperIndex), so stop performing
side-effectful updates to config during composition (remove references to
isVKD3D/isVortekLike in that block).
- Around line 535-554: The code sets version fields by directly indexing
dxvkVersionsAll[0] and d7vkVersionsAll[0] which can throw
IndexOutOfBoundsException; update the dxwrapper switch in
ContainerConfigDialog.kt (symbols: dxvkVersionIndex, d7vkVersionIndex,
dxvkVersionsAll, d7vkVersionsAll, currentConfig.put) to first check that the
respective list is not empty (e.g., if (dxvkVersionsAll.isNotEmpty()) {
dxvkVersionIndex = 0; val newVersion =
StringUtils.parseIdentifier(dxvkVersionsAll[0]); currentConfig.put("version",
newVersion) } else { /* set a safe default or skip putting version */ }) and do
the equivalent for d7vkVersionsAll so you only parse and store index 0 when
present and avoid updating the index when the list is empty.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 907fb3a and 66299d6.

📒 Files selected for processing (2)
  • app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt
  • app/src/main/res/values/strings.xml
🔇 Additional comments (7)
app/src/main/res/values/strings.xml (1)

117-117: LGTM! String resource properly added.

The D7VK version string resource follows the same pattern as the existing DXVK version string (line 116) and is correctly placed in the Win Components section for proper internationalization.

app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt (6)

149-149: LGTM! D7VK version lists properly initialized.

The D7VK version base and runtime lists follow the same pattern as DXVK versions, ensuring consistency across wrapper implementations.

Also applies to: 191-191


231-231: LGTM! D7VK content profiles properly loaded.

The D7VK versions are correctly augmented with installed content profiles, following the same pattern as DXVK and VKD3D.


479-479: LGTM! D7VK version index state properly initialized.

The D7VK version index state variable follows the same pattern as the DXVK version index.


482-516: Good addition, but bounds checking still needed.

The validation logic properly fixes version mismatches when loading containers, which prevents crashes from stale or invalid version references. However, the bounds checking issue flagged in past reviews (lines 494-500 and 507-513) still applies: accessing d7vkVersionsAll[0] or dxvkVersionsAll[0] without checking for empty lists can throw IndexOutOfBoundsException.

Add defensive checks before accessing index 0:

"d7vk" -> {
    val isValidD7VKVersion = d7vkVersionsAll.any {
        StringUtils.parseIdentifier(it) == savedVersion
    }
    if (!isValidD7VKVersion && d7vkVersionsAll.isNotEmpty()) {
        val defaultVersion = StringUtils.parseIdentifier(d7vkVersionsAll[0])
        currentConfig.put("version", defaultVersion)
        config = config.copy(dxwrapperConfig = currentConfig.toString())
        d7vkVersionIndex = 0
    } else if (d7vkVersionsAll.isEmpty()) {
        // Handle empty list case - perhaps log warning or use a hardcoded default
        timber.log.Timber.w("D7VK versions list is empty, cannot reset version")
    }
}

Similar pattern for the "dxvk" case.


599-618: LGTM! D7VK version dropdown properly implemented.

The D7VK version dropdown is correctly implemented with:

  • Proper use of string resource for the title (line 606)
  • Bounds checking via coerceIn (line 607)
  • Correct state management and config updates
  • Conditional visibility based on wrapper selection

715-743: Good improvement to scope DXVK version handling.

The addition of the wrapper type check (lines 715-718) ensures DXVK version logic only runs when the DXVK wrapper is actually selected, preventing unintended version updates for D7VK or VKD3D wrappers. This makes the version management more robust and prevents conflicts between different wrapper types.

@phobos665 phobos665 marked this pull request as draft January 7, 2026 12:01
@phobos665 phobos665 marked this pull request as ready for review January 7, 2026 12:28
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt (1)

706-715: Missing D7VK version index synchronization.

DXVK has this LaunchedEffect to sync the version index from config.dxwrapperConfig when the dialog loads, ensuring the UI displays the correct saved version. D7VK lacks equivalent logic. When the dialog loads with a saved D7VK container, d7vkVersionIndex remains at its initial value of 0 (line 479) instead of reflecting the actual saved version, causing the dropdown at line 610 to display the first version in the list rather than the configured version.

🔄 Proposed fix: Add D7VK version index sync

Add a similar effect for D7VK after line 715:

        LaunchedEffect(versionsLoaded, d7vkVersionsAll, config.dxwrapper, config.dxwrapperConfig) {
            if (!versionsLoaded) return@LaunchedEffect
            if (config.dxwrapper != "d7vk") return@LaunchedEffect
            val kvs = KeyValueSet(config.dxwrapperConfig)
            val configuredVersion = kvs.get("version")
            val foundIndex = d7vkVersionsAll.indexOfFirst { StringUtils.parseIdentifier(it) == configuredVersion }
            val defaultIndex = d7vkVersionsAll.indexOfFirst { StringUtils.parseIdentifier(it) == DefaultVersion.D7VK }.coerceAtLeast(0)
            val newIdx = if (foundIndex >= 0) foundIndex else defaultIndex
            if (d7vkVersionIndex != newIdx) d7vkVersionIndex = newIdx
        }
🤖 Fix all issues with AI agents
In
@app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt:
- Around line 595-600: The code block that builds and mutates `config` using
`val version = if (isVortekLike) "1.10.3" else "2.4.1"`,
`KeyValueSet(config.dxwrapperConfig)` and `config = config.copy(dxwrapperConfig
= currentConfig.toString())` must be removed because it performs a
composition-side effect that is already handled in
`LaunchedEffect(graphicsDriverIndex, dxWrapperIndex)` and incorrectly runs for
D7VK; delete that entire else-branch so DXVK/VKD3D versioning is only set by the
existing `LaunchedEffect` and D7VK retains its own handling in the D7VK-specific
code paths.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66299d6 and 9ed15fc.

📒 Files selected for processing (3)
  • app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
  • app/src/main/res/values/strings.xml
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/src/main/res/values/strings.xml
  • app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
🧰 Additional context used
🧬 Code graph analysis (1)
app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt (3)
app/src/main/java/com/winlator/core/KeyValueSet.java (1)
  • KeyValueSet (7-169)
app/src/main/java/app/gamenative/ui/component/settings/SettingsListDropdown.kt (1)
  • SettingsListDropdown (40-125)
app/src/main/java/app/gamenative/ui/theme/Color.kt (1)
  • settingsTileColors (27-32)
🔇 Additional comments (4)
app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt (4)

149-149: LGTM: D7VK state initialization follows established patterns.

The D7VK version lists and state variables are initialized consistently with the existing DXVK implementation.

Also applies to: 191-191, 231-231, 479-479


482-516: LGTM: Validation logic properly handles empty version lists.

The bounds checks (isNotEmpty()) correctly prevent IndexOutOfBoundsException when version lists are empty, addressing concerns from previous reviews.


535-558: LGTM: Wrapper switching safely resets versions with bounds checking.

The addition of isNotEmpty() guards before accessing [0] correctly addresses the IndexOutOfBoundsException concerns raised in previous reviews.


602-621: LGTM: D7VK version dropdown properly implemented.

The dropdown uses proper string resources (addressing the previous review comment) and safely handles bounds with coerceIn. The version selection logic correctly updates dxwrapperConfig.

Comment on lines 595 to 600
} else {
// Ensure default version for vortek-like when hidden
val version = if (isVortekLike) "1.10.3" else "2.4.1"
val currentConfig = KeyValueSet(config.dxwrapperConfig)
currentConfig.put("version", version)
config = config.copy(dxwrapperConfig = currentConfig.toString())
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Refactor: Remove composition side effect (duplicate issue).

This block mutates config state during composition and was flagged in previous reviews as redundant. The logic is already handled in LaunchedEffect(graphicsDriverIndex, dxWrapperIndex) at line 691. Additionally, this block incorrectly runs when D7VK is selected (due to the condition at line 575), setting a DXVK/VKD3D version when D7VK should use its own version handling at lines 602-621.

♻️ Remove redundant block
                     )
-                } else {
-                    val version = if (isVortekLike) "1.10.3" else "2.4.1"
-                    val currentConfig = KeyValueSet(config.dxwrapperConfig)
-                    currentConfig.put("version", version)
-                    config = config.copy(dxwrapperConfig = currentConfig.toString())
                 }
             }
🤖 Prompt for AI Agents
In
@app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt
around lines 595 - 600, The code block that builds and mutates `config` using
`val version = if (isVortekLike) "1.10.3" else "2.4.1"`,
`KeyValueSet(config.dxwrapperConfig)` and `config = config.copy(dxwrapperConfig
= currentConfig.toString())` must be removed because it performs a
composition-side effect that is already handled in
`LaunchedEffect(graphicsDriverIndex, dxWrapperIndex)` and incorrectly runs for
D7VK; delete that entire else-branch so DXVK/VKD3D versioning is only set by the
existing `LaunchedEffect` and D7VK retains its own handling in the D7VK-specific
code paths.

@phobos665 phobos665 marked this pull request as draft January 8, 2026 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant