summaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-06-14 11:58:36 +0200
committerGravatar Fernando Sahmkow2021-06-16 21:35:03 +0200
commit954ad2a61ee597b67b978b36898f008885d3adb0 (patch)
tree4d0a3600e090c942bc3f553fdbdd7c24229a985e /src/video_core/texture_cache
parentReaper: Tune it up to be an smart GC. (diff)
downloadyuzu-954ad2a61ee597b67b978b36898f008885d3adb0.tar.gz
yuzu-954ad2a61ee597b67b978b36898f008885d3adb0.tar.xz
yuzu-954ad2a61ee597b67b978b36898f008885d3adb0.zip
Reaper: Setup settings and final tuning.
Diffstat (limited to 'src/video_core/texture_cache')
-rw-r--r--src/video_core/texture_cache/image_base.h8
-rw-r--r--src/video_core/texture_cache/texture_cache.h55
2 files changed, 34 insertions, 29 deletions
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h
index 40c047ea1..e326cab71 100644
--- a/src/video_core/texture_cache/image_base.h
+++ b/src/video_core/texture_cache/image_base.h
@@ -27,10 +27,10 @@ enum class ImageFlagBits : u32 {
27 Picked = 1 << 7, ///< Temporary flag to mark the image as picked 27 Picked = 1 << 7, ///< Temporary flag to mark the image as picked
28 28
29 // Garbage Collection Flags 29 // Garbage Collection Flags
30 BadOverlap = 1 << 8, ///< This image overlaps other but doesn't fit, has higher 30 BadOverlap = 1 << 8, ///< This image overlaps other but doesn't fit, has higher
31 ///< garbage collection priority 31 ///< garbage collection priority
32 Alias = 1 << 9, ///< This image has aliases and has priority on garbage 32 Alias = 1 << 9, ///< This image has aliases and has priority on garbage
33 ///< collection 33 ///< collection
34}; 34};
35DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits) 35DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)
36 36
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index cf48f7b02..8685f4418 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -22,6 +22,7 @@
22#include "common/common_funcs.h" 22#include "common/common_funcs.h"
23#include "common/common_types.h" 23#include "common/common_types.h"
24#include "common/logging/log.h" 24#include "common/logging/log.h"
25#include "common/settings.h"
25#include "video_core/compatible_formats.h" 26#include "video_core/compatible_formats.h"
26#include "video_core/delayed_destruction_ring.h" 27#include "video_core/delayed_destruction_ring.h"
27#include "video_core/dirty_flags.h" 28#include "video_core/dirty_flags.h"
@@ -384,6 +385,15 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
384 385
385template <class P> 386template <class P>
386void TextureCache<P>::TickFrame() { 387void TextureCache<P>::TickFrame() {
388 const bool enabled_gc = Settings::values.use_caches_gc.GetValue();
389 if (!enabled_gc) {
390 // @Note(Blinkhawk): compile error with SCOPE_EXIT on msvc.
391 sentenced_images.Tick();
392 sentenced_framebuffers.Tick();
393 sentenced_image_view.Tick();
394 ++frame_tick;
395 return;
396 }
387 const bool high_priority_mode = total_used_memory >= expected_memory; 397 const bool high_priority_mode = total_used_memory >= expected_memory;
388 const bool aggressive_mode = total_used_memory >= critical_memory; 398 const bool aggressive_mode = total_used_memory >= critical_memory;
389 const u64 ticks_to_destroy = high_priority_mode ? 60 : 100; 399 const u64 ticks_to_destroy = high_priority_mode ? 60 : 100;
@@ -397,22 +407,20 @@ void TextureCache<P>::TickFrame() {
397 } 407 }
398 const auto [image_id, image] = *deletion_iterator; 408 const auto [image_id, image] = *deletion_iterator;
399 const bool is_alias = True(image->flags & ImageFlagBits::Alias); 409 const bool is_alias = True(image->flags & ImageFlagBits::Alias);
400 if (is_alias && image->aliased_images.size() <= 1) {
401 ++deletion_iterator;
402 continue;
403 }
404 const bool is_bad_overlap = True(image->flags & ImageFlagBits::BadOverlap); 410 const bool is_bad_overlap = True(image->flags & ImageFlagBits::BadOverlap);
405 const bool must_download = image->IsSafeDownload(); 411 const bool must_download = image->IsSafeDownload();
406 const u64 ticks_needed = is_bad_overlap ? ticks_to_destroy >> 4 : ticks_to_destroy; 412 bool should_care = is_bad_overlap || is_alias || (high_priority_mode && !must_download);
407 const bool should_care = 413 const u64 ticks_needed =
408 aggressive_mode || is_bad_overlap || is_alias || (high_priority_mode && !must_download); 414 is_bad_overlap
415 ? ticks_to_destroy >> 4
416 : ((should_care && aggressive_mode) ? ticks_to_destroy >> 1 : ticks_to_destroy);
417 should_care |= aggressive_mode;
409 if (should_care && image->frame_tick + ticks_needed < frame_tick) { 418 if (should_care && image->frame_tick + ticks_needed < frame_tick) {
410 if (is_bad_overlap) { 419 if (is_bad_overlap) {
411 const bool overlap_check = 420 const bool overlap_check =
412 std::ranges::all_of(image->overlapping_images, [&](const ImageId& overlap_id) { 421 std::ranges::all_of(image->overlapping_images, [&](const ImageId& overlap_id) {
413 auto& overlap = slot_images[overlap_id]; 422 auto& overlap = slot_images[overlap_id];
414 return (overlap.frame_tick >= image->frame_tick) && 423 return overlap.frame_tick >= image->frame_tick;
415 (overlap.modification_tick > image->modification_tick);
416 }); 424 });
417 if (!overlap_check) { 425 if (!overlap_check) {
418 ++deletion_iterator; 426 ++deletion_iterator;
@@ -420,23 +428,20 @@ void TextureCache<P>::TickFrame() {
420 } 428 }
421 } 429 }
422 if (!is_bad_overlap && must_download) { 430 if (!is_bad_overlap && must_download) {
423 if (is_alias) { 431 const bool alias_check =
424 const bool alias_check = 432 std::ranges::none_of(image->aliased_images, [&](const AliasedImage& alias) {
425 std::ranges::all_of(image->aliased_images, [&](const AliasedImage& alias) { 433 auto& alias_image = slot_images[alias.id];
426 auto& alias_image = slot_images[alias.id]; 434 return (alias_image.frame_tick < image->frame_tick) ||
427 return (alias_image.frame_tick >= image->frame_tick) && 435 (alias_image.modification_tick < image->modification_tick);
428 (alias_image.modification_tick > image->modification_tick); 436 });
429 }); 437
430 if (!alias_check) { 438 if (alias_check) {
431 ++deletion_iterator; 439 auto map = runtime.DownloadStagingBuffer(image->unswizzled_size_bytes);
432 continue; 440 const auto copies = FullDownloadCopies(image->info);
433 } 441 image->DownloadMemory(map, copies);
442 runtime.Finish();
443 SwizzleImage(gpu_memory, image->gpu_addr, image->info, copies, map.mapped_span);
434 } 444 }
435 auto map = runtime.DownloadStagingBuffer(image->unswizzled_size_bytes);
436 const auto copies = FullDownloadCopies(image->info);
437 image->DownloadMemory(map, copies);
438 runtime.Finish();
439 SwizzleImage(gpu_memory, image->gpu_addr, image->info, copies, map.mapped_span);
440 } 445 }
441 if (True(image->flags & ImageFlagBits::Tracked)) { 446 if (True(image->flags & ImageFlagBits::Tracked)) {
442 UntrackImage(*image); 447 UntrackImage(*image);