summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar FernandoS272018-11-02 20:04:01 -0400
committerGravatar FernandoS272018-11-11 12:53:25 -0400
commit3088e36237b2d9f90c8ea4688c8d1e69c2dccfe7 (patch)
tree4d79855e10794f26b0d5d898abb278b78f7debd8 /src
parentMerge pull request #1669 from ReinUsesLisp/fixup-gs (diff)
downloadyuzu-3088e36237b2d9f90c8ea4688c8d1e69c2dccfe7.tar.gz
yuzu-3088e36237b2d9f90c8ea4688c8d1e69c2dccfe7.tar.xz
yuzu-3088e36237b2d9f90c8ea4688c8d1e69c2dccfe7.zip
Improved GPU Caches lookup Speed
Diffstat (limited to 'src')
-rw-r--r--src/video_core/rasterizer_cache.h35
1 files changed, 17 insertions, 18 deletions
diff --git a/src/video_core/rasterizer_cache.h b/src/video_core/rasterizer_cache.h
index 6d41321fa..bcf0c15a4 100644
--- a/src/video_core/rasterizer_cache.h
+++ b/src/video_core/rasterizer_cache.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <set> 7#include <set>
8#include <unordered_map>
8 9
9#include <boost/icl/interval_map.hpp> 10#include <boost/icl/interval_map.hpp>
10#include <boost/range/iterator_range_core.hpp> 11#include <boost/range/iterator_range_core.hpp>
@@ -88,29 +89,25 @@ public:
88 89
89 /// Invalidates everything in the cache 90 /// Invalidates everything in the cache
90 void InvalidateAll() { 91 void InvalidateAll() {
91 while (object_cache.begin() != object_cache.end()) { 92 while (interval_cache.begin() != interval_cache.end()) {
92 Unregister(*object_cache.begin()->second.begin()); 93 Unregister(*interval_cache.begin()->second.begin());
93 } 94 }
94 } 95 }
95 96
96protected: 97protected:
97 /// Tries to get an object from the cache with the specified address 98 /// Tries to get an object from the cache with the specified address
98 T TryGet(VAddr addr) const { 99 T TryGet(VAddr addr) const {
99 const ObjectInterval interval{addr}; 100 const auto iter = map_cache.find(addr);
100 for (auto& pair : boost::make_iterator_range(object_cache.equal_range(interval))) { 101 if (iter != map_cache.end())
101 for (auto& cached_object : pair.second) { 102 return iter->second;
102 if (cached_object->GetAddr() == addr) {
103 return cached_object;
104 }
105 }
106 }
107 return nullptr; 103 return nullptr;
108 } 104 }
109 105
110 /// Register an object into the cache 106 /// Register an object into the cache
111 void Register(const T& object) { 107 void Register(const T& object) {
112 object->SetIsRegistered(true); 108 object->SetIsRegistered(true);
113 object_cache.add({GetInterval(object), ObjectSet{object}}); 109 interval_cache.add({GetInterval(object), ObjectSet{object}});
110 map_cache.insert({object->GetAddr(), object});
114 rasterizer.UpdatePagesCachedCount(object->GetAddr(), object->GetSizeInBytes(), 1); 111 rasterizer.UpdatePagesCachedCount(object->GetAddr(), object->GetSizeInBytes(), 1);
115 } 112 }
116 113
@@ -118,13 +115,13 @@ protected:
118 void Unregister(const T& object) { 115 void Unregister(const T& object) {
119 object->SetIsRegistered(false); 116 object->SetIsRegistered(false);
120 rasterizer.UpdatePagesCachedCount(object->GetAddr(), object->GetSizeInBytes(), -1); 117 rasterizer.UpdatePagesCachedCount(object->GetAddr(), object->GetSizeInBytes(), -1);
121
122 // Only flush if use_accurate_gpu_emulation is enabled, as it incurs a performance hit 118 // Only flush if use_accurate_gpu_emulation is enabled, as it incurs a performance hit
123 if (Settings::values.use_accurate_gpu_emulation) { 119 if (Settings::values.use_accurate_gpu_emulation) {
124 FlushObject(object); 120 FlushObject(object);
125 } 121 }
126 122
127 object_cache.subtract({GetInterval(object), ObjectSet{object}}); 123 interval_cache.subtract({GetInterval(object), ObjectSet{object}});
124 map_cache.erase(object->GetAddr());
128 } 125 }
129 126
130 /// Returns a ticks counter used for tracking when cached objects were last modified 127 /// Returns a ticks counter used for tracking when cached objects were last modified
@@ -141,7 +138,7 @@ private:
141 138
142 std::vector<T> objects; 139 std::vector<T> objects;
143 const ObjectInterval interval{addr, addr + size}; 140 const ObjectInterval interval{addr, addr + size};
144 for (auto& pair : boost::make_iterator_range(object_cache.equal_range(interval))) { 141 for (auto& pair : boost::make_iterator_range(interval_cache.equal_range(interval))) {
145 for (auto& cached_object : pair.second) { 142 for (auto& cached_object : pair.second) {
146 if (!cached_object) { 143 if (!cached_object) {
147 continue; 144 continue;
@@ -167,15 +164,17 @@ private:
167 } 164 }
168 165
169 using ObjectSet = std::set<T>; 166 using ObjectSet = std::set<T>;
170 using ObjectCache = boost::icl::interval_map<VAddr, ObjectSet>; 167 using ObjectCache = std::unordered_map<VAddr, T>;
171 using ObjectInterval = typename ObjectCache::interval_type; 168 using IntervalCache = boost::icl::interval_map<VAddr, ObjectSet>;
169 using ObjectInterval = typename IntervalCache::interval_type;
172 170
173 static auto GetInterval(const T& object) { 171 static auto GetInterval(const T& object) {
174 return ObjectInterval::right_open(object->GetAddr(), 172 return ObjectInterval::right_open(object->GetAddr(),
175 object->GetAddr() + object->GetSizeInBytes()); 173 object->GetAddr() + object->GetSizeInBytes());
176 } 174 }
177 175
178 ObjectCache object_cache; ///< Cache of objects 176 ObjectCache map_cache;
179 u64 modified_ticks{}; ///< Counter of cache state ticks, used for in-order flushing 177 IntervalCache interval_cache; ///< Cache of objects
178 u64 modified_ticks{}; ///< Counter of cache state ticks, used for in-order flushing
180 VideoCore::RasterizerInterface& rasterizer; 179 VideoCore::RasterizerInterface& rasterizer;
181}; 180};