Merge pull request #5785 from ReinUsesLisp/buffer-dma
video_core/memory_manager: Flush destination buffer on CopyBlock
This commit is contained in:
		| @@ -314,17 +314,29 @@ void MemoryManager::WriteBlockUnsafe(GPUVAddr gpu_dest_addr, const void* src_buf | ||||
|     } | ||||
| } | ||||
|  | ||||
| void MemoryManager::FlushRegion(GPUVAddr gpu_addr, size_t size) const { | ||||
|     size_t remaining_size{size}; | ||||
|     size_t page_index{gpu_addr >> page_bits}; | ||||
|     size_t page_offset{gpu_addr & page_mask}; | ||||
|     while (remaining_size > 0) { | ||||
|         const size_t num_bytes{std::min(page_size - page_offset, remaining_size)}; | ||||
|         if (const auto page_addr{GpuToCpuAddress(page_index << page_bits)}; page_addr) { | ||||
|             rasterizer->FlushRegion(*page_addr + page_offset, num_bytes); | ||||
|         } | ||||
|         ++page_index; | ||||
|         page_offset = 0; | ||||
|         remaining_size -= num_bytes; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void MemoryManager::CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size) { | ||||
|     std::vector<u8> tmp_buffer(size); | ||||
|     ReadBlock(gpu_src_addr, tmp_buffer.data(), size); | ||||
|     WriteBlock(gpu_dest_addr, tmp_buffer.data(), size); | ||||
| } | ||||
|  | ||||
| void MemoryManager::CopyBlockUnsafe(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, | ||||
|                                     std::size_t size) { | ||||
|     std::vector<u8> tmp_buffer(size); | ||||
|     ReadBlockUnsafe(gpu_src_addr, tmp_buffer.data(), size); | ||||
|     WriteBlockUnsafe(gpu_dest_addr, tmp_buffer.data(), size); | ||||
|     // The output block must be flushed in case it has data modified from the GPU. | ||||
|     // Fixes NPC geometry in Zombie Panic in Wonderland DX | ||||
|     FlushRegion(gpu_dest_addr, size); | ||||
|     WriteBlock(gpu_dest_addr, tmp_buffer.data(), size); | ||||
| } | ||||
|  | ||||
| bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) const { | ||||
|   | ||||
| @@ -107,7 +107,6 @@ public: | ||||
|      */ | ||||
|     void ReadBlockUnsafe(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const; | ||||
|     void WriteBlockUnsafe(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size); | ||||
|     void CopyBlockUnsafe(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size); | ||||
|  | ||||
|     /** | ||||
|      * IsGranularRange checks if a gpu region can be simply read with a pointer. | ||||
| @@ -131,6 +130,8 @@ private: | ||||
|     void TryLockPage(PageEntry page_entry, std::size_t size); | ||||
|     void TryUnlockPage(PageEntry page_entry, std::size_t size); | ||||
|  | ||||
|     void FlushRegion(GPUVAddr gpu_addr, size_t size) const; | ||||
|  | ||||
|     [[nodiscard]] static constexpr std::size_t PageEntryIndex(GPUVAddr gpu_addr) { | ||||
|         return (gpu_addr >> page_bits) & page_table_mask; | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 bunnei
					bunnei