gl_rasterizer_cache: Track page counts in CPU virtual addresses.
This commit is contained in:
+4
-15
@@ -332,8 +332,8 @@ u8* GetPhysicalPointer(PAddr address) {
|
|||||||
return target_pointer;
|
return target_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) {
|
void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) {
|
||||||
if (gpu_addr == 0) {
|
if (vaddr == 0) {
|
||||||
return;
|
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
|
// 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.
|
// assumes the specified GPU address region is contiguous as well.
|
||||||
|
|
||||||
u64 num_pages = ((gpu_addr + size - 1) >> PAGE_BITS) - (gpu_addr >> PAGE_BITS) + 1;
|
u64 num_pages = ((vaddr + size - 1) >> PAGE_BITS) - (vaddr >> PAGE_BITS) + 1;
|
||||||
for (unsigned i = 0; i < num_pages; ++i, gpu_addr += PAGE_SIZE) {
|
for (unsigned i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) {
|
||||||
boost::optional<VAddr> 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;
|
|
||||||
|
|
||||||
PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
|
PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
|
||||||
|
|
||||||
if (cached) {
|
if (cached) {
|
||||||
|
|||||||
+1
-1
@@ -266,7 +266,7 @@ enum class FlushMode {
|
|||||||
/**
|
/**
|
||||||
* Mark each page touching the region as cached.
|
* 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
|
* Flushes and invalidates any externally cached rasterizer resources touching the given virtual
|
||||||
|
|||||||
@@ -523,7 +523,7 @@ void RasterizerCacheOpenGL::RegisterSurface(const Surface& surface) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
surface_cache[surface_key] = 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) {
|
void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) {
|
||||||
@@ -536,7 +536,7 @@ void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePagesCachedCount(params.addr, params.size_in_bytes, -1);
|
UpdatePagesCachedCount(params.cpu_addr, params.size_in_bytes, -1);
|
||||||
surface_cache.erase(search);
|
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));
|
return boost::make_iterator_range(map.equal_range(interval));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerCacheOpenGL::UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) {
|
void RasterizerCacheOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
|
||||||
const u64 num_pages = ((addr + size - 1) >> Tegra::MemoryManager::PAGE_BITS) -
|
const u64 num_pages =
|
||||||
(addr >> Tegra::MemoryManager::PAGE_BITS) + 1;
|
((addr + size - 1) >> Memory::PAGE_BITS) - (addr >> Memory::PAGE_BITS) + 1;
|
||||||
const u64 page_start = addr >> Tegra::MemoryManager::PAGE_BITS;
|
const u64 page_start = addr >> Memory::PAGE_BITS;
|
||||||
const u64 page_end = page_start + num_pages;
|
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
|
// 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 auto interval = pair.first & pages_interval;
|
||||||
const int count = pair.second;
|
const int count = pair.second;
|
||||||
|
|
||||||
const Tegra::GPUVAddr interval_start_addr = boost::icl::first(interval)
|
const VAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS;
|
||||||
<< Tegra::MemoryManager::PAGE_BITS;
|
const VAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS;
|
||||||
const Tegra::GPUVAddr interval_end_addr = boost::icl::last_next(interval)
|
|
||||||
<< Tegra::MemoryManager::PAGE_BITS;
|
|
||||||
const u64 interval_size = interval_end_addr - interval_start_addr;
|
const u64 interval_size = interval_end_addr - interval_start_addr;
|
||||||
|
|
||||||
if (delta > 0 && count == delta)
|
if (delta > 0 && count == delta)
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ private:
|
|||||||
void UnregisterSurface(const Surface& surface);
|
void UnregisterSurface(const Surface& surface);
|
||||||
|
|
||||||
/// Increase/decrease the number of surface in pages touching the specified region
|
/// 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<SurfaceKey, Surface> surface_cache;
|
std::unordered_map<SurfaceKey, Surface> surface_cache;
|
||||||
PageMap cached_pages;
|
PageMap cached_pages;
|
||||||
|
|||||||
Reference in New Issue
Block a user