summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h6
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp2
-rw-r--r--src/video_core/texture_cache/image_base.h10
-rw-r--r--src/video_core/texture_cache/texture_cache.h36
6 files changed, 36 insertions, 24 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 644c6e57e..21bfb76a4 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -464,9 +464,9 @@ BufferCache<P>::BufferCache(VideoCore::RasterizerInterface& rasterizer_,
464 const s64 device_memory = static_cast<s64>(runtime.GetDeviceLocalMemory()); 464 const s64 device_memory = static_cast<s64>(runtime.GetDeviceLocalMemory());
465 const s64 min_spacing_expected = device_memory - 1_GiB - 512_MiB; 465 const s64 min_spacing_expected = device_memory - 1_GiB - 512_MiB;
466 const s64 min_spacing_critical = device_memory - 1_GiB; 466 const s64 min_spacing_critical = device_memory - 1_GiB;
467 const s64 mem_tresshold = std::min(device_memory, TARGET_THRESHOLD); 467 const s64 mem_threshold = std::min(device_memory, TARGET_THRESHOLD);
468 const s64 min_vacancy_expected = (6 * mem_tresshold) / 10; 468 const s64 min_vacancy_expected = (6 * mem_threshold) / 10;
469 const s64 min_vacancy_critical = (3 * mem_tresshold) / 10; 469 const s64 min_vacancy_critical = (3 * mem_threshold) / 10;
470 minimum_memory = static_cast<u64>( 470 minimum_memory = static_cast<u64>(
471 std::max(std::min(device_memory - min_vacancy_expected, min_spacing_expected), 471 std::max(std::min(device_memory - min_vacancy_expected, min_spacing_expected),
472 DEFAULT_EXPECTED_MEMORY)); 472 DEFAULT_EXPECTED_MEMORY));
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 45db72e6f..f73b0af5f 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -150,7 +150,7 @@ u64 BufferCacheRuntime::GetDeviceMemoryUsage() const {
150 if (GLAD_GL_NVX_gpu_memory_info) { 150 if (GLAD_GL_NVX_gpu_memory_info) {
151 GLint cur_avail_mem_kb = 0; 151 GLint cur_avail_mem_kb = 0;
152 glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &cur_avail_mem_kb); 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; 153 return device_access_memory - static_cast<u64>(cur_avail_mem_kb) * 1_KiB;
154 } 154 }
155 return 2_GiB; 155 return 2_GiB;
156} 156}
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 40f52eacb..63586d9d5 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -513,7 +513,7 @@ u64 TextureCacheRuntime::GetDeviceMemoryUsage() const {
513 if (GLAD_GL_NVX_gpu_memory_info) { 513 if (GLAD_GL_NVX_gpu_memory_info) {
514 GLint cur_avail_mem_kb = 0; 514 GLint cur_avail_mem_kb = 0;
515 glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &cur_avail_mem_kb); 515 glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &cur_avail_mem_kb);
516 return static_cast<u64>(cur_avail_mem_kb) * 1_KiB; 516 return device_access_memory - static_cast<u64>(cur_avail_mem_kb) * 1_KiB;
517 } 517 }
518 return 2_GiB; 518 return 2_GiB;
519} 519}
@@ -695,7 +695,7 @@ Image::Image(TextureCacheRuntime& runtime_, const VideoCommon::ImageInfo& info_,
695 } 695 }
696 if (IsConverted(runtime->device, info.format, info.type)) { 696 if (IsConverted(runtime->device, info.format, info.type)) {
697 flags |= ImageFlagBits::Converted; 697 flags |= ImageFlagBits::Converted;
698 flags |= ImageFlagBits::GCProtected; 698 flags |= ImageFlagBits::CostlyLoad;
699 gl_internal_format = IsPixelFormatSRGB(info.format) ? GL_SRGB8_ALPHA8 : GL_RGBA8; 699 gl_internal_format = IsPixelFormatSRGB(info.format) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
700 gl_format = GL_RGBA; 700 gl_format = GL_RGBA;
701 gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; 701 gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 884f501ef..f2890d263 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -1211,7 +1211,7 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu
1211 } else { 1211 } else {
1212 flags |= VideoCommon::ImageFlagBits::Converted; 1212 flags |= VideoCommon::ImageFlagBits::Converted;
1213 } 1213 }
1214 flags |= VideoCommon::ImageFlagBits::GCProtected; 1214 flags |= VideoCommon::ImageFlagBits::CostlyLoad;
1215 } 1215 }
1216 if (runtime->device.HasDebuggingToolAttached()) { 1216 if (runtime->device.HasDebuggingToolAttached()) {
1217 original_image.SetObjectNameEXT(VideoCommon::Name(*this).c_str()); 1217 original_image.SetObjectNameEXT(VideoCommon::Name(*this).c_str());
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h
index 279f39269..dd0106432 100644
--- a/src/video_core/texture_cache/image_base.h
+++ b/src/video_core/texture_cache/image_base.h
@@ -29,11 +29,11 @@ enum class ImageFlagBits : u32 {
29 Sparse = 1 << 9, ///< Image has non continous submemory. 29 Sparse = 1 << 9, ///< Image has non continous submemory.
30 30
31 // Garbage Collection Flags 31 // Garbage Collection Flags
32 BadOverlap = 1 << 10, ///< This image overlaps other but doesn't fit, has higher 32 BadOverlap = 1 << 10, ///< This image overlaps other but doesn't fit, has higher
33 ///< garbage collection priority 33 ///< garbage collection priority
34 Alias = 1 << 11, ///< This image has aliases and has priority on garbage 34 Alias = 1 << 11, ///< This image has aliases and has priority on garbage
35 ///< collection 35 ///< collection
36 GCProtected = 1 << 12, ///< Protected from low-tier GC as they are costy to load back. 36 CostlyLoad = 1 << 12, ///< Protected from low-tier GC as it is costly to load back.
37 37
38 // Rescaler 38 // Rescaler
39 Rescaled = 1 << 13, 39 Rescaled = 1 << 13,
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 7b6bd8697..efc1c4525 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -53,17 +53,16 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
53 const s64 device_memory = static_cast<s64>(runtime.GetDeviceLocalMemory()); 53 const s64 device_memory = static_cast<s64>(runtime.GetDeviceLocalMemory());
54 const s64 min_spacing_expected = device_memory - 1_GiB - 512_MiB; 54 const s64 min_spacing_expected = device_memory - 1_GiB - 512_MiB;
55 const s64 min_spacing_critical = device_memory - 1_GiB; 55 const s64 min_spacing_critical = device_memory - 1_GiB;
56 const s64 mem_tresshold = std::min(device_memory, TARGET_THRESHOLD); 56 const s64 mem_threshold = std::min(device_memory, TARGET_THRESHOLD);
57 const s64 min_vacancy_expected = (6 * mem_tresshold) / 10; 57 const s64 min_vacancy_expected = (6 * mem_threshold) / 10;
58 const s64 min_vacancy_critical = (3 * mem_tresshold) / 10; 58 const s64 min_vacancy_critical = (3 * mem_threshold) / 10;
59 expected_memory = static_cast<u64>( 59 expected_memory = static_cast<u64>(
60 std::max(std::min(device_memory - min_vacancy_expected, min_spacing_expected), 60 std::max(std::min(device_memory - min_vacancy_expected, min_spacing_expected),
61 DEFAULT_EXPECTED_MEMORY)); 61 DEFAULT_EXPECTED_MEMORY));
62 critical_memory = static_cast<u64>( 62 critical_memory = static_cast<u64>(
63 std::max(std::min(device_memory - min_vacancy_critical, min_spacing_critical), 63 std::max(std::min(device_memory - min_vacancy_critical, min_spacing_critical),
64 DEFAULT_CRITICAL_MEMORY)); 64 DEFAULT_CRITICAL_MEMORY));
65 minimum_memory = static_cast<u64>((device_memory - mem_tresshold) / 2); 65 minimum_memory = static_cast<u64>((device_memory - mem_threshold) / 2);
66 LOG_CRITICAL(Debug, "Available Memory: {}", device_memory / 1_MiB);
67 } else { 66 } else {
68 expected_memory = DEFAULT_EXPECTED_MEMORY + 512_MiB; 67 expected_memory = DEFAULT_EXPECTED_MEMORY + 512_MiB;
69 critical_memory = DEFAULT_CRITICAL_MEMORY + 1_GiB; 68 critical_memory = DEFAULT_CRITICAL_MEMORY + 1_GiB;
@@ -73,11 +72,12 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
73 72
74template <class P> 73template <class P>
75void TextureCache<P>::RunGarbageCollector() { 74void TextureCache<P>::RunGarbageCollector() {
76 const bool high_priority_mode = total_used_memory >= expected_memory; 75 bool high_priority_mode = total_used_memory >= expected_memory;
77 const bool aggressive_mode = total_used_memory >= critical_memory; 76 bool aggressive_mode = total_used_memory >= critical_memory;
78 const u64 ticks_to_destroy = aggressive_mode ? 10ULL : high_priority_mode ? 25ULL : 100ULL; 77 const u64 ticks_to_destroy = aggressive_mode ? 10ULL : high_priority_mode ? 25ULL : 50ULL;
79 size_t num_iterations = aggressive_mode ? 300 : (high_priority_mode ? 50 : 10); 78 size_t num_iterations = aggressive_mode ? 40 : (high_priority_mode ? 20 : 10);
80 const auto clean_up = [this, &num_iterations, high_priority_mode](ImageId image_id) { 79 const auto clean_up = [this, &num_iterations, &high_priority_mode,
80 &aggressive_mode](ImageId image_id) {
81 if (num_iterations == 0) { 81 if (num_iterations == 0) {
82 return true; 82 return true;
83 } 83 }
@@ -85,7 +85,8 @@ void TextureCache<P>::RunGarbageCollector() {
85 auto& image = slot_images[image_id]; 85 auto& image = slot_images[image_id];
86 const bool must_download = 86 const bool must_download =
87 image.IsSafeDownload() && False(image.flags & ImageFlagBits::BadOverlap); 87 image.IsSafeDownload() && False(image.flags & ImageFlagBits::BadOverlap);
88 if (!high_priority_mode && must_download) { 88 if (!high_priority_mode &&
89 (must_download || True(image.flags & ImageFlagBits::CostlyLoad))) {
89 return false; 90 return false;
90 } 91 }
91 if (must_download) { 92 if (must_download) {
@@ -100,6 +101,18 @@ void TextureCache<P>::RunGarbageCollector() {
100 } 101 }
101 UnregisterImage(image_id); 102 UnregisterImage(image_id);
102 DeleteImage(image_id, image.scale_tick > frame_tick + 5); 103 DeleteImage(image_id, image.scale_tick > frame_tick + 5);
104 if (total_used_memory < critical_memory) {
105 if (aggressive_mode) {
106 // Sink the aggresiveness.
107 num_iterations >>= 2;
108 aggressive_mode = false;
109 return false;
110 }
111 if (high_priority_mode && total_used_memory < expected_memory) {
112 num_iterations >>= 1;
113 high_priority_mode = false;
114 }
115 }
103 return false; 116 return false;
104 }; 117 };
105 lru_cache.ForEachItemBelow(frame_tick - ticks_to_destroy, clean_up); 118 lru_cache.ForEachItemBelow(frame_tick - ticks_to_destroy, clean_up);
@@ -120,7 +133,6 @@ void TextureCache<P>::TickFrame() {
120 runtime.TickFrame(); 133 runtime.TickFrame();
121 critical_gc = 0; 134 critical_gc = 0;
122 ++frame_tick; 135 ++frame_tick;
123 LOG_CRITICAL(Debug, "Current memory: {}", total_used_memory / 1_MiB);
124} 136}
125 137
126template <class P> 138template <class P>