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 475d9192c6..40de2bdff5 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
@@ -28,6 +28,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
SYNC_MEMORY_OPERATIONS("sync_memory_operations"),
BUFFER_REORDER_DISABLE("disable_buffer_reorder"),
RENDERER_DEBUG("debug"),
+ RENDERER_PATCH_OLD_QCOM_DRIVERS("patch_old_qcom_drivers"),
RENDERER_VERTEX_INPUT_DYNAMIC_STATE("vertex_input_dynamic_state"),
RENDERER_PROVOKING_VERTEX("provoking_vertex"),
RENDERER_DESCRIPTOR_INDEXING("descriptor_indexing"),
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
index 62929bf371..72ec709696 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
@@ -766,6 +766,14 @@ abstract class SettingsItem(
descriptionId = R.string.renderer_debug_description
)
)
+ // BCn texture patching debug override
+ put(
+ SwitchSetting(
+ BooleanSetting.RENDERER_PATCH_OLD_QCOM_DRIVERS,
+ titleId = R.string.patch_old_qcom_drivers,
+ descriptionId = R.string.patch_old_qcom_drivers_description
+ )
+ )
put(
SwitchSetting(
BooleanSetting.USE_AUTO_STUB,
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
index 8d05abf703..3fb89a7b0e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -1161,6 +1161,7 @@ class SettingsFragmentPresenter(
add(HeaderSetting(R.string.gpu))
add(IntSetting.RENDERER_BACKEND.key)
add(BooleanSetting.RENDERER_DEBUG.key)
+ add(BooleanSetting.RENDERER_PATCH_OLD_QCOM_DRIVERS.key)
add(HeaderSetting(R.string.cpu))
add(IntSetting.CPU_BACKEND.key)
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 9002d74bb8..72cd1170c4 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -524,6 +524,8 @@
API
Graphics debugging
Sets the graphics API to a slow debugging mode.
+ BCn Texture Patching
+ Override automatic BCn texture format detection on Adreno GPUs. Normally auto-detected based on Android version (enabled on API 28+).
Fastmem
Logging
diff --git a/src/common/settings.h b/src/common/settings.h
index 4a8d352c5f..3c7b4fe82b 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -556,6 +556,11 @@ struct Values {
linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug};
Setting enable_renderdoc_hotkey{linkage, false, "renderdoc_hotkey",
Category::RendererDebug};
+#if defined(ANDROID) && defined(ARCHITECTURE_arm64)
+ // Debug override for automatic BCn patching detection
+ Setting patch_old_qcom_drivers{linkage, true, "patch_old_qcom_drivers",
+ Category::RendererDebug};
+#endif
SwitchableSetting disable_buffer_reorder{linkage, false, "disable_buffer_reorder",
Category::RendererDebug,
Specialization::Default,
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 2ce19c8e18..524b93dfdf 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -24,6 +24,7 @@
#if defined(ANDROID) && defined(ARCHITECTURE_arm64)
#include
+#include
#endif
namespace Vulkan {
@@ -502,24 +503,45 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
features.features.shaderInt64 = false;
#if defined(ANDROID) && defined(ARCHITECTURE_arm64)
- // Patch the driver to enable BCn textures.
+ // BCn patching only safe on Android 9+ (API 28+). Older versions crash on driver load.
const auto major = (properties.properties.driverVersion >> 24) << 2;
const auto minor = (properties.properties.driverVersion >> 12) & 0xFFFU;
const auto vendor = properties.properties.vendorID;
const auto patch_status = adrenotools_get_bcn_type(major, minor, vendor);
+ const int api_level = android_get_device_api_level();
+
+ bool should_patch_bcn = api_level >= 28;
+ const bool bcn_debug_override = Settings::values.patch_old_qcom_drivers.GetValue();
+ if (bcn_debug_override != should_patch_bcn) {
+ LOG_WARNING(Render_Vulkan,
+ "BCn patch debug override active: {} (auto-detected: {})",
+ bcn_debug_override, should_patch_bcn);
+ should_patch_bcn = bcn_debug_override;
+ }
if (patch_status == ADRENOTOOLS_BCN_PATCH) {
- LOG_INFO(Render_Vulkan, "Patching Adreno driver to support BCn texture formats");
- if (adrenotools_patch_bcn(
- reinterpret_cast(dld.vkGetPhysicalDeviceFormatProperties))) {
- OverrideBcnFormats(format_properties);
+ if (should_patch_bcn) {
+ LOG_INFO(Render_Vulkan,
+ "Patching Adreno driver to support BCn texture formats "
+ "(Android API {}, Driver {}.{})", api_level, major, minor);
+ if (adrenotools_patch_bcn(
+ reinterpret_cast(dld.vkGetPhysicalDeviceFormatProperties))) {
+ OverrideBcnFormats(format_properties);
+ } else {
+ LOG_ERROR(Render_Vulkan, "BCn patch failed! Driver code may now crash");
+ }
} else {
- LOG_ERROR(Render_Vulkan, "Patch failed! Driver code may now crash");
+ LOG_WARNING(Render_Vulkan,
+ "BCn texture patching skipped for stability (Android API {} < 28). "
+ "Driver version {}.{} would support patching, but may crash on older Android.",
+ api_level, major, minor);
}
} else if (patch_status == ADRENOTOOLS_BCN_BLOB) {
- LOG_INFO(Render_Vulkan, "Adreno driver supports BCn textures without patches");
+ LOG_INFO(Render_Vulkan, "Adreno driver supports BCn textures natively (no patch needed)");
} else {
- LOG_WARNING(Render_Vulkan, "Adreno driver can't be patched to enable BCn textures");
+ LOG_INFO(Render_Vulkan,
+ "Adreno driver does not support BCn texture patching (Android API {}, Driver {}.{})",
+ api_level, major, minor);
}
#endif
}