diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index 5c21ea7dc1..90d6110a62 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -69,7 +69,9 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { SHOW_SHADERS_BUILDING("show_shaders_building"), DEBUG_FLUSH_BY_LINE("flush_line"), - USE_LRU_CACHE("use_lru_cache"); + USE_LRU_CACHE("use_lru_cache"), + + DONT_SHOW_DRIVER_SHADER_WARNING("dont_show_driver_shader_warning"); // external fun isFrameSkippingEnabled(): Boolean diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt index f521343272..23334f05eb 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later package org.yuzu.yuzu_emu.fragments @@ -91,6 +91,12 @@ class DriverManagerFragment : Fragment() { } } + driverViewModel.shouldShowDriverShaderDialog.collect(viewLifecycleOwner) { shouldShow -> + if (shouldShow) { + showDriverShaderWipeDialog() + } + } + if (!driverViewModel.isInteractionAllowed.value) { DriversLoadingDialogFragment().show( childFragmentManager, @@ -236,4 +242,18 @@ class DriverManagerFragment : Fragment() { ).show(requireActivity().supportFragmentManager, MessageDialogFragment.TAG) } } + + private fun showDriverShaderWipeDialog() { + com.google.android.material.dialog.MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.driver_shader_wipe_dialog_title) + .setMessage(R.string.driver_shader_wipe_dialog_message) + .setPositiveButton(android.R.string.ok) { _, _ -> + driverViewModel.onDriverShaderDialogDismissed(dontShowAgain = false) + } + .setNegativeButton(R.string.dont_show_again) { _, _ -> + driverViewModel.onDriverShaderDialogDismissed(dontShowAgain = true) + } + .setCancelable(false) + .show() + } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt index a49c887a12..d26320bbb3 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -16,6 +19,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.YuzuApplication +import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting import org.yuzu.yuzu_emu.features.settings.model.StringSetting import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile import org.yuzu.yuzu_emu.model.Driver.Companion.toDriver @@ -52,9 +56,15 @@ class DriverViewModel : ViewModel() { private val driversToDelete = mutableListOf() + private var previousDriverPath: String = "" + + private val _shouldShowDriverShaderDialog = MutableStateFlow(false) + val shouldShowDriverShaderDialog: StateFlow get() = _shouldShowDriverShaderDialog + init { updateDriverList() updateDriverNameForGame(null) + previousDriverPath = StringSetting.DRIVER_PATH.getString() } fun reloadDriverData() { @@ -79,6 +89,7 @@ class DriverViewModel : ViewModel() { newDriverList.add(it.second.toDriver(it.second == selectedDriver)) } _driverList.value = newDriverList + previousDriverPath = StringSetting.DRIVER_PATH.getString() } fun onOpenDriverManager(game: Game?) { @@ -92,12 +103,49 @@ class DriverViewModel : ViewModel() { _showClearButton.value = value } - fun onDriverSelected(position: Int) { + fun onDriverSelected(position: Int, skipShaderWipe: Boolean = false) { + val newDriverPath = if (position == 0) { + "" + } else { + driverData[position - 1].first + } + + if (!skipShaderWipe && newDriverPath != previousDriverPath) { + wipeAllShaders() + + if (!BooleanSetting.DONT_SHOW_DRIVER_SHADER_WARNING.getBoolean(needsGlobal = true)) { + _shouldShowDriverShaderDialog.value = true + } + } + if (position == 0) { StringSetting.DRIVER_PATH.setString("") } else { StringSetting.DRIVER_PATH.setString(driverData[position - 1].first) } + previousDriverPath = newDriverPath + } + + fun onDriverShaderDialogDismissed(dontShowAgain: Boolean) { + if (dontShowAgain) { + BooleanSetting.DONT_SHOW_DRIVER_SHADER_WARNING.setBoolean(true) + NativeConfig.saveGlobalConfig() + } + _shouldShowDriverShaderDialog.value = false + } + + private fun wipeAllShaders() { + viewModelScope.launch { + withContext(Dispatchers.IO) { + val shaderDir = File( + YuzuApplication.appContext.getExternalFilesDir(null)?.canonicalPath + + "/shader/" + ) + if (shaderDir.exists()) { + shaderDir.deleteRecursively() + } + } + } } fun onDriverRemoved(removedPosition: Int, selectedPosition: Int) { diff --git a/src/android/app/src/main/jni/android_settings.h b/src/android/app/src/main/jni/android_settings.h index 8a46a22df1..19ac95652b 100644 --- a/src/android/app/src/main/jni/android_settings.h +++ b/src/android/app/src/main/jni/android_settings.h @@ -182,9 +182,9 @@ namespace AndroidSettings { Settings::Specialization::Default, true, true, &show_soc_overlay}; - Settings::Setting dont_show_eden_veil_warning{linkage, false, - "dont_show_eden_veil_warning", - Settings::Category::Miscellaneous}; + Settings::Setting dont_show_driver_shader_warning{linkage, false, + "dont_show_driver_shader_warning", + Settings::Category::Android, Settings::Specialization::Default, true, true}; }; extern Values values; diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 6ea171ea2b..7d0579155e 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -722,6 +722,8 @@ Removes all shaders built while playing this game You will experience more stuttering as the shader cache regenerates Cleared shaders successfully + Shaders Cleared + Eden has automatically cleared all shader caches to maintain Vulkan pipeline validation. This is required when switching GPU drivers to prevent crashes and graphical corruption. You may experience some stuttering as shaders rebuild. Addons: %1$s Save data Manage save data specific to this game