diff options
| author | 2020-02-11 18:59:44 -0300 | |
|---|---|---|
| committer | 2020-02-14 17:38:27 -0300 | |
| commit | bcd348f2388cf944f2ac49364a8d13b47cc21456 (patch) | |
| tree | 7aefb0077b4d8902bdab3f3026361173a71046e3 /src/video_core/query_cache.h | |
| parent | query_cache: Abstract OpenGL implementation (diff) | |
| download | yuzu-bcd348f2388cf944f2ac49364a8d13b47cc21456.tar.gz yuzu-bcd348f2388cf944f2ac49364a8d13b47cc21456.tar.xz yuzu-bcd348f2388cf944f2ac49364a8d13b47cc21456.zip | |
vk_query_cache: Implement generic query cache on Vulkan
Diffstat (limited to 'src/video_core/query_cache.h')
| -rw-r--r-- | src/video_core/query_cache.h | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h index 4c9151ce8..069032121 100644 --- a/src/video_core/query_cache.h +++ b/src/video_core/query_cache.h | |||
| @@ -88,7 +88,8 @@ private: | |||
| 88 | std::shared_ptr<HostCounter> last; | 88 | std::shared_ptr<HostCounter> last; |
| 89 | }; | 89 | }; |
| 90 | 90 | ||
| 91 | template <class QueryCache, class CachedQuery, class CounterStream, class HostCounter> | 91 | template <class QueryCache, class CachedQuery, class CounterStream, class HostCounter, |
| 92 | class QueryPool> | ||
| 92 | class QueryCacheBase { | 93 | class QueryCacheBase { |
| 93 | public: | 94 | public: |
| 94 | explicit QueryCacheBase(Core::System& system, VideoCore::RasterizerInterface& rasterizer) | 95 | explicit QueryCacheBase(Core::System& system, VideoCore::RasterizerInterface& rasterizer) |
| @@ -127,15 +128,25 @@ public: | |||
| 127 | 128 | ||
| 128 | /// Updates counters from GPU state. Expected to be called once per draw, clear or dispatch. | 129 | /// Updates counters from GPU state. Expected to be called once per draw, clear or dispatch. |
| 129 | void UpdateCounters() { | 130 | void UpdateCounters() { |
| 131 | std::unique_lock lock{mutex}; | ||
| 130 | const auto& regs = system.GPU().Maxwell3D().regs; | 132 | const auto& regs = system.GPU().Maxwell3D().regs; |
| 131 | Stream(VideoCore::QueryType::SamplesPassed).Update(regs.samplecnt_enable); | 133 | Stream(VideoCore::QueryType::SamplesPassed).Update(regs.samplecnt_enable); |
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | /// Resets a counter to zero. It doesn't disable the query after resetting. | 136 | /// Resets a counter to zero. It doesn't disable the query after resetting. |
| 135 | void ResetCounter(VideoCore::QueryType type) { | 137 | void ResetCounter(VideoCore::QueryType type) { |
| 138 | std::unique_lock lock{mutex}; | ||
| 136 | Stream(type).Reset(); | 139 | Stream(type).Reset(); |
| 137 | } | 140 | } |
| 138 | 141 | ||
| 142 | /// Disable all active streams. Expected to be called at the end of a command buffer. | ||
| 143 | void DisableStreams() { | ||
| 144 | std::unique_lock lock{mutex}; | ||
| 145 | for (auto& stream : streams) { | ||
| 146 | stream.Update(false); | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 139 | /// Returns a new host counter. | 150 | /// Returns a new host counter. |
| 140 | std::shared_ptr<HostCounter> Counter(std::shared_ptr<HostCounter> dependency, | 151 | std::shared_ptr<HostCounter> Counter(std::shared_ptr<HostCounter> dependency, |
| 141 | VideoCore::QueryType type) { | 152 | VideoCore::QueryType type) { |
| @@ -148,6 +159,9 @@ public: | |||
| 148 | return streams[static_cast<std::size_t>(type)]; | 159 | return streams[static_cast<std::size_t>(type)]; |
| 149 | } | 160 | } |
| 150 | 161 | ||
| 162 | protected: | ||
| 163 | std::array<QueryPool, VideoCore::NumQueryTypes> query_pools; | ||
| 164 | |||
| 151 | private: | 165 | private: |
| 152 | /// Flushes a memory range to guest memory and removes it from the cache. | 166 | /// Flushes a memory range to guest memory and removes it from the cache. |
| 153 | void FlushAndRemoveRegion(CacheAddr addr, std::size_t size) { | 167 | void FlushAndRemoveRegion(CacheAddr addr, std::size_t size) { |
| @@ -213,8 +227,16 @@ private: | |||
| 213 | template <class QueryCache, class HostCounter> | 227 | template <class QueryCache, class HostCounter> |
| 214 | class HostCounterBase { | 228 | class HostCounterBase { |
| 215 | public: | 229 | public: |
| 216 | explicit HostCounterBase(std::shared_ptr<HostCounter> dependency) | 230 | explicit HostCounterBase(std::shared_ptr<HostCounter> dependency_) |
| 217 | : dependency{std::move(dependency)} {} | 231 | : dependency{std::move(dependency_)}, depth{dependency ? (dependency->Depth() + 1) : 0} { |
| 232 | // Avoid nesting too many dependencies to avoid a stack overflow when these are deleted. | ||
| 233 | static constexpr u64 depth_threshold = 96; | ||
| 234 | if (depth > depth_threshold) { | ||
| 235 | depth = 0; | ||
| 236 | base_result = dependency->Query(); | ||
| 237 | dependency = nullptr; | ||
| 238 | } | ||
| 239 | } | ||
| 218 | 240 | ||
| 219 | /// Returns the current value of the query. | 241 | /// Returns the current value of the query. |
| 220 | u64 Query() { | 242 | u64 Query() { |
| @@ -222,9 +244,10 @@ public: | |||
| 222 | return *result; | 244 | return *result; |
| 223 | } | 245 | } |
| 224 | 246 | ||
| 225 | u64 value = BlockingQuery(); | 247 | u64 value = BlockingQuery() + base_result; |
| 226 | if (dependency) { | 248 | if (dependency) { |
| 227 | value += dependency->Query(); | 249 | value += dependency->Query(); |
| 250 | dependency = nullptr; | ||
| 228 | } | 251 | } |
| 229 | 252 | ||
| 230 | return *(result = value); | 253 | return *(result = value); |
| @@ -235,6 +258,10 @@ public: | |||
| 235 | return result.has_value(); | 258 | return result.has_value(); |
| 236 | } | 259 | } |
| 237 | 260 | ||
| 261 | u64 Depth() const noexcept { | ||
| 262 | return depth; | ||
| 263 | } | ||
| 264 | |||
| 238 | protected: | 265 | protected: |
| 239 | /// Returns the value of query from the backend API blocking as needed. | 266 | /// Returns the value of query from the backend API blocking as needed. |
| 240 | virtual u64 BlockingQuery() const = 0; | 267 | virtual u64 BlockingQuery() const = 0; |
| @@ -242,6 +269,8 @@ protected: | |||
| 242 | private: | 269 | private: |
| 243 | std::shared_ptr<HostCounter> dependency; ///< Counter to add to this value. | 270 | std::shared_ptr<HostCounter> dependency; ///< Counter to add to this value. |
| 244 | std::optional<u64> result; ///< Filled with the already returned value. | 271 | std::optional<u64> result; ///< Filled with the already returned value. |
| 272 | u64 depth; ///< Number of nested dependencies. | ||
| 273 | u64 base_result = 0; ///< Equivalent to nested dependencies value. | ||
| 245 | }; | 274 | }; |
| 246 | 275 | ||
| 247 | template <class HostCounter> | 276 | template <class HostCounter> |