From a11bc4a382ebca52bdf0aab1a9474351e8d85cef Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 19 Jan 2021 21:59:53 -0300 Subject: Initial Reaper Setup WIP --- src/video_core/texture_cache/texture_cache.h | 44 +++++++++++++++++++++------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 59b7c678b..45ef155b5 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -353,6 +353,7 @@ private: u64 modification_tick = 0; u64 frame_tick = 0; + typename SlotVector::Iterator deletion_iterator; }; template @@ -373,10 +374,41 @@ TextureCache

::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& // This way the null resource becomes a compile time constant void(slot_image_views.insert(runtime, NullImageParams{})); void(slot_samplers.insert(runtime, sampler_descriptor)); + + deletion_iterator = slot_images.begin(); } template void TextureCache

::TickFrame() { + static constexpr u64 ticks_to_destroy = 120; + int num_iterations = 32; + for (; num_iterations > 0; --num_iterations) { + if (deletion_iterator == slot_images.end()) { + deletion_iterator = slot_images.begin(); + if (deletion_iterator == slot_images.end()) { + break; + } + } + const auto [image_id, image] = *deletion_iterator; + if (image->frame_tick + ticks_to_destroy < frame_tick) { + if (image->IsSafeDownload() && + std::ranges::none_of(image->aliased_images, [&](const AliasedImage& alias) { + return slot_images[alias.id].modification_tick > image->modification_tick; + })) { + auto map = runtime.DownloadStagingBuffer(image->unswizzled_size_bytes); + const auto copies = FullDownloadCopies(image->info); + image->DownloadMemory(map, copies); + runtime.Finish(); + SwizzleImage(gpu_memory, image->gpu_addr, image->info, copies, map.mapped_span); + } + if (True(image->flags & ImageFlagBits::Tracked)) { + UntrackImage(*image); + } + UnregisterImage(image_id); + DeleteImage(image_id); + } + ++deletion_iterator; + } // Tick sentenced resources in this order to ensure they are destroyed in the right order sentenced_images.Tick(); sentenced_framebuffers.Tick(); @@ -568,17 +600,7 @@ template void TextureCache

::DownloadMemory(VAddr cpu_addr, size_t size) { std::vector images; ForEachImageInRegion(cpu_addr, size, [this, &images](ImageId image_id, ImageBase& image) { - // Skip images that were not modified from the GPU - if (False(image.flags & ImageFlagBits::GpuModified)) { - return; - } - // Skip images that .are. modified from the CPU - // We don't want to write sensitive data from the guest - if (True(image.flags & ImageFlagBits::CpuModified)) { - return; - } - if (image.info.num_samples > 1) { - LOG_WARNING(HW_GPU, "MSAA image downloads are not implemented"); + if (!image.IsSafeDownload()) { return; } image.flags &= ~ImageFlagBits::GpuModified; -- cgit v1.2.3 From d8ad6aa18754eeebbcc1a59a683c7c3ff216ebe7 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 13 Jun 2021 15:47:54 +0200 Subject: Reaper: Tune it up to be an smart GC. --- src/video_core/texture_cache/texture_cache.h | 84 +++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 8 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 45ef155b5..cf48f7b02 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -75,6 +75,9 @@ class TextureCache { /// Sampler ID for bugged sampler ids static constexpr SamplerId NULL_SAMPLER_ID{0}; + static constexpr u64 expected_memory = 1024ULL * 1024ULL * 1024ULL; + static constexpr u64 critical_memory = 2 * 1024ULL * 1024ULL * 1024ULL; + using Runtime = typename P::Runtime; using Image = typename P::Image; using ImageAlloc = typename P::ImageAlloc; @@ -333,6 +336,7 @@ private: std::unordered_map, IdentityHash> page_table; bool has_deleted_images = false; + u64 total_used_memory = 0; SlotVector slot_images; SlotVector slot_image_views; @@ -380,8 +384,10 @@ TextureCache

::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& template void TextureCache

::TickFrame() { - static constexpr u64 ticks_to_destroy = 120; - int num_iterations = 32; + const bool high_priority_mode = total_used_memory >= expected_memory; + const bool aggressive_mode = total_used_memory >= critical_memory; + const u64 ticks_to_destroy = high_priority_mode ? 60 : 100; + int num_iterations = aggressive_mode ? 256 : (high_priority_mode ? 128 : 64); for (; num_iterations > 0; --num_iterations) { if (deletion_iterator == slot_images.end()) { deletion_iterator = slot_images.begin(); @@ -390,11 +396,42 @@ void TextureCache

::TickFrame() { } } const auto [image_id, image] = *deletion_iterator; - if (image->frame_tick + ticks_to_destroy < frame_tick) { - if (image->IsSafeDownload() && - std::ranges::none_of(image->aliased_images, [&](const AliasedImage& alias) { - return slot_images[alias.id].modification_tick > image->modification_tick; - })) { + const bool is_alias = True(image->flags & ImageFlagBits::Alias); + if (is_alias && image->aliased_images.size() <= 1) { + ++deletion_iterator; + continue; + } + const bool is_bad_overlap = True(image->flags & ImageFlagBits::BadOverlap); + const bool must_download = image->IsSafeDownload(); + const u64 ticks_needed = is_bad_overlap ? ticks_to_destroy >> 4 : ticks_to_destroy; + const bool should_care = + aggressive_mode || is_bad_overlap || is_alias || (high_priority_mode && !must_download); + if (should_care && image->frame_tick + ticks_needed < frame_tick) { + if (is_bad_overlap) { + const bool overlap_check = + std::ranges::all_of(image->overlapping_images, [&](const ImageId& overlap_id) { + auto& overlap = slot_images[overlap_id]; + return (overlap.frame_tick >= image->frame_tick) && + (overlap.modification_tick > image->modification_tick); + }); + if (!overlap_check) { + ++deletion_iterator; + continue; + } + } + if (!is_bad_overlap && must_download) { + if (is_alias) { + const bool alias_check = + std::ranges::all_of(image->aliased_images, [&](const AliasedImage& alias) { + auto& alias_image = slot_images[alias.id]; + return (alias_image.frame_tick >= image->frame_tick) && + (alias_image.modification_tick > image->modification_tick); + }); + if (!alias_check) { + ++deletion_iterator; + continue; + } + } auto map = runtime.DownloadStagingBuffer(image->unswizzled_size_bytes); const auto copies = FullDownloadCopies(image->info); image->DownloadMemory(map, copies); @@ -406,10 +443,12 @@ void TextureCache

::TickFrame() { } UnregisterImage(image_id); DeleteImage(image_id); + if (is_bad_overlap) { + num_iterations++; + } } ++deletion_iterator; } - // Tick sentenced resources in this order to ensure they are destroyed in the right order sentenced_images.Tick(); sentenced_framebuffers.Tick(); sentenced_image_view.Tick(); @@ -989,6 +1028,7 @@ ImageId TextureCache

::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA std::vector overlap_ids; std::vector left_aliased_ids; std::vector right_aliased_ids; + std::vector bad_overlap_ids; ForEachImageInRegion(cpu_addr, size_bytes, [&](ImageId overlap_id, ImageBase& overlap) { if (info.type != overlap.info.type) { return; @@ -1014,9 +1054,14 @@ ImageId TextureCache

::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA const ImageBase new_image_base(new_info, gpu_addr, cpu_addr); if (IsSubresource(new_info, overlap, gpu_addr, options, broken_views, native_bgr)) { left_aliased_ids.push_back(overlap_id); + overlap.flags |= ImageFlagBits::Alias; } else if (IsSubresource(overlap.info, new_image_base, overlap.gpu_addr, options, broken_views, native_bgr)) { right_aliased_ids.push_back(overlap_id); + overlap.flags |= ImageFlagBits::Alias; + } else { + bad_overlap_ids.push_back(overlap_id); + overlap.flags |= ImageFlagBits::BadOverlap; } }); const ImageId new_image_id = slot_images.insert(runtime, new_info, gpu_addr, cpu_addr); @@ -1044,10 +1089,18 @@ ImageId TextureCache

::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA for (const ImageId aliased_id : right_aliased_ids) { ImageBase& aliased = slot_images[aliased_id]; AddImageAlias(new_image_base, aliased, new_image_id, aliased_id); + new_image.flags |= ImageFlagBits::Alias; } for (const ImageId aliased_id : left_aliased_ids) { ImageBase& aliased = slot_images[aliased_id]; AddImageAlias(aliased, new_image_base, aliased_id, new_image_id); + new_image.flags |= ImageFlagBits::Alias; + } + for (const ImageId aliased_id : bad_overlap_ids) { + ImageBase& aliased = slot_images[aliased_id]; + aliased.overlapping_images.push_back(new_image_id); + new_image.overlapping_images.push_back(aliased_id); + new_image.flags |= ImageFlagBits::BadOverlap; } RegisterImage(new_image_id); return new_image_id; @@ -1217,6 +1270,8 @@ void TextureCache

::RegisterImage(ImageId image_id) { image.flags |= ImageFlagBits::Registered; ForEachPage(image.cpu_addr, image.guest_size_bytes, [this, image_id](u64 page) { page_table[page].push_back(image_id); }); + total_used_memory += + Common::AlignUp(std::max(image.guest_size_bytes, image.unswizzled_size_bytes), 1024); } template @@ -1225,6 +1280,9 @@ void TextureCache

::UnregisterImage(ImageId image_id) { ASSERT_MSG(True(image.flags & ImageFlagBits::Registered), "Trying to unregister an already registered image"); image.flags &= ~ImageFlagBits::Registered; + image.flags &= ~ImageFlagBits::BadOverlap; + total_used_memory -= + Common::AlignUp(std::max(image.guest_size_bytes, image.unswizzled_size_bytes), 1024); ForEachPage(image.cpu_addr, image.guest_size_bytes, [this, image_id](u64 page) { const auto page_it = page_table.find(page); if (page_it == page_table.end()) { @@ -1298,9 +1356,19 @@ void TextureCache

::DeleteImage(ImageId image_id) { std::erase_if(other_image.aliased_images, [image_id](const AliasedImage& other_alias) { return other_alias.id == image_id; }); + other_image.CheckAliasState(); ASSERT_MSG(num_removed_aliases == 1, "Invalid number of removed aliases: {}", num_removed_aliases); } + for (const ImageId overlap_id : image.overlapping_images) { + ImageBase& other_image = slot_images[overlap_id]; + [[maybe_unused]] const size_t num_removed_overlaps = std::erase_if( + other_image.overlapping_images, + [image_id](const ImageId other_overlap_id) { return other_overlap_id == image_id; }); + other_image.CheckBadOverlapState(); + ASSERT_MSG(num_removed_overlaps == 1, "Invalid number of removed overlapps: {}", + num_removed_overlaps); + } for (const ImageViewId image_view_id : image_view_ids) { sentenced_image_view.Push(std::move(slot_image_views[image_view_id])); slot_image_views.erase(image_view_id); -- cgit v1.2.3 From 954ad2a61ee597b67b978b36898f008885d3adb0 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 14 Jun 2021 11:58:36 +0200 Subject: Reaper: Setup settings and final tuning. --- src/video_core/texture_cache/texture_cache.h | 55 +++++++++++++++------------- 1 file changed, 30 insertions(+), 25 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/logging/log.h" +#include "common/settings.h" #include "video_core/compatible_formats.h" #include "video_core/delayed_destruction_ring.h" #include "video_core/dirty_flags.h" @@ -384,6 +385,15 @@ TextureCache

::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& template void TextureCache

::TickFrame() { + const bool enabled_gc = Settings::values.use_caches_gc.GetValue(); + if (!enabled_gc) { + // @Note(Blinkhawk): compile error with SCOPE_EXIT on msvc. + sentenced_images.Tick(); + sentenced_framebuffers.Tick(); + sentenced_image_view.Tick(); + ++frame_tick; + return; + } const bool high_priority_mode = total_used_memory >= expected_memory; const bool aggressive_mode = total_used_memory >= critical_memory; const u64 ticks_to_destroy = high_priority_mode ? 60 : 100; @@ -397,22 +407,20 @@ void TextureCache

::TickFrame() { } const auto [image_id, image] = *deletion_iterator; const bool is_alias = True(image->flags & ImageFlagBits::Alias); - if (is_alias && image->aliased_images.size() <= 1) { - ++deletion_iterator; - continue; - } const bool is_bad_overlap = True(image->flags & ImageFlagBits::BadOverlap); const bool must_download = image->IsSafeDownload(); - const u64 ticks_needed = is_bad_overlap ? ticks_to_destroy >> 4 : ticks_to_destroy; - const bool should_care = - aggressive_mode || is_bad_overlap || is_alias || (high_priority_mode && !must_download); + bool should_care = is_bad_overlap || is_alias || (high_priority_mode && !must_download); + const u64 ticks_needed = + is_bad_overlap + ? ticks_to_destroy >> 4 + : ((should_care && aggressive_mode) ? ticks_to_destroy >> 1 : ticks_to_destroy); + should_care |= aggressive_mode; if (should_care && image->frame_tick + ticks_needed < frame_tick) { if (is_bad_overlap) { const bool overlap_check = std::ranges::all_of(image->overlapping_images, [&](const ImageId& overlap_id) { auto& overlap = slot_images[overlap_id]; - return (overlap.frame_tick >= image->frame_tick) && - (overlap.modification_tick > image->modification_tick); + return overlap.frame_tick >= image->frame_tick; }); if (!overlap_check) { ++deletion_iterator; @@ -420,23 +428,20 @@ void TextureCache

::TickFrame() { } } if (!is_bad_overlap && must_download) { - if (is_alias) { - const bool alias_check = - std::ranges::all_of(image->aliased_images, [&](const AliasedImage& alias) { - auto& alias_image = slot_images[alias.id]; - return (alias_image.frame_tick >= image->frame_tick) && - (alias_image.modification_tick > image->modification_tick); - }); - if (!alias_check) { - ++deletion_iterator; - continue; - } + const bool alias_check = + std::ranges::none_of(image->aliased_images, [&](const AliasedImage& alias) { + auto& alias_image = slot_images[alias.id]; + return (alias_image.frame_tick < image->frame_tick) || + (alias_image.modification_tick < image->modification_tick); + }); + + if (alias_check) { + auto map = runtime.DownloadStagingBuffer(image->unswizzled_size_bytes); + const auto copies = FullDownloadCopies(image->info); + image->DownloadMemory(map, copies); + runtime.Finish(); + SwizzleImage(gpu_memory, image->gpu_addr, image->info, copies, map.mapped_span); } - auto map = runtime.DownloadStagingBuffer(image->unswizzled_size_bytes); - const auto copies = FullDownloadCopies(image->info); - image->DownloadMemory(map, copies); - runtime.Finish(); - SwizzleImage(gpu_memory, image->gpu_addr, image->info, copies, map.mapped_span); } if (True(image->flags & ImageFlagBits::Tracked)) { UntrackImage(*image); -- cgit v1.2.3 From 0dd98842bf87bdd0735d187f8d183ef7593ad747 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 14 Jun 2021 13:42:22 +0200 Subject: Reaper: Address Feedback. --- src/video_core/texture_cache/texture_cache.h | 38 ++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 @@ #include "common/alignment.h" #include "common/common_funcs.h" +#include "common/common_sizes.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/settings.h" @@ -76,8 +77,8 @@ class TextureCache { /// Sampler ID for bugged sampler ids static constexpr SamplerId NULL_SAMPLER_ID{0}; - static constexpr u64 expected_memory = 1024ULL * 1024ULL * 1024ULL; - static constexpr u64 critical_memory = 2 * 1024ULL * 1024ULL * 1024ULL; + static constexpr u64 EXPECTED_MEMORY = Common::Size_1_GB; + static constexpr u64 CRITICAL_MEMORY = Common::Size_2_GB; using Runtime = typename P::Runtime; using Image = typename P::Image; @@ -394,8 +395,8 @@ void TextureCache

::TickFrame() { ++frame_tick; return; } - const bool high_priority_mode = total_used_memory >= expected_memory; - const bool aggressive_mode = total_used_memory >= critical_memory; + const bool high_priority_mode = total_used_memory >= EXPECTED_MEMORY; + const bool aggressive_mode = total_used_memory >= CRITICAL_MEMORY; const u64 ticks_to_destroy = high_priority_mode ? 60 : 100; int num_iterations = aggressive_mode ? 256 : (high_priority_mode ? 128 : 64); for (; num_iterations > 0; --num_iterations) { @@ -405,7 +406,8 @@ void TextureCache

::TickFrame() { break; } } - const auto [image_id, image] = *deletion_iterator; + auto [image_id, image_tmp] = *deletion_iterator; + Image* image = image_tmp; // fix clang error. const bool is_alias = True(image->flags & ImageFlagBits::Alias); const bool is_bad_overlap = True(image->flags & ImageFlagBits::BadOverlap); const bool must_download = image->IsSafeDownload(); @@ -417,8 +419,8 @@ void TextureCache

::TickFrame() { should_care |= aggressive_mode; if (should_care && image->frame_tick + ticks_needed < frame_tick) { if (is_bad_overlap) { - const bool overlap_check = - std::ranges::all_of(image->overlapping_images, [&](const ImageId& overlap_id) { + const bool overlap_check = std::ranges::all_of( + image->overlapping_images, [&, image](const ImageId& overlap_id) { auto& overlap = slot_images[overlap_id]; return overlap.frame_tick >= image->frame_tick; }); @@ -428,8 +430,8 @@ void TextureCache

::TickFrame() { } } if (!is_bad_overlap && must_download) { - const bool alias_check = - std::ranges::none_of(image->aliased_images, [&](const AliasedImage& alias) { + const bool alias_check = std::ranges::none_of( + image->aliased_images, [&, image](const AliasedImage& alias) { auto& alias_image = slot_images[alias.id]; return (alias_image.frame_tick < image->frame_tick) || (alias_image.modification_tick < image->modification_tick); @@ -1275,8 +1277,13 @@ void TextureCache

::RegisterImage(ImageId image_id) { image.flags |= ImageFlagBits::Registered; ForEachPage(image.cpu_addr, image.guest_size_bytes, [this, image_id](u64 page) { page_table[page].push_back(image_id); }); - total_used_memory += - Common::AlignUp(std::max(image.guest_size_bytes, image.unswizzled_size_bytes), 1024); + u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes); + if ((IsPixelFormatASTC(image.info.format) && + True(image.flags & ImageFlagBits::AcceleratedUpload)) || + True(image.flags & ImageFlagBits::Converted)) { + tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); + } + total_used_memory += Common::AlignUp(tentative_size, 1024); } template @@ -1286,8 +1293,13 @@ void TextureCache

::UnregisterImage(ImageId image_id) { "Trying to unregister an already registered image"); image.flags &= ~ImageFlagBits::Registered; image.flags &= ~ImageFlagBits::BadOverlap; - total_used_memory -= - Common::AlignUp(std::max(image.guest_size_bytes, image.unswizzled_size_bytes), 1024); + u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes); + if ((IsPixelFormatASTC(image.info.format) && + True(image.flags & ImageFlagBits::AcceleratedUpload)) || + True(image.flags & ImageFlagBits::Converted)) { + tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); + } + total_used_memory -= Common::AlignUp(tentative_size, 1024); ForEachPage(image.cpu_addr, image.guest_size_bytes, [this, image_id](u64 page) { const auto page_it = page_table.find(page); if (page_it == page_table.end()) { -- cgit v1.2.3 From ca6f47c6862a24dfa78f3d25c8b7819636218cdd Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 17 Jun 2021 00:29:48 +0200 Subject: Reaper: Change memory restrictions on TC depending on host memory on VK. --- src/video_core/texture_cache/texture_cache.h | 46 +++++++++++++++++++--------- 1 file changed, 31 insertions(+), 15 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 8ff6f4e01..64b576cbc 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -71,14 +71,16 @@ class TextureCache { static constexpr bool FRAMEBUFFER_BLITS = P::FRAMEBUFFER_BLITS; /// True when some copies have to be emulated static constexpr bool HAS_EMULATED_COPIES = P::HAS_EMULATED_COPIES; + /// True when the API can provide info about the memory of the device. + static constexpr bool HAS_DEVICE_MEMORY_INFO = P::HAS_DEVICE_MEMORY_INFO; /// Image view ID for null descriptors static constexpr ImageViewId NULL_IMAGE_VIEW_ID{0}; /// Sampler ID for bugged sampler ids static constexpr SamplerId NULL_SAMPLER_ID{0}; - static constexpr u64 EXPECTED_MEMORY = Common::Size_1_GB; - static constexpr u64 CRITICAL_MEMORY = Common::Size_2_GB; + static constexpr u64 DEFAULT_EXPECTED_MEMORY = Common::Size_1_GB; + static constexpr u64 DEFAULT_CRITICAL_MEMORY = Common::Size_2_GB; using Runtime = typename P::Runtime; using Image = typename P::Image; @@ -108,6 +110,9 @@ public: /// Notify the cache that a new frame has been queued void TickFrame(); + /// Runs the Garbage Collector. + void RunGarbageCollector(); + /// Return a constant reference to the given image view id [[nodiscard]] const ImageView& GetImageView(ImageViewId id) const noexcept; @@ -339,6 +344,8 @@ private: bool has_deleted_images = false; u64 total_used_memory = 0; + u64 expected_memory; + u64 critical_memory; SlotVector slot_images; SlotVector slot_image_views; @@ -382,21 +389,23 @@ TextureCache

::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& void(slot_samplers.insert(runtime, sampler_descriptor)); deletion_iterator = slot_images.begin(); + + if constexpr (HAS_DEVICE_MEMORY_INFO) { + const auto device_memory = runtime.GetDeviceLocalMemory(); + const u64 possible_expected_memory = (device_memory * 3) / 10; + const u64 possible_critical_memory = (device_memory * 6) / 10; + expected_memory = std::max(possible_expected_memory, DEFAULT_EXPECTED_MEMORY); + critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY); + } else { + expected_memory = DEFAULT_EXPECTED_MEMORY; + critical_memory = DEFAULT_CRITICAL_MEMORY; + } } template -void TextureCache

::TickFrame() { - const bool enabled_gc = Settings::values.use_caches_gc.GetValue(); - if (!enabled_gc) { - // @Note(Blinkhawk): compile error with SCOPE_EXIT on msvc. - sentenced_images.Tick(); - sentenced_framebuffers.Tick(); - sentenced_image_view.Tick(); - ++frame_tick; - return; - } - const bool high_priority_mode = total_used_memory >= EXPECTED_MEMORY; - const bool aggressive_mode = total_used_memory >= CRITICAL_MEMORY; +void TextureCache

::RunGarbageCollector() { + const bool high_priority_mode = total_used_memory >= expected_memory; + const bool aggressive_mode = total_used_memory >= critical_memory; const u64 ticks_to_destroy = high_priority_mode ? 60 : 100; int num_iterations = aggressive_mode ? 256 : (high_priority_mode ? 128 : 64); for (; num_iterations > 0; --num_iterations) { @@ -451,11 +460,18 @@ void TextureCache

::TickFrame() { UnregisterImage(image_id); DeleteImage(image_id); if (is_bad_overlap) { - num_iterations++; + ++num_iterations; } } ++deletion_iterator; } +} + +template +void TextureCache

::TickFrame() { + if (Settings::values.use_caches_gc.GetValue()) { + RunGarbageCollector(); + } sentenced_images.Tick(); sentenced_framebuffers.Tick(); sentenced_image_view.Tick(); -- cgit v1.2.3 From 569a1962c093319c89079c52b5cb6fff139c8174 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 20 Jun 2021 17:07:17 +0200 Subject: Reaper: Guarantee correct deletion. --- src/video_core/texture_cache/texture_cache.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 64b576cbc..6ee654dc1 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -397,8 +397,9 @@ TextureCache

::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& expected_memory = std::max(possible_expected_memory, DEFAULT_EXPECTED_MEMORY); critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY); } else { - expected_memory = DEFAULT_EXPECTED_MEMORY; - critical_memory = DEFAULT_CRITICAL_MEMORY; + // on OGL we can be more conservatives as the driver takes care. + expected_memory = DEFAULT_EXPECTED_MEMORY + Common::Size_512_MB; + critical_memory = DEFAULT_CRITICAL_MEMORY + Common::Size_1_GB; } } -- cgit v1.2.3 From f9b940a442d50875d2b45a0f2f380ccad88670da Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 22 Jun 2021 22:07:17 +0200 Subject: Reaper: Set minimum cleaning limit on OGL. --- src/video_core/texture_cache/texture_cache.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 6ee654dc1..e7f8478b4 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -344,6 +344,7 @@ private: bool has_deleted_images = false; u64 total_used_memory = 0; + u64 minimum_memory; u64 expected_memory; u64 critical_memory; @@ -396,10 +397,12 @@ TextureCache

::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& const u64 possible_critical_memory = (device_memory * 6) / 10; expected_memory = std::max(possible_expected_memory, DEFAULT_EXPECTED_MEMORY); critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY); + minimum_memory = 0; } else { // on OGL we can be more conservatives as the driver takes care. expected_memory = DEFAULT_EXPECTED_MEMORY + Common::Size_512_MB; critical_memory = DEFAULT_CRITICAL_MEMORY + Common::Size_1_GB; + minimum_memory = expected_memory; } } @@ -470,7 +473,7 @@ void TextureCache

::RunGarbageCollector() { template void TextureCache

::TickFrame() { - if (Settings::values.use_caches_gc.GetValue()) { + if (Settings::values.use_caches_gc.GetValue() && total_used_memory > minimum_memory) { RunGarbageCollector(); } sentenced_images.Tick(); -- cgit v1.2.3