summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h12
-rw-r--r--src/video_core/gpu.cpp2
-rw-r--r--src/video_core/gpu_thread.cpp7
-rw-r--r--src/video_core/rasterizer_interface.h10
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h1
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h1
-rw-r--r--src/video_core/texture_cache/texture_cache.h15
9 files changed, 48 insertions, 8 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 5b14d52e2..df4c0211e 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -145,6 +145,18 @@ public:
145 } 145 }
146 } 146 }
147 147
148 bool MustFlushRegion(VAddr addr, std::size_t size) {
149 std::lock_guard lock{mutex};
150
151 std::vector<MapInterval> objects = GetMapsInRange(addr, size);
152 for (auto& object : objects) {
153 if (object->IsModified() && object->IsRegistered()) {
154 return true;
155 }
156 }
157 return false;
158 }
159
148 /// Mark the specified region as being invalidated 160 /// Mark the specified region as being invalidated
149 void InvalidateRegion(VAddr addr, u64 size) { 161 void InvalidateRegion(VAddr addr, u64 size) {
150 std::lock_guard lock{mutex}; 162 std::lock_guard lock{mutex};
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index d05b6a9d2..19d3bd305 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -147,7 +147,7 @@ void GPU::SyncGuestHost() {
147} 147}
148 148
149void GPU::OnCommandListEnd() { 149void GPU::OnCommandListEnd() {
150 renderer.Rasterizer().ReleaseFences(); 150 renderer->Rasterizer().ReleaseFences();
151} 151}
152// Note that, traditionally, methods are treated as 4-byte addressable locations, and hence 152// Note that, traditionally, methods are treated as 4-byte addressable locations, and hence
153// their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4. 153// their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4.
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 251a9d911..672f8d2fa 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -6,6 +6,7 @@
6#include "common/microprofile.h" 6#include "common/microprofile.h"
7#include "core/core.h" 7#include "core/core.h"
8#include "core/frontend/emu_window.h" 8#include "core/frontend/emu_window.h"
9#include "core/settings.h"
9#include "video_core/dma_pusher.h" 10#include "video_core/dma_pusher.h"
10#include "video_core/gpu.h" 11#include "video_core/gpu.h"
11#include "video_core/gpu_thread.h" 12#include "video_core/gpu_thread.h"
@@ -80,7 +81,11 @@ void ThreadManager::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
80} 81}
81 82
82void ThreadManager::FlushRegion(VAddr addr, u64 size) { 83void ThreadManager::FlushRegion(VAddr addr, u64 size) {
83 PushCommand(FlushRegionCommand(addr, size)); 84 if (system.Renderer().Rasterizer().MustFlushRegion(addr, size)) {
85 u64 fence = PushCommand(FlushRegionCommand(addr, size));
86 while (fence < state.signaled_fence.load(std::memory_order_relaxed)) {
87 }
88 }
84} 89}
85 90
86void ThreadManager::InvalidateRegion(VAddr addr, u64 size) { 91void ThreadManager::InvalidateRegion(VAddr addr, u64 size) {
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 72f65b166..228752131 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -49,13 +49,9 @@ public:
49 /// Records a GPU query and caches it 49 /// Records a GPU query and caches it
50 virtual void Query(GPUVAddr gpu_addr, QueryType type, std::optional<u64> timestamp) = 0; 50 virtual void Query(GPUVAddr gpu_addr, QueryType type, std::optional<u64> timestamp) = 0;
51 51
52 virtual void SignalFence(GPUVAddr addr, u32 value) { 52 virtual void SignalFence(GPUVAddr addr, u32 value) {}
53 53
54 } 54 virtual void ReleaseFences() {}
55
56 virtual void ReleaseFences() {
57
58 }
59 55
60 /// Notify rasterizer that all caches should be flushed to Switch memory 56 /// Notify rasterizer that all caches should be flushed to Switch memory
61 virtual void FlushAll() = 0; 57 virtual void FlushAll() = 0;
@@ -63,6 +59,8 @@ public:
63 /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory 59 /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
64 virtual void FlushRegion(VAddr addr, u64 size) = 0; 60 virtual void FlushRegion(VAddr addr, u64 size) = 0;
65 61
62 virtual bool MustFlushRegion(VAddr addr, u64 size) = 0;
63
66 /// Notify rasterizer that any caches of the specified region should be invalidated 64 /// Notify rasterizer that any caches of the specified region should be invalidated
67 virtual void InvalidateRegion(VAddr addr, u64 size) = 0; 65 virtual void InvalidateRegion(VAddr addr, u64 size) = 0;
68 66
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 35bed444f..bbf37a00d 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -650,6 +650,10 @@ void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) {
650 query_cache.FlushRegion(addr, size); 650 query_cache.FlushRegion(addr, size);
651} 651}
652 652
653bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size) {
654 return texture_cache.MustFlushRegion(addr, size) || buffer_cache.MustFlushRegion(addr, size);
655}
656
653void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { 657void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) {
654 MICROPROFILE_SCOPE(OpenGL_CacheManagement); 658 MICROPROFILE_SCOPE(OpenGL_CacheManagement);
655 if (addr == 0 || size == 0) { 659 if (addr == 0 || size == 0) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 6d173a922..5c0f88e6f 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -67,6 +67,7 @@ public:
67 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override; 67 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override;
68 void FlushAll() override; 68 void FlushAll() override;
69 void FlushRegion(VAddr addr, u64 size) override; 69 void FlushRegion(VAddr addr, u64 size) override;
70 bool MustFlushRegion(VAddr addr, u64 size) override;
70 void InvalidateRegion(VAddr addr, u64 size) override; 71 void InvalidateRegion(VAddr addr, u64 size) override;
71 void OnCPUWrite(VAddr addr, u64 size) override; 72 void OnCPUWrite(VAddr addr, u64 size) override;
72 void SyncGuestHost() override; 73 void SyncGuestHost() override;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 4d0c90aa3..9437a4aa1 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -514,6 +514,10 @@ void RasterizerVulkan::FlushRegion(VAddr addr, u64 size) {
514 query_cache.FlushRegion(addr, size); 514 query_cache.FlushRegion(addr, size);
515} 515}
516 516
517bool RasterizerVulkan::MustFlushRegion(VAddr addr, u64 size) {
518 return texture_cache.MustFlushRegion(addr, size) || buffer_cache.MustFlushRegion(addr, size);
519}
520
517void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { 521void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) {
518 if (addr == 0 || size == 0) { 522 if (addr == 0 || size == 0) {
519 return; 523 return;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 285f731bc..7002a4fa3 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -118,6 +118,7 @@ public:
118 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override; 118 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override;
119 void FlushAll() override; 119 void FlushAll() override;
120 void FlushRegion(VAddr addr, u64 size) override; 120 void FlushRegion(VAddr addr, u64 size) override;
121 bool MustFlushRegion(VAddr addr, u64 size) override;
121 void InvalidateRegion(VAddr addr, u64 size) override; 122 void InvalidateRegion(VAddr addr, u64 size) override;
122 void OnCPUWrite(VAddr addr, u64 size) override; 123 void OnCPUWrite(VAddr addr, u64 size) override;
123 void SyncGuestHost() override; 124 void SyncGuestHost() override;
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 04fe69c11..e251a30c3 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -116,6 +116,21 @@ public:
116 } 116 }
117 } 117 }
118 118
119 bool MustFlushRegion(VAddr addr, std::size_t size) {
120 std::lock_guard lock{mutex};
121
122 auto surfaces = GetSurfacesInRegion(addr, size);
123 if (surfaces.empty()) {
124 return false;
125 }
126 for (const auto& surface : surfaces) {
127 if (surface->IsModified()) {
128 return true;
129 }
130 }
131 return false;
132 }
133
119 TView GetTextureSurface(const Tegra::Texture::TICEntry& tic, 134 TView GetTextureSurface(const Tegra::Texture::TICEntry& tic,
120 const VideoCommon::Shader::Sampler& entry) { 135 const VideoCommon::Shader::Sampler& entry) {
121 std::lock_guard lock{mutex}; 136 std::lock_guard lock{mutex};