From 83255ee68f74a2dc6b64c99529434044d220d413 Mon Sep 17 00:00:00 2001 From: Lander Gallastegi Date: Thu, 17 Apr 2025 14:26:07 +0200 Subject: [PATCH] Queue coverage --- src/video_core/buffer_cache/buffer_cache.cpp | 25 ++++++++++++++++--- src/video_core/buffer_cache/buffer_cache.h | 10 +++++++- .../renderer_vulkan/vk_rasterizer.cpp | 1 + 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_cache.cpp b/src/video_core/buffer_cache/buffer_cache.cpp index 38a874d8f..877770bc7 100644 --- a/src/video_core/buffer_cache/buffer_cache.cpp +++ b/src/video_core/buffer_cache/buffer_cache.cpp @@ -323,9 +323,28 @@ BufferId BufferCache::FindBuffer(VAddr device_addr, u32 size) { return CreateBuffer(device_addr, size); } -void BufferCache::MapMemory(VAddr device_addr, u64 size) { - const u64 page_start = device_addr >> CACHING_PAGEBITS; - const u64 page_end = Common::DivCeil(device_addr + size, CACHING_PAGESIZE); +void BufferCache::QueueCoverage(VAddr device_addr, u64 size) { + std::scoped_lock lk{mutex}; + const u64 start = device_addr; + const u64 end = device_addr + size; + auto queue_range = decltype(covered_regions)::interval_type::right_open(start, end); + queued_coverage += queue_range; +} + +void BufferCache::CoverQueuedRegions() { + std::scoped_lock lk{mutex}; + if (queued_coverage.empty()) { + return; + } + for (const auto& range : queued_coverage) { + CoverMemory(range.lower(), range.upper()); + } + queued_coverage.clear(); +} + +void BufferCache::CoverMemory(u64 start, u64 end) { + const u64 page_start = start >> CACHING_PAGEBITS; + const u64 page_end = Common::DivCeil(end, CACHING_PAGESIZE); auto interval = decltype(covered_regions)::interval_type::right_open(page_start, page_end); auto interval_set = boost::icl::interval_set{interval}; auto uncovered_ranges = interval_set - covered_regions; diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index bab6bf98e..74d45005f 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -119,8 +119,15 @@ public: /// Return true when a CPU region is modified from the GPU [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); + /// Return buffer id for the specified region [[nodiscard]] BufferId FindBuffer(VAddr device_addr, u32 size); + /// Queue a region for coverage for DMA. + void QueueCoverage(VAddr device_addr, u64 size); + + /// Covers all queued regions. + void CoverQueuedRegions(); + private: template void ForEachBufferInRange(VAddr device_addr, u64 size, Func&& func) { @@ -164,7 +171,7 @@ private: void DeleteBuffer(BufferId buffer_id); - void MapMemory(VAddr device_addr, u64 size); + void CoverMemory(u64 start, u64 end); const Vulkan::Instance& instance; Vulkan::Scheduler& scheduler; @@ -176,6 +183,7 @@ private: StreamBuffer stream_buffer; Buffer gds_buffer; Buffer bda_pagetable_buffer; + boost::icl::interval_set queued_coverage; boost::icl::interval_set covered_regions; std::vector imported_buffers; std::shared_mutex mutex; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index a1bb9af14..c12e3335e 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -946,6 +946,7 @@ void Rasterizer::MapMemory(VAddr addr, u64 size) { mapped_ranges += decltype(mapped_ranges)::interval_type::right_open(addr, addr + size); } page_manager.OnGpuMap(addr, size); + buffer_cache.QueueCoverage(addr, size); } void Rasterizer::UnmapMemory(VAddr addr, u64 size) {