diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2021-01-18 04:56:59 +0100 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2021-02-13 06:17:24 +0100 |
commit | ec9354d6d92f4190d06dfb6b86e0098fa0108eac (patch) | |
tree | 64240fcee73fd362c21eed3667fbbf6475d46313 /src/video_core | |
parent | buffer_cache: Skip cache on small uploads on Vulkan (diff) | |
download | yuzu-ec9354d6d92f4190d06dfb6b86e0098fa0108eac.tar yuzu-ec9354d6d92f4190d06dfb6b86e0098fa0108eac.tar.gz yuzu-ec9354d6d92f4190d06dfb6b86e0098fa0108eac.tar.bz2 yuzu-ec9354d6d92f4190d06dfb6b86e0098fa0108eac.tar.lz yuzu-ec9354d6d92f4190d06dfb6b86e0098fa0108eac.tar.xz yuzu-ec9354d6d92f4190d06dfb6b86e0098fa0108eac.tar.zst yuzu-ec9354d6d92f4190d06dfb6b86e0098fa0108eac.zip |
Diffstat (limited to '')
-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 { struct Empty {}; + struct OverlapResult { + std::vector<BufferId> ids; + VAddr begin; + VAddr end; + }; + struct Binding { VAddr cpu_addr{}; u32 size{}; @@ -220,6 +226,10 @@ private: [[nodiscard]] BufferId FindBuffer(VAddr cpu_addr, u32 size); + [[nodiscard]] OverlapResult ResolveOverlaps(VAddr cpu_addr, u32 wanted_size); + + void JoinOverlap(BufferId new_buffer_id, BufferId overlap_id); + [[nodiscard]] BufferId CreateBuffer(VAddr cpu_addr, u32 wanted_size); void Register(BufferId buffer_id); @@ -988,12 +998,12 @@ BufferId BufferCache<P>::FindBuffer(VAddr cpu_addr, u32 size) { } template <class P> -BufferId BufferCache<P>::CreateBuffer(VAddr cpu_addr, u32 wanted_size) { +typename BufferCache<P>::OverlapResult BufferCache<P>::ResolveOverlaps(VAddr cpu_addr, + u32 wanted_size) { std::vector<BufferId> overlap_ids; - VAddr cpu_addr_begin = cpu_addr; - VAddr cpu_addr_end = cpu_addr + wanted_size; - for (; cpu_addr >> PAGE_BITS < Common::DivCeil(cpu_addr_end, PAGE_SIZE); - cpu_addr += PAGE_SIZE) { + VAddr begin = cpu_addr; + VAddr end = cpu_addr + wanted_size; + for (; cpu_addr >> PAGE_BITS < Common::DivCeil(end, PAGE_SIZE); cpu_addr += PAGE_SIZE) { const BufferId overlap_id = page_table[cpu_addr >> PAGE_BITS]; if (!overlap_id) { continue; @@ -1005,35 +1015,48 @@ BufferId BufferCache<P>::CreateBuffer(VAddr cpu_addr, u32 wanted_size) { overlap.Pick(); overlap_ids.push_back(overlap_id); const VAddr overlap_cpu_addr = overlap.CpuAddr(); - if (overlap_cpu_addr < cpu_addr_begin) { - cpu_addr = cpu_addr_begin = overlap_cpu_addr; + if (overlap_cpu_addr < begin) { + cpu_addr = begin = overlap_cpu_addr; } - cpu_addr_end = std::max(cpu_addr_end, overlap_cpu_addr + overlap.SizeBytes()); + end = std::max(end, overlap_cpu_addr + overlap.SizeBytes()); } - const u32 size = static_cast<u32>(cpu_addr_end - cpu_addr_begin); - const BufferId new_buffer_id = slot_buffers.insert(runtime, rasterizer, cpu_addr_begin, size); - Buffer& new_buffer = slot_buffers[new_buffer_id]; + return OverlapResult{ + .ids = std::move(overlap_ids), + .begin = begin, + .end = end, + }; +} - for (const BufferId overlap_id : overlap_ids) { - Buffer& overlap = slot_buffers[overlap_id]; - overlap.Unpick(); +template <class P> +void BufferCache<P>::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id) { + Buffer& new_buffer = slot_buffers[new_buffer_id]; + Buffer& overlap = slot_buffers[overlap_id]; - std::vector<BufferCopy> copies; - const size_t dst_base_offset = overlap.CpuAddr() - new_buffer.CpuAddr(); - overlap.ForEachDownloadRange([&](u64 begin, u64 range_size) { - copies.push_back(BufferCopy{ - .src_offset = begin, - .dst_offset = dst_base_offset + begin, - .size = range_size, - }); - new_buffer.UnmarkRegionAsCpuModified(begin, range_size); - new_buffer.MarkRegionAsGpuModified(begin, range_size); + std::vector<BufferCopy> copies; + const size_t dst_base_offset = overlap.CpuAddr() - new_buffer.CpuAddr(); + overlap.ForEachDownloadRange([&](u64 begin, u64 range_size) { + copies.push_back(BufferCopy{ + .src_offset = begin, + .dst_offset = dst_base_offset + begin, + .size = range_size, }); - if (!copies.empty()) { - runtime.CopyBuffer(slot_buffers[new_buffer_id], overlap, copies); - } - ReplaceBufferDownloads(overlap_id, new_buffer_id); - DeleteBuffer(overlap_id); + new_buffer.UnmarkRegionAsCpuModified(begin, range_size); + new_buffer.MarkRegionAsGpuModified(begin, range_size); + }); + if (!copies.empty()) { + runtime.CopyBuffer(slot_buffers[new_buffer_id], overlap, copies); + } + ReplaceBufferDownloads(overlap_id, new_buffer_id); + DeleteBuffer(overlap_id); +} + +template <class P> +BufferId BufferCache<P>::CreateBuffer(VAddr cpu_addr, u32 wanted_size) { + const OverlapResult overlap = ResolveOverlaps(cpu_addr, wanted_size); + const u32 size = static_cast<u32>(overlap.end - overlap.begin); + const BufferId new_buffer_id = slot_buffers.insert(runtime, rasterizer, overlap.begin, size); + for (const BufferId overlap_id : overlap.ids) { + JoinOverlap(new_buffer_id, overlap_id); } Register(new_buffer_id); return new_buffer_id; |