diff options
| author | 2017-09-24 20:52:46 -0500 | |
|---|---|---|
| committer | 2017-09-25 19:37:45 -0500 | |
| commit | 41f6c9f87f3cd231954cd401be39653c4f78740a (patch) | |
| tree | f5d6f959c025dbd3b78621bcca920bed14317997 | |
| parent | Merge pull request #2928 from huwpascoe/master (diff) | |
| download | yuzu-41f6c9f87f3cd231954cd401be39653c4f78740a.tar.gz yuzu-41f6c9f87f3cd231954cd401be39653c4f78740a.tar.xz yuzu-41f6c9f87f3cd231954cd401be39653c4f78740a.zip | |
Memory/RasterizerCache: Ignore unmapped memory regions when caching physical regions.
Not all physical regions need to be mapped into the address space of every process, for example, system modules do not have a VRAM mapping.
This fixes a crash when loading applets and system modules.
| -rw-r--r-- | src/core/memory.cpp | 17 |
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) { |