summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2022-11-20 03:07:14 +0100
committerGravatar Fernando Sahmkow2023-01-01 16:43:58 -0500
commit3630bfaef332768e08ecc0c34cd4bca83a2579f8 (patch)
tree6bd52f659411c16300ab437a418df3e0283d1c31 /src
parentVulkan: Allow stagging buffer deferrals. (diff)
downloadyuzu-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.txt1
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h2
-rw-r--r--src/video_core/cache_types.h24
-rw-r--r--src/video_core/memory_manager.cpp60
-rw-r--r--src/video_core/memory_manager.h25
-rw-r--r--src/video_core/rasterizer_interface.h13
-rw-r--r--src/video_core/renderer_null/null_rasterizer.cpp8
-rw-r--r--src/video_core/renderer_null/null_rasterizer.h12
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp51
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h13
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp52
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h13
-rw-r--r--src/video_core/texture_cache/texture_cache.h3
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h2
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
214private: 214private:
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
9namespace VideoCommon {
10
11enum 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};
22DECLARE_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
358template <bool is_safe> 358template <bool is_safe>
359void MemoryManager::ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, 359void 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
398void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const { 398void 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
402void MemoryManager::ReadBlockUnsafe(GPUVAddr gpu_src_addr, void* dest_buffer, 403void 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
407template <bool is_safe> 408template <bool is_safe>
408void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, 409void 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
446void MemoryManager::WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size) { 447void 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
450void MemoryManager::WriteBlockUnsafe(GPUVAddr gpu_dest_addr, const void* src_buffer, 452void 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
455void MemoryManager::FlushRegion(GPUVAddr gpu_addr, size_t size) const { 457void 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
478bool MemoryManager::IsMemoryDirty(GPUVAddr gpu_addr, size_t size) const { 481bool 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
550void MemoryManager::InvalidateRegion(GPUVAddr gpu_addr, size_t size) const { 554void 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
573void MemoryManager::CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size) { 578void 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
583bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) const { 589bool 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
17namespace VideoCore { 18namespace 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) {}
40void RasterizerNull::DisableGraphicsUniformBuffer(size_t stage, u32 index) {} 40void RasterizerNull::DisableGraphicsUniformBuffer(size_t stage, u32 index) {}
41void RasterizerNull::FlushAll() {} 41void RasterizerNull::FlushAll() {}
42void RasterizerNull::FlushRegion(VAddr addr, u64 size) {} 42void RasterizerNull::FlushRegion(VAddr addr, u64 size, VideoCommon::CacheType) {}
43bool RasterizerNull::MustFlushRegion(VAddr addr, u64 size) { 43bool RasterizerNull::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheType) {
44 return false; 44 return false;
45} 45}
46void RasterizerNull::InvalidateRegion(VAddr addr, u64 size) {} 46void RasterizerNull::InvalidateRegion(VAddr addr, u64 size, VideoCommon::CacheType) {}
47void RasterizerNull::OnCPUWrite(VAddr addr, u64 size) {} 47void RasterizerNull::OnCPUWrite(VAddr addr, u64 size) {}
48void RasterizerNull::InvalidateGPUCache() {} 48void RasterizerNull::InvalidateGPUCache() {}
49void RasterizerNull::UnmapMemory(VAddr addr, u64 size) {} 49void RasterizerNull::UnmapMemory(VAddr addr, u64 size) {}
@@ -61,7 +61,7 @@ void RasterizerNull::SignalSyncPoint(u32 value) {
61} 61}
62void RasterizerNull::SignalReference() {} 62void RasterizerNull::SignalReference() {}
63void RasterizerNull::ReleaseFences() {} 63void RasterizerNull::ReleaseFences() {}
64void RasterizerNull::FlushAndInvalidateRegion(VAddr addr, u64 size) {} 64void RasterizerNull::FlushAndInvalidateRegion(VAddr addr, u64 size, VideoCommon::CacheType) {}
65void RasterizerNull::WaitForIdle() {} 65void RasterizerNull::WaitForIdle() {}
66void RasterizerNull::FragmentBarrier() {} 66void RasterizerNull::FragmentBarrier() {}
67void RasterizerNull::TiledCacheBarrier() {} 67void 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
353void RasterizerOpenGL::FlushAll() {} 353void RasterizerOpenGL::FlushAll() {}
354 354
355void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) { 355void 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
371bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size) { 373bool 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
380void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { 390void 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
397void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { 411void 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
461void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { 475void 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
468void RasterizerOpenGL::WaitForIdle() { 483void 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
424void RasterizerVulkan::FlushAll() {} 424void RasterizerVulkan::FlushAll() {}
425 425
426void RasterizerVulkan::FlushRegion(VAddr addr, u64 size) { 426void 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
441bool RasterizerVulkan::MustFlushRegion(VAddr addr, u64 size) { 443bool 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
447void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { 460void 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
463void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) { 480void 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
525void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { 542void 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
532void RasterizerVulkan::WaitForIdle() { 550void 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
208private: 208private:
209 /// Iterate over all page indices in a range 209 /// Iterate over all page indices in a range