Merge pull request #2954 from Subv/cache_unmapped_mem

Memory/RasterizerCache: Ignore unmapped memory regions when caching physical regions
This commit is contained in:
James Rowe 2017-09-26 16:55:47 -06:00 committed by GitHub
commit 5620327e03
1 changed files with 16 additions and 1 deletions

View File

@ -325,8 +325,15 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) {
for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) { for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) {
boost::optional<VAddr> maybe_vaddr = PhysicalToVirtualAddress(paddr); boost::optional<VAddr> maybe_vaddr = PhysicalToVirtualAddress(paddr);
if (!maybe_vaddr) // While the physical <-> virtual mapping is 1:1 for the regions supported by the cache,
// some games (like Pokemon Super Mystery Dungeon) will try to use textures that go beyond
// the end address of VRAM, causing the Virtual->Physical translation to fail when flushing
// parts of the texture.
if (!maybe_vaddr) {
LOG_ERROR(HW_Memory,
"Trying to flush a cached region to an invalid physical address %08X", paddr);
continue; continue;
}
VAddr vaddr = *maybe_vaddr; VAddr vaddr = *maybe_vaddr;
u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS]; u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS];
@ -338,6 +345,10 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) {
if (res_count == 0) { if (res_count == 0) {
PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
switch (page_type) { switch (page_type) {
case PageType::Unmapped:
// It is not necessary for a process to have this region mapped into its address
// space, for example, a system module need not have a VRAM mapping.
break;
case PageType::Memory: case PageType::Memory:
page_type = PageType::RasterizerCachedMemory; page_type = PageType::RasterizerCachedMemory;
current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr;
@ -356,6 +367,10 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) {
if (res_count == 0) { if (res_count == 0) {
PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
switch (page_type) { switch (page_type) {
case PageType::Unmapped:
// It is not necessary for a process to have this region mapped into its address
// space, for example, a system module need not have a VRAM mapping.
break;
case PageType::RasterizerCachedMemory: { case PageType::RasterizerCachedMemory: {
u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK);
if (pointer == nullptr) { if (pointer == nullptr) {