diff options
| author | 2019-07-20 12:54:31 -0400 | |
|---|---|---|
| committer | 2019-08-21 12:14:26 -0400 | |
| commit | 6ce2c850470e4d0600d69a11ae2347a643a44a65 (patch) | |
| tree | 443a8a1893d24e9dfd090c8664de3bb77c245133 /src/video_core/buffer_cache | |
| parent | Buffer_Cache: Implement barriers. (diff) | |
| download | yuzu-6ce2c850470e4d0600d69a11ae2347a643a44a65.tar.gz yuzu-6ce2c850470e4d0600d69a11ae2347a643a44a65.tar.xz yuzu-6ce2c850470e4d0600d69a11ae2347a643a44a65.zip | |
Buffer_Cache: Implement flushing.
Diffstat (limited to 'src/video_core/buffer_cache')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 03b288233..38ce16ed5 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -79,12 +79,16 @@ public: | |||
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | void Map(std::size_t max_size) { | 81 | void Map(std::size_t max_size) { |
| 82 | std::lock_guard lock{mutex}; | ||
| 83 | |||
| 82 | std::tie(buffer_ptr, buffer_offset_base, invalidated) = stream_buffer->Map(max_size, 4); | 84 | std::tie(buffer_ptr, buffer_offset_base, invalidated) = stream_buffer->Map(max_size, 4); |
| 83 | buffer_offset = buffer_offset_base; | 85 | buffer_offset = buffer_offset_base; |
| 84 | } | 86 | } |
| 85 | 87 | ||
| 86 | /// Finishes the upload stream, returns true on bindings invalidation. | 88 | /// Finishes the upload stream, returns true on bindings invalidation. |
| 87 | bool Unmap() { | 89 | bool Unmap() { |
| 90 | std::lock_guard lock{mutex}; | ||
| 91 | |||
| 88 | stream_buffer->Unmap(buffer_offset - buffer_offset_base); | 92 | stream_buffer->Unmap(buffer_offset - buffer_offset_base); |
| 89 | return std::exchange(invalidated, false); | 93 | return std::exchange(invalidated, false); |
| 90 | } | 94 | } |
| @@ -103,7 +107,15 @@ public: | |||
| 103 | void FlushRegion(CacheAddr addr, std::size_t size) { | 107 | void FlushRegion(CacheAddr addr, std::size_t size) { |
| 104 | std::lock_guard lock{mutex}; | 108 | std::lock_guard lock{mutex}; |
| 105 | 109 | ||
| 106 | // TODO | 110 | std::vector<MapInterval> objects = GetMapsInRange(addr, size); |
| 111 | std::sort(objects.begin(), objects.end(), [](const MapInterval& a, const MapInterval& b) { | ||
| 112 | return a->GetModificationTick() < b->GetModificationTick(); | ||
| 113 | }); | ||
| 114 | for (auto& object : objects) { | ||
| 115 | if (object->IsModified() && object->IsRegistered()) { | ||
| 116 | FlushMap(object); | ||
| 117 | } | ||
| 118 | } | ||
| 107 | } | 119 | } |
| 108 | 120 | ||
| 109 | /// Mark the specified region as being invalidated | 121 | /// Mark the specified region as being invalidated |
| @@ -205,11 +217,13 @@ private: | |||
| 205 | CacheAddr new_start = cache_addr; | 217 | CacheAddr new_start = cache_addr; |
| 206 | CacheAddr new_end = cache_addr_end; | 218 | CacheAddr new_end = cache_addr_end; |
| 207 | bool write_inheritance = false; | 219 | bool write_inheritance = false; |
| 220 | bool modified_inheritance = false; | ||
| 208 | // Calculate new buffer parameters | 221 | // Calculate new buffer parameters |
| 209 | for (auto& overlap : overlaps) { | 222 | for (auto& overlap : overlaps) { |
| 210 | new_start = std::min(overlap->GetStart(), new_start); | 223 | new_start = std::min(overlap->GetStart(), new_start); |
| 211 | new_end = std::max(overlap->GetEnd(), new_end); | 224 | new_end = std::max(overlap->GetEnd(), new_end); |
| 212 | write_inheritance |= overlap->IsWritten(); | 225 | write_inheritance |= overlap->IsWritten(); |
| 226 | modified_inheritance |= overlap->IsModified(); | ||
| 213 | } | 227 | } |
| 214 | GPUVAddr new_gpu_addr = gpu_addr + new_start - cache_addr; | 228 | GPUVAddr new_gpu_addr = gpu_addr + new_start - cache_addr; |
| 215 | for (auto& overlap : overlaps) { | 229 | for (auto& overlap : overlaps) { |
| @@ -217,6 +231,9 @@ private: | |||
| 217 | } | 231 | } |
| 218 | UpdateBlock(block, new_start, new_end, overlaps); | 232 | UpdateBlock(block, new_start, new_end, overlaps); |
| 219 | MapInterval new_map = CreateMap(new_start, new_end, new_gpu_addr); | 233 | MapInterval new_map = CreateMap(new_start, new_end, new_gpu_addr); |
| 234 | if (modified_inheritance) { | ||
| 235 | new_map->MarkAsModified(true, GetModifiedTicks()); | ||
| 236 | } | ||
| 220 | Register(new_map, write_inheritance); | 237 | Register(new_map, write_inheritance); |
| 221 | return new_map; | 238 | return new_map; |
| 222 | } | 239 | } |
| @@ -258,6 +275,14 @@ private: | |||
| 258 | return ++modified_ticks; | 275 | return ++modified_ticks; |
| 259 | } | 276 | } |
| 260 | 277 | ||
| 278 | void FlushMap(MapInterval map) { | ||
| 279 | std::size_t size = map->GetEnd() - map->GetStart(); | ||
| 280 | TBuffer block = blocks[map->GetStart() >> block_page_bits]; | ||
| 281 | u8* host_ptr = FromCacheAddr(map->GetStart()); | ||
| 282 | DownloadBlockData(block, block->GetOffset(map->GetStart()), size, host_ptr); | ||
| 283 | map->MarkAsModified(false, 0); | ||
| 284 | } | ||
| 285 | |||
| 261 | BufferInfo StreamBufferUpload(const void* raw_pointer, std::size_t size, | 286 | BufferInfo StreamBufferUpload(const void* raw_pointer, std::size_t size, |
| 262 | std::size_t alignment) { | 287 | std::size_t alignment) { |
| 263 | AlignBuffer(alignment); | 288 | AlignBuffer(alignment); |