From ee67baba489135a4f2baf40d625a6319d8bebd2d Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 30 Jun 2018 02:09:34 -0400 Subject: [PATCH] gl_rasterizer_cache: Track page counts in CPU virtual addresses. --- src/core/memory.cpp | 19 ++++--------------- src/core/memory.h | 2 +- .../renderer_opengl/gl_rasterizer_cache.cpp | 18 ++++++++---------- .../renderer_opengl/gl_rasterizer_cache.h | 2 +- 4 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index f070dee7dc..a0e1c8a8ac 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -332,8 +332,8 @@ u8* GetPhysicalPointer(PAddr address) { return target_pointer; } -void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) { - if (gpu_addr == 0) { +void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { + if (vaddr == 0) { return; } @@ -342,19 +342,8 @@ void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) // CPU pages, hence why we iterate on a CPU page basis (note: GPU page size is different). This // assumes the specified GPU address region is contiguous as well. - u64 num_pages = ((gpu_addr + size - 1) >> PAGE_BITS) - (gpu_addr >> PAGE_BITS) + 1; - for (unsigned i = 0; i < num_pages; ++i, gpu_addr += PAGE_SIZE) { - boost::optional maybe_vaddr = - Core::System::GetInstance().GPU().memory_manager->GpuToCpuAddress(gpu_addr); - // The GPU <-> CPU virtual memory mapping is not 1:1 - if (!maybe_vaddr) { - NGLOG_ERROR(HW_Memory, - "Trying to flush a cached region to an invalid physical address {:016X}", - gpu_addr); - continue; - } - VAddr vaddr = *maybe_vaddr; - + u64 num_pages = ((vaddr + size - 1) >> PAGE_BITS) - (vaddr >> PAGE_BITS) + 1; + for (unsigned i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) { PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; if (cached) { diff --git a/src/core/memory.h b/src/core/memory.h index 8d5d017a46..48015cfa43 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -266,7 +266,7 @@ enum class FlushMode { /** * Mark each page touching the region as cached. */ -void RasterizerMarkRegionCached(Tegra::GPUVAddr start, u64 size, bool cached); +void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached); /** * Flushes and invalidates any externally cached rasterizer resources touching the given virtual diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 4746b54ad3..1872d0723d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -523,7 +523,7 @@ void RasterizerCacheOpenGL::RegisterSurface(const Surface& surface) { } surface_cache[surface_key] = surface; - UpdatePagesCachedCount(params.addr, params.size_in_bytes, 1); + UpdatePagesCachedCount(params.cpu_addr, params.size_in_bytes, 1); } void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) { @@ -536,7 +536,7 @@ void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) { return; } - UpdatePagesCachedCount(params.addr, params.size_in_bytes, -1); + UpdatePagesCachedCount(params.cpu_addr, params.size_in_bytes, -1); surface_cache.erase(search); } @@ -545,10 +545,10 @@ constexpr auto RangeFromInterval(Map& map, const Interval& interval) { return boost::make_iterator_range(map.equal_range(interval)); } -void RasterizerCacheOpenGL::UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) { - const u64 num_pages = ((addr + size - 1) >> Tegra::MemoryManager::PAGE_BITS) - - (addr >> Tegra::MemoryManager::PAGE_BITS) + 1; - const u64 page_start = addr >> Tegra::MemoryManager::PAGE_BITS; +void RasterizerCacheOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { + const u64 num_pages = + ((addr + size - 1) >> Memory::PAGE_BITS) - (addr >> Memory::PAGE_BITS) + 1; + const u64 page_start = addr >> Memory::PAGE_BITS; const u64 page_end = page_start + num_pages; // Interval maps will erase segments if count reaches 0, so if delta is negative we have to @@ -561,10 +561,8 @@ void RasterizerCacheOpenGL::UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 siz const auto interval = pair.first & pages_interval; const int count = pair.second; - const Tegra::GPUVAddr interval_start_addr = boost::icl::first(interval) - << Tegra::MemoryManager::PAGE_BITS; - const Tegra::GPUVAddr interval_end_addr = boost::icl::last_next(interval) - << Tegra::MemoryManager::PAGE_BITS; + const VAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS; + const VAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS; const u64 interval_size = interval_end_addr - interval_start_addr; if (delta > 0 && count == delta) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index a06129e73b..5e7b32c4c3 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -367,7 +367,7 @@ private: void UnregisterSurface(const Surface& surface); /// Increase/decrease the number of surface in pages touching the specified region - void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta); + void UpdatePagesCachedCount(VAddr addr, u64 size, int delta); std::unordered_map surface_cache; PageMap cached_pages;