diff options
| author | 2019-07-19 13:22:27 -0400 | |
|---|---|---|
| committer | 2019-08-21 12:14:23 -0400 | |
| commit | 86d8563314c615d60c7b59748467ffb71904b0c4 (patch) | |
| tree | f954328c9299fe8c241da7007259a98e7fdd451a /src/video_core/buffer_cache | |
| parent | Video_Core: Implement a new Buffer Cache (diff) | |
| download | yuzu-86d8563314c615d60c7b59748467ffb71904b0c4.tar.gz yuzu-86d8563314c615d60c7b59748467ffb71904b0c4.tar.xz yuzu-86d8563314c615d60c7b59748467ffb71904b0c4.zip | |
Buffer_Cache: Fixes and optimizations.
Diffstat (limited to 'src/video_core/buffer_cache')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 104 | ||||
| -rw-r--r-- | src/video_core/buffer_cache/map_interval.h | 2 |
2 files changed, 38 insertions, 68 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 6c467eb80..e36f85705 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -15,8 +15,8 @@ | |||
| 15 | #include "common/alignment.h" | 15 | #include "common/alignment.h" |
| 16 | #include "common/common_types.h" | 16 | #include "common/common_types.h" |
| 17 | #include "core/core.h" | 17 | #include "core/core.h" |
| 18 | #include "video_core/buffer_cache/map_interval.h" | ||
| 19 | #include "video_core/buffer_cache/buffer_block.h" | 18 | #include "video_core/buffer_cache/buffer_block.h" |
| 19 | #include "video_core/buffer_cache/map_interval.h" | ||
| 20 | #include "video_core/memory_manager.h" | 20 | #include "video_core/memory_manager.h" |
| 21 | 21 | ||
| 22 | namespace VideoCore { | 22 | namespace VideoCore { |
| @@ -42,7 +42,7 @@ public: | |||
| 42 | const auto cache_addr = ToCacheAddr(host_ptr); | 42 | const auto cache_addr = ToCacheAddr(host_ptr); |
| 43 | 43 | ||
| 44 | auto block = GetBlock(cache_addr, size); | 44 | auto block = GetBlock(cache_addr, size); |
| 45 | MapAddress(block, gpu_addr, cache_addr, size, is_written); | 45 | MapAddress(block, gpu_addr, cache_addr, size); |
| 46 | 46 | ||
| 47 | const u64 offset = static_cast<u64>(block->GetOffset(cache_addr)); | 47 | const u64 offset = static_cast<u64>(block->GetOffset(cache_addr)); |
| 48 | 48 | ||
| @@ -149,86 +149,56 @@ protected: | |||
| 149 | 149 | ||
| 150 | private: | 150 | private: |
| 151 | void MapAddress(const TBuffer& block, const GPUVAddr gpu_addr, const CacheAddr cache_addr, | 151 | void MapAddress(const TBuffer& block, const GPUVAddr gpu_addr, const CacheAddr cache_addr, |
| 152 | const std::size_t size, bool is_written) { | 152 | const std::size_t size) { |
| 153 | 153 | ||
| 154 | std::vector<MapInterval> overlaps = GetMapsInRange(cache_addr, size); | 154 | std::vector<MapInterval> overlaps = GetMapsInRange(cache_addr, size); |
| 155 | if (overlaps.empty()) { | 155 | if (overlaps.empty()) { |
| 156 | const CacheAddr cache_addr_end = cache_addr + size; | 156 | const CacheAddr cache_addr_end = cache_addr + size; |
| 157 | MapInterval new_interval{cache_addr, cache_addr_end}; | 157 | MapInterval new_interval{cache_addr, cache_addr_end}; |
| 158 | if (!is_written) { | 158 | u8* host_ptr = FromCacheAddr(cache_addr); |
| 159 | u8* host_ptr = FromCacheAddr(cache_addr); | 159 | UploadBlockData(block, block->GetOffset(cache_addr), size, host_ptr); |
| 160 | UploadBlockData(block, block->GetOffset(cache_addr), size, host_ptr); | ||
| 161 | } | ||
| 162 | Register(new_interval, gpu_addr); | 160 | Register(new_interval, gpu_addr); |
| 163 | return; | 161 | return; |
| 164 | } | 162 | } |
| 165 | 163 | ||
| 164 | const CacheAddr cache_addr_end = cache_addr + size; | ||
| 166 | if (overlaps.size() == 1) { | 165 | if (overlaps.size() == 1) { |
| 167 | MapInterval current_map = overlaps[0]; | 166 | const MapInterval& current_map = overlaps[0]; |
| 168 | const CacheAddr cache_addr_end = cache_addr + size; | ||
| 169 | if (current_map.IsInside(cache_addr, cache_addr_end)) { | 167 | if (current_map.IsInside(cache_addr, cache_addr_end)) { |
| 170 | return; | 168 | return; |
| 171 | } | 169 | } |
| 172 | const CacheAddr new_start = std::min(cache_addr, current_map.start); | 170 | } |
| 173 | const CacheAddr new_end = std::max(cache_addr_end, current_map.end); | 171 | CacheAddr new_start = cache_addr; |
| 174 | const GPUVAddr new_gpu_addr = gpu_addr + new_start - cache_addr; | 172 | CacheAddr new_end = cache_addr_end; |
| 175 | const std::size_t new_size = static_cast<std::size_t>(new_end - new_start); | 173 | // Calculate new buffer parameters |
| 176 | MapInterval new_interval{new_start, new_end}; | 174 | for (auto& overlap : overlaps) { |
| 177 | const std::size_t offset = current_map.start - new_start; | 175 | new_start = std::min(overlap.start, new_start); |
| 178 | const std::size_t size = current_map.end - current_map.start; | 176 | new_end = std::max(overlap.end, new_end); |
| 179 | // Upload the remaining data | 177 | } |
| 180 | if (!is_written) { | 178 | GPUVAddr new_gpu_addr = gpu_addr + new_start - cache_addr; |
| 181 | u8* host_ptr = FromCacheAddr(new_start); | 179 | for (auto& overlap : overlaps) { |
| 182 | if (new_start == cache_addr && new_end == cache_addr_end) { | 180 | Unregister(overlap); |
| 183 | std::size_t first_size = current_map.start - new_start; | 181 | } |
| 184 | if (first_size > 0) { | 182 | UpdateBlock(block, new_start, new_end, overlaps); |
| 185 | UploadBlockData(block, block->GetOffset(new_start), first_size, host_ptr); | 183 | MapInterval new_interval{new_start, new_end}; |
| 186 | } | 184 | Register(new_interval, new_gpu_addr); |
| 185 | } | ||
| 187 | 186 | ||
| 188 | std::size_t second_size = new_end - current_map.end; | 187 | void UpdateBlock(const TBuffer& block, CacheAddr start, CacheAddr end, |
| 189 | if (second_size > 0) { | 188 | std::vector<MapInterval>& overlaps) { |
| 190 | u8* host_ptr2 = FromCacheAddr(current_map.end); | 189 | const IntervalType base_interval{start, end}; |
| 191 | UploadBlockData(block, block->GetOffset(current_map.end), second_size, | 190 | IntervalCache interval_set{}; |
| 192 | host_ptr2); | 191 | interval_set.add(base_interval); |
| 193 | } | 192 | for (auto& overlap : overlaps) { |
| 194 | } else { | 193 | const IntervalType subtract{overlap.start, overlap.end}; |
| 195 | if (new_start == cache_addr) { | 194 | interval_set.subtract(subtract); |
| 196 | std::size_t second_size = new_end - current_map.end; | 195 | } |
| 197 | if (second_size > 0) { | 196 | for (auto& interval : interval_set) { |
| 198 | u8* host_ptr2 = FromCacheAddr(current_map.end); | 197 | std::size_t size = interval.upper() - interval.lower(); |
| 199 | UploadBlockData(block, block->GetOffset(current_map.end), second_size, | 198 | if (size > 0) { |
| 200 | host_ptr2); | 199 | u8* host_ptr = FromCacheAddr(interval.lower()); |
| 201 | } | 200 | UploadBlockData(block, block->GetOffset(interval.lower()), size, host_ptr); |
| 202 | } else { | ||
| 203 | std::size_t first_size = current_map.start - new_start; | ||
| 204 | if (first_size > 0) { | ||
| 205 | UploadBlockData(block, block->GetOffset(new_start), first_size, host_ptr); | ||
| 206 | } | ||
| 207 | } | ||
| 208 | } | ||
| 209 | } | ||
| 210 | Unregister(current_map); | ||
| 211 | Register(new_interval, new_gpu_addr); | ||
| 212 | } else { | ||
| 213 | // Calculate new buffer parameters | ||
| 214 | GPUVAddr new_gpu_addr = gpu_addr; | ||
| 215 | CacheAddr start = cache_addr; | ||
| 216 | CacheAddr end = cache_addr + size; | ||
| 217 | for (auto& overlap : overlaps) { | ||
| 218 | start = std::min(overlap.start, start); | ||
| 219 | end = std::max(overlap.end, end); | ||
| 220 | } | ||
| 221 | new_gpu_addr = gpu_addr + start - cache_addr; | ||
| 222 | MapInterval new_interval{start, end}; | ||
| 223 | for (auto& overlap : overlaps) { | ||
| 224 | Unregister(overlap); | ||
| 225 | } | ||
| 226 | std::size_t new_size = end - start; | ||
| 227 | if (!is_written) { | ||
| 228 | u8* host_ptr = FromCacheAddr(start); | ||
| 229 | UploadBlockData(block, block->GetOffset(start), new_size, host_ptr); | ||
| 230 | } | 201 | } |
| 231 | Register(new_interval, new_gpu_addr); | ||
| 232 | } | 202 | } |
| 233 | } | 203 | } |
| 234 | 204 | ||
diff --git a/src/video_core/buffer_cache/map_interval.h b/src/video_core/buffer_cache/map_interval.h index 652a35dcd..c1cd52ca4 100644 --- a/src/video_core/buffer_cache/map_interval.h +++ b/src/video_core/buffer_cache/map_interval.h | |||
| @@ -14,7 +14,7 @@ struct MapInterval { | |||
| 14 | MapInterval(const CacheAddr start, const CacheAddr end) : start{start}, end{end} {} | 14 | MapInterval(const CacheAddr start, const CacheAddr end) : start{start}, end{end} {} |
| 15 | CacheAddr start; | 15 | CacheAddr start; |
| 16 | CacheAddr end; | 16 | CacheAddr end; |
| 17 | bool IsInside(const CacheAddr other_start, const CacheAddr other_end) { | 17 | bool IsInside(const CacheAddr other_start, const CacheAddr other_end) const { |
| 18 | return (start <= other_start && other_end <= end); | 18 | return (start <= other_start && other_end <= end); |
| 19 | } | 19 | } |
| 20 | 20 | ||