Browse Source

[android] Wipe shader cache on GPU Driver change (#2984)

A permanently dismissible warning dialog is shown to let the suer know of this change

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2984
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: kleidis <kleidis1@protonmail.com>
Co-committed-by: kleidis <kleidis1@protonmail.com>
pull/3045/head
kleidis 1 month ago
committed by crueter
parent
commit
c2794985b2
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 4
      src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt
  2. 22
      src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt
  3. 50
      src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt
  4. 6
      src/android/app/src/main/jni/android_settings.h
  5. 2
      src/android/app/src/main/res/values/strings.xml

4
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

22
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()
}
}

50
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<String>()
private var previousDriverPath: String = ""
private val _shouldShowDriverShaderDialog = MutableStateFlow(false)
val shouldShowDriverShaderDialog: StateFlow<Boolean> 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) {

6
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<bool> dont_show_eden_veil_warning{linkage, false,
"dont_show_eden_veil_warning",
Settings::Category::Miscellaneous};
Settings::Setting<bool> dont_show_driver_shader_warning{linkage, false,
"dont_show_driver_shader_warning",
Settings::Category::Android, Settings::Specialization::Default, true, true};
};
extern Values values;

2
src/android/app/src/main/res/values/strings.xml

@ -722,6 +722,8 @@
<string name="clear_shader_cache_description">Removes all shaders built while playing this game</string>
<string name="clear_shader_cache_warning_description">You will experience more stuttering as the shader cache regenerates</string>
<string name="cleared_shaders_successfully">Cleared shaders successfully</string>
<string name="driver_shader_wipe_dialog_title">Shaders Cleared</string>
<string name="driver_shader_wipe_dialog_message">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.</string>
<string name="addons_game">Addons: %1$s</string>
<string name="save_data">Save data</string>
<string name="save_data_description">Manage save data specific to this game</string>

Loading…
Cancel
Save