::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManag
"VRAM Management initialized: limit={}MB, expected={}MB, critical={}MB, gc_level={}",
vram_limit_bytes / 1_MiB, expected_memory / 1_MiB, critical_memory / 1_MiB,
static_cast ::RunGarbageCollector() {
return false;
}
- // FIXED: VRAM leak prevention - Prioritize sparse textures if enabled
+ // FIXED: Android Adreno 740 native ASTC eviction
+ // Prioritize sparse textures if enabled
const bool is_sparse = True(image.flags & ImageFlagBits::Sparse);
- const u64 image_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
+ // Use compressed size for eviction on Android with native ASTC support
+ const u64 image_size = use_compressed_eviction
+ ? image.compressed_size_bytes
+ : std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
const bool is_large = image_size >= LARGE_TEXTURE_THRESHOLD;
// Skip costly loads unless aggressive/emergency mode, unless it's a large sparse texture
@@ -426,7 +456,11 @@ u64 TextureCache ::EvictToFreeMemory(u64 target_bytes) {
return false;
}
- const u64 image_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
+ // FIXED: Android Adreno 740 native ASTC eviction
+ // Use compressed size for eviction on Android with native ASTC support
+ const u64 image_size = use_compressed_eviction
+ ? image.compressed_size_bytes
+ : std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
if (True(image.flags & ImageFlagBits::Tracked)) {
UntrackImage(image, image_id);
@@ -455,7 +489,11 @@ u64 TextureCache ::EvictSparseTexturesPriority(u64 target_bytes) {
auto& image = slot_images[image_id];
if (True(image.flags & ImageFlagBits::Sparse) &&
False(image.flags & ImageFlagBits::IsDecoding)) {
- const u64 size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
+ // FIXED: Android Adreno 740 native ASTC eviction
+ // Use compressed size for eviction on Android with native ASTC support
+ const u64 size = use_compressed_eviction
+ ? image.compressed_size_bytes
+ : std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
sparse_textures.emplace_back(image_id, size);
}
return false;
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 70a91e5d4..849507fdf 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -506,6 +506,10 @@ public:
u64 last_gc_frame = 0; // Last frame GC was run
bool emergency_gc_triggered = false; // Emergency GC flag
+ // FIXED: Android Adreno 740 native ASTC eviction
+ // When true, use compressed_size_bytes for eviction calculations on Android + Adreno 7xx
+ bool use_compressed_eviction = false;
+
struct BufferDownload {
GPUVAddr address;
size_t size;
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index f1318a045..e89108300 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -441,6 +441,22 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
nvidia_arch = GetNvidiaArchitecture(physical, supported_extensions);
}
+ // FIXED: Android Adreno 740 native ASTC eviction
+ // Detect Adreno GPUs and check for native ASTC support
+ is_adreno = is_qualcomm || is_turnip;
+ if (is_adreno) {
+ // Adreno 7xx series devices (Adreno 730, 740, 750+) support native ASTC
+ // Device IDs: 0x43050a01 (SD8 Gen 2), 0x43052c01 (SD8 Elite), etc.
+ // Generally 0x43050000+ indicates Adreno 7xx series
+ is_adreno_7xx_or_newer = (device_id >= 0x43050000);
+ supports_native_astc = is_adreno_7xx_or_newer && is_optimal_astc_supported;
+
+ if (supports_native_astc) {
+ LOG_INFO(Render_Vulkan,
+ "Adreno 7xx detected — using native ASTC, eviction on compressed size");
+ }
+ }
+
SetupFamilies(surface);
const auto queue_cis = GetDeviceQueueCreateInfos();
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index 03b19a084..49c4b238c 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -722,6 +722,22 @@ public:
return nvidia_arch;
}
+ // FIXED: Android Adreno 740 native ASTC eviction
+ /// Returns true if the device is an Adreno GPU (Qualcomm or Turnip driver)
+ [[nodiscard]] bool IsAdrenoGpu() const noexcept {
+ return is_adreno;
+ }
+
+ /// Returns true if the device is Adreno 7xx series or newer (Adreno 730, 740, 750+)
+ [[nodiscard]] bool IsAdreno7xxOrNewer() const noexcept {
+ return is_adreno_7xx_or_newer;
+ }
+
+ /// Returns true if the device supports native ASTC decoding and compressed size eviction
+ [[nodiscard]] bool SupportsNativeAstc() const noexcept {
+ return supports_native_astc;
+ }
+
private:
/// Checks if the physical device is suitable and configures the object state
/// with all necessary info about its properties.
@@ -843,6 +859,11 @@ private:
u32 sets_per_pool{}; ///< Sets per Description Pool
NvidiaArchitecture nvidia_arch{NvidiaArchitecture::Arch_AmpereOrNewer};
+ // FIXED: Android Adreno 740 native ASTC eviction
+ bool is_adreno{}; ///< Is Adreno GPU (Qualcomm or Turnip driver)
+ bool is_adreno_7xx_or_newer{}; ///< Is Adreno 7xx series or newer
+ bool supports_native_astc{}; ///< Supports native ASTC with compressed eviction
+
// Telemetry parameters
std::set