Merge pull request #2954 from Subv/cache_unmapped_mem
Memory/RasterizerCache: Ignore unmapped memory regions when caching physical regions
This commit is contained in:
		@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user