| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -83,19 +83,13 @@ static void MapPages(u32 base, u32 size, u8* memory, PageType type) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              (base + size) * PAGE_SIZE);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    u32 end = base + size;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                 FlushMode::FlushAndInvalidate);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    u32 end = base + size;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    while (base != end) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %08X", base);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // null here
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (current_page_table->attributes[base] == PageType::RasterizerCachedMemory ||
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            current_page_table->attributes[base] == PageType::RasterizerCachedSpecial) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(base << PAGE_BITS),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               PAGE_SIZE);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        current_page_table->attributes[base] = type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        current_page_table->pointers[base] = memory;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        current_page_table->cached_res_count[base] = 0;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -189,7 +183,7 @@ T Read(const VAddr vaddr) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    case PageType::RasterizerCachedMemory: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        T value;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        std::memcpy(&value, GetPointerFromVMA(vaddr), sizeof(T));
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -198,8 +192,7 @@ T Read(const VAddr vaddr) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    case PageType::Special:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    case PageType::RasterizerCachedSpecial: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    default:
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -229,8 +222,7 @@ void Write(const VAddr vaddr, const T data) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    case PageType::RasterizerCachedMemory: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -238,8 +230,7 @@ void Write(const VAddr vaddr, const T data) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    case PageType::RasterizerCachedSpecial: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -369,11 +360,48 @@ void RasterizerFlushRegion(PAddr start, u32 size) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // null here
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (VideoCore::g_renderer != nullptr) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // null here
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (VideoCore::g_renderer != nullptr) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        VAddr end = start + size;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        auto CheckRegion = [&](VAddr region_start, VAddr region_end) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (start >= region_end || end <= region_start) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                // No overlap with region
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            VAddr overlap_start = std::max(start, region_start);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            VAddr overlap_end = std::min(end, region_end);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            PAddr physical_start = TryVirtualToPhysicalAddress(overlap_start).value();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            u32 overlap_size = overlap_end - overlap_start;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            auto* rasterizer = VideoCore::g_renderer->Rasterizer();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            switch (mode) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            case FlushMode::Flush:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                rasterizer->FlushRegion(physical_start, overlap_size);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            case FlushMode::FlushAndInvalidate:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                rasterizer->FlushAndInvalidateRegion(physical_start, overlap_size);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        };
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        CheckRegion(LINEAR_HEAP_VADDR, LINEAR_HEAP_VADDR_END);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        CheckRegion(NEW_LINEAR_HEAP_VADDR, NEW_LINEAR_HEAP_VADDR_END);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        CheckRegion(VRAM_VADDR, VRAM_VADDR_END);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				u8 Read8(const VAddr addr) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return Read<u8>(addr);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -420,16 +448,13 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        case PageType::RasterizerCachedMemory: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        case PageType::RasterizerCachedSpecial: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -490,18 +515,13 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        case PageType::RasterizerCachedMemory: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        case PageType::RasterizerCachedSpecial: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -547,18 +567,13 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        case PageType::RasterizerCachedMemory: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        case PageType::RasterizerCachedSpecial: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                               copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -603,15 +618,13 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        case PageType::RasterizerCachedMemory: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        case PageType::RasterizerCachedSpecial: {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            std::vector<u8> buffer(copy_amount);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size());
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |