diff --git a/app/src/main/assets/dxwrapper/d7vk-1.1.tzst b/app/src/main/assets/dxwrapper/d7vk-1.1.tzst new file mode 100644 index 000000000..0bdffc3a4 Binary files /dev/null and b/app/src/main/assets/dxwrapper/d7vk-1.1.tzst differ diff --git a/app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt b/app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt index 24e0ba689..f77458173 100644 --- a/app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt +++ b/app/src/main/java/app/gamenative/ui/component/dialog/ContainerConfigDialog.kt @@ -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) @@ -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 @@ -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() @@ -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 { @@ -491,14 +532,39 @@ 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, @@ -506,7 +572,7 @@ fun ContainerConfigDialog( 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)) }, @@ -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()) } } + // 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" @@ -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 @@ -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 { @@ -2069,4 +2155,3 @@ private fun ExecutablePathDropdown( } } } - diff --git a/app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt b/app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt index e1d96bc9f..d227c3a40 100644 --- a/app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt +++ b/app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt @@ -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- if (xServerState.value.dxwrapper == "vkd3d") { @@ -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( diff --git a/app/src/main/java/com/winlator/container/Container.java b/app/src/main/java/com/winlator/container/Container.java index 21dc53d7d..7a4ca3d43 100644 --- a/app/src/main/java/com/winlator/container/Container.java +++ b/app/src/main/java/com/winlator/container/Container.java @@ -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); } } diff --git a/app/src/main/java/com/winlator/contents/ContentProfile.java b/app/src/main/java/com/winlator/contents/ContentProfile.java index 2e019786f..8c0f32e0c 100644 --- a/app/src/main/java/com/winlator/contents/ContentProfile.java +++ b/app/src/main/java/com/winlator/contents/ContentProfile.java @@ -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"), diff --git a/app/src/main/java/com/winlator/core/DefaultVersion.java b/app/src/main/java/com/winlator/core/DefaultVersion.java index 356de8885..1b65a6377 100644 --- a/app/src/main/java/com/winlator/core/DefaultVersion.java +++ b/app/src/main/java/com/winlator/core/DefaultVersion.java @@ -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"; diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 41d070f6d..7448ffa73 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -76,9 +76,13 @@ WineD3D DXVK + D7VK VKD3D CNC DDraw + + 1.1 + async-1.10.3 2.7.1 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4b8c42622..0e4b0b3ae 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -118,6 +118,7 @@ Windows Media Decoder OpenGL DXVK Version + D7VK Version Run Edit Remove