Memory: Remove count of cached pages and add InvalidateRegion

In a future commit, the count of cached pages will be reintroduced in
the actual surface cache. Also adds an Invalidate only to the cache
which marks a region as invalid in order to try to avoid a costly flush
from 3ds memory
This commit is contained in:
James Rowe 2017-11-23 10:43:12 -07:00
parent c821c14908
commit 13606a6d0b
8 changed files with 50 additions and 54 deletions

View file

@ -50,7 +50,6 @@ static void MapPages(PageTable& page_table, u32 base, u32 size, u8* memory, Page
page_table.attributes[base] = type;
page_table.pointers[base] = memory;
page_table.cached_res_count[base] = 0;
base += 1;
if (memory != nullptr)
@ -200,7 +199,7 @@ void Write(const VAddr vaddr, const T data) {
ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
break;
case PageType::RasterizerCachedMemory: {
RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate);
RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Invalidate);
std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T));
break;
}
@ -208,7 +207,7 @@ void Write(const VAddr vaddr, const T data) {
WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data);
break;
case PageType::RasterizerCachedSpecial: {
RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate);
RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Invalidate);
WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data);
break;
}
@ -334,7 +333,7 @@ u8* GetPhysicalPointer(PAddr address) {
return target_pointer;
}
void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) {
void RasterizerMarkRegionCached(PAddr start, u32 size, bool cached) {
if (start == 0) {
return;
}
@ -355,14 +354,10 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) {
}
VAddr vaddr = *maybe_vaddr;
u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS];
ASSERT_MSG(count_delta <= UINT8_MAX - res_count,
"Rasterizer resource cache counter overflow!");
ASSERT_MSG(count_delta >= -res_count, "Rasterizer resource cache counter underflow!");
PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
// Switch page type to cached if now cached
if (res_count == 0) {
PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
if (cached) {
// Switch page type to cached if now cached
switch (page_type) {
case PageType::Unmapped:
// It is not necessary for a process to have this region mapped into its address
@ -378,13 +373,8 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) {
default:
UNREACHABLE();
}
}
res_count += count_delta;
// Switch page type to uncached if now uncached
if (res_count == 0) {
PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
} else {
// Switch page type to uncached if now uncached
switch (page_type) {
case PageType::Unmapped:
// It is not necessary for a process to have this region mapped into its address
@ -419,6 +409,12 @@ void RasterizerFlushRegion(PAddr start, u32 size) {
}
}
void RasterizerInvalidateRegion(PAddr start, u32 size) {
if (VideoCore::g_renderer != nullptr) {
VideoCore::g_renderer->Rasterizer()->InvalidateRegion(start, size);
}
}
void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) {
// Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
// null here
@ -450,6 +446,9 @@ void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) {
case FlushMode::Flush:
rasterizer->FlushRegion(physical_start, overlap_size);
break;
case FlushMode::Invalidate:
rasterizer->InvalidateRegion(physical_start, overlap_size);
break;
case FlushMode::FlushAndInvalidate:
rasterizer->FlushAndInvalidateRegion(physical_start, overlap_size);
break;
@ -588,7 +587,7 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi
}
case PageType::RasterizerCachedMemory: {
RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
FlushMode::FlushAndInvalidate);
FlushMode::Invalidate);
std::memcpy(GetPointerFromVMA(process, current_vaddr), src_buffer, copy_amount);
break;
}
@ -596,7 +595,7 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi
MMIORegionPointer handler = GetMMIOHandler(page_table, current_vaddr);
DEBUG_ASSERT(handler);
RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
FlushMode::FlushAndInvalidate);
FlushMode::Invalidate);
handler->WriteBlock(current_vaddr, src_buffer, copy_amount);
break;
}
@ -648,7 +647,7 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const size
}
case PageType::RasterizerCachedMemory: {
RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
FlushMode::FlushAndInvalidate);
FlushMode::Invalidate);
std::memset(GetPointerFromVMA(process, current_vaddr), 0, copy_amount);
break;
}
@ -656,7 +655,7 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const size
MMIORegionPointer handler = GetMMIOHandler(page_table, current_vaddr);
DEBUG_ASSERT(handler);
RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
FlushMode::FlushAndInvalidate);
FlushMode::Invalidate);
handler->WriteBlock(current_vaddr, zeros.data(), copy_amount);
break;
}