Quick change to previous GC adjustment

This commit is contained in:
CamilleLaVey
2026-09-18 03:30:06 -04:00
parent 08741c919a
commit 228a400752
5 changed files with 23 additions and 14 deletions
+12 -6
View File
@@ -33,10 +33,12 @@ BufferCache<P>::BufferCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, R
device_local_memory = runtime.GetDeviceLocalMemory(); device_local_memory = runtime.GetDeviceLocalMemory();
const auto thresholds = VideoCommon::MakeReclaimThresholds( const auto thresholds = VideoCommon::MakeReclaimThresholds(
device_local_memory, static_cast<u64>(TARGET_THRESHOLD), device_local_memory, static_cast<u64>(TARGET_THRESHOLD),
static_cast<u64>(DEFAULT_EXPECTED_MEMORY), static_cast<u64>(DEFAULT_CRITICAL_MEMORY)); static_cast<u64>(DEFAULT_EXPECTED_MEMORY), static_cast<u64>(DEFAULT_CRITICAL_MEMORY),
HEAP_PRESSURE_HEADROOM);
minimum_memory = thresholds.minimum; minimum_memory = thresholds.minimum;
expected_memory = thresholds.expected; expected_memory = thresholds.expected;
critical_memory = thresholds.critical; critical_memory = thresholds.critical;
heap_headroom = thresholds.headroom;
} }
template <class P> template <class P>
@@ -52,11 +54,11 @@ void BufferCache<P>::ReclaimInline() {
if (num_iterations == 0) { if (num_iterations == 0) {
return true; return true;
} }
--num_iterations;
Buffer& buffer = slot_buffers[buffer_id]; Buffer& buffer = slot_buffers[buffer_id];
if (memory_tracker.IsRegionGpuModified(buffer.CpuAddr(), buffer.SizeBytes())) { if (memory_tracker.IsRegionGpuModified(buffer.CpuAddr(), buffer.SizeBytes())) {
return false; return false;
} }
--num_iterations;
DeleteBuffer(buffer_id); DeleteBuffer(buffer_id);
return false; return false;
}; };
@@ -116,8 +118,7 @@ void BufferCache<P>::TickFrame() {
heap_pressure = false; heap_pressure = false;
if (device_local_memory != 0 && runtime.CanReportMemoryUsage()) { if (device_local_memory != 0 && runtime.CanReportMemoryUsage()) {
heap_pressure = runtime.GetDeviceMemoryUsage() + HEAP_PRESSURE_HEADROOM >= heap_pressure = runtime.GetDeviceMemoryUsage() + heap_headroom >= device_local_memory;
device_local_memory;
} }
if (total_used_memory >= minimum_memory || heap_pressure) { if (total_used_memory >= minimum_memory || heap_pressure) {
RunGarbageCollector(); RunGarbageCollector();
@@ -363,6 +364,7 @@ void BufferCache<P>::DisableGraphicsUniformBuffer(size_t stage, u32 index) {
template <class P> template <class P>
void BufferCache<P>::UpdateGraphicsBuffers(bool is_indexed) { void BufferCache<P>::UpdateGraphicsBuffers(bool is_indexed) {
ReclaimInline();
do { do {
channel_state->has_deleted_buffers = false; channel_state->has_deleted_buffers = false;
DoUpdateGraphicsBuffers(is_indexed); DoUpdateGraphicsBuffers(is_indexed);
@@ -371,6 +373,7 @@ void BufferCache<P>::UpdateGraphicsBuffers(bool is_indexed) {
template <class P> template <class P>
void BufferCache<P>::UpdateComputeBuffers() { void BufferCache<P>::UpdateComputeBuffers() {
ReclaimInline();
do { do {
channel_state->has_deleted_buffers = false; channel_state->has_deleted_buffers = false;
DoUpdateComputeBuffers(); DoUpdateComputeBuffers();
@@ -1343,7 +1346,7 @@ void BufferCache<P>::UpdateIndexBuffer() {
inline_buffer_id = CreateBuffer(0, buffer_size, false); inline_buffer_id = CreateBuffer(0, buffer_size, false);
} }
if (slot_buffers[inline_buffer_id].SizeBytes() < buffer_size) [[unlikely]] { if (slot_buffers[inline_buffer_id].SizeBytes() < buffer_size) [[unlikely]] {
slot_buffers.erase(inline_buffer_id); DeleteBuffer(inline_buffer_id, true);
inline_buffer_id = CreateBuffer(0, buffer_size, false); inline_buffer_id = CreateBuffer(0, buffer_size, false);
} }
channel_state->index_buffer = Binding{ channel_state->index_buffer = Binding{
@@ -1693,7 +1696,6 @@ void BufferCache<P>::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id,
template <class P> template <class P>
BufferId BufferCache<P>::CreateBuffer(DAddr device_addr, u32 wanted_size, BufferId BufferCache<P>::CreateBuffer(DAddr device_addr, u32 wanted_size,
bool sparse_compatible) { bool sparse_compatible) {
ReclaimInline();
DAddr device_addr_end = Common::AlignUp(device_addr + wanted_size, CACHING_PAGESIZE); DAddr device_addr_end = Common::AlignUp(device_addr + wanted_size, CACHING_PAGESIZE);
device_addr = Common::AlignDown(device_addr, CACHING_PAGESIZE); device_addr = Common::AlignDown(device_addr, CACHING_PAGESIZE);
wanted_size = static_cast<u32>(device_addr_end - device_addr); wanted_size = static_cast<u32>(device_addr_end - device_addr);
@@ -1994,6 +1996,10 @@ void BufferCache<P>::DeleteBuffer(BufferId buffer_id, bool do_not_mark) {
memory_tracker.MarkRegionAsCpuModified(buffer.CpuAddr(), buffer.SizeBytes()); memory_tracker.MarkRegionAsCpuModified(buffer.CpuAddr(), buffer.SizeBytes());
} }
if (inline_buffer_id == buffer_id) {
inline_buffer_id = NULL_BUFFER_ID;
}
Unregister(buffer_id); Unregister(buffer_id);
#ifdef YUZU_LEGACY #ifdef YUZU_LEGACY
@@ -549,6 +549,7 @@ private:
u64 minimum_memory = 0; u64 minimum_memory = 0;
u64 expected_memory = 0; u64 expected_memory = 0;
u64 critical_memory = 0; u64 critical_memory = 0;
u64 heap_headroom = 0;
bool heap_pressure = false; bool heap_pressure = false;
BufferId inline_buffer_id; BufferId inline_buffer_id;
#ifdef YUZU_LEGACY #ifdef YUZU_LEGACY
+4 -1
View File
@@ -13,12 +13,14 @@ struct ReclaimThresholds {
u64 minimum{}; u64 minimum{};
u64 expected{}; u64 expected{};
u64 critical{}; u64 critical{};
u64 headroom{};
}; };
[[nodiscard]] constexpr ReclaimThresholds MakeReclaimThresholds(u64 device_local_memory, [[nodiscard]] constexpr ReclaimThresholds MakeReclaimThresholds(u64 device_local_memory,
u64 target_threshold, u64 target_threshold,
u64 default_expected, u64 default_expected,
u64 default_critical) { u64 default_critical,
u64 default_headroom) {
u64 critical = default_critical; u64 critical = default_critical;
if (device_local_memory != 0) { if (device_local_memory != 0) {
const u64 budget = (std::min)(device_local_memory, target_threshold); const u64 budget = (std::min)(device_local_memory, target_threshold);
@@ -29,6 +31,7 @@ struct ReclaimThresholds {
.minimum = (expected * 3) / 4, .minimum = (expected * 3) / 4,
.expected = expected, .expected = expected,
.critical = critical, .critical = critical,
.headroom = (std::clamp)(device_local_memory / 4, default_headroom, default_headroom * 2),
}; };
} }
+4 -5
View File
@@ -62,10 +62,12 @@ TextureCache<P>::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManag
} }
const auto thresholds = VideoCommon::MakeReclaimThresholds( const auto thresholds = VideoCommon::MakeReclaimThresholds(
device_local_memory, static_cast<u64>(TARGET_THRESHOLD), device_local_memory, static_cast<u64>(TARGET_THRESHOLD),
static_cast<u64>(DEFAULT_EXPECTED_MEMORY), static_cast<u64>(DEFAULT_CRITICAL_MEMORY)); static_cast<u64>(DEFAULT_EXPECTED_MEMORY), static_cast<u64>(DEFAULT_CRITICAL_MEMORY),
HEAP_PRESSURE_HEADROOM);
minimum_memory = thresholds.minimum; minimum_memory = thresholds.minimum;
expected_memory = thresholds.expected; expected_memory = thresholds.expected;
critical_memory = thresholds.critical; critical_memory = thresholds.critical;
heap_headroom = thresholds.headroom;
} }
template <class P> template <class P>
@@ -127,8 +129,7 @@ template <class P>
void TextureCache<P>::TickFrame() { void TextureCache<P>::TickFrame() {
heap_pressure = false; heap_pressure = false;
if (device_local_memory != 0 && runtime.CanReportMemoryUsage()) { if (device_local_memory != 0 && runtime.CanReportMemoryUsage()) {
heap_pressure = runtime.GetDeviceMemoryUsage() + HEAP_PRESSURE_HEADROOM >= heap_pressure = runtime.GetDeviceMemoryUsage() + heap_headroom >= device_local_memory;
device_local_memory;
} }
if (total_used_memory > minimum_memory || heap_pressure) { if (total_used_memory > minimum_memory || heap_pressure) {
RunGarbageCollector(); RunGarbageCollector();
@@ -1320,8 +1321,6 @@ u64 TextureCache<P>::GetScaledImageSizeBytes(const ImageBase& image) {
template <class P> template <class P>
void TextureCache<P>::QueueAsyncDecode(Image& image, ImageId image_id) { void TextureCache<P>::QueueAsyncDecode(Image& image, ImageId image_id) {
UNIMPLEMENTED_IF(False(image.flags & ImageFlagBits::Converted)); UNIMPLEMENTED_IF(False(image.flags & ImageFlagBits::Converted));
LOG_INFO(HW_GPU, "Queuing async texture decode");
image.flags |= ImageFlagBits::IsDecoding; image.flags |= ImageFlagBits::IsDecoding;
auto decode = std::make_unique<AsyncDecodeContext>(); auto decode = std::make_unique<AsyncDecodeContext>();
auto* decode_ptr = decode.get(); auto* decode_ptr = decode.get();
@@ -446,6 +446,7 @@ private:
u64 minimum_memory = 0; u64 minimum_memory = 0;
u64 expected_memory = 0; u64 expected_memory = 0;
u64 critical_memory = 0; u64 critical_memory = 0;
u64 heap_headroom = 0;
bool heap_pressure = false; bool heap_pressure = false;
struct BufferDownload { struct BufferDownload {
@@ -498,8 +499,7 @@ private:
u64 modification_tick = 0; u64 modification_tick = 0;
u64 frame_tick = 0; u64 frame_tick = 0;
Common::ThreadWorker texture_decode_worker{1, "TextureDecoder", {}, Common::ThreadWorker texture_decode_worker{1, "TextureDecoder"};
Common::ThreadPlacement::Efficiency};
std::vector<std::unique_ptr<AsyncDecodeContext>> async_decodes; std::vector<std::unique_ptr<AsyncDecodeContext>> async_decodes;
// Join caching // Join caching