summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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) {
325 325
326 for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) { 326 for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) {
327 boost::optional<VAddr> maybe_vaddr = PhysicalToVirtualAddress(paddr); 327 boost::optional<VAddr> maybe_vaddr = PhysicalToVirtualAddress(paddr);
328 if (!maybe_vaddr) 328 // While the physical <-> virtual mapping is 1:1 for the regions supported by the cache,
329 // some games (like Pokemon Super Mystery Dungeon) will try to use textures that go beyond
330 // the end address of VRAM, causing the Virtual->Physical translation to fail when flushing
331 // parts of the texture.
332 if (!maybe_vaddr) {
333 LOG_ERROR(HW_Memory,
334 "Trying to flush a cached region to an invalid physical address %08X", paddr);
329 continue; 335 continue;
336 }
330 VAddr vaddr = *maybe_vaddr; 337 VAddr vaddr = *maybe_vaddr;
331 338
332 u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS]; 339 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) {
338 if (res_count == 0) { 345 if (res_count == 0) {
339 PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; 346 PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
340 switch (page_type) { 347 switch (page_type) {
348 case PageType::Unmapped:
349 // It is not necessary for a process to have this region mapped into its address
350 // space, for example, a system module need not have a VRAM mapping.
351 break;
341 case PageType::Memory: 352 case PageType::Memory:
342 page_type = PageType::RasterizerCachedMemory; 353 page_type = PageType::RasterizerCachedMemory;
343 current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; 354 current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr;
@@ -356,6 +367,10 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) {
356 if (res_count == 0) { 367 if (res_count == 0) {
357 PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; 368 PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
358 switch (page_type) { 369 switch (page_type) {
370 case PageType::Unmapped:
371 // It is not necessary for a process to have this region mapped into its address
372 // space, for example, a system module need not have a VRAM mapping.
373 break;
359 case PageType::RasterizerCachedMemory: { 374 case PageType::RasterizerCachedMemory: {
360 u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); 375 u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK);
361 if (pointer == nullptr) { 376 if (pointer == nullptr) {