Reaper: Address Feedback.
This commit is contained in:
parent
954ad2a61e
commit
0dd98842bf
6 changed files with 43 additions and 20 deletions
|
@ -24,6 +24,7 @@ enum : u64 {
|
||||||
Size_128_MB = 128ULL * Size_1_MB,
|
Size_128_MB = 128ULL * Size_1_MB,
|
||||||
Size_448_MB = 448ULL * Size_1_MB,
|
Size_448_MB = 448ULL * Size_1_MB,
|
||||||
Size_507_MB = 507ULL * Size_1_MB,
|
Size_507_MB = 507ULL * Size_1_MB,
|
||||||
|
Size_512_MB = 512ULL * Size_1_MB,
|
||||||
Size_562_MB = 562ULL * Size_1_MB,
|
Size_562_MB = 562ULL * Size_1_MB,
|
||||||
Size_1554_MB = 1554ULL * Size_1_MB,
|
Size_1554_MB = 1554ULL * Size_1_MB,
|
||||||
Size_2048_MB = 2048ULL * Size_1_MB,
|
Size_2048_MB = 2048ULL * Size_1_MB,
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
|
||||||
|
#include "common/common_sizes.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/div_ceil.h"
|
#include "common/div_ceil.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
|
@ -65,8 +66,8 @@ class BufferCache {
|
||||||
|
|
||||||
static constexpr BufferId NULL_BUFFER_ID{0};
|
static constexpr BufferId NULL_BUFFER_ID{0};
|
||||||
|
|
||||||
static constexpr u64 expected_memory = 512ULL * 1024ULL * 1024ULL;
|
static constexpr u64 EXPECTED_MEMORY = Common::Size_512_MB;
|
||||||
static constexpr u64 critical_memory = 1024ULL * 1024ULL * 1024ULL;
|
static constexpr u64 CRITICAL_MEMORY = Common::Size_1_GB;
|
||||||
|
|
||||||
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
||||||
|
|
||||||
|
@ -368,13 +369,13 @@ void BufferCache<P>::TickFrame() {
|
||||||
const bool skip_preferred = hits * 256 < shots * 251;
|
const bool skip_preferred = hits * 256 < shots * 251;
|
||||||
uniform_buffer_skip_cache_size = skip_preferred ? DEFAULT_SKIP_CACHE_SIZE : 0;
|
uniform_buffer_skip_cache_size = skip_preferred ? DEFAULT_SKIP_CACHE_SIZE : 0;
|
||||||
|
|
||||||
const bool activate_gc = enabled_gc && total_used_memory >= expected_memory;
|
const bool activate_gc = enabled_gc && total_used_memory >= EXPECTED_MEMORY;
|
||||||
if (!activate_gc) {
|
if (!activate_gc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const bool agressive_gc = total_used_memory >= critical_memory;
|
const bool aggressive_gc = total_used_memory >= CRITICAL_MEMORY;
|
||||||
const u64 ticks_to_destroy = agressive_gc ? 60 : 120;
|
const u64 ticks_to_destroy = aggressive_gc ? 60 : 120;
|
||||||
int num_iterations = agressive_gc ? 64 : 32;
|
int num_iterations = aggressive_gc ? 64 : 32;
|
||||||
for (; num_iterations > 0; --num_iterations) {
|
for (; num_iterations > 0; --num_iterations) {
|
||||||
if (deletion_iterator == slot_buffers.end()) {
|
if (deletion_iterator == slot_buffers.end()) {
|
||||||
deletion_iterator = slot_buffers.begin();
|
deletion_iterator = slot_buffers.begin();
|
||||||
|
|
|
@ -283,4 +283,11 @@ std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
|
||||||
return {DefaultBlockWidth(format), DefaultBlockHeight(format)};
|
return {DefaultBlockWidth(format), DefaultBlockHeight(format)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format) {
|
||||||
|
constexpr u64 RGBA8_PIXEL_SIZE = 4;
|
||||||
|
const u64 base_block_size = static_cast<u64>(DefaultBlockWidth(format)) *
|
||||||
|
static_cast<u64>(DefaultBlockHeight(format)) * RGBA8_PIXEL_SIZE;
|
||||||
|
return (base_size * base_block_size) / BytesPerBlock(format);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace VideoCore::Surface
|
} // namespace VideoCore::Surface
|
||||||
|
|
|
@ -462,4 +462,6 @@ bool IsPixelFormatSRGB(PixelFormat format);
|
||||||
|
|
||||||
std::pair<u32, u32> GetASTCBlockSize(PixelFormat format);
|
std::pair<u32, u32> GetASTCBlockSize(PixelFormat format);
|
||||||
|
|
||||||
|
u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format);
|
||||||
|
|
||||||
} // namespace VideoCore::Surface
|
} // namespace VideoCore::Surface
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
|
#include "common/common_sizes.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
@ -76,8 +77,8 @@ class TextureCache {
|
||||||
/// Sampler ID for bugged sampler ids
|
/// Sampler ID for bugged sampler ids
|
||||||
static constexpr SamplerId NULL_SAMPLER_ID{0};
|
static constexpr SamplerId NULL_SAMPLER_ID{0};
|
||||||
|
|
||||||
static constexpr u64 expected_memory = 1024ULL * 1024ULL * 1024ULL;
|
static constexpr u64 EXPECTED_MEMORY = Common::Size_1_GB;
|
||||||
static constexpr u64 critical_memory = 2 * 1024ULL * 1024ULL * 1024ULL;
|
static constexpr u64 CRITICAL_MEMORY = Common::Size_2_GB;
|
||||||
|
|
||||||
using Runtime = typename P::Runtime;
|
using Runtime = typename P::Runtime;
|
||||||
using Image = typename P::Image;
|
using Image = typename P::Image;
|
||||||
|
@ -394,8 +395,8 @@ void TextureCache<P>::TickFrame() {
|
||||||
++frame_tick;
|
++frame_tick;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const bool high_priority_mode = total_used_memory >= expected_memory;
|
const bool high_priority_mode = total_used_memory >= EXPECTED_MEMORY;
|
||||||
const bool aggressive_mode = total_used_memory >= critical_memory;
|
const bool aggressive_mode = total_used_memory >= CRITICAL_MEMORY;
|
||||||
const u64 ticks_to_destroy = high_priority_mode ? 60 : 100;
|
const u64 ticks_to_destroy = high_priority_mode ? 60 : 100;
|
||||||
int num_iterations = aggressive_mode ? 256 : (high_priority_mode ? 128 : 64);
|
int num_iterations = aggressive_mode ? 256 : (high_priority_mode ? 128 : 64);
|
||||||
for (; num_iterations > 0; --num_iterations) {
|
for (; num_iterations > 0; --num_iterations) {
|
||||||
|
@ -405,7 +406,8 @@ void TextureCache<P>::TickFrame() {
|
||||||
break;
|
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_alias = True(image->flags & ImageFlagBits::Alias);
|
||||||
const bool is_bad_overlap = True(image->flags & ImageFlagBits::BadOverlap);
|
const bool is_bad_overlap = True(image->flags & ImageFlagBits::BadOverlap);
|
||||||
const bool must_download = image->IsSafeDownload();
|
const bool must_download = image->IsSafeDownload();
|
||||||
|
@ -417,8 +419,8 @@ void TextureCache<P>::TickFrame() {
|
||||||
should_care |= aggressive_mode;
|
should_care |= aggressive_mode;
|
||||||
if (should_care && image->frame_tick + ticks_needed < frame_tick) {
|
if (should_care && image->frame_tick + ticks_needed < frame_tick) {
|
||||||
if (is_bad_overlap) {
|
if (is_bad_overlap) {
|
||||||
const bool overlap_check =
|
const bool overlap_check = std::ranges::all_of(
|
||||||
std::ranges::all_of(image->overlapping_images, [&](const ImageId& overlap_id) {
|
image->overlapping_images, [&, image](const ImageId& overlap_id) {
|
||||||
auto& overlap = slot_images[overlap_id];
|
auto& overlap = slot_images[overlap_id];
|
||||||
return overlap.frame_tick >= image->frame_tick;
|
return overlap.frame_tick >= image->frame_tick;
|
||||||
});
|
});
|
||||||
|
@ -428,8 +430,8 @@ void TextureCache<P>::TickFrame() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!is_bad_overlap && must_download) {
|
if (!is_bad_overlap && must_download) {
|
||||||
const bool alias_check =
|
const bool alias_check = std::ranges::none_of(
|
||||||
std::ranges::none_of(image->aliased_images, [&](const AliasedImage& alias) {
|
image->aliased_images, [&, image](const AliasedImage& alias) {
|
||||||
auto& alias_image = slot_images[alias.id];
|
auto& alias_image = slot_images[alias.id];
|
||||||
return (alias_image.frame_tick < image->frame_tick) ||
|
return (alias_image.frame_tick < image->frame_tick) ||
|
||||||
(alias_image.modification_tick < image->modification_tick);
|
(alias_image.modification_tick < image->modification_tick);
|
||||||
|
@ -1275,8 +1277,13 @@ void TextureCache<P>::RegisterImage(ImageId image_id) {
|
||||||
image.flags |= ImageFlagBits::Registered;
|
image.flags |= ImageFlagBits::Registered;
|
||||||
ForEachPage(image.cpu_addr, image.guest_size_bytes,
|
ForEachPage(image.cpu_addr, image.guest_size_bytes,
|
||||||
[this, image_id](u64 page) { page_table[page].push_back(image_id); });
|
[this, image_id](u64 page) { page_table[page].push_back(image_id); });
|
||||||
total_used_memory +=
|
u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
|
||||||
Common::AlignUp(std::max(image.guest_size_bytes, image.unswizzled_size_bytes), 1024);
|
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 <class P>
|
template <class P>
|
||||||
|
@ -1286,8 +1293,13 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
|
||||||
"Trying to unregister an already registered image");
|
"Trying to unregister an already registered image");
|
||||||
image.flags &= ~ImageFlagBits::Registered;
|
image.flags &= ~ImageFlagBits::Registered;
|
||||||
image.flags &= ~ImageFlagBits::BadOverlap;
|
image.flags &= ~ImageFlagBits::BadOverlap;
|
||||||
total_used_memory -=
|
u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
|
||||||
Common::AlignUp(std::max(image.guest_size_bytes, image.unswizzled_size_bytes), 1024);
|
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) {
|
ForEachPage(image.cpu_addr, image.guest_size_bytes, [this, image_id](u64 page) {
|
||||||
const auto page_it = page_table.find(page);
|
const auto page_it = page_table.find(page);
|
||||||
if (page_it == page_table.end()) {
|
if (page_it == page_table.end()) {
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="use_caches_gc">
|
<widget class="QCheckBox" name="use_caches_gc">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<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>
|
<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>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Enable GPU caches garbage collection (unsafe)</string>
|
<string>Enable GPU caches garbage collection (unsafe)</string>
|
||||||
|
|
Loading…
Reference in a new issue