summaryrefslogtreecommitdiff
path: root/src/video_core/buffer_cache
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-04-04 02:54:55 -0300
committerGravatar ReinUsesLisp2020-04-16 02:33:34 -0300
commit090fd3fefab9ef251e6e5bf4011280a657340f2a (patch)
treeacfdc14d7e948ae296859d3d112f356f3279680c /src/video_core/buffer_cache
parentMerge pull request #3636 from ReinUsesLisp/drop-vk-hpp (diff)
downloadyuzu-090fd3fefab9ef251e6e5bf4011280a657340f2a.tar.gz
yuzu-090fd3fefab9ef251e6e5bf4011280a657340f2a.tar.xz
yuzu-090fd3fefab9ef251e6e5bf4011280a657340f2a.zip
buffer_cache: Return handles instead of pointer to handles
The original idea of returning pointers is that handles can be moved. The problem is that the implementation didn't take that in mind and made everything harder to work with. This commit drops pointer to handles and returns the handles themselves. While it is still true that handles can be invalidated, this way we get an old handle instead of a dangling pointer. This problem can be solved in the future with sparse buffers.
Diffstat (limited to 'src/video_core/buffer_cache')
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h47
1 files changed, 22 insertions, 25 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index b57c0d4d4..83e7a1cde 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -29,10 +29,10 @@ namespace VideoCommon {
29 29
30using MapInterval = std::shared_ptr<MapIntervalBase>; 30using MapInterval = std::shared_ptr<MapIntervalBase>;
31 31
32template <typename TBuffer, typename TBufferType, typename StreamBuffer> 32template <typename OwnerBuffer, typename BufferType, typename StreamBuffer>
33class BufferCache { 33class BufferCache {
34public: 34public:
35 using BufferInfo = std::pair<const TBufferType*, u64>; 35 using BufferInfo = std::pair<BufferType, u64>;
36 36
37 BufferInfo UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment = 4, 37 BufferInfo UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment = 4,
38 bool is_written = false, bool use_fast_cbuf = false) { 38 bool is_written = false, bool use_fast_cbuf = false) {
@@ -89,9 +89,7 @@ public:
89 } 89 }
90 } 90 }
91 91
92 const u64 offset = static_cast<u64>(block->GetOffset(cpu_addr)); 92 return {ToHandle(block), static_cast<u64>(block->GetOffset(cpu_addr))};
93
94 return {ToHandle(block), offset};
95 } 93 }
96 94
97 /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset. 95 /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset.
@@ -156,7 +154,7 @@ public:
156 } 154 }
157 } 155 }
158 156
159 virtual const TBufferType* GetEmptyBuffer(std::size_t size) = 0; 157 virtual BufferType GetEmptyBuffer(std::size_t size) = 0;
160 158
161protected: 159protected:
162 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system, 160 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system,
@@ -166,19 +164,19 @@ protected:
166 164
167 ~BufferCache() = default; 165 ~BufferCache() = default;
168 166
169 virtual const TBufferType* ToHandle(const TBuffer& storage) = 0; 167 virtual BufferType ToHandle(const OwnerBuffer& storage) = 0;
170 168
171 virtual void WriteBarrier() = 0; 169 virtual void WriteBarrier() = 0;
172 170
173 virtual TBuffer CreateBlock(VAddr cpu_addr, std::size_t size) = 0; 171 virtual OwnerBuffer CreateBlock(VAddr cpu_addr, std::size_t size) = 0;
174 172
175 virtual void UploadBlockData(const TBuffer& buffer, std::size_t offset, std::size_t size, 173 virtual void UploadBlockData(const OwnerBuffer& buffer, std::size_t offset, std::size_t size,
176 const u8* data) = 0; 174 const u8* data) = 0;
177 175
178 virtual void DownloadBlockData(const TBuffer& buffer, std::size_t offset, std::size_t size, 176 virtual void DownloadBlockData(const OwnerBuffer& buffer, std::size_t offset, std::size_t size,
179 u8* data) = 0; 177 u8* data) = 0;
180 178
181 virtual void CopyBlock(const TBuffer& src, const TBuffer& dst, std::size_t src_offset, 179 virtual void CopyBlock(const OwnerBuffer& src, const OwnerBuffer& dst, std::size_t src_offset,
182 std::size_t dst_offset, std::size_t size) = 0; 180 std::size_t dst_offset, std::size_t size) = 0;
183 181
184 virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) { 182 virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) {
@@ -221,9 +219,8 @@ private:
221 return std::make_shared<MapIntervalBase>(start, end, gpu_addr); 219 return std::make_shared<MapIntervalBase>(start, end, gpu_addr);
222 } 220 }
223 221
224 MapInterval MapAddress(const TBuffer& block, const GPUVAddr gpu_addr, const VAddr cpu_addr, 222 MapInterval MapAddress(const OwnerBuffer& block, const GPUVAddr gpu_addr, const VAddr cpu_addr,
225 const std::size_t size) { 223 const std::size_t size) {
226
227 std::vector<MapInterval> overlaps = GetMapsInRange(cpu_addr, size); 224 std::vector<MapInterval> overlaps = GetMapsInRange(cpu_addr, size);
228 if (overlaps.empty()) { 225 if (overlaps.empty()) {
229 auto& memory_manager = system.GPU().MemoryManager(); 226 auto& memory_manager = system.GPU().MemoryManager();
@@ -272,7 +269,7 @@ private:
272 return new_map; 269 return new_map;
273 } 270 }
274 271
275 void UpdateBlock(const TBuffer& block, VAddr start, VAddr end, 272 void UpdateBlock(const OwnerBuffer& block, VAddr start, VAddr end,
276 std::vector<MapInterval>& overlaps) { 273 std::vector<MapInterval>& overlaps) {
277 const IntervalType base_interval{start, end}; 274 const IntervalType base_interval{start, end};
278 IntervalSet interval_set{}; 275 IntervalSet interval_set{};
@@ -313,7 +310,7 @@ private:
313 310
314 void FlushMap(MapInterval map) { 311 void FlushMap(MapInterval map) {
315 std::size_t size = map->GetEnd() - map->GetStart(); 312 std::size_t size = map->GetEnd() - map->GetStart();
316 TBuffer block = blocks[map->GetStart() >> block_page_bits]; 313 OwnerBuffer block = blocks[map->GetStart() >> block_page_bits];
317 staging_buffer.resize(size); 314 staging_buffer.resize(size);
318 DownloadBlockData(block, block->GetOffset(map->GetStart()), size, staging_buffer.data()); 315 DownloadBlockData(block, block->GetOffset(map->GetStart()), size, staging_buffer.data());
319 system.Memory().WriteBlockUnsafe(map->GetStart(), staging_buffer.data(), size); 316 system.Memory().WriteBlockUnsafe(map->GetStart(), staging_buffer.data(), size);
@@ -328,7 +325,7 @@ private:
328 325
329 buffer_ptr += size; 326 buffer_ptr += size;
330 buffer_offset += size; 327 buffer_offset += size;
331 return {&stream_buffer_handle, uploaded_offset}; 328 return {stream_buffer_handle, uploaded_offset};
332 } 329 }
333 330
334 void AlignBuffer(std::size_t alignment) { 331 void AlignBuffer(std::size_t alignment) {
@@ -338,11 +335,11 @@ private:
338 buffer_offset = offset_aligned; 335 buffer_offset = offset_aligned;
339 } 336 }
340 337
341 TBuffer EnlargeBlock(TBuffer buffer) { 338 OwnerBuffer EnlargeBlock(OwnerBuffer buffer) {
342 const std::size_t old_size = buffer->GetSize(); 339 const std::size_t old_size = buffer->GetSize();
343 const std::size_t new_size = old_size + block_page_size; 340 const std::size_t new_size = old_size + block_page_size;
344 const VAddr cpu_addr = buffer->GetCpuAddr(); 341 const VAddr cpu_addr = buffer->GetCpuAddr();
345 TBuffer new_buffer = CreateBlock(cpu_addr, new_size); 342 OwnerBuffer new_buffer = CreateBlock(cpu_addr, new_size);
346 CopyBlock(buffer, new_buffer, 0, 0, old_size); 343 CopyBlock(buffer, new_buffer, 0, 0, old_size);
347 buffer->SetEpoch(epoch); 344 buffer->SetEpoch(epoch);
348 pending_destruction.push_back(buffer); 345 pending_destruction.push_back(buffer);
@@ -356,14 +353,14 @@ private:
356 return new_buffer; 353 return new_buffer;
357 } 354 }
358 355
359 TBuffer MergeBlocks(TBuffer first, TBuffer second) { 356 OwnerBuffer MergeBlocks(OwnerBuffer first, OwnerBuffer second) {
360 const std::size_t size_1 = first->GetSize(); 357 const std::size_t size_1 = first->GetSize();
361 const std::size_t size_2 = second->GetSize(); 358 const std::size_t size_2 = second->GetSize();
362 const VAddr first_addr = first->GetCpuAddr(); 359 const VAddr first_addr = first->GetCpuAddr();
363 const VAddr second_addr = second->GetCpuAddr(); 360 const VAddr second_addr = second->GetCpuAddr();
364 const VAddr new_addr = std::min(first_addr, second_addr); 361 const VAddr new_addr = std::min(first_addr, second_addr);
365 const std::size_t new_size = size_1 + size_2; 362 const std::size_t new_size = size_1 + size_2;
366 TBuffer new_buffer = CreateBlock(new_addr, new_size); 363 OwnerBuffer new_buffer = CreateBlock(new_addr, new_size);
367 CopyBlock(first, new_buffer, 0, new_buffer->GetOffset(first_addr), size_1); 364 CopyBlock(first, new_buffer, 0, new_buffer->GetOffset(first_addr), size_1);
368 CopyBlock(second, new_buffer, 0, new_buffer->GetOffset(second_addr), size_2); 365 CopyBlock(second, new_buffer, 0, new_buffer->GetOffset(second_addr), size_2);
369 first->SetEpoch(epoch); 366 first->SetEpoch(epoch);
@@ -380,8 +377,8 @@ private:
380 return new_buffer; 377 return new_buffer;
381 } 378 }
382 379
383 TBuffer GetBlock(const VAddr cpu_addr, const std::size_t size) { 380 OwnerBuffer GetBlock(const VAddr cpu_addr, const std::size_t size) {
384 TBuffer found{}; 381 OwnerBuffer found;
385 const VAddr cpu_addr_end = cpu_addr + size - 1; 382 const VAddr cpu_addr_end = cpu_addr + size - 1;
386 u64 page_start = cpu_addr >> block_page_bits; 383 u64 page_start = cpu_addr >> block_page_bits;
387 const u64 page_end = cpu_addr_end >> block_page_bits; 384 const u64 page_end = cpu_addr_end >> block_page_bits;
@@ -457,7 +454,7 @@ private:
457 Core::System& system; 454 Core::System& system;
458 455
459 std::unique_ptr<StreamBuffer> stream_buffer; 456 std::unique_ptr<StreamBuffer> stream_buffer;
460 TBufferType stream_buffer_handle{}; 457 BufferType stream_buffer_handle{};
461 458
462 bool invalidated = false; 459 bool invalidated = false;
463 460
@@ -475,9 +472,9 @@ private:
475 472
476 static constexpr u64 block_page_bits = 21; 473 static constexpr u64 block_page_bits = 21;
477 static constexpr u64 block_page_size = 1ULL << block_page_bits; 474 static constexpr u64 block_page_size = 1ULL << block_page_bits;
478 std::unordered_map<u64, TBuffer> blocks; 475 std::unordered_map<u64, OwnerBuffer> blocks;
479 476
480 std::list<TBuffer> pending_destruction; 477 std::list<OwnerBuffer> pending_destruction;
481 u64 epoch = 0; 478 u64 epoch = 0;
482 u64 modified_ticks = 0; 479 u64 modified_ticks = 0;
483 480