summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2022-01-16 05:05:34 +0100
committerGravatar Fernando Sahmkow2022-03-25 01:51:51 +0100
commit5e982a781201a12c4cee6af2908e4732b4c8d945 (patch)
tree480bba2bae6f2618b657e3ddb9729eff65c94c2d /src
parentGarbage Collection: Redesign the algorithm to do a better use of memory. (diff)
downloadyuzu-5e982a781201a12c4cee6af2908e4732b4c8d945.tar.gz
yuzu-5e982a781201a12c4cee6af2908e4732b4c8d945.tar.xz
yuzu-5e982a781201a12c4cee6af2908e4732b4c8d945.zip
Buffer Cache: Tune to the levels of the new GC.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h34
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp18
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h12
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.cpp12
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.h6
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h2
6 files changed, 78 insertions, 6 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 200d792dd..644c6e57e 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -76,8 +76,9 @@ class BufferCache {
76 76
77 static constexpr BufferId NULL_BUFFER_ID{0}; 77 static constexpr BufferId NULL_BUFFER_ID{0};
78 78
79 static constexpr u64 EXPECTED_MEMORY = 512_MiB; 79 static constexpr s64 DEFAULT_EXPECTED_MEMORY = 512_MiB;
80 static constexpr u64 CRITICAL_MEMORY = 1_GiB; 80 static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB;
81 static constexpr s64 TARGET_THRESHOLD = 4_GiB;
81 82
82 using Maxwell = Tegra::Engines::Maxwell3D::Regs; 83 using Maxwell = Tegra::Engines::Maxwell3D::Regs;
83 84
@@ -436,6 +437,8 @@ private:
436 Common::LeastRecentlyUsedCache<LRUItemParams> lru_cache; 437 Common::LeastRecentlyUsedCache<LRUItemParams> lru_cache;
437 u64 frame_tick = 0; 438 u64 frame_tick = 0;
438 u64 total_used_memory = 0; 439 u64 total_used_memory = 0;
440 u64 minimum_memory = 0;
441 u64 critical_memory = 0;
439 442
440 std::array<BufferId, ((1ULL << 39) >> PAGE_BITS)> page_table; 443 std::array<BufferId, ((1ULL << 39) >> PAGE_BITS)> page_table;
441}; 444};
@@ -451,11 +454,30 @@ BufferCache<P>::BufferCache(VideoCore::RasterizerInterface& rasterizer_,
451 // Ensure the first slot is used for the null buffer 454 // Ensure the first slot is used for the null buffer
452 void(slot_buffers.insert(runtime, NullBufferParams{})); 455 void(slot_buffers.insert(runtime, NullBufferParams{}));
453 common_ranges.clear(); 456 common_ranges.clear();
457
458 if (!runtime.CanReportMemoryUsage()) {
459 minimum_memory = DEFAULT_EXPECTED_MEMORY;
460 critical_memory = DEFAULT_CRITICAL_MEMORY;
461 return;
462 }
463
464 const s64 device_memory = static_cast<s64>(runtime.GetDeviceLocalMemory());
465 const s64 min_spacing_expected = device_memory - 1_GiB - 512_MiB;
466 const s64 min_spacing_critical = device_memory - 1_GiB;
467 const s64 mem_tresshold = std::min(device_memory, TARGET_THRESHOLD);
468 const s64 min_vacancy_expected = (6 * mem_tresshold) / 10;
469 const s64 min_vacancy_critical = (3 * mem_tresshold) / 10;
470 minimum_memory = static_cast<u64>(
471 std::max(std::min(device_memory - min_vacancy_expected, min_spacing_expected),
472 DEFAULT_EXPECTED_MEMORY));
473 critical_memory = static_cast<u64>(
474 std::max(std::min(device_memory - min_vacancy_critical, min_spacing_critical),
475 DEFAULT_CRITICAL_MEMORY));
454} 476}
455 477
456template <class P> 478template <class P>
457void BufferCache<P>::RunGarbageCollector() { 479void BufferCache<P>::RunGarbageCollector() {
458 const bool aggressive_gc = total_used_memory >= CRITICAL_MEMORY; 480 const bool aggressive_gc = total_used_memory >= critical_memory;
459 const u64 ticks_to_destroy = aggressive_gc ? 60 : 120; 481 const u64 ticks_to_destroy = aggressive_gc ? 60 : 120;
460 int num_iterations = aggressive_gc ? 64 : 32; 482 int num_iterations = aggressive_gc ? 64 : 32;
461 const auto clean_up = [this, &num_iterations](BufferId buffer_id) { 483 const auto clean_up = [this, &num_iterations](BufferId buffer_id) {
@@ -486,7 +508,11 @@ void BufferCache<P>::TickFrame() {
486 const bool skip_preferred = hits * 256 < shots * 251; 508 const bool skip_preferred = hits * 256 < shots * 251;
487 uniform_buffer_skip_cache_size = skip_preferred ? DEFAULT_SKIP_CACHE_SIZE : 0; 509 uniform_buffer_skip_cache_size = skip_preferred ? DEFAULT_SKIP_CACHE_SIZE : 0;
488 510
489 if (total_used_memory >= EXPECTED_MEMORY) { 511 // If we can obtain the memory info, use it instead of the estimate.
512 if (runtime.CanReportMemoryUsage()) {
513 total_used_memory = runtime.GetDeviceMemoryUsage();
514 }
515 if (total_used_memory >= minimum_memory) {
490 RunGarbageCollector(); 516 RunGarbageCollector();
491 } 517 }
492 ++frame_tick; 518 ++frame_tick;
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index d4dd10bb6..45db72e6f 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -135,6 +135,24 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_)
135 buffer.Create(); 135 buffer.Create();
136 glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY); 136 glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY);
137 } 137 }
138
139 device_access_memory = []() -> u64 {
140 if (GLAD_GL_NVX_gpu_memory_info) {
141 GLint cur_avail_mem_kb = 0;
142 glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &cur_avail_mem_kb);
143 return static_cast<u64>(cur_avail_mem_kb) * 1_KiB;
144 }
145 return 2_GiB; // Return minimum requirements
146 }();
147}
148
149u64 BufferCacheRuntime::GetDeviceMemoryUsage() const {
150 if (GLAD_GL_NVX_gpu_memory_info) {
151 GLint cur_avail_mem_kb = 0;
152 glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &cur_avail_mem_kb);
153 return static_cast<u64>(cur_avail_mem_kb) * 1_KiB;
154 }
155 return 2_GiB;
138} 156}
139 157
140void BufferCacheRuntime::CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer, 158void BufferCacheRuntime::CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer,
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index 7287731b6..86a265fee 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -151,6 +151,16 @@ public:
151 use_storage_buffers = use_storage_buffers_; 151 use_storage_buffers = use_storage_buffers_;
152 } 152 }
153 153
154 u64 GetDeviceLocalMemory() const {
155 return device_access_memory;
156 }
157
158 u64 GetDeviceMemoryUsage() const;
159
160 bool CanReportMemoryUsage() const {
161 return GLAD_GL_NVX_gpu_memory_info;
162 }
163
154private: 164private:
155 static constexpr std::array PABO_LUT{ 165 static constexpr std::array PABO_LUT{
156 GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV, GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV, 166 GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV, GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV,
@@ -184,6 +194,8 @@ private:
184 std::array<OGLBuffer, VideoCommon::NUM_COMPUTE_UNIFORM_BUFFERS> copy_compute_uniforms; 194 std::array<OGLBuffer, VideoCommon::NUM_COMPUTE_UNIFORM_BUFFERS> copy_compute_uniforms;
185 195
186 u32 index_buffer_offset = 0; 196 u32 index_buffer_offset = 0;
197
198 u64 device_access_memory;
187}; 199};
188 200
189struct BufferCacheParams { 201struct BufferCacheParams {
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index 5ffd93499..def838c34 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -141,6 +141,18 @@ StagingBufferRef BufferCacheRuntime::DownloadStagingBuffer(size_t size) {
141 return staging_pool.Request(size, MemoryUsage::Download); 141 return staging_pool.Request(size, MemoryUsage::Download);
142} 142}
143 143
144u64 BufferCacheRuntime::GetDeviceLocalMemory() const {
145 return device.GetDeviceLocalMemory();
146}
147
148u64 BufferCacheRuntime::GetDeviceMemoryUsage() const {
149 return device.GetDeviceMemoryUsage();
150}
151
152bool BufferCacheRuntime::CanReportMemoryUsage() const {
153 return device.CanReportMemoryUsage();
154}
155
144void BufferCacheRuntime::Finish() { 156void BufferCacheRuntime::Finish() {
145 scheduler.Finish(); 157 scheduler.Finish();
146} 158}
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
index 1ee0d8420..d7fdd18ff 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.h
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -65,6 +65,12 @@ public:
65 65
66 void Finish(); 66 void Finish();
67 67
68 u64 GetDeviceLocalMemory() const;
69
70 u64 GetDeviceMemoryUsage() const;
71
72 bool CanReportMemoryUsage() const;
73
68 [[nodiscard]] StagingBufferRef UploadStagingBuffer(size_t size); 74 [[nodiscard]] StagingBufferRef UploadStagingBuffer(size_t size);
69 75
70 [[nodiscard]] StagingBufferRef DownloadStagingBuffer(size_t size); 76 [[nodiscard]] StagingBufferRef DownloadStagingBuffer(size_t size);
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 5dabc344b..b1324edf3 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -60,8 +60,6 @@ class TextureCache {
60 static constexpr bool HAS_DEVICE_MEMORY_INFO = P::HAS_DEVICE_MEMORY_INFO; 60 static constexpr bool HAS_DEVICE_MEMORY_INFO = P::HAS_DEVICE_MEMORY_INFO;
61 61
62 static constexpr s64 TARGET_THRESHOLD = 4_GiB; 62 static constexpr s64 TARGET_THRESHOLD = 4_GiB;
63 static constexpr s64 MIN_VACANCY_EXPECTED = (6 * TARGET_THRESHOLD) / 10;
64 static constexpr s64 MIN_VACANCY_CRITICAL = (3 * TARGET_THRESHOLD) / 10;
65 static constexpr s64 DEFAULT_EXPECTED_MEMORY = 1_GiB + 125_MiB; 63 static constexpr s64 DEFAULT_EXPECTED_MEMORY = 1_GiB + 125_MiB;
66 static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB + 625_MiB; 64 static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB + 625_MiB;
67 static constexpr size_t GC_EMERGENCY_COUNTS = 2; 65 static constexpr size_t GC_EMERGENCY_COUNTS = 2;