summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/common_sizes.h1
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h13
-rw-r--r--src/video_core/surface.cpp7
-rw-r--r--src/video_core/surface.h2
-rw-r--r--src/video_core/texture_cache/texture_cache.h38
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.ui2
6 files changed, 43 insertions, 20 deletions
diff --git a/src/common/common_sizes.h b/src/common/common_sizes.h
index 7e9fd968b..d07b7ee5a 100644
--- a/src/common/common_sizes.h
+++ b/src/common/common_sizes.h
@@ -24,6 +24,7 @@ enum : u64 {
24 Size_128_MB = 128ULL * Size_1_MB, 24 Size_128_MB = 128ULL * Size_1_MB,
25 Size_448_MB = 448ULL * Size_1_MB, 25 Size_448_MB = 448ULL * Size_1_MB,
26 Size_507_MB = 507ULL * Size_1_MB, 26 Size_507_MB = 507ULL * Size_1_MB,
27 Size_512_MB = 512ULL * Size_1_MB,
27 Size_562_MB = 562ULL * Size_1_MB, 28 Size_562_MB = 562ULL * Size_1_MB,
28 Size_1554_MB = 1554ULL * Size_1_MB, 29 Size_1554_MB = 1554ULL * Size_1_MB,
29 Size_2048_MB = 2048ULL * Size_1_MB, 30 Size_2048_MB = 2048ULL * Size_1_MB,
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index a8fb21d92..82a4a10d6 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -16,6 +16,7 @@
16 16
17#include <boost/container/small_vector.hpp> 17#include <boost/container/small_vector.hpp>
18 18
19#include "common/common_sizes.h"
19#include "common/common_types.h" 20#include "common/common_types.h"
20#include "common/div_ceil.h" 21#include "common/div_ceil.h"
21#include "common/microprofile.h" 22#include "common/microprofile.h"
@@ -65,8 +66,8 @@ class BufferCache {
65 66
66 static constexpr BufferId NULL_BUFFER_ID{0}; 67 static constexpr BufferId NULL_BUFFER_ID{0};
67 68
68 static constexpr u64 expected_memory = 512ULL * 1024ULL * 1024ULL; 69 static constexpr u64 EXPECTED_MEMORY = Common::Size_512_MB;
69 static constexpr u64 critical_memory = 1024ULL * 1024ULL * 1024ULL; 70 static constexpr u64 CRITICAL_MEMORY = Common::Size_1_GB;
70 71
71 using Maxwell = Tegra::Engines::Maxwell3D::Regs; 72 using Maxwell = Tegra::Engines::Maxwell3D::Regs;
72 73
@@ -368,13 +369,13 @@ void BufferCache<P>::TickFrame() {
368 const bool skip_preferred = hits * 256 < shots * 251; 369 const bool skip_preferred = hits * 256 < shots * 251;
369 uniform_buffer_skip_cache_size = skip_preferred ? DEFAULT_SKIP_CACHE_SIZE : 0; 370 uniform_buffer_skip_cache_size = skip_preferred ? DEFAULT_SKIP_CACHE_SIZE : 0;
370 371
371 const bool activate_gc = enabled_gc && total_used_memory >= expected_memory; 372 const bool activate_gc = enabled_gc && total_used_memory >= EXPECTED_MEMORY;
372 if (!activate_gc) { 373 if (!activate_gc) {
373 return; 374 return;
374 } 375 }
375 const bool agressive_gc = total_used_memory >= critical_memory; 376 const bool aggressive_gc = total_used_memory >= CRITICAL_MEMORY;
376 const u64 ticks_to_destroy = agressive_gc ? 60 : 120; 377 const u64 ticks_to_destroy = aggressive_gc ? 60 : 120;
377 int num_iterations = agressive_gc ? 64 : 32; 378 int num_iterations = aggressive_gc ? 64 : 32;
378 for (; num_iterations > 0; --num_iterations) { 379 for (; num_iterations > 0; --num_iterations) {
379 if (deletion_iterator == slot_buffers.end()) { 380 if (deletion_iterator == slot_buffers.end()) {
380 deletion_iterator = slot_buffers.begin(); 381 deletion_iterator = slot_buffers.begin();
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index 6308aef94..eb1746265 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -283,4 +283,11 @@ std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
283 return {DefaultBlockWidth(format), DefaultBlockHeight(format)}; 283 return {DefaultBlockWidth(format), DefaultBlockHeight(format)};
284} 284}
285 285
286u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format) {
287 constexpr u64 RGBA8_PIXEL_SIZE = 4;
288 const u64 base_block_size = static_cast<u64>(DefaultBlockWidth(format)) *
289 static_cast<u64>(DefaultBlockHeight(format)) * RGBA8_PIXEL_SIZE;
290 return (base_size * base_block_size) / BytesPerBlock(format);
291}
292
286} // namespace VideoCore::Surface 293} // namespace VideoCore::Surface
diff --git a/src/video_core/surface.h b/src/video_core/surface.h
index c40ab89d0..1503db81f 100644
--- a/src/video_core/surface.h
+++ b/src/video_core/surface.h
@@ -462,4 +462,6 @@ bool IsPixelFormatSRGB(PixelFormat format);
462 462
463std::pair<u32, u32> GetASTCBlockSize(PixelFormat format); 463std::pair<u32, u32> GetASTCBlockSize(PixelFormat format);
464 464
465u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format);
466
465} // namespace VideoCore::Surface 467} // namespace VideoCore::Surface
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 8685f4418..8ff6f4e01 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -20,6 +20,7 @@
20 20
21#include "common/alignment.h" 21#include "common/alignment.h"
22#include "common/common_funcs.h" 22#include "common/common_funcs.h"
23#include "common/common_sizes.h"
23#include "common/common_types.h" 24#include "common/common_types.h"
24#include "common/logging/log.h" 25#include "common/logging/log.h"
25#include "common/settings.h" 26#include "common/settings.h"
@@ -76,8 +77,8 @@ class TextureCache {
76 /// Sampler ID for bugged sampler ids 77 /// Sampler ID for bugged sampler ids
77 static constexpr SamplerId NULL_SAMPLER_ID{0}; 78 static constexpr SamplerId NULL_SAMPLER_ID{0};
78 79
79 static constexpr u64 expected_memory = 1024ULL * 1024ULL * 1024ULL; 80 static constexpr u64 EXPECTED_MEMORY = Common::Size_1_GB;
80 static constexpr u64 critical_memory = 2 * 1024ULL * 1024ULL * 1024ULL; 81 static constexpr u64 CRITICAL_MEMORY = Common::Size_2_GB;
81 82
82 using Runtime = typename P::Runtime; 83 using Runtime = typename P::Runtime;
83 using Image = typename P::Image; 84 using Image = typename P::Image;
@@ -394,8 +395,8 @@ void TextureCache<P>::TickFrame() {
394 ++frame_tick; 395 ++frame_tick;
395 return; 396 return;
396 } 397 }
397 const bool high_priority_mode = total_used_memory >= expected_memory; 398 const bool high_priority_mode = total_used_memory >= EXPECTED_MEMORY;
398 const bool aggressive_mode = total_used_memory >= critical_memory; 399 const bool aggressive_mode = total_used_memory >= CRITICAL_MEMORY;
399 const u64 ticks_to_destroy = high_priority_mode ? 60 : 100; 400 const u64 ticks_to_destroy = high_priority_mode ? 60 : 100;
400 int num_iterations = aggressive_mode ? 256 : (high_priority_mode ? 128 : 64); 401 int num_iterations = aggressive_mode ? 256 : (high_priority_mode ? 128 : 64);
401 for (; num_iterations > 0; --num_iterations) { 402 for (; num_iterations > 0; --num_iterations) {
@@ -405,7 +406,8 @@ void TextureCache<P>::TickFrame() {
405 break; 406 break;
406 } 407 }
407 } 408 }
408 const auto [image_id, image] = *deletion_iterator; 409 auto [image_id, image_tmp] = *deletion_iterator;
410 Image* image = image_tmp; // fix clang error.
409 const bool is_alias = True(image->flags & ImageFlagBits::Alias); 411 const bool is_alias = True(image->flags & ImageFlagBits::Alias);
410 const bool is_bad_overlap = True(image->flags & ImageFlagBits::BadOverlap); 412 const bool is_bad_overlap = True(image->flags & ImageFlagBits::BadOverlap);
411 const bool must_download = image->IsSafeDownload(); 413 const bool must_download = image->IsSafeDownload();
@@ -417,8 +419,8 @@ void TextureCache<P>::TickFrame() {
417 should_care |= aggressive_mode; 419 should_care |= aggressive_mode;
418 if (should_care && image->frame_tick + ticks_needed < frame_tick) { 420 if (should_care && image->frame_tick + ticks_needed < frame_tick) {
419 if (is_bad_overlap) { 421 if (is_bad_overlap) {
420 const bool overlap_check = 422 const bool overlap_check = std::ranges::all_of(
421 std::ranges::all_of(image->overlapping_images, [&](const ImageId& overlap_id) { 423 image->overlapping_images, [&, image](const ImageId& overlap_id) {
422 auto& overlap = slot_images[overlap_id]; 424 auto& overlap = slot_images[overlap_id];
423 return overlap.frame_tick >= image->frame_tick; 425 return overlap.frame_tick >= image->frame_tick;
424 }); 426 });
@@ -428,8 +430,8 @@ void TextureCache<P>::TickFrame() {
428 } 430 }
429 } 431 }
430 if (!is_bad_overlap && must_download) { 432 if (!is_bad_overlap && must_download) {
431 const bool alias_check = 433 const bool alias_check = std::ranges::none_of(
432 std::ranges::none_of(image->aliased_images, [&](const AliasedImage& alias) { 434 image->aliased_images, [&, image](const AliasedImage& alias) {
433 auto& alias_image = slot_images[alias.id]; 435 auto& alias_image = slot_images[alias.id];
434 return (alias_image.frame_tick < image->frame_tick) || 436 return (alias_image.frame_tick < image->frame_tick) ||
435 (alias_image.modification_tick < image->modification_tick); 437 (alias_image.modification_tick < image->modification_tick);
@@ -1275,8 +1277,13 @@ void TextureCache<P>::RegisterImage(ImageId image_id) {
1275 image.flags |= ImageFlagBits::Registered; 1277 image.flags |= ImageFlagBits::Registered;
1276 ForEachPage(image.cpu_addr, image.guest_size_bytes, 1278 ForEachPage(image.cpu_addr, image.guest_size_bytes,
1277 [this, image_id](u64 page) { page_table[page].push_back(image_id); }); 1279 [this, image_id](u64 page) { page_table[page].push_back(image_id); });
1278 total_used_memory += 1280 u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
1279 Common::AlignUp(std::max(image.guest_size_bytes, image.unswizzled_size_bytes), 1024); 1281 if ((IsPixelFormatASTC(image.info.format) &&
1282 True(image.flags & ImageFlagBits::AcceleratedUpload)) ||
1283 True(image.flags & ImageFlagBits::Converted)) {
1284 tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format);
1285 }
1286 total_used_memory += Common::AlignUp(tentative_size, 1024);
1280} 1287}
1281 1288
1282template <class P> 1289template <class P>
@@ -1286,8 +1293,13 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
1286 "Trying to unregister an already registered image"); 1293 "Trying to unregister an already registered image");
1287 image.flags &= ~ImageFlagBits::Registered; 1294 image.flags &= ~ImageFlagBits::Registered;
1288 image.flags &= ~ImageFlagBits::BadOverlap; 1295 image.flags &= ~ImageFlagBits::BadOverlap;
1289 total_used_memory -= 1296 u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
1290 Common::AlignUp(std::max(image.guest_size_bytes, image.unswizzled_size_bytes), 1024); 1297 if ((IsPixelFormatASTC(image.info.format) &&
1298 True(image.flags & ImageFlagBits::AcceleratedUpload)) ||
1299 True(image.flags & ImageFlagBits::Converted)) {
1300 tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format);
1301 }
1302 total_used_memory -= Common::AlignUp(tentative_size, 1024);
1291 ForEachPage(image.cpu_addr, image.guest_size_bytes, [this, image_id](u64 page) { 1303 ForEachPage(image.cpu_addr, image.guest_size_bytes, [this, image_id](u64 page) {
1292 const auto page_it = page_table.find(page); 1304 const auto page_it = page_table.find(page);
1293 if (page_it == page_table.end()) { 1305 if (page_it == page_table.end()) {
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui
index 3566e9bfa..4bab3d074 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.ui
+++ b/src/yuzu/configuration/configure_graphics_advanced.ui
@@ -106,7 +106,7 @@
106 <item> 106 <item>
107 <widget class="QCheckBox" name="use_caches_gc"> 107 <widget class="QCheckBox" name="use_caches_gc">
108 <property name="toolTip"> 108 <property name="toolTip">
109 <string>Enables garbage collection for the GPU caches, this will try to keep VRAM within 3-4Gb and flush least used textures/buffers. This option may be unsafe on a few games</string> 109 <string>Enables garbage collection for the GPU caches, this will try to keep VRAM within 3-4 GB by flushing the least used textures/buffers. May cause issues in a few games.</string>
110 </property> 110 </property>
111 <property name="text"> 111 <property name="text">
112 <string>Enable GPU caches garbage collection (unsafe)</string> 112 <string>Enable GPU caches garbage collection (unsafe)</string>