mirror of
https://git.h3cjp.net/H3cJP/citra.git
synced 2024-12-29 06:36:41 +00:00
Merge pull request #5785 from ReinUsesLisp/buffer-dma
video_core/memory_manager: Flush destination buffer on CopyBlock
This commit is contained in:
commit
62766b1326
|
@ -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) {
|
void MemoryManager::CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size) {
|
||||||
std::vector<u8> tmp_buffer(size);
|
std::vector<u8> tmp_buffer(size);
|
||||||
ReadBlock(gpu_src_addr, tmp_buffer.data(), 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,
|
// The output block must be flushed in case it has data modified from the GPU.
|
||||||
std::size_t size) {
|
// Fixes NPC geometry in Zombie Panic in Wonderland DX
|
||||||
std::vector<u8> tmp_buffer(size);
|
FlushRegion(gpu_dest_addr, size);
|
||||||
ReadBlockUnsafe(gpu_src_addr, tmp_buffer.data(), size);
|
WriteBlock(gpu_dest_addr, tmp_buffer.data(), size);
|
||||||
WriteBlockUnsafe(gpu_dest_addr, tmp_buffer.data(), size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) const {
|
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 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 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.
|
* 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 TryLockPage(PageEntry page_entry, std::size_t size);
|
||||||
void TryUnlockPage(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) {
|
[[nodiscard]] static constexpr std::size_t PageEntryIndex(GPUVAddr gpu_addr) {
|
||||||
return (gpu_addr >> page_bits) & page_table_mask;
|
return (gpu_addr >> page_bits) & page_table_mask;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue