diff options
| -rw-r--r-- | src/video_core/memory_manager.cpp | 74 | ||||
| -rw-r--r-- | src/video_core/memory_manager.h | 5 |
2 files changed, 32 insertions, 47 deletions
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index dce00e829..055c79a8e 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -265,7 +265,8 @@ size_t MemoryManager::BytesToMapEnd(GPUVAddr gpu_addr) const noexcept { | |||
| 265 | return it->second - (gpu_addr - it->first); | 265 | return it->second - (gpu_addr - it->first); |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const { | 268 | void MemoryManager::ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size, |
| 269 | bool is_safe) const { | ||
| 269 | std::size_t remaining_size{size}; | 270 | std::size_t remaining_size{size}; |
| 270 | std::size_t page_index{gpu_src_addr >> page_bits}; | 271 | std::size_t page_index{gpu_src_addr >> page_bits}; |
| 271 | std::size_t page_offset{gpu_src_addr & page_mask}; | 272 | std::size_t page_offset{gpu_src_addr & page_mask}; |
| @@ -276,11 +277,15 @@ void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::siz | |||
| 276 | 277 | ||
| 277 | if (const auto page_addr{GpuToCpuAddress(page_index << page_bits)}; page_addr) { | 278 | if (const auto page_addr{GpuToCpuAddress(page_index << page_bits)}; page_addr) { |
| 278 | const auto src_addr{*page_addr + page_offset}; | 279 | const auto src_addr{*page_addr + page_offset}; |
| 279 | 280 | if (is_safe) { | |
| 280 | // Flush must happen on the rasterizer interface, such that memory is always synchronous | 281 | // Flush must happen on the rasterizer interface, such that memory is always |
| 281 | // when it is read (even when in asynchronous GPU mode). Fixes Dead Cells title menu. | 282 | // synchronous when it is read (even when in asynchronous GPU mode). |
| 282 | rasterizer->FlushRegion(src_addr, copy_amount); | 283 | // Fixes Dead Cells title menu. |
| 284 | rasterizer->FlushRegion(src_addr, copy_amount); | ||
| 285 | } | ||
| 283 | system.Memory().ReadBlockUnsafe(src_addr, dest_buffer, copy_amount); | 286 | system.Memory().ReadBlockUnsafe(src_addr, dest_buffer, copy_amount); |
| 287 | } else { | ||
| 288 | std::memset(dest_buffer, 0, copy_amount); | ||
| 284 | } | 289 | } |
| 285 | 290 | ||
| 286 | page_index++; | 291 | page_index++; |
| @@ -290,31 +295,17 @@ void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::siz | |||
| 290 | } | 295 | } |
| 291 | } | 296 | } |
| 292 | 297 | ||
| 298 | void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const { | ||
| 299 | ReadBlockImpl(gpu_src_addr, dest_buffer, size, true); | ||
| 300 | } | ||
| 301 | |||
| 293 | void MemoryManager::ReadBlockUnsafe(GPUVAddr gpu_src_addr, void* dest_buffer, | 302 | void MemoryManager::ReadBlockUnsafe(GPUVAddr gpu_src_addr, void* dest_buffer, |
| 294 | const std::size_t size) const { | 303 | const std::size_t size) const { |
| 295 | std::size_t remaining_size{size}; | 304 | ReadBlockImpl(gpu_src_addr, dest_buffer, size, false); |
| 296 | std::size_t page_index{gpu_src_addr >> page_bits}; | ||
| 297 | std::size_t page_offset{gpu_src_addr & page_mask}; | ||
| 298 | |||
| 299 | while (remaining_size > 0) { | ||
| 300 | const std::size_t copy_amount{ | ||
| 301 | std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; | ||
| 302 | |||
| 303 | if (const auto page_addr{GpuToCpuAddress(page_index << page_bits)}; page_addr) { | ||
| 304 | const auto src_addr{*page_addr + page_offset}; | ||
| 305 | system.Memory().ReadBlockUnsafe(src_addr, dest_buffer, copy_amount); | ||
| 306 | } else { | ||
| 307 | std::memset(dest_buffer, 0, copy_amount); | ||
| 308 | } | ||
| 309 | |||
| 310 | page_index++; | ||
| 311 | page_offset = 0; | ||
| 312 | dest_buffer = static_cast<u8*>(dest_buffer) + copy_amount; | ||
| 313 | remaining_size -= copy_amount; | ||
| 314 | } | ||
| 315 | } | 305 | } |
| 316 | 306 | ||
| 317 | void MemoryManager::WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size) { | 307 | void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size, |
| 308 | bool is_safe) { | ||
| 318 | std::size_t remaining_size{size}; | 309 | std::size_t remaining_size{size}; |
| 319 | std::size_t page_index{gpu_dest_addr >> page_bits}; | 310 | std::size_t page_index{gpu_dest_addr >> page_bits}; |
| 320 | std::size_t page_offset{gpu_dest_addr & page_mask}; | 311 | std::size_t page_offset{gpu_dest_addr & page_mask}; |
| @@ -326,9 +317,11 @@ void MemoryManager::WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, s | |||
| 326 | if (const auto page_addr{GpuToCpuAddress(page_index << page_bits)}; page_addr) { | 317 | if (const auto page_addr{GpuToCpuAddress(page_index << page_bits)}; page_addr) { |
| 327 | const auto dest_addr{*page_addr + page_offset}; | 318 | const auto dest_addr{*page_addr + page_offset}; |
| 328 | 319 | ||
| 329 | // Invalidate must happen on the rasterizer interface, such that memory is always | 320 | if (is_safe) { |
| 330 | // synchronous when it is written (even when in asynchronous GPU mode). | 321 | // Invalidate must happen on the rasterizer interface, such that memory is always |
| 331 | rasterizer->InvalidateRegion(dest_addr, copy_amount); | 322 | // synchronous when it is written (even when in asynchronous GPU mode). |
| 323 | rasterizer->InvalidateRegion(dest_addr, copy_amount); | ||
| 324 | } | ||
| 332 | system.Memory().WriteBlockUnsafe(dest_addr, src_buffer, copy_amount); | 325 | system.Memory().WriteBlockUnsafe(dest_addr, src_buffer, copy_amount); |
| 333 | } | 326 | } |
| 334 | 327 | ||
| @@ -339,26 +332,13 @@ void MemoryManager::WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, s | |||
| 339 | } | 332 | } |
| 340 | } | 333 | } |
| 341 | 334 | ||
| 335 | void MemoryManager::WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size) { | ||
| 336 | WriteBlockImpl(gpu_dest_addr, src_buffer, size, true); | ||
| 337 | } | ||
| 338 | |||
| 342 | void MemoryManager::WriteBlockUnsafe(GPUVAddr gpu_dest_addr, const void* src_buffer, | 339 | void MemoryManager::WriteBlockUnsafe(GPUVAddr gpu_dest_addr, const void* src_buffer, |
| 343 | std::size_t size) { | 340 | std::size_t size) { |
| 344 | std::size_t remaining_size{size}; | 341 | WriteBlockImpl(gpu_dest_addr, src_buffer, size, false); |
| 345 | std::size_t page_index{gpu_dest_addr >> page_bits}; | ||
| 346 | std::size_t page_offset{gpu_dest_addr & page_mask}; | ||
| 347 | |||
| 348 | while (remaining_size > 0) { | ||
| 349 | const std::size_t copy_amount{ | ||
| 350 | std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; | ||
| 351 | |||
| 352 | if (const auto page_addr{GpuToCpuAddress(page_index << page_bits)}; page_addr) { | ||
| 353 | const auto dest_addr{*page_addr + page_offset}; | ||
| 354 | system.Memory().WriteBlockUnsafe(dest_addr, src_buffer, copy_amount); | ||
| 355 | } | ||
| 356 | |||
| 357 | page_index++; | ||
| 358 | page_offset = 0; | ||
| 359 | src_buffer = static_cast<const u8*>(src_buffer) + copy_amount; | ||
| 360 | remaining_size -= copy_amount; | ||
| 361 | } | ||
| 362 | } | 342 | } |
| 363 | 343 | ||
| 364 | void MemoryManager::FlushRegion(GPUVAddr gpu_addr, size_t size) const { | 344 | void MemoryManager::FlushRegion(GPUVAddr gpu_addr, size_t size) const { |
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 99d13e7f6..38d8d9d74 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h | |||
| @@ -155,6 +155,11 @@ private: | |||
| 155 | 155 | ||
| 156 | void FlushRegion(GPUVAddr gpu_addr, size_t size) const; | 156 | void FlushRegion(GPUVAddr gpu_addr, size_t size) const; |
| 157 | 157 | ||
| 158 | void ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size, | ||
| 159 | bool is_safe) const; | ||
| 160 | void WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size, | ||
| 161 | bool is_safe); | ||
| 162 | |||
| 158 | [[nodiscard]] static constexpr std::size_t PageEntryIndex(GPUVAddr gpu_addr) { | 163 | [[nodiscard]] static constexpr std::size_t PageEntryIndex(GPUVAddr gpu_addr) { |
| 159 | return (gpu_addr >> page_bits) & page_table_mask; | 164 | return (gpu_addr >> page_bits) & page_table_mask; |
| 160 | } | 165 | } |