diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 50 | ||||
| -rw-r--r-- | src/video_core/fence_manager.h | 15 | ||||
| -rw-r--r-- | src/video_core/gpu_thread.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_fence_manager.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_fence_manager.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 3 |
6 files changed, 69 insertions, 10 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index df4c0211e..d72df90ef 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include "common/common_types.h" | 21 | #include "common/common_types.h" |
| 22 | #include "core/core.h" | 22 | #include "core/core.h" |
| 23 | #include "core/memory.h" | 23 | #include "core/memory.h" |
| 24 | #include "core/settings.h" | ||
| 24 | #include "video_core/buffer_cache/buffer_block.h" | 25 | #include "video_core/buffer_cache/buffer_block.h" |
| 25 | #include "video_core/buffer_cache/map_interval.h" | 26 | #include "video_core/buffer_cache/map_interval.h" |
| 26 | #include "video_core/memory_manager.h" | 27 | #include "video_core/memory_manager.h" |
| @@ -80,6 +81,9 @@ public: | |||
| 80 | auto map = MapAddress(block, gpu_addr, cpu_addr, size); | 81 | auto map = MapAddress(block, gpu_addr, cpu_addr, size); |
| 81 | if (is_written) { | 82 | if (is_written) { |
| 82 | map->MarkAsModified(true, GetModifiedTicks()); | 83 | map->MarkAsModified(true, GetModifiedTicks()); |
| 84 | if (Settings::IsGPULevelHigh() && Settings::values.use_asynchronous_gpu_emulation) { | ||
| 85 | AsyncFlushMap(map); | ||
| 86 | } | ||
| 83 | if (!map->IsWritten()) { | 87 | if (!map->IsWritten()) { |
| 84 | map->MarkAsWritten(true); | 88 | map->MarkAsWritten(true); |
| 85 | MarkRegionAsWritten(map->GetStart(), map->GetEnd() - 1); | 89 | MarkRegionAsWritten(map->GetStart(), map->GetEnd() - 1); |
| @@ -193,6 +197,39 @@ public: | |||
| 193 | marked_for_unregister.clear(); | 197 | marked_for_unregister.clear(); |
| 194 | } | 198 | } |
| 195 | 199 | ||
| 200 | void CommitAsyncFlushes() { | ||
| 201 | commited_flushes.push_back(uncommited_flushes); | ||
| 202 | uncommited_flushes.reset(); | ||
| 203 | } | ||
| 204 | |||
| 205 | bool ShouldWaitAsyncFlushes() { | ||
| 206 | if (commited_flushes.empty()) { | ||
| 207 | return false; | ||
| 208 | } | ||
| 209 | auto& flush_list = commited_flushes.front(); | ||
| 210 | if (!flush_list) { | ||
| 211 | return false; | ||
| 212 | } | ||
| 213 | return true; | ||
| 214 | } | ||
| 215 | |||
| 216 | void PopAsyncFlushes() { | ||
| 217 | if (commited_flushes.empty()) { | ||
| 218 | return; | ||
| 219 | } | ||
| 220 | auto& flush_list = commited_flushes.front(); | ||
| 221 | if (!flush_list) { | ||
| 222 | commited_flushes.pop_front(); | ||
| 223 | return; | ||
| 224 | } | ||
| 225 | for (MapInterval& map : *flush_list) { | ||
| 226 | if (map->IsRegistered()) { | ||
| 227 | FlushMap(map); | ||
| 228 | } | ||
| 229 | } | ||
| 230 | commited_flushes.pop_front(); | ||
| 231 | } | ||
| 232 | |||
| 196 | virtual BufferType GetEmptyBuffer(std::size_t size) = 0; | 233 | virtual BufferType GetEmptyBuffer(std::size_t size) = 0; |
| 197 | 234 | ||
| 198 | protected: | 235 | protected: |
| @@ -316,6 +353,9 @@ private: | |||
| 316 | MapInterval new_map = CreateMap(new_start, new_end, new_gpu_addr); | 353 | MapInterval new_map = CreateMap(new_start, new_end, new_gpu_addr); |
| 317 | if (modified_inheritance) { | 354 | if (modified_inheritance) { |
| 318 | new_map->MarkAsModified(true, GetModifiedTicks()); | 355 | new_map->MarkAsModified(true, GetModifiedTicks()); |
| 356 | if (Settings::IsGPULevelHigh() && Settings::values.use_asynchronous_gpu_emulation) { | ||
| 357 | AsyncFlushMap(new_map); | ||
| 358 | } | ||
| 319 | } | 359 | } |
| 320 | Register(new_map, write_inheritance); | 360 | Register(new_map, write_inheritance); |
| 321 | return new_map; | 361 | return new_map; |
| @@ -502,6 +542,13 @@ private: | |||
| 502 | return false; | 542 | return false; |
| 503 | } | 543 | } |
| 504 | 544 | ||
| 545 | void AsyncFlushMap(MapInterval& map) { | ||
| 546 | if (!uncommited_flushes) { | ||
| 547 | uncommited_flushes = std::make_shared<std::list<MapInterval>>(); | ||
| 548 | } | ||
| 549 | uncommited_flushes->push_back(map); | ||
| 550 | } | ||
| 551 | |||
| 505 | VideoCore::RasterizerInterface& rasterizer; | 552 | VideoCore::RasterizerInterface& rasterizer; |
| 506 | Core::System& system; | 553 | Core::System& system; |
| 507 | 554 | ||
| @@ -533,6 +580,9 @@ private: | |||
| 533 | std::vector<u8> staging_buffer; | 580 | std::vector<u8> staging_buffer; |
| 534 | std::list<MapInterval> marked_for_unregister; | 581 | std::list<MapInterval> marked_for_unregister; |
| 535 | 582 | ||
| 583 | std::shared_ptr<std::list<MapInterval>> uncommited_flushes{}; | ||
| 584 | std::list<std::shared_ptr<std::list<MapInterval>>> commited_flushes; | ||
| 585 | |||
| 536 | std::recursive_mutex mutex; | 586 | std::recursive_mutex mutex; |
| 537 | }; | 587 | }; |
| 538 | 588 | ||
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h index 036f3996c..c4b190503 100644 --- a/src/video_core/fence_manager.h +++ b/src/video_core/fence_manager.h | |||
| @@ -6,8 +6,8 @@ | |||
| 6 | 6 | ||
| 7 | #include <algorithm> | 7 | #include <algorithm> |
| 8 | #include <array> | 8 | #include <array> |
| 9 | #include <queue> | ||
| 10 | #include <memory> | 9 | #include <memory> |
| 10 | #include <queue> | ||
| 11 | 11 | ||
| 12 | #include "common/assert.h" | 12 | #include "common/assert.h" |
| 13 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| @@ -37,7 +37,7 @@ private: | |||
| 37 | u32 payload; | 37 | u32 payload; |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | template <typename TFence, typename TTextureCache> | 40 | template <typename TFence, typename TTextureCache, typename TTBufferCache> |
| 41 | class FenceManager { | 41 | class FenceManager { |
| 42 | public: | 42 | public: |
| 43 | void SignalFence(GPUVAddr addr, u32 value) { | 43 | void SignalFence(GPUVAddr addr, u32 value) { |
| @@ -46,6 +46,7 @@ public: | |||
| 46 | QueueFence(new_fence); | 46 | QueueFence(new_fence); |
| 47 | fences.push(new_fence); | 47 | fences.push(new_fence); |
| 48 | texture_cache.CommitAsyncFlushes(); | 48 | texture_cache.CommitAsyncFlushes(); |
| 49 | buffer_cache.CommitAsyncFlushes(); | ||
| 49 | rasterizer.FlushCommands(); | 50 | rasterizer.FlushCommands(); |
| 50 | rasterizer.SyncGuestHost(); | 51 | rasterizer.SyncGuestHost(); |
| 51 | } | 52 | } |
| @@ -54,10 +55,12 @@ public: | |||
| 54 | while (!fences.empty()) { | 55 | while (!fences.empty()) { |
| 55 | TFence& current_fence = fences.front(); | 56 | TFence& current_fence = fences.front(); |
| 56 | bool should_wait = texture_cache.ShouldWaitAsyncFlushes(); | 57 | bool should_wait = texture_cache.ShouldWaitAsyncFlushes(); |
| 58 | should_wait |= buffer_cache.ShouldWaitAsyncFlushes(); | ||
| 57 | if (should_wait) { | 59 | if (should_wait) { |
| 58 | WaitFence(current_fence); | 60 | WaitFence(current_fence); |
| 59 | } | 61 | } |
| 60 | texture_cache.PopAsyncFlushes(); | 62 | texture_cache.PopAsyncFlushes(); |
| 63 | buffer_cache.PopAsyncFlushes(); | ||
| 61 | auto& gpu{system.GPU()}; | 64 | auto& gpu{system.GPU()}; |
| 62 | auto& memory_manager{gpu.MemoryManager()}; | 65 | auto& memory_manager{gpu.MemoryManager()}; |
| 63 | memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload()); | 66 | memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload()); |
| @@ -67,8 +70,9 @@ public: | |||
| 67 | 70 | ||
| 68 | protected: | 71 | protected: |
| 69 | FenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 72 | FenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, |
| 70 | TTextureCache& texture_cache) | 73 | TTextureCache& texture_cache, TTBufferCache& buffer_cache) |
| 71 | : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache} {} | 74 | : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache}, buffer_cache{ |
| 75 | buffer_cache} {} | ||
| 72 | 76 | ||
| 73 | virtual TFence CreateFence(GPUVAddr addr, u32 value) = 0; | 77 | virtual TFence CreateFence(GPUVAddr addr, u32 value) = 0; |
| 74 | virtual void QueueFence(TFence& fence) = 0; | 78 | virtual void QueueFence(TFence& fence) = 0; |
| @@ -78,16 +82,19 @@ protected: | |||
| 78 | Core::System& system; | 82 | Core::System& system; |
| 79 | VideoCore::RasterizerInterface& rasterizer; | 83 | VideoCore::RasterizerInterface& rasterizer; |
| 80 | TTextureCache& texture_cache; | 84 | TTextureCache& texture_cache; |
| 85 | TTBufferCache& buffer_cache; | ||
| 81 | 86 | ||
| 82 | private: | 87 | private: |
| 83 | void TryReleasePendingFences() { | 88 | void TryReleasePendingFences() { |
| 84 | while (!fences.empty()) { | 89 | while (!fences.empty()) { |
| 85 | TFence& current_fence = fences.front(); | 90 | TFence& current_fence = fences.front(); |
| 86 | bool should_wait = texture_cache.ShouldWaitAsyncFlushes(); | 91 | bool should_wait = texture_cache.ShouldWaitAsyncFlushes(); |
| 92 | should_wait |= buffer_cache.ShouldWaitAsyncFlushes(); | ||
| 87 | if (should_wait && !IsFenceSignaled(current_fence)) { | 93 | if (should_wait && !IsFenceSignaled(current_fence)) { |
| 88 | return; | 94 | return; |
| 89 | } | 95 | } |
| 90 | texture_cache.PopAsyncFlushes(); | 96 | texture_cache.PopAsyncFlushes(); |
| 97 | buffer_cache.PopAsyncFlushes(); | ||
| 91 | auto& gpu{system.GPU()}; | 98 | auto& gpu{system.GPU()}; |
| 92 | auto& memory_manager{gpu.MemoryManager()}; | 99 | auto& memory_manager{gpu.MemoryManager()}; |
| 93 | memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload()); | 100 | memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload()); |
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 1c3ab2145..3e2be00e9 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp | |||
| @@ -81,7 +81,7 @@ void ThreadManager::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | |||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | void ThreadManager::FlushRegion(VAddr addr, u64 size) { | 83 | void ThreadManager::FlushRegion(VAddr addr, u64 size) { |
| 84 | if (!Settings::IsGPULevelExtreme()) { | 84 | if (!Settings::IsGPULevelHigh()) { |
| 85 | return; | 85 | return; |
| 86 | } | 86 | } |
| 87 | if (system.Renderer().Rasterizer().MustFlushRegion(addr, size)) { | 87 | if (system.Renderer().Rasterizer().MustFlushRegion(addr, size)) { |
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.cpp b/src/video_core/renderer_opengl/gl_fence_manager.cpp index 4517ef150..69dd3211b 100644 --- a/src/video_core/renderer_opengl/gl_fence_manager.cpp +++ b/src/video_core/renderer_opengl/gl_fence_manager.cpp | |||
| @@ -33,8 +33,8 @@ void GLInnerFence::Wait() { | |||
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | FenceManagerOpenGL::FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 35 | FenceManagerOpenGL::FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, |
| 36 | TextureCacheOpenGL& texture_cache) | 36 | TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache) |
| 37 | : GenericFenceManager(system, rasterizer, texture_cache) {} | 37 | : GenericFenceManager(system, rasterizer, texture_cache, buffer_cache) {} |
| 38 | 38 | ||
| 39 | Fence FenceManagerOpenGL::CreateFence(GPUVAddr addr, u32 value) { | 39 | Fence FenceManagerOpenGL::CreateFence(GPUVAddr addr, u32 value) { |
| 40 | return std::make_shared<GLInnerFence>(addr, value); | 40 | return std::make_shared<GLInnerFence>(addr, value); |
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.h b/src/video_core/renderer_opengl/gl_fence_manager.h index 3cfa8b1d0..b48d5eaa0 100644 --- a/src/video_core/renderer_opengl/gl_fence_manager.h +++ b/src/video_core/renderer_opengl/gl_fence_manager.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "video_core/fence_manager.h" | 11 | #include "video_core/fence_manager.h" |
| 12 | #include "video_core/renderer_opengl/gl_buffer_cache.h" | ||
| 12 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 13 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 13 | #include "video_core/renderer_opengl/gl_texture_cache.h" | 14 | #include "video_core/renderer_opengl/gl_texture_cache.h" |
| 14 | 15 | ||
| @@ -30,12 +31,12 @@ private: | |||
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | using Fence = std::shared_ptr<GLInnerFence>; | 33 | using Fence = std::shared_ptr<GLInnerFence>; |
| 33 | using GenericFenceManager = VideoCommon::FenceManager<Fence, TextureCacheOpenGL>; | 34 | using GenericFenceManager = VideoCommon::FenceManager<Fence, TextureCacheOpenGL, OGLBufferCache>; |
| 34 | 35 | ||
| 35 | class FenceManagerOpenGL final : public GenericFenceManager { | 36 | class FenceManagerOpenGL final : public GenericFenceManager { |
| 36 | public: | 37 | public: |
| 37 | FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 38 | FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, |
| 38 | TextureCacheOpenGL& texture_cache); | 39 | TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache); |
| 39 | 40 | ||
| 40 | protected: | 41 | protected: |
| 41 | Fence CreateFence(GPUVAddr addr, u32 value) override; | 42 | Fence CreateFence(GPUVAddr addr, u32 value) override; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index db7eae065..88914828c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -102,7 +102,8 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind | |||
| 102 | shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system}, | 102 | shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system}, |
| 103 | screen_info{info}, program_manager{program_manager}, state_tracker{state_tracker}, | 103 | screen_info{info}, program_manager{program_manager}, state_tracker{state_tracker}, |
| 104 | buffer_cache{*this, system, device, STREAM_BUFFER_SIZE}, fence_manager{system, *this, | 104 | buffer_cache{*this, system, device, STREAM_BUFFER_SIZE}, fence_manager{system, *this, |
| 105 | texture_cache} { | 105 | texture_cache, |
| 106 | buffer_cache} { | ||
| 106 | CheckExtensions(); | 107 | CheckExtensions(); |
| 107 | } | 108 | } |
| 108 | 109 | ||