summaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/memory.cpp')
-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 68a6b1ac2..2f5cdcefe 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -316,8 +316,15 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) {
316 316
317 for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) { 317 for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) {
318 boost::optional<VAddr> maybe_vaddr = PhysicalToVirtualAddress(paddr); 318 boost::optional<VAddr> maybe_vaddr = PhysicalToVirtualAddress(paddr);
319 if (!maybe_vaddr) 319 // While the physical <-> virtual mapping is 1:1 for the regions supported by the cache,
320 // some games (like Pokemon Super Mystery Dungeon) will try to use textures that go beyond
321 // the end address of VRAM, causing the Virtual->Physical translation to fail when flushing
322 // parts of the texture.
323 if (!maybe_vaddr) {
324 LOG_ERROR(HW_Memory,
325 "Trying to flush a cached region to an invalid physical address %08X", paddr);
320 continue; 326 continue;
327 }
321 VAddr vaddr = *maybe_vaddr; 328 VAddr vaddr = *maybe_vaddr;
322 329
323 u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS]; 330 u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS];
@@ -329,6 +336,10 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) {
329 if (res_count == 0) { 336 if (res_count == 0) {
330 PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; 337 PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
331 switch (page_type) { 338 switch (page_type) {
339 case PageType::Unmapped:
340 // It is not necessary for a process to have this region mapped into its address
341 // space, for example, a system module need not have a VRAM mapping.
342 break;
332 case PageType::Memory: 343 case PageType::Memory:
333 page_type = PageType::RasterizerCachedMemory; 344 page_type = PageType::RasterizerCachedMemory;
334 current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; 345 current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr;
@@ -347,6 +358,10 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) {
347 if (res_count == 0) { 358 if (res_count == 0) {
348 PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; 359 PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS];
349 switch (page_type) { 360 switch (page_type) {
361 case PageType::Unmapped:
362 // It is not necessary for a process to have this region mapped into its address
363 // space, for example, a system module need not have a VRAM mapping.
364 break;
350 case PageType::RasterizerCachedMemory: { 365 case PageType::RasterizerCachedMemory: {
351 u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); 366 u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK);
352 if (pointer == nullptr) { 367 if (pointer == nullptr) {