diff options
| author | 2020-05-27 23:05:50 -0300 | |
|---|---|---|
| committer | 2020-05-27 23:05:50 -0300 | |
| commit | 3b2dee88e67eaa968fd0dba19d10871e0b6570b9 (patch) | |
| tree | 2a5b4ec8137821e0de61ff8a1860e3c71a6eb443 /src/video_core/buffer_cache | |
| parent | Merge pull request #3981 from ReinUsesLisp/bar (diff) | |
| download | yuzu-3b2dee88e67eaa968fd0dba19d10871e0b6570b9.tar.gz yuzu-3b2dee88e67eaa968fd0dba19d10871e0b6570b9.tar.xz yuzu-3b2dee88e67eaa968fd0dba19d10871e0b6570b9.zip | |
buffer_cache: Avoid copying twice on certain cases
Avoid copying to a staging buffer on non-granular memory addresses.
Add a callable argument to StreamBufferUpload to be able to copy to the
staging buffer directly from ReadBlockUnsafe.
Diffstat (limited to 'src/video_core/buffer_cache')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index d9a4a1b4d..b88fce2cd 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -56,24 +56,28 @@ public: | |||
| 56 | if (use_fast_cbuf || size < max_stream_size) { | 56 | if (use_fast_cbuf || size < max_stream_size) { |
| 57 | if (!is_written && !IsRegionWritten(cpu_addr, cpu_addr + size - 1)) { | 57 | if (!is_written && !IsRegionWritten(cpu_addr, cpu_addr + size - 1)) { |
| 58 | auto& memory_manager = system.GPU().MemoryManager(); | 58 | auto& memory_manager = system.GPU().MemoryManager(); |
| 59 | const bool is_granular = memory_manager.IsGranularRange(gpu_addr, size); | ||
| 59 | if (use_fast_cbuf) { | 60 | if (use_fast_cbuf) { |
| 60 | if (memory_manager.IsGranularRange(gpu_addr, size)) { | 61 | u8* dest; |
| 61 | const auto host_ptr = memory_manager.GetPointer(gpu_addr); | 62 | if (is_granular) { |
| 62 | return ConstBufferUpload(host_ptr, size); | 63 | dest = memory_manager.GetPointer(gpu_addr); |
| 63 | } else { | 64 | } else { |
| 64 | staging_buffer.resize(size); | 65 | staging_buffer.resize(size); |
| 65 | memory_manager.ReadBlockUnsafe(gpu_addr, staging_buffer.data(), size); | 66 | dest = staging_buffer.data(); |
| 66 | return ConstBufferUpload(staging_buffer.data(), size); | 67 | memory_manager.ReadBlockUnsafe(gpu_addr, dest, size); |
| 67 | } | 68 | } |
| 69 | return ConstBufferUpload(dest, size); | ||
| 70 | } | ||
| 71 | if (is_granular) { | ||
| 72 | u8* const host_ptr = memory_manager.GetPointer(gpu_addr); | ||
| 73 | return StreamBufferUpload(size, alignment, [host_ptr, size](u8* dest) { | ||
| 74 | std::memcpy(dest, host_ptr, size); | ||
| 75 | }); | ||
| 68 | } else { | 76 | } else { |
| 69 | if (memory_manager.IsGranularRange(gpu_addr, size)) { | 77 | return StreamBufferUpload( |
| 70 | const auto host_ptr = memory_manager.GetPointer(gpu_addr); | 78 | size, alignment, [&memory_manager, gpu_addr, size](u8* dest) { |
| 71 | return StreamBufferUpload(host_ptr, size, alignment); | 79 | memory_manager.ReadBlockUnsafe(gpu_addr, dest, size); |
| 72 | } else { | 80 | }); |
| 73 | staging_buffer.resize(size); | ||
| 74 | memory_manager.ReadBlockUnsafe(gpu_addr, staging_buffer.data(), size); | ||
| 75 | return StreamBufferUpload(staging_buffer.data(), size, alignment); | ||
| 76 | } | ||
| 77 | } | 81 | } |
| 78 | } | 82 | } |
| 79 | } | 83 | } |
| @@ -101,7 +105,9 @@ public: | |||
| 101 | BufferInfo UploadHostMemory(const void* raw_pointer, std::size_t size, | 105 | BufferInfo UploadHostMemory(const void* raw_pointer, std::size_t size, |
| 102 | std::size_t alignment = 4) { | 106 | std::size_t alignment = 4) { |
| 103 | std::lock_guard lock{mutex}; | 107 | std::lock_guard lock{mutex}; |
| 104 | return StreamBufferUpload(raw_pointer, size, alignment); | 108 | return StreamBufferUpload(size, alignment, [raw_pointer, size](u8* dest) { |
| 109 | std::memcpy(dest, raw_pointer, size); | ||
| 110 | }); | ||
| 105 | } | 111 | } |
| 106 | 112 | ||
| 107 | void Map(std::size_t max_size) { | 113 | void Map(std::size_t max_size) { |
| @@ -424,11 +430,11 @@ private: | |||
| 424 | map->MarkAsModified(false, 0); | 430 | map->MarkAsModified(false, 0); |
| 425 | } | 431 | } |
| 426 | 432 | ||
| 427 | BufferInfo StreamBufferUpload(const void* raw_pointer, std::size_t size, | 433 | template <typename Callable> |
| 428 | std::size_t alignment) { | 434 | BufferInfo StreamBufferUpload(std::size_t size, std::size_t alignment, Callable&& callable) { |
| 429 | AlignBuffer(alignment); | 435 | AlignBuffer(alignment); |
| 430 | const std::size_t uploaded_offset = buffer_offset; | 436 | const std::size_t uploaded_offset = buffer_offset; |
| 431 | std::memcpy(buffer_ptr, raw_pointer, size); | 437 | callable(buffer_ptr); |
| 432 | 438 | ||
| 433 | buffer_ptr += size; | 439 | buffer_ptr += size; |
| 434 | buffer_offset += size; | 440 | buffer_offset += size; |