Skip to content
Draft
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
Binary file added app/src/main/assets/dxwrapper/d7vk-1.1.tzst
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ fun ContainerConfigDialog(
val dxWrappers = stringArrayResource(R.array.dxwrapper_entries).toList()
// Start with defaults from resources
val dxvkVersionsBase = stringArrayResource(R.array.dxvk_version_entries).toList()
val d7vkVersionsBase = stringArrayResource(R.array.d7vk_version_entries).toList()
val vkd3dVersionsBase = stringArrayResource(R.array.vkd3d_version_entries).toList()
val audioDrivers = stringArrayResource(R.array.audio_driver_entries).toList()
val gpuCards = ContainerUtils.getGPUCards(context)
Expand Down Expand Up @@ -187,6 +188,7 @@ fun ContainerConfigDialog(
val baseWrapperVersions = stringArrayResource(R.array.wrapper_graphics_driver_version_entries).toList()
var wrapperVersions by remember { mutableStateOf(baseWrapperVersions) }
var dxvkVersionsAll by remember { mutableStateOf(dxvkVersionsBase) }
var d7vkVersionsAll by remember { mutableStateOf(d7vkVersionsBase) }
var vkd3dVersions by remember { mutableStateOf(vkd3dVersionsBase) }
var box64BionicVersions by remember { mutableStateOf(box64BionicVersionsBase) }
var wowBox64Versions by remember { mutableStateOf(wowBox64VersionsBase) } // reuse existing base list
Expand Down Expand Up @@ -226,6 +228,7 @@ fun ContainerConfigDialog(
}

dxvkVersionsAll = (dxvkVersionsBase + profilesToDisplay(mgr.getProfiles(ContentProfile.ContentType.CONTENT_TYPE_DXVK))).distinct()
d7vkVersionsAll = (d7vkVersionsBase + profilesToDisplay(mgr.getProfiles(ContentProfile.ContentType.CONTENT_TYPE_D7VK))).distinct()
vkd3dVersions = (vkd3dVersionsBase + profilesToDisplay(mgr.getProfiles(ContentProfile.ContentType.CONTENT_TYPE_VKD3D))).distinct()
box64BionicVersions = (box64BionicVersionsBase + profilesToDisplay(mgr.getProfiles(ContentProfile.ContentType.CONTENT_TYPE_BOX64))).distinct()
wowBox64Versions = (wowBox64Versions + profilesToDisplay(mgr.getProfiles(ContentProfile.ContentType.CONTENT_TYPE_WOWBOX64))).distinct()
Expand Down Expand Up @@ -473,6 +476,44 @@ fun ContainerConfigDialog(
}

var dxvkVersionIndex by rememberSaveable { mutableIntStateOf(0) }
var d7vkVersionIndex by rememberSaveable { mutableIntStateOf(0) }

// Validate and fix version mismatch when loading container
LaunchedEffect(versionsLoaded, config.dxwrapper) {
if (!versionsLoaded) return@LaunchedEffect

val currentConfig = KeyValueSet(config.dxwrapperConfig)
val savedVersion = currentConfig.get("version")

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])
currentConfig.put("version", defaultVersion)
config = config.copy(dxwrapperConfig = currentConfig.toString())
d7vkVersionIndex = 0
}
}
"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])
currentConfig.put("version", defaultVersion)
config = config.copy(dxwrapperConfig = currentConfig.toString())
dxvkVersionIndex = 0
}
}
}
}

// VKD3D version control (forced depending on driver)
fun vkd3dForcedVersion(): String {
Expand All @@ -491,22 +532,47 @@ fun ContainerConfigDialog(
items = dxWrappers,
onItemSelected = {
dxWrapperIndex = it
config = config.copy(dxwrapper = StringUtils.parseIdentifier(dxWrappers[it]))
val newWrapper = StringUtils.parseIdentifier(dxWrappers[it])
config = config.copy(dxwrapper = newWrapper)
// Reset version to default when switching wrappers
val currentConfig = KeyValueSet(config.dxwrapperConfig)
when (newWrapper) {
"dxvk" -> {
if (dxvkVersionsAll.isNotEmpty()) {
dxvkVersionIndex = 0
val newVersion = StringUtils.parseIdentifier(dxvkVersionsAll[0])
currentConfig.put("version", newVersion)
}
}
"d7vk" -> {
if (d7vkVersionsAll.isNotEmpty()) {
d7vkVersionIndex = 0
val newVersion = StringUtils.parseIdentifier(d7vkVersionsAll[0])
currentConfig.put("version", newVersion)
}
}
"vkd3d" -> {
currentConfig.put("vkd3dVersion", vkd3dForcedVersion())
}
}
config = config.copy(dxwrapperConfig = currentConfig.toString())
},
)
// DXVK Version Dropdown (conditionally visible and constrained)
run {
val driverType = StringUtils.parseIdentifier(graphicsDrivers[graphicsDriverIndex])
val isVortekLike = config.containerVariant.equals(Container.GLIBC) && driverType == "vortek" || driverType == "adreno" || driverType == "sd-8-elite"
val isVKD3D = StringUtils.parseIdentifier(dxWrappers[dxWrapperIndex]) == "vkd3d"
val wrapperType = StringUtils.parseIdentifier(dxWrappers[dxWrapperIndex])
val isVKD3D = wrapperType == "vkd3d"
val isD7VK = wrapperType == "d7vk"
val items =
if (!inspectionMode && isVortekLike && GPUHelper.vkGetApiVersionSafe() < GPUHelper.vkMakeVersion(
1,
3,
0
)
) listOf("1.10.3", "1.10.9-sarek", "1.9.2", "async-1.10.3") else dxvkVersionsAll
if (!isVKD3D) {
if (!isVKD3D && !isD7VK) {
SettingsListDropdown(
colors = settingsTileColors(),
title = { Text(text = stringResource(R.string.dxvk_version)) },
Expand All @@ -527,13 +593,32 @@ fun ContainerConfigDialog(
},
)
} 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())
}
Comment on lines 595 to 600
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.

}
// D7VK Version Dropdown
run {
val wrapperType = StringUtils.parseIdentifier(dxWrappers[dxWrapperIndex])
val isD7VK = wrapperType == "d7vk"
if (isD7VK) {
SettingsListDropdown(
colors = settingsTileColors(),
title = { Text(text = stringResource(R.string.d7vk_version)) },
value = d7vkVersionIndex.coerceIn(0, (d7vkVersionsAll.size - 1).coerceAtLeast(0)),
items = d7vkVersionsAll,
onItemSelected = {
d7vkVersionIndex = it
val version = StringUtils.parseIdentifier(d7vkVersionsAll[it])
val currentConfig = KeyValueSet(config.dxwrapperConfig)
currentConfig.put("version", version)
config = config.copy(dxwrapperConfig = currentConfig.toString())
}
)
}
}
// VKD3D Version UI (visible only when VKD3D selected)
run {
val isVKD3D = StringUtils.parseIdentifier(dxWrappers[dxWrapperIndex]) == "vkd3d"
Expand Down Expand Up @@ -630,6 +715,10 @@ fun ContainerConfigDialog(
}
// When DXVK version defaults to an 'async' build, enable DXVK_ASYNC by default
LaunchedEffect(dxvkVersionIndex, graphicsDriverIndex, dxWrapperIndex) {
// Only run this effect when DXVK wrapper is selected
val wrapperIsDxvk = StringUtils.parseIdentifier(dxWrappers[dxWrapperIndex]) == "dxvk"
if (!wrapperIsDxvk) return@LaunchedEffect

val (isVortekLike, effectiveList) = currentDxvkContext()
if (dxvkVersionIndex !in effectiveList.indices) dxvkVersionIndex = 0

Expand All @@ -641,11 +730,8 @@ fun ContainerConfigDialog(
} else selectedVersion
val envSet = EnvVars(config.envVars)
// Update dxwrapperConfig version only when DXVK wrapper selected
val wrapperIsDxvk = StringUtils.parseIdentifier(dxWrappers[dxWrapperIndex]) == "dxvk"
val kvs = KeyValueSet(config.dxwrapperConfig)
if (wrapperIsDxvk) {
kvs.put("version", version)
}
kvs.put("version", version)
if (version.contains("async", ignoreCase = true)) {
kvs.put("async", "1")
} else {
Expand Down Expand Up @@ -2069,4 +2155,3 @@ private fun ExecutablePathDropdown(
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2344,6 +2344,17 @@ private fun setupWineSystemFiles(
dxwrapper = "dxvk-" + xServerState.value.dxwrapperConfig?.get("version"),
)
}
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,
)
}

// Also normalize VKD3D to include version like vkd3d-<version>
if (xServerState.value.dxwrapper == "vkd3d") {
Expand Down Expand Up @@ -2523,12 +2534,12 @@ private fun extractDXWrapperFiles(
}
}
else -> {
// Handle dxvk-*, d8vk-* and d7vk-* versions (dxvk-2.4.1, d7vk-1.0, etc.)
val profile: ContentProfile? = contentsManager.getProfileByEntryName(dxwrapper)
// This block handles dxvk-VERSION strings
Timber.i("Extracting DXVK/D8VK DLLs for dxwrapper: $dxwrapper")
Timber.i("Extracting DXVK/D7VK/D8VK DLLs for dxwrapper: $dxwrapper")
restoreOriginalDllFiles(context, container, containerManager, imageFs, "d3d12.dll", "d3d12core.dll", "ddraw.dll")
if (profile != null) {
Timber.d("Applying user-defined DXVK content profile: " + dxwrapper)
Timber.d("Applying user-defined content profile: " + dxwrapper)
contentsManager.applyContent(profile);
} else {
TarCompressorUtils.extract(
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/winlator/container/Container.java
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ public static void checkObsoleteOrMissingProperties(JSONObject data) {
if (dxwrapper.equals("original-wined3d")) {
data.put("dxwrapper", DEFAULT_DXWRAPPER);
}
else if (dxwrapper.startsWith("d8vk-") || dxwrapper.startsWith("dxvk-")) {
else if (dxwrapper.startsWith("d8vk-") || dxwrapper.startsWith("d7vk-") || dxwrapper.startsWith("dxvk-")) {
data.put("dxwrapper", dxwrapper);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public enum ContentType {
CONTENT_TYPE_VORTEK("Vortek"),
CONTENT_TYPE_VIRGL("VirGL"),
CONTENT_TYPE_DXVK("DXVK"),
CONTENT_TYPE_D7VK("D7VK"),
CONTENT_TYPE_VKD3D("VKD3D"),
CONTENT_TYPE_BOX64("Box64"),
CONTENT_TYPE_WOWBOX64("WOWBox64"),
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/winlator/core/DefaultVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public abstract class DefaultVersion {
public static final String VIRGL = "23.1.9";
public static String DXVK = "2.6.1-gplasync";
public static final String D8VK = "1.0";
public static final String D7VK = "1.1";
public static String VKD3D = "2.14.1";
public static final String CNC_DDRAW = "6.6";
public static final String VORTEK = "2.1-22.2.5";
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,13 @@
<string-array name="dxwrapper_entries">
<item>WineD3D</item>
<item>DXVK</item>
<item>D7VK</item>
<item>VKD3D</item>
<item>CNC DDraw</item>
</string-array>
<string-array name="d7vk_version_entries">
<item>1.1</item>
</string-array>
<string-array name="dxvk_version_entries">
<item>async-1.10.3</item>
<item>2.7.1</item>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
<string name="wmdecoder">Windows Media Decoder</string>
<string name="opengl">OpenGL</string>
<string name="dxvk_version">DXVK Version</string>
<string name="d7vk_version">D7VK Version</string>
<string name="run">Run</string>
<string name="edit">Edit</string>
<string name="remove">Remove</string>
Expand Down
Loading