diff options
| author | 2022-11-20 03:07:14 +0100 | |
|---|---|---|
| committer | 2023-01-01 16:43:58 -0500 | |
| commit | 3630bfaef332768e08ecc0c34cd4bca83a2579f8 (patch) | |
| tree | 6bd52f659411c16300ab437a418df3e0283d1c31 /src | |
| parent | Vulkan: Allow stagging buffer deferrals. (diff) | |
| download | yuzu-3630bfaef332768e08ecc0c34cd4bca83a2579f8.tar.gz yuzu-3630bfaef332768e08ecc0c34cd4bca83a2579f8.tar.xz yuzu-3630bfaef332768e08ecc0c34cd4bca83a2579f8.zip | |
RasterizerMemory: Add filtering for flushing/invalidation operations.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 2 | ||||
| -rw-r--r-- | src/video_core/cache_types.h | 24 | ||||
| -rw-r--r-- | src/video_core/memory_manager.cpp | 60 | ||||
| -rw-r--r-- | src/video_core/memory_manager.h | 25 | ||||
| -rw-r--r-- | src/video_core/rasterizer_interface.h | 13 | ||||
| -rw-r--r-- | src/video_core/renderer_null/null_rasterizer.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_null/null_rasterizer.h | 12 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 51 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 13 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 52 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 13 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 3 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 2 |
14 files changed, 186 insertions, 93 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index fd71bf186..aa271a377 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -13,6 +13,7 @@ add_library(video_core STATIC | |||
| 13 | buffer_cache/buffer_base.h | 13 | buffer_cache/buffer_base.h |
| 14 | buffer_cache/buffer_cache.cpp | 14 | buffer_cache/buffer_cache.cpp |
| 15 | buffer_cache/buffer_cache.h | 15 | buffer_cache/buffer_cache.h |
| 16 | cache_types.h | ||
| 16 | cdma_pusher.cpp | 17 | cdma_pusher.cpp |
| 17 | cdma_pusher.h | 18 | cdma_pusher.h |
| 18 | compatible_formats.cpp | 19 | compatible_formats.cpp |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index f86edaa3e..bdc0681b7 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -208,7 +208,7 @@ public: | |||
| 208 | 208 | ||
| 209 | [[nodiscard]] std::pair<Buffer*, u32> GetDrawIndirectBuffer(); | 209 | [[nodiscard]] std::pair<Buffer*, u32> GetDrawIndirectBuffer(); |
| 210 | 210 | ||
| 211 | std::mutex mutex; | 211 | std::recursive_mutex mutex; |
| 212 | Runtime& runtime; | 212 | Runtime& runtime; |
| 213 | 213 | ||
| 214 | private: | 214 | private: |
diff --git a/src/video_core/cache_types.h b/src/video_core/cache_types.h new file mode 100644 index 000000000..1a5db3c55 --- /dev/null +++ b/src/video_core/cache_types.h | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "common/common_funcs.h" | ||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | namespace VideoCommon { | ||
| 10 | |||
| 11 | enum class CacheType : u32 { | ||
| 12 | None = 0, | ||
| 13 | TextureCache = 1 << 0, | ||
| 14 | QueryCache = 1 << 1, | ||
| 15 | BufferCache = 1 << 2, | ||
| 16 | ShaderCache = 1 << 3, | ||
| 17 | NoTextureCache = QueryCache | BufferCache | ShaderCache, | ||
| 18 | NoBufferCache = TextureCache | QueryCache | ShaderCache, | ||
| 19 | NoQueryCache = TextureCache | BufferCache | ShaderCache, | ||
| 20 | All = TextureCache | QueryCache | BufferCache | ShaderCache, | ||
| 21 | }; | ||
| 22 | DECLARE_ENUM_FLAG_OPERATORS(CacheType) | ||
| 23 | |||
| 24 | } // namespace VideoCommon | ||
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 4fcae9909..3a5cdeb39 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -356,8 +356,8 @@ inline void MemoryManager::MemoryOperation(GPUVAddr gpu_src_addr, std::size_t si | |||
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | template <bool is_safe> | 358 | template <bool is_safe> |
| 359 | void MemoryManager::ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, | 359 | void MemoryManager::ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size, |
| 360 | std::size_t size) const { | 360 | [[maybe_unused]] VideoCommon::CacheType which) const { |
| 361 | auto set_to_zero = [&]([[maybe_unused]] std::size_t page_index, | 361 | auto set_to_zero = [&]([[maybe_unused]] std::size_t page_index, |
| 362 | [[maybe_unused]] std::size_t offset, std::size_t copy_amount) { | 362 | [[maybe_unused]] std::size_t offset, std::size_t copy_amount) { |
| 363 | std::memset(dest_buffer, 0, copy_amount); | 363 | std::memset(dest_buffer, 0, copy_amount); |
| @@ -367,7 +367,7 @@ void MemoryManager::ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, | |||
| 367 | const VAddr cpu_addr_base = | 367 | const VAddr cpu_addr_base = |
| 368 | (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset; | 368 | (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset; |
| 369 | if constexpr (is_safe) { | 369 | if constexpr (is_safe) { |
| 370 | rasterizer->FlushRegion(cpu_addr_base, copy_amount); | 370 | rasterizer->FlushRegion(cpu_addr_base, copy_amount, which); |
| 371 | } | 371 | } |
| 372 | u8* physical = memory.GetPointer(cpu_addr_base); | 372 | u8* physical = memory.GetPointer(cpu_addr_base); |
| 373 | std::memcpy(dest_buffer, physical, copy_amount); | 373 | std::memcpy(dest_buffer, physical, copy_amount); |
| @@ -377,7 +377,7 @@ void MemoryManager::ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, | |||
| 377 | const VAddr cpu_addr_base = | 377 | const VAddr cpu_addr_base = |
| 378 | (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset; | 378 | (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset; |
| 379 | if constexpr (is_safe) { | 379 | if constexpr (is_safe) { |
| 380 | rasterizer->FlushRegion(cpu_addr_base, copy_amount); | 380 | rasterizer->FlushRegion(cpu_addr_base, copy_amount, which); |
| 381 | } | 381 | } |
| 382 | if (!IsBigPageContinous(page_index)) [[unlikely]] { | 382 | if (!IsBigPageContinous(page_index)) [[unlikely]] { |
| 383 | memory.ReadBlockUnsafe(cpu_addr_base, dest_buffer, copy_amount); | 383 | memory.ReadBlockUnsafe(cpu_addr_base, dest_buffer, copy_amount); |
| @@ -395,18 +395,19 @@ void MemoryManager::ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, | |||
| 395 | MemoryOperation<true>(gpu_src_addr, size, mapped_big, set_to_zero, read_short_pages); | 395 | MemoryOperation<true>(gpu_src_addr, size, mapped_big, set_to_zero, read_short_pages); |
| 396 | } | 396 | } |
| 397 | 397 | ||
| 398 | void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const { | 398 | void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size, |
| 399 | ReadBlockImpl<true>(gpu_src_addr, dest_buffer, size); | 399 | VideoCommon::CacheType which) const { |
| 400 | ReadBlockImpl<true>(gpu_src_addr, dest_buffer, size, which); | ||
| 400 | } | 401 | } |
| 401 | 402 | ||
| 402 | void MemoryManager::ReadBlockUnsafe(GPUVAddr gpu_src_addr, void* dest_buffer, | 403 | void MemoryManager::ReadBlockUnsafe(GPUVAddr gpu_src_addr, void* dest_buffer, |
| 403 | const std::size_t size) const { | 404 | const std::size_t size) const { |
| 404 | ReadBlockImpl<false>(gpu_src_addr, dest_buffer, size); | 405 | ReadBlockImpl<false>(gpu_src_addr, dest_buffer, size, VideoCommon::CacheType::None); |
| 405 | } | 406 | } |
| 406 | 407 | ||
| 407 | template <bool is_safe> | 408 | template <bool is_safe> |
| 408 | void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, | 409 | void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size, |
| 409 | std::size_t size) { | 410 | [[maybe_unused]] VideoCommon::CacheType which) { |
| 410 | auto just_advance = [&]([[maybe_unused]] std::size_t page_index, | 411 | auto just_advance = [&]([[maybe_unused]] std::size_t page_index, |
| 411 | [[maybe_unused]] std::size_t offset, std::size_t copy_amount) { | 412 | [[maybe_unused]] std::size_t offset, std::size_t copy_amount) { |
| 412 | src_buffer = static_cast<const u8*>(src_buffer) + copy_amount; | 413 | src_buffer = static_cast<const u8*>(src_buffer) + copy_amount; |
| @@ -415,7 +416,7 @@ void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffe | |||
| 415 | const VAddr cpu_addr_base = | 416 | const VAddr cpu_addr_base = |
| 416 | (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset; | 417 | (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset; |
| 417 | if constexpr (is_safe) { | 418 | if constexpr (is_safe) { |
| 418 | rasterizer->InvalidateRegion(cpu_addr_base, copy_amount); | 419 | rasterizer->InvalidateRegion(cpu_addr_base, copy_amount, which); |
| 419 | } | 420 | } |
| 420 | u8* physical = memory.GetPointer(cpu_addr_base); | 421 | u8* physical = memory.GetPointer(cpu_addr_base); |
| 421 | std::memcpy(physical, src_buffer, copy_amount); | 422 | std::memcpy(physical, src_buffer, copy_amount); |
| @@ -425,7 +426,7 @@ void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffe | |||
| 425 | const VAddr cpu_addr_base = | 426 | const VAddr cpu_addr_base = |
| 426 | (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset; | 427 | (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset; |
| 427 | if constexpr (is_safe) { | 428 | if constexpr (is_safe) { |
| 428 | rasterizer->InvalidateRegion(cpu_addr_base, copy_amount); | 429 | rasterizer->InvalidateRegion(cpu_addr_base, copy_amount, which); |
| 429 | } | 430 | } |
| 430 | if (!IsBigPageContinous(page_index)) [[unlikely]] { | 431 | if (!IsBigPageContinous(page_index)) [[unlikely]] { |
| 431 | memory.WriteBlockUnsafe(cpu_addr_base, src_buffer, copy_amount); | 432 | memory.WriteBlockUnsafe(cpu_addr_base, src_buffer, copy_amount); |
| @@ -443,16 +444,18 @@ void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffe | |||
| 443 | MemoryOperation<true>(gpu_dest_addr, size, mapped_big, just_advance, write_short_pages); | 444 | MemoryOperation<true>(gpu_dest_addr, size, mapped_big, just_advance, write_short_pages); |
| 444 | } | 445 | } |
| 445 | 446 | ||
| 446 | void MemoryManager::WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size) { | 447 | void MemoryManager::WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size, |
| 447 | WriteBlockImpl<true>(gpu_dest_addr, src_buffer, size); | 448 | VideoCommon::CacheType which) { |
| 449 | WriteBlockImpl<true>(gpu_dest_addr, src_buffer, size, which); | ||
| 448 | } | 450 | } |
| 449 | 451 | ||
| 450 | void MemoryManager::WriteBlockUnsafe(GPUVAddr gpu_dest_addr, const void* src_buffer, | 452 | void MemoryManager::WriteBlockUnsafe(GPUVAddr gpu_dest_addr, const void* src_buffer, |
| 451 | std::size_t size) { | 453 | std::size_t size) { |
| 452 | WriteBlockImpl<false>(gpu_dest_addr, src_buffer, size); | 454 | WriteBlockImpl<false>(gpu_dest_addr, src_buffer, size, VideoCommon::CacheType::None); |
| 453 | } | 455 | } |
| 454 | 456 | ||
| 455 | void MemoryManager::FlushRegion(GPUVAddr gpu_addr, size_t size) const { | 457 | void MemoryManager::FlushRegion(GPUVAddr gpu_addr, size_t size, |
| 458 | VideoCommon::CacheType which) const { | ||
| 456 | auto do_nothing = [&]([[maybe_unused]] std::size_t page_index, | 459 | auto do_nothing = [&]([[maybe_unused]] std::size_t page_index, |
| 457 | [[maybe_unused]] std::size_t offset, | 460 | [[maybe_unused]] std::size_t offset, |
| 458 | [[maybe_unused]] std::size_t copy_amount) {}; | 461 | [[maybe_unused]] std::size_t copy_amount) {}; |
| @@ -460,12 +463,12 @@ void MemoryManager::FlushRegion(GPUVAddr gpu_addr, size_t size) const { | |||
| 460 | auto mapped_normal = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { | 463 | auto mapped_normal = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { |
| 461 | const VAddr cpu_addr_base = | 464 | const VAddr cpu_addr_base = |
| 462 | (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset; | 465 | (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset; |
| 463 | rasterizer->FlushRegion(cpu_addr_base, copy_amount); | 466 | rasterizer->FlushRegion(cpu_addr_base, copy_amount, which); |
| 464 | }; | 467 | }; |
| 465 | auto mapped_big = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { | 468 | auto mapped_big = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { |
| 466 | const VAddr cpu_addr_base = | 469 | const VAddr cpu_addr_base = |
| 467 | (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset; | 470 | (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset; |
| 468 | rasterizer->FlushRegion(cpu_addr_base, copy_amount); | 471 | rasterizer->FlushRegion(cpu_addr_base, copy_amount, which); |
| 469 | }; | 472 | }; |
| 470 | auto flush_short_pages = [&](std::size_t page_index, std::size_t offset, | 473 | auto flush_short_pages = [&](std::size_t page_index, std::size_t offset, |
| 471 | std::size_t copy_amount) { | 474 | std::size_t copy_amount) { |
| @@ -475,7 +478,8 @@ void MemoryManager::FlushRegion(GPUVAddr gpu_addr, size_t size) const { | |||
| 475 | MemoryOperation<true>(gpu_addr, size, mapped_big, do_nothing, flush_short_pages); | 478 | MemoryOperation<true>(gpu_addr, size, mapped_big, do_nothing, flush_short_pages); |
| 476 | } | 479 | } |
| 477 | 480 | ||
| 478 | bool MemoryManager::IsMemoryDirty(GPUVAddr gpu_addr, size_t size) const { | 481 | bool MemoryManager::IsMemoryDirty(GPUVAddr gpu_addr, size_t size, |
| 482 | VideoCommon::CacheType which) const { | ||
| 479 | bool result = false; | 483 | bool result = false; |
| 480 | auto do_nothing = [&]([[maybe_unused]] std::size_t page_index, | 484 | auto do_nothing = [&]([[maybe_unused]] std::size_t page_index, |
| 481 | [[maybe_unused]] std::size_t offset, | 485 | [[maybe_unused]] std::size_t offset, |
| @@ -484,13 +488,13 @@ bool MemoryManager::IsMemoryDirty(GPUVAddr gpu_addr, size_t size) const { | |||
| 484 | auto mapped_normal = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { | 488 | auto mapped_normal = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { |
| 485 | const VAddr cpu_addr_base = | 489 | const VAddr cpu_addr_base = |
| 486 | (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset; | 490 | (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset; |
| 487 | result |= rasterizer->MustFlushRegion(cpu_addr_base, copy_amount); | 491 | result |= rasterizer->MustFlushRegion(cpu_addr_base, copy_amount, which); |
| 488 | return result; | 492 | return result; |
| 489 | }; | 493 | }; |
| 490 | auto mapped_big = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { | 494 | auto mapped_big = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { |
| 491 | const VAddr cpu_addr_base = | 495 | const VAddr cpu_addr_base = |
| 492 | (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset; | 496 | (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset; |
| 493 | result |= rasterizer->MustFlushRegion(cpu_addr_base, copy_amount); | 497 | result |= rasterizer->MustFlushRegion(cpu_addr_base, copy_amount, which); |
| 494 | return result; | 498 | return result; |
| 495 | }; | 499 | }; |
| 496 | auto check_short_pages = [&](std::size_t page_index, std::size_t offset, | 500 | auto check_short_pages = [&](std::size_t page_index, std::size_t offset, |
| @@ -547,7 +551,8 @@ size_t MemoryManager::GetMemoryLayoutSize(GPUVAddr gpu_addr, size_t max_size) co | |||
| 547 | return kind_map.GetContinousSizeFrom(gpu_addr); | 551 | return kind_map.GetContinousSizeFrom(gpu_addr); |
| 548 | } | 552 | } |
| 549 | 553 | ||
| 550 | void MemoryManager::InvalidateRegion(GPUVAddr gpu_addr, size_t size) const { | 554 | void MemoryManager::InvalidateRegion(GPUVAddr gpu_addr, size_t size, |
| 555 | VideoCommon::CacheType which) const { | ||
| 551 | auto do_nothing = [&]([[maybe_unused]] std::size_t page_index, | 556 | auto do_nothing = [&]([[maybe_unused]] std::size_t page_index, |
| 552 | [[maybe_unused]] std::size_t offset, | 557 | [[maybe_unused]] std::size_t offset, |
| 553 | [[maybe_unused]] std::size_t copy_amount) {}; | 558 | [[maybe_unused]] std::size_t copy_amount) {}; |
| @@ -555,12 +560,12 @@ void MemoryManager::InvalidateRegion(GPUVAddr gpu_addr, size_t size) const { | |||
| 555 | auto mapped_normal = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { | 560 | auto mapped_normal = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { |
| 556 | const VAddr cpu_addr_base = | 561 | const VAddr cpu_addr_base = |
| 557 | (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset; | 562 | (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset; |
| 558 | rasterizer->InvalidateRegion(cpu_addr_base, copy_amount); | 563 | rasterizer->InvalidateRegion(cpu_addr_base, copy_amount, which); |
| 559 | }; | 564 | }; |
| 560 | auto mapped_big = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { | 565 | auto mapped_big = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) { |
| 561 | const VAddr cpu_addr_base = | 566 | const VAddr cpu_addr_base = |
| 562 | (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset; | 567 | (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset; |
| 563 | rasterizer->InvalidateRegion(cpu_addr_base, copy_amount); | 568 | rasterizer->InvalidateRegion(cpu_addr_base, copy_amount, which); |
| 564 | }; | 569 | }; |
| 565 | auto invalidate_short_pages = [&](std::size_t page_index, std::size_t offset, | 570 | auto invalidate_short_pages = [&](std::size_t page_index, std::size_t offset, |
| 566 | std::size_t copy_amount) { | 571 | std::size_t copy_amount) { |
| @@ -570,14 +575,15 @@ void MemoryManager::InvalidateRegion(GPUVAddr gpu_addr, size_t size) const { | |||
| 570 | MemoryOperation<true>(gpu_addr, size, mapped_big, do_nothing, invalidate_short_pages); | 575 | MemoryOperation<true>(gpu_addr, size, mapped_big, do_nothing, invalidate_short_pages); |
| 571 | } | 576 | } |
| 572 | 577 | ||
| 573 | void MemoryManager::CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size) { | 578 | void MemoryManager::CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size, |
| 579 | VideoCommon::CacheType which) { | ||
| 574 | std::vector<u8> tmp_buffer(size); | 580 | std::vector<u8> tmp_buffer(size); |
| 575 | ReadBlock(gpu_src_addr, tmp_buffer.data(), size); | 581 | ReadBlock(gpu_src_addr, tmp_buffer.data(), size, which); |
| 576 | 582 | ||
| 577 | // The output block must be flushed in case it has data modified from the GPU. | 583 | // The output block must be flushed in case it has data modified from the GPU. |
| 578 | // Fixes NPC geometry in Zombie Panic in Wonderland DX | 584 | // Fixes NPC geometry in Zombie Panic in Wonderland DX |
| 579 | FlushRegion(gpu_dest_addr, size); | 585 | FlushRegion(gpu_dest_addr, size, which); |
| 580 | WriteBlock(gpu_dest_addr, tmp_buffer.data(), size); | 586 | WriteBlock(gpu_dest_addr, tmp_buffer.data(), size, which); |
| 581 | } | 587 | } |
| 582 | 588 | ||
| 583 | bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) const { | 589 | bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) const { |
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 50043a8ae..828e13439 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "common/multi_level_page_table.h" | 12 | #include "common/multi_level_page_table.h" |
| 13 | #include "common/range_map.h" | 13 | #include "common/range_map.h" |
| 14 | #include "common/virtual_buffer.h" | 14 | #include "common/virtual_buffer.h" |
| 15 | #include "video_core/cache_types.h" | ||
| 15 | #include "video_core/pte_kind.h" | 16 | #include "video_core/pte_kind.h" |
| 16 | 17 | ||
| 17 | namespace VideoCore { | 18 | namespace VideoCore { |
| @@ -60,9 +61,12 @@ public: | |||
| 60 | * in the Host Memory counterpart. Note: This functions cause Host GPU Memory | 61 | * in the Host Memory counterpart. Note: This functions cause Host GPU Memory |
| 61 | * Flushes and Invalidations, respectively to each operation. | 62 | * Flushes and Invalidations, respectively to each operation. |
| 62 | */ | 63 | */ |
| 63 | void ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const; | 64 | void ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size, |
| 64 | void WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size); | 65 | VideoCommon::CacheType which = VideoCommon::CacheType::All) const; |
| 65 | void CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size); | 66 | void WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size, |
| 67 | VideoCommon::CacheType which = VideoCommon::CacheType::All); | ||
| 68 | void CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size, | ||
| 69 | VideoCommon::CacheType which = VideoCommon::CacheType::All); | ||
| 66 | 70 | ||
| 67 | /** | 71 | /** |
| 68 | * ReadBlockUnsafe and WriteBlockUnsafe are special versions of ReadBlock and | 72 | * ReadBlockUnsafe and WriteBlockUnsafe are special versions of ReadBlock and |
| @@ -105,11 +109,14 @@ public: | |||
| 105 | GPUVAddr MapSparse(GPUVAddr gpu_addr, std::size_t size, bool is_big_pages = true); | 109 | GPUVAddr MapSparse(GPUVAddr gpu_addr, std::size_t size, bool is_big_pages = true); |
| 106 | void Unmap(GPUVAddr gpu_addr, std::size_t size); | 110 | void Unmap(GPUVAddr gpu_addr, std::size_t size); |
| 107 | 111 | ||
| 108 | void FlushRegion(GPUVAddr gpu_addr, size_t size) const; | 112 | void FlushRegion(GPUVAddr gpu_addr, size_t size, |
| 113 | VideoCommon::CacheType which = VideoCommon::CacheType::All) const; | ||
| 109 | 114 | ||
| 110 | void InvalidateRegion(GPUVAddr gpu_addr, size_t size) const; | 115 | void InvalidateRegion(GPUVAddr gpu_addr, size_t size, |
| 116 | VideoCommon::CacheType which = VideoCommon::CacheType::All) const; | ||
| 111 | 117 | ||
| 112 | bool IsMemoryDirty(GPUVAddr gpu_addr, size_t size) const; | 118 | bool IsMemoryDirty(GPUVAddr gpu_addr, size_t size, |
| 119 | VideoCommon::CacheType which = VideoCommon::CacheType::All) const; | ||
| 113 | 120 | ||
| 114 | size_t MaxContinousRange(GPUVAddr gpu_addr, size_t size) const; | 121 | size_t MaxContinousRange(GPUVAddr gpu_addr, size_t size) const; |
| 115 | 122 | ||
| @@ -128,10 +135,12 @@ private: | |||
| 128 | FuncReserved&& func_reserved, FuncUnmapped&& func_unmapped) const; | 135 | FuncReserved&& func_reserved, FuncUnmapped&& func_unmapped) const; |
| 129 | 136 | ||
| 130 | template <bool is_safe> | 137 | template <bool is_safe> |
| 131 | void ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const; | 138 | void ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size, |
| 139 | VideoCommon::CacheType which) const; | ||
| 132 | 140 | ||
| 133 | template <bool is_safe> | 141 | template <bool is_safe> |
| 134 | void WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size); | 142 | void WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size, |
| 143 | VideoCommon::CacheType which); | ||
| 135 | 144 | ||
| 136 | template <bool is_big_page> | 145 | template <bool is_big_page> |
| 137 | [[nodiscard]] std::size_t PageEntryIndex(GPUVAddr gpu_addr) const { | 146 | [[nodiscard]] std::size_t PageEntryIndex(GPUVAddr gpu_addr) const { |
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 641b95c7c..6d8d2b666 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <span> | 8 | #include <span> |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "common/polyfill_thread.h" | 10 | #include "common/polyfill_thread.h" |
| 11 | #include "video_core/cache_types.h" | ||
| 11 | #include "video_core/engines/fermi_2d.h" | 12 | #include "video_core/engines/fermi_2d.h" |
| 12 | #include "video_core/gpu.h" | 13 | #include "video_core/gpu.h" |
| 13 | 14 | ||
| @@ -83,13 +84,16 @@ public: | |||
| 83 | virtual void FlushAll() = 0; | 84 | virtual void FlushAll() = 0; |
| 84 | 85 | ||
| 85 | /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory | 86 | /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory |
| 86 | virtual void FlushRegion(VAddr addr, u64 size) = 0; | 87 | virtual void FlushRegion(VAddr addr, u64 size, |
| 88 | VideoCommon::CacheType which = VideoCommon::CacheType::All) = 0; | ||
| 87 | 89 | ||
| 88 | /// Check if the the specified memory area requires flushing to CPU Memory. | 90 | /// Check if the the specified memory area requires flushing to CPU Memory. |
| 89 | virtual bool MustFlushRegion(VAddr addr, u64 size) = 0; | 91 | virtual bool MustFlushRegion(VAddr addr, u64 size, |
| 92 | VideoCommon::CacheType which = VideoCommon::CacheType::All) = 0; | ||
| 90 | 93 | ||
| 91 | /// Notify rasterizer that any caches of the specified region should be invalidated | 94 | /// Notify rasterizer that any caches of the specified region should be invalidated |
| 92 | virtual void InvalidateRegion(VAddr addr, u64 size) = 0; | 95 | virtual void InvalidateRegion(VAddr addr, u64 size, |
| 96 | VideoCommon::CacheType which = VideoCommon::CacheType::All) = 0; | ||
| 93 | 97 | ||
| 94 | /// Notify rasterizer that any caches of the specified region are desync with guest | 98 | /// Notify rasterizer that any caches of the specified region are desync with guest |
| 95 | virtual void OnCPUWrite(VAddr addr, u64 size) = 0; | 99 | virtual void OnCPUWrite(VAddr addr, u64 size) = 0; |
| @@ -105,7 +109,8 @@ public: | |||
| 105 | 109 | ||
| 106 | /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory | 110 | /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory |
| 107 | /// and invalidated | 111 | /// and invalidated |
| 108 | virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; | 112 | virtual void FlushAndInvalidateRegion( |
| 113 | VAddr addr, u64 size, VideoCommon::CacheType which = VideoCommon::CacheType::All) = 0; | ||
| 109 | 114 | ||
| 110 | /// Notify the host renderer to wait for previous primitive and compute operations. | 115 | /// Notify the host renderer to wait for previous primitive and compute operations. |
| 111 | virtual void WaitForIdle() = 0; | 116 | virtual void WaitForIdle() = 0; |
diff --git a/src/video_core/renderer_null/null_rasterizer.cpp b/src/video_core/renderer_null/null_rasterizer.cpp index 9734d84bc..2c11345d7 100644 --- a/src/video_core/renderer_null/null_rasterizer.cpp +++ b/src/video_core/renderer_null/null_rasterizer.cpp | |||
| @@ -39,11 +39,11 @@ void RasterizerNull::BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr | |||
| 39 | u32 size) {} | 39 | u32 size) {} |
| 40 | void RasterizerNull::DisableGraphicsUniformBuffer(size_t stage, u32 index) {} | 40 | void RasterizerNull::DisableGraphicsUniformBuffer(size_t stage, u32 index) {} |
| 41 | void RasterizerNull::FlushAll() {} | 41 | void RasterizerNull::FlushAll() {} |
| 42 | void RasterizerNull::FlushRegion(VAddr addr, u64 size) {} | 42 | void RasterizerNull::FlushRegion(VAddr addr, u64 size, VideoCommon::CacheType) {} |
| 43 | bool RasterizerNull::MustFlushRegion(VAddr addr, u64 size) { | 43 | bool RasterizerNull::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheType) { |
| 44 | return false; | 44 | return false; |
| 45 | } | 45 | } |
| 46 | void RasterizerNull::InvalidateRegion(VAddr addr, u64 size) {} | 46 | void RasterizerNull::InvalidateRegion(VAddr addr, u64 size, VideoCommon::CacheType) {} |
| 47 | void RasterizerNull::OnCPUWrite(VAddr addr, u64 size) {} | 47 | void RasterizerNull::OnCPUWrite(VAddr addr, u64 size) {} |
| 48 | void RasterizerNull::InvalidateGPUCache() {} | 48 | void RasterizerNull::InvalidateGPUCache() {} |
| 49 | void RasterizerNull::UnmapMemory(VAddr addr, u64 size) {} | 49 | void RasterizerNull::UnmapMemory(VAddr addr, u64 size) {} |
| @@ -61,7 +61,7 @@ void RasterizerNull::SignalSyncPoint(u32 value) { | |||
| 61 | } | 61 | } |
| 62 | void RasterizerNull::SignalReference() {} | 62 | void RasterizerNull::SignalReference() {} |
| 63 | void RasterizerNull::ReleaseFences() {} | 63 | void RasterizerNull::ReleaseFences() {} |
| 64 | void RasterizerNull::FlushAndInvalidateRegion(VAddr addr, u64 size) {} | 64 | void RasterizerNull::FlushAndInvalidateRegion(VAddr addr, u64 size, VideoCommon::CacheType) {} |
| 65 | void RasterizerNull::WaitForIdle() {} | 65 | void RasterizerNull::WaitForIdle() {} |
| 66 | void RasterizerNull::FragmentBarrier() {} | 66 | void RasterizerNull::FragmentBarrier() {} |
| 67 | void RasterizerNull::TiledCacheBarrier() {} | 67 | void RasterizerNull::TiledCacheBarrier() {} |
diff --git a/src/video_core/renderer_null/null_rasterizer.h b/src/video_core/renderer_null/null_rasterizer.h index ecf77ba42..2112aa70e 100644 --- a/src/video_core/renderer_null/null_rasterizer.h +++ b/src/video_core/renderer_null/null_rasterizer.h | |||
| @@ -38,9 +38,12 @@ public: | |||
| 38 | void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size) override; | 38 | void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size) override; |
| 39 | void DisableGraphicsUniformBuffer(size_t stage, u32 index) override; | 39 | void DisableGraphicsUniformBuffer(size_t stage, u32 index) override; |
| 40 | void FlushAll() override; | 40 | void FlushAll() override; |
| 41 | void FlushRegion(VAddr addr, u64 size) override; | 41 | void FlushRegion(VAddr addr, u64 size, |
| 42 | bool MustFlushRegion(VAddr addr, u64 size) override; | 42 | VideoCommon::CacheType which = VideoCommon::CacheType::All) override; |
| 43 | void InvalidateRegion(VAddr addr, u64 size) override; | 43 | bool MustFlushRegion(VAddr addr, u64 size, |
| 44 | VideoCommon::CacheType which = VideoCommon::CacheType::All) override; | ||
| 45 | void InvalidateRegion(VAddr addr, u64 size, | ||
| 46 | VideoCommon::CacheType which = VideoCommon::CacheType::All) override; | ||
| 44 | void OnCPUWrite(VAddr addr, u64 size) override; | 47 | void OnCPUWrite(VAddr addr, u64 size) override; |
| 45 | void InvalidateGPUCache() override; | 48 | void InvalidateGPUCache() override; |
| 46 | void UnmapMemory(VAddr addr, u64 size) override; | 49 | void UnmapMemory(VAddr addr, u64 size) override; |
| @@ -50,7 +53,8 @@ public: | |||
| 50 | void SignalSyncPoint(u32 value) override; | 53 | void SignalSyncPoint(u32 value) override; |
| 51 | void SignalReference() override; | 54 | void SignalReference() override; |
| 52 | void ReleaseFences() override; | 55 | void ReleaseFences() override; |
| 53 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; | 56 | void FlushAndInvalidateRegion( |
| 57 | VAddr addr, u64 size, VideoCommon::CacheType which = VideoCommon::CacheType::All) override; | ||
| 54 | void WaitForIdle() override; | 58 | void WaitForIdle() override; |
| 55 | void FragmentBarrier() override; | 59 | void FragmentBarrier() override; |
| 56 | void TiledCacheBarrier() override; | 60 | void TiledCacheBarrier() override; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 0807d0b88..d58dcedea 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -352,46 +352,60 @@ void RasterizerOpenGL::DisableGraphicsUniformBuffer(size_t stage, u32 index) { | |||
| 352 | 352 | ||
| 353 | void RasterizerOpenGL::FlushAll() {} | 353 | void RasterizerOpenGL::FlushAll() {} |
| 354 | 354 | ||
| 355 | void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) { | 355 | void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { |
| 356 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | 356 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); |
| 357 | if (addr == 0 || size == 0) { | 357 | if (addr == 0 || size == 0) { |
| 358 | return; | 358 | return; |
| 359 | } | 359 | } |
| 360 | { | 360 | if (bool(which & VideoCommon::CacheType::TextureCache)) { |
| 361 | std::scoped_lock lock{texture_cache.mutex}; | 361 | std::scoped_lock lock{texture_cache.mutex}; |
| 362 | texture_cache.DownloadMemory(addr, size); | 362 | texture_cache.DownloadMemory(addr, size); |
| 363 | } | 363 | } |
| 364 | { | 364 | if ((bool(which & VideoCommon::CacheType::BufferCache))) { |
| 365 | std::scoped_lock lock{buffer_cache.mutex}; | 365 | std::scoped_lock lock{buffer_cache.mutex}; |
| 366 | buffer_cache.DownloadMemory(addr, size); | 366 | buffer_cache.DownloadMemory(addr, size); |
| 367 | } | 367 | } |
| 368 | query_cache.FlushRegion(addr, size); | 368 | if ((bool(which & VideoCommon::CacheType::QueryCache))) { |
| 369 | query_cache.FlushRegion(addr, size); | ||
| 370 | } | ||
| 369 | } | 371 | } |
| 370 | 372 | ||
| 371 | bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size) { | 373 | bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { |
| 372 | std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex}; | 374 | if ((bool(which & VideoCommon::CacheType::BufferCache))) { |
| 375 | std::scoped_lock lock{buffer_cache.mutex}; | ||
| 376 | if (buffer_cache.IsRegionGpuModified(addr, size)) { | ||
| 377 | return true; | ||
| 378 | } | ||
| 379 | } | ||
| 373 | if (!Settings::IsGPULevelHigh()) { | 380 | if (!Settings::IsGPULevelHigh()) { |
| 374 | return buffer_cache.IsRegionGpuModified(addr, size); | 381 | return false; |
| 382 | } | ||
| 383 | if (bool(which & VideoCommon::CacheType::TextureCache)) { | ||
| 384 | std::scoped_lock lock{texture_cache.mutex}; | ||
| 385 | return texture_cache.IsRegionGpuModified(addr, size); | ||
| 375 | } | 386 | } |
| 376 | return texture_cache.IsRegionGpuModified(addr, size) || | 387 | return false; |
| 377 | buffer_cache.IsRegionGpuModified(addr, size); | ||
| 378 | } | 388 | } |
| 379 | 389 | ||
| 380 | void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { | 390 | void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { |
| 381 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | 391 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); |
| 382 | if (addr == 0 || size == 0) { | 392 | if (addr == 0 || size == 0) { |
| 383 | return; | 393 | return; |
| 384 | } | 394 | } |
| 385 | { | 395 | if (bool(which & VideoCommon::CacheType::TextureCache)) { |
| 386 | std::scoped_lock lock{texture_cache.mutex}; | 396 | std::scoped_lock lock{texture_cache.mutex}; |
| 387 | texture_cache.WriteMemory(addr, size); | 397 | texture_cache.WriteMemory(addr, size); |
| 388 | } | 398 | } |
| 389 | { | 399 | if (bool(which & VideoCommon::CacheType::BufferCache)) { |
| 390 | std::scoped_lock lock{buffer_cache.mutex}; | 400 | std::scoped_lock lock{buffer_cache.mutex}; |
| 391 | buffer_cache.WriteMemory(addr, size); | 401 | buffer_cache.WriteMemory(addr, size); |
| 392 | } | 402 | } |
| 393 | shader_cache.InvalidateRegion(addr, size); | 403 | if (bool(which & VideoCommon::CacheType::ShaderCache)) { |
| 394 | query_cache.InvalidateRegion(addr, size); | 404 | shader_cache.InvalidateRegion(addr, size); |
| 405 | } | ||
| 406 | if (bool(which & VideoCommon::CacheType::QueryCache)) { | ||
| 407 | query_cache.InvalidateRegion(addr, size); | ||
| 408 | } | ||
| 395 | } | 409 | } |
| 396 | 410 | ||
| 397 | void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { | 411 | void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { |
| @@ -458,11 +472,12 @@ void RasterizerOpenGL::ReleaseFences() { | |||
| 458 | fence_manager.WaitPendingFences(); | 472 | fence_manager.WaitPendingFences(); |
| 459 | } | 473 | } |
| 460 | 474 | ||
| 461 | void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { | 475 | void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size, |
| 476 | VideoCommon::CacheType which) { | ||
| 462 | if (Settings::IsGPULevelExtreme()) { | 477 | if (Settings::IsGPULevelExtreme()) { |
| 463 | FlushRegion(addr, size); | 478 | FlushRegion(addr, size, which); |
| 464 | } | 479 | } |
| 465 | InvalidateRegion(addr, size); | 480 | InvalidateRegion(addr, size, which); |
| 466 | } | 481 | } |
| 467 | 482 | ||
| 468 | void RasterizerOpenGL::WaitForIdle() { | 483 | void RasterizerOpenGL::WaitForIdle() { |
| @@ -531,7 +546,7 @@ void RasterizerOpenGL::AccelerateInlineToMemory(GPUVAddr address, size_t copy_si | |||
| 531 | } | 546 | } |
| 532 | gpu_memory->WriteBlockUnsafe(address, memory.data(), copy_size); | 547 | gpu_memory->WriteBlockUnsafe(address, memory.data(), copy_size); |
| 533 | { | 548 | { |
| 534 | std::unique_lock<std::mutex> lock{buffer_cache.mutex}; | 549 | std::unique_lock<std::recursive_mutex> lock{buffer_cache.mutex}; |
| 535 | if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) { | 550 | if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) { |
| 536 | buffer_cache.WriteMemory(*cpu_addr, copy_size); | 551 | buffer_cache.WriteMemory(*cpu_addr, copy_size); |
| 537 | } | 552 | } |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index efd19f880..94e65d64b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -77,9 +77,12 @@ public: | |||
| 77 | void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size) override; | 77 | void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size) override; |
| 78 | void DisableGraphicsUniformBuffer(size_t stage, u32 index) override; | 78 | void DisableGraphicsUniformBuffer(size_t stage, u32 index) override; |
| 79 | void FlushAll() override; | 79 | void FlushAll() override; |
| 80 | void FlushRegion(VAddr addr, u64 size) override; | 80 | void FlushRegion(VAddr addr, u64 size, |
| 81 | bool MustFlushRegion(VAddr addr, u64 size) override; | 81 | VideoCommon::CacheType which = VideoCommon::CacheType::All) override; |
| 82 | void InvalidateRegion(VAddr addr, u64 size) override; | 82 | bool MustFlushRegion(VAddr addr, u64 size, |
| 83 | VideoCommon::CacheType which = VideoCommon::CacheType::All) override; | ||
| 84 | void InvalidateRegion(VAddr addr, u64 size, | ||
| 85 | VideoCommon::CacheType which = VideoCommon::CacheType::All) override; | ||
| 83 | void OnCPUWrite(VAddr addr, u64 size) override; | 86 | void OnCPUWrite(VAddr addr, u64 size) override; |
| 84 | void InvalidateGPUCache() override; | 87 | void InvalidateGPUCache() override; |
| 85 | void UnmapMemory(VAddr addr, u64 size) override; | 88 | void UnmapMemory(VAddr addr, u64 size) override; |
| @@ -89,7 +92,9 @@ public: | |||
| 89 | void SignalSyncPoint(u32 value) override; | 92 | void SignalSyncPoint(u32 value) override; |
| 90 | void SignalReference() override; | 93 | void SignalReference() override; |
| 91 | void ReleaseFences() override; | 94 | void ReleaseFences() override; |
| 92 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; | 95 | void FlushAndInvalidateRegion( |
| 96 | VAddr addr, u64 size, | ||
| 97 | VideoCommon::CacheType which = VideoCommon::CacheType::All) override; | ||
| 93 | void WaitForIdle() override; | 98 | void WaitForIdle() override; |
| 94 | void FragmentBarrier() override; | 99 | void FragmentBarrier() override; |
| 95 | void TiledCacheBarrier() override; | 100 | void TiledCacheBarrier() override; |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 143af93c5..463c49f9c 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -423,41 +423,58 @@ void Vulkan::RasterizerVulkan::DisableGraphicsUniformBuffer(size_t stage, u32 in | |||
| 423 | 423 | ||
| 424 | void RasterizerVulkan::FlushAll() {} | 424 | void RasterizerVulkan::FlushAll() {} |
| 425 | 425 | ||
| 426 | void RasterizerVulkan::FlushRegion(VAddr addr, u64 size) { | 426 | void RasterizerVulkan::FlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { |
| 427 | if (addr == 0 || size == 0) { | 427 | if (addr == 0 || size == 0) { |
| 428 | return; | 428 | return; |
| 429 | } | 429 | } |
| 430 | { | 430 | if (bool(which & VideoCommon::CacheType::TextureCache)) { |
| 431 | std::scoped_lock lock{texture_cache.mutex}; | 431 | std::scoped_lock lock{texture_cache.mutex}; |
| 432 | texture_cache.DownloadMemory(addr, size); | 432 | texture_cache.DownloadMemory(addr, size); |
| 433 | } | 433 | } |
| 434 | { | 434 | if ((bool(which & VideoCommon::CacheType::BufferCache))) { |
| 435 | std::scoped_lock lock{buffer_cache.mutex}; | 435 | std::scoped_lock lock{buffer_cache.mutex}; |
| 436 | buffer_cache.DownloadMemory(addr, size); | 436 | buffer_cache.DownloadMemory(addr, size); |
| 437 | } | 437 | } |
| 438 | query_cache.FlushRegion(addr, size); | 438 | if ((bool(which & VideoCommon::CacheType::QueryCache))) { |
| 439 | query_cache.FlushRegion(addr, size); | ||
| 440 | } | ||
| 439 | } | 441 | } |
| 440 | 442 | ||
| 441 | bool RasterizerVulkan::MustFlushRegion(VAddr addr, u64 size) { | 443 | bool RasterizerVulkan::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { |
| 442 | std::scoped_lock lock{texture_cache.mutex, buffer_cache.mutex}; | 444 | if ((bool(which & VideoCommon::CacheType::BufferCache))) { |
| 443 | return texture_cache.IsRegionGpuModified(addr, size) || | 445 | std::scoped_lock lock{buffer_cache.mutex}; |
| 444 | buffer_cache.IsRegionGpuModified(addr, size); | 446 | if (buffer_cache.IsRegionGpuModified(addr, size)) { |
| 447 | return true; | ||
| 448 | } | ||
| 449 | } | ||
| 450 | if (!Settings::IsGPULevelHigh()) { | ||
| 451 | return false; | ||
| 452 | } | ||
| 453 | if (bool(which & VideoCommon::CacheType::TextureCache)) { | ||
| 454 | std::scoped_lock lock{texture_cache.mutex}; | ||
| 455 | return texture_cache.IsRegionGpuModified(addr, size); | ||
| 456 | } | ||
| 457 | return false; | ||
| 445 | } | 458 | } |
| 446 | 459 | ||
| 447 | void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { | 460 | void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { |
| 448 | if (addr == 0 || size == 0) { | 461 | if (addr == 0 || size == 0) { |
| 449 | return; | 462 | return; |
| 450 | } | 463 | } |
| 451 | { | 464 | if (bool(which & VideoCommon::CacheType::TextureCache)) { |
| 452 | std::scoped_lock lock{texture_cache.mutex}; | 465 | std::scoped_lock lock{texture_cache.mutex}; |
| 453 | texture_cache.WriteMemory(addr, size); | 466 | texture_cache.WriteMemory(addr, size); |
| 454 | } | 467 | } |
| 455 | { | 468 | if ((bool(which & VideoCommon::CacheType::BufferCache))) { |
| 456 | std::scoped_lock lock{buffer_cache.mutex}; | 469 | std::scoped_lock lock{buffer_cache.mutex}; |
| 457 | buffer_cache.WriteMemory(addr, size); | 470 | buffer_cache.WriteMemory(addr, size); |
| 458 | } | 471 | } |
| 459 | pipeline_cache.InvalidateRegion(addr, size); | 472 | if ((bool(which & VideoCommon::CacheType::QueryCache))) { |
| 460 | query_cache.InvalidateRegion(addr, size); | 473 | query_cache.InvalidateRegion(addr, size); |
| 474 | } | ||
| 475 | if ((bool(which & VideoCommon::CacheType::ShaderCache))) { | ||
| 476 | pipeline_cache.InvalidateRegion(addr, size); | ||
| 477 | } | ||
| 461 | } | 478 | } |
| 462 | 479 | ||
| 463 | void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) { | 480 | void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) { |
| @@ -522,11 +539,12 @@ void RasterizerVulkan::ReleaseFences() { | |||
| 522 | fence_manager.WaitPendingFences(); | 539 | fence_manager.WaitPendingFences(); |
| 523 | } | 540 | } |
| 524 | 541 | ||
| 525 | void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { | 542 | void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size, |
| 543 | VideoCommon::CacheType which) { | ||
| 526 | if (Settings::IsGPULevelExtreme()) { | 544 | if (Settings::IsGPULevelExtreme()) { |
| 527 | FlushRegion(addr, size); | 545 | FlushRegion(addr, size, which); |
| 528 | } | 546 | } |
| 529 | InvalidateRegion(addr, size); | 547 | InvalidateRegion(addr, size, which); |
| 530 | } | 548 | } |
| 531 | 549 | ||
| 532 | void RasterizerVulkan::WaitForIdle() { | 550 | void RasterizerVulkan::WaitForIdle() { |
| @@ -602,7 +620,7 @@ void RasterizerVulkan::AccelerateInlineToMemory(GPUVAddr address, size_t copy_si | |||
| 602 | } | 620 | } |
| 603 | gpu_memory->WriteBlockUnsafe(address, memory.data(), copy_size); | 621 | gpu_memory->WriteBlockUnsafe(address, memory.data(), copy_size); |
| 604 | { | 622 | { |
| 605 | std::unique_lock<std::mutex> lock{buffer_cache.mutex}; | 623 | std::unique_lock<std::recursive_mutex> lock{buffer_cache.mutex}; |
| 606 | if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) { | 624 | if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) { |
| 607 | buffer_cache.WriteMemory(*cpu_addr, copy_size); | 625 | buffer_cache.WriteMemory(*cpu_addr, copy_size); |
| 608 | } | 626 | } |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 839de6b26..82b28a54a 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h | |||
| @@ -73,9 +73,12 @@ public: | |||
| 73 | void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size) override; | 73 | void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size) override; |
| 74 | void DisableGraphicsUniformBuffer(size_t stage, u32 index) override; | 74 | void DisableGraphicsUniformBuffer(size_t stage, u32 index) override; |
| 75 | void FlushAll() override; | 75 | void FlushAll() override; |
| 76 | void FlushRegion(VAddr addr, u64 size) override; | 76 | void FlushRegion(VAddr addr, u64 size, |
| 77 | bool MustFlushRegion(VAddr addr, u64 size) override; | 77 | VideoCommon::CacheType which = VideoCommon::CacheType::All) override; |
| 78 | void InvalidateRegion(VAddr addr, u64 size) override; | 78 | bool MustFlushRegion(VAddr addr, u64 size, |
| 79 | VideoCommon::CacheType which = VideoCommon::CacheType::All) override; | ||
| 80 | void InvalidateRegion(VAddr addr, u64 size, | ||
| 81 | VideoCommon::CacheType which = VideoCommon::CacheType::All) override; | ||
| 79 | void OnCPUWrite(VAddr addr, u64 size) override; | 82 | void OnCPUWrite(VAddr addr, u64 size) override; |
| 80 | void InvalidateGPUCache() override; | 83 | void InvalidateGPUCache() override; |
| 81 | void UnmapMemory(VAddr addr, u64 size) override; | 84 | void UnmapMemory(VAddr addr, u64 size) override; |
| @@ -85,7 +88,9 @@ public: | |||
| 85 | void SignalSyncPoint(u32 value) override; | 88 | void SignalSyncPoint(u32 value) override; |
| 86 | void SignalReference() override; | 89 | void SignalReference() override; |
| 87 | void ReleaseFences() override; | 90 | void ReleaseFences() override; |
| 88 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; | 91 | void FlushAndInvalidateRegion( |
| 92 | VAddr addr, u64 size, | ||
| 93 | VideoCommon::CacheType which = VideoCommon::CacheType::All) override; | ||
| 89 | void WaitForIdle() override; | 94 | void WaitForIdle() override; |
| 90 | void FragmentBarrier() override; | 95 | void FragmentBarrier() override; |
| 91 | void TiledCacheBarrier() override; | 96 | void TiledCacheBarrier() override; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 27c82cd20..7fe451b5a 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -740,7 +740,8 @@ void TextureCache<P>::UploadImageContents(Image& image, StagingBuffer& staging) | |||
| 740 | const GPUVAddr gpu_addr = image.gpu_addr; | 740 | const GPUVAddr gpu_addr = image.gpu_addr; |
| 741 | 741 | ||
| 742 | if (True(image.flags & ImageFlagBits::AcceleratedUpload)) { | 742 | if (True(image.flags & ImageFlagBits::AcceleratedUpload)) { |
| 743 | gpu_memory->ReadBlockUnsafe(gpu_addr, mapped_span.data(), mapped_span.size_bytes()); | 743 | gpu_memory->ReadBlock(gpu_addr, mapped_span.data(), mapped_span.size_bytes(), |
| 744 | VideoCommon::CacheType::NoTextureCache); | ||
| 744 | const auto uploads = FullUploadSwizzles(image.info); | 745 | const auto uploads = FullUploadSwizzles(image.info); |
| 745 | runtime.AccelerateImageUpload(image, staging, uploads); | 746 | runtime.AccelerateImageUpload(image, staging, uploads); |
| 746 | return; | 747 | return; |
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 4fd677a80..6b2898705 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h | |||
| @@ -203,7 +203,7 @@ public: | |||
| 203 | /// Create channel state. | 203 | /// Create channel state. |
| 204 | void CreateChannel(Tegra::Control::ChannelState& channel) final override; | 204 | void CreateChannel(Tegra::Control::ChannelState& channel) final override; |
| 205 | 205 | ||
| 206 | std::mutex mutex; | 206 | std::recursive_mutex mutex; |
| 207 | 207 | ||
| 208 | private: | 208 | private: |
| 209 | /// Iterate over all page indices in a range | 209 | /// Iterate over all page indices in a range |