diff options
| author | 2021-01-18 00:56:59 -0300 | |
|---|---|---|
| committer | 2021-02-13 02:17:24 -0300 | |
| commit | ec9354d6d92f4190d06dfb6b86e0098fa0108eac (patch) | |
| tree | 64240fcee73fd362c21eed3667fbbf6475d46313 /src/video_core/buffer_cache | |
| parent | buffer_cache: Skip cache on small uploads on Vulkan (diff) | |
| download | yuzu-ec9354d6d92f4190d06dfb6b86e0098fa0108eac.tar.gz yuzu-ec9354d6d92f4190d06dfb6b86e0098fa0108eac.tar.xz yuzu-ec9354d6d92f4190d06dfb6b86e0098fa0108eac.zip | |
buffer_cache: Split CreateBuffer in separate functions
Allow adding functionality to each function without making CreateBuffer
more complex.
Diffstat (limited to 'src/video_core/buffer_cache')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 81 |
1 files changed, 52 insertions, 29 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index bd8507610..3c44c3b39 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -71,6 +71,12 @@ class BufferCache { | |||
| 71 | 71 | ||
| 72 | struct Empty {}; | 72 | struct Empty {}; |
| 73 | 73 | ||
| 74 | struct OverlapResult { | ||
| 75 | std::vector<BufferId> ids; | ||
| 76 | VAddr begin; | ||
| 77 | VAddr end; | ||
| 78 | }; | ||
| 79 | |||
| 74 | struct Binding { | 80 | struct Binding { |
| 75 | VAddr cpu_addr{}; | 81 | VAddr cpu_addr{}; |
| 76 | u32 size{}; | 82 | u32 size{}; |
| @@ -220,6 +226,10 @@ private: | |||
| 220 | 226 | ||
| 221 | [[nodiscard]] BufferId FindBuffer(VAddr cpu_addr, u32 size); | 227 | [[nodiscard]] BufferId FindBuffer(VAddr cpu_addr, u32 size); |
| 222 | 228 | ||
| 229 | [[nodiscard]] OverlapResult ResolveOverlaps(VAddr cpu_addr, u32 wanted_size); | ||
| 230 | |||
| 231 | void JoinOverlap(BufferId new_buffer_id, BufferId overlap_id); | ||
| 232 | |||
| 223 | [[nodiscard]] BufferId CreateBuffer(VAddr cpu_addr, u32 wanted_size); | 233 | [[nodiscard]] BufferId CreateBuffer(VAddr cpu_addr, u32 wanted_size); |
| 224 | 234 | ||
| 225 | void Register(BufferId buffer_id); | 235 | void Register(BufferId buffer_id); |
| @@ -988,12 +998,12 @@ BufferId BufferCache<P>::FindBuffer(VAddr cpu_addr, u32 size) { | |||
| 988 | } | 998 | } |
| 989 | 999 | ||
| 990 | template <class P> | 1000 | template <class P> |
| 991 | BufferId BufferCache<P>::CreateBuffer(VAddr cpu_addr, u32 wanted_size) { | 1001 | typename BufferCache<P>::OverlapResult BufferCache<P>::ResolveOverlaps(VAddr cpu_addr, |
| 1002 | u32 wanted_size) { | ||
| 992 | std::vector<BufferId> overlap_ids; | 1003 | std::vector<BufferId> overlap_ids; |
| 993 | VAddr cpu_addr_begin = cpu_addr; | 1004 | VAddr begin = cpu_addr; |
| 994 | VAddr cpu_addr_end = cpu_addr + wanted_size; | 1005 | VAddr end = cpu_addr + wanted_size; |
| 995 | for (; cpu_addr >> PAGE_BITS < Common::DivCeil(cpu_addr_end, PAGE_SIZE); | 1006 | for (; cpu_addr >> PAGE_BITS < Common::DivCeil(end, PAGE_SIZE); cpu_addr += PAGE_SIZE) { |
| 996 | cpu_addr += PAGE_SIZE) { | ||
| 997 | const BufferId overlap_id = page_table[cpu_addr >> PAGE_BITS]; | 1007 | const BufferId overlap_id = page_table[cpu_addr >> PAGE_BITS]; |
| 998 | if (!overlap_id) { | 1008 | if (!overlap_id) { |
| 999 | continue; | 1009 | continue; |
| @@ -1005,35 +1015,48 @@ BufferId BufferCache<P>::CreateBuffer(VAddr cpu_addr, u32 wanted_size) { | |||
| 1005 | overlap.Pick(); | 1015 | overlap.Pick(); |
| 1006 | overlap_ids.push_back(overlap_id); | 1016 | overlap_ids.push_back(overlap_id); |
| 1007 | const VAddr overlap_cpu_addr = overlap.CpuAddr(); | 1017 | const VAddr overlap_cpu_addr = overlap.CpuAddr(); |
| 1008 | if (overlap_cpu_addr < cpu_addr_begin) { | 1018 | if (overlap_cpu_addr < begin) { |
| 1009 | cpu_addr = cpu_addr_begin = overlap_cpu_addr; | 1019 | cpu_addr = begin = overlap_cpu_addr; |
| 1010 | } | 1020 | } |
| 1011 | cpu_addr_end = std::max(cpu_addr_end, overlap_cpu_addr + overlap.SizeBytes()); | 1021 | end = std::max(end, overlap_cpu_addr + overlap.SizeBytes()); |
| 1012 | } | 1022 | } |
| 1013 | const u32 size = static_cast<u32>(cpu_addr_end - cpu_addr_begin); | 1023 | return OverlapResult{ |
| 1014 | const BufferId new_buffer_id = slot_buffers.insert(runtime, rasterizer, cpu_addr_begin, size); | 1024 | .ids = std::move(overlap_ids), |
| 1015 | Buffer& new_buffer = slot_buffers[new_buffer_id]; | 1025 | .begin = begin, |
| 1026 | .end = end, | ||
| 1027 | }; | ||
| 1028 | } | ||
| 1016 | 1029 | ||
| 1017 | for (const BufferId overlap_id : overlap_ids) { | 1030 | template <class P> |
| 1018 | Buffer& overlap = slot_buffers[overlap_id]; | 1031 | void BufferCache<P>::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id) { |
| 1019 | overlap.Unpick(); | 1032 | Buffer& new_buffer = slot_buffers[new_buffer_id]; |
| 1033 | Buffer& overlap = slot_buffers[overlap_id]; | ||
| 1020 | 1034 | ||
| 1021 | std::vector<BufferCopy> copies; | 1035 | std::vector<BufferCopy> copies; |
| 1022 | const size_t dst_base_offset = overlap.CpuAddr() - new_buffer.CpuAddr(); | 1036 | const size_t dst_base_offset = overlap.CpuAddr() - new_buffer.CpuAddr(); |
| 1023 | overlap.ForEachDownloadRange([&](u64 begin, u64 range_size) { | 1037 | overlap.ForEachDownloadRange([&](u64 begin, u64 range_size) { |
| 1024 | copies.push_back(BufferCopy{ | 1038 | copies.push_back(BufferCopy{ |
| 1025 | .src_offset = begin, | 1039 | .src_offset = begin, |
| 1026 | .dst_offset = dst_base_offset + begin, | 1040 | .dst_offset = dst_base_offset + begin, |
| 1027 | .size = range_size, | 1041 | .size = range_size, |
| 1028 | }); | ||
| 1029 | new_buffer.UnmarkRegionAsCpuModified(begin, range_size); | ||
| 1030 | new_buffer.MarkRegionAsGpuModified(begin, range_size); | ||
| 1031 | }); | 1042 | }); |
| 1032 | if (!copies.empty()) { | 1043 | new_buffer.UnmarkRegionAsCpuModified(begin, range_size); |
| 1033 | runtime.CopyBuffer(slot_buffers[new_buffer_id], overlap, copies); | 1044 | new_buffer.MarkRegionAsGpuModified(begin, range_size); |
| 1034 | } | 1045 | }); |
| 1035 | ReplaceBufferDownloads(overlap_id, new_buffer_id); | 1046 | if (!copies.empty()) { |
| 1036 | DeleteBuffer(overlap_id); | 1047 | runtime.CopyBuffer(slot_buffers[new_buffer_id], overlap, copies); |
| 1048 | } | ||
| 1049 | ReplaceBufferDownloads(overlap_id, new_buffer_id); | ||
| 1050 | DeleteBuffer(overlap_id); | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | template <class P> | ||
| 1054 | BufferId BufferCache<P>::CreateBuffer(VAddr cpu_addr, u32 wanted_size) { | ||
| 1055 | const OverlapResult overlap = ResolveOverlaps(cpu_addr, wanted_size); | ||
| 1056 | const u32 size = static_cast<u32>(overlap.end - overlap.begin); | ||
| 1057 | const BufferId new_buffer_id = slot_buffers.insert(runtime, rasterizer, overlap.begin, size); | ||
| 1058 | for (const BufferId overlap_id : overlap.ids) { | ||
| 1059 | JoinOverlap(new_buffer_id, overlap_id); | ||
| 1037 | } | 1060 | } |
| 1038 | Register(new_buffer_id); | 1061 | Register(new_buffer_id); |
| 1039 | return new_buffer_id; | 1062 | return new_buffer_id; |