summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames Rowe <jroweboy@gmail.com>2017-09-26 16:55:47 -0600
committerGitHub <noreply@github.com>2017-09-26 16:55:47 -0600
commit5620327e0342bd908359805f396748335fba04a2 (patch)
tree04f2fdeff8af5c67c0158cc5b11073b3e09be176 /src
parent0c20da7fde7ed659977ce145e003c6b2f42b7290 (diff)
parent41f6c9f87f3cd231954cd401be39653c4f78740a (diff)
Merge pull request #2954 from Subv/cache_unmapped_mem
Memory/RasterizerCache: Ignore unmapped memory regions when caching physical regions
Diffstat (limited to 'src')
-rw-r--r--src/core/memory.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index a6b5f6c99..9b394f84b 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -325,8 +325,15 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) {
for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) {
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;
+ }
VAddr vaddr = *maybe_vaddr;
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) {
PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
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:
page_type = PageType::RasterizerCachedMemory;
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) {
PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
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: {
u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK);
if (pointer == nullptr) {