summaryrefslogtreecommitdiff
path: root/src/video_core/buffer_cache
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-07-19 13:22:27 -0400
committerGravatar FernandoS272019-08-21 12:14:23 -0400
commit86d8563314c615d60c7b59748467ffb71904b0c4 (patch)
treef954328c9299fe8c241da7007259a98e7fdd451a /src/video_core/buffer_cache
parentVideo_Core: Implement a new Buffer Cache (diff)
downloadyuzu-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.h104
-rw-r--r--src/video_core/buffer_cache/map_interval.h2
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
22namespace VideoCore { 22namespace 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
150private: 150private:
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