diff options
| author | 2018-11-02 20:04:01 -0400 | |
|---|---|---|
| committer | 2018-11-11 12:53:25 -0400 | |
| commit | 3088e36237b2d9f90c8ea4688c8d1e69c2dccfe7 (patch) | |
| tree | 4d79855e10794f26b0d5d898abb278b78f7debd8 /src | |
| parent | Merge pull request #1669 from ReinUsesLisp/fixup-gs (diff) | |
| download | yuzu-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.h | 35 |
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 | ||
| 96 | protected: | 97 | protected: |
| 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 | }; |