diff options
| author | Fernando Sahmkow <fsahmkow27@gmail.com> | 2020-02-18 17:20:39 -0400 | 
|---|---|---|
| committer | Fernando Sahmkow <fsahmkow27@gmail.com> | 2020-04-22 11:36:15 -0400 | 
| commit | b10db7e4a5f43414679b7969ea309b1829937a37 (patch) | |
| tree | 5a2df21d974ee17488ee01960a823ae6f89d9edb /src/video_core | |
| parent | 4adfc9bb0870296b372dc96296436538d6aa6c32 (diff) | |
FenceManager: Implement async buffer cache flushes on High settings
Diffstat (limited to 'src/video_core')
| -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 @@  #include "common/common_types.h"  #include "core/core.h"  #include "core/memory.h" +#include "core/settings.h"  #include "video_core/buffer_cache/buffer_block.h"  #include "video_core/buffer_cache/map_interval.h"  #include "video_core/memory_manager.h" @@ -80,6 +81,9 @@ public:          auto map = MapAddress(block, gpu_addr, cpu_addr, size);          if (is_written) {              map->MarkAsModified(true, GetModifiedTicks()); +            if (Settings::IsGPULevelHigh() && Settings::values.use_asynchronous_gpu_emulation) { +                AsyncFlushMap(map); +            }              if (!map->IsWritten()) {                  map->MarkAsWritten(true);                  MarkRegionAsWritten(map->GetStart(), map->GetEnd() - 1); @@ -193,6 +197,39 @@ public:          marked_for_unregister.clear();      } +    void CommitAsyncFlushes() { +        commited_flushes.push_back(uncommited_flushes); +        uncommited_flushes.reset(); +    } + +    bool ShouldWaitAsyncFlushes() { +        if (commited_flushes.empty()) { +            return false; +        } +        auto& flush_list = commited_flushes.front(); +        if (!flush_list) { +            return false; +        } +        return true; +    } + +    void PopAsyncFlushes() { +        if (commited_flushes.empty()) { +            return; +        } +        auto& flush_list = commited_flushes.front(); +        if (!flush_list) { +            commited_flushes.pop_front(); +            return; +        } +        for (MapInterval& map : *flush_list) { +            if (map->IsRegistered()) { +                FlushMap(map); +            } +        } +        commited_flushes.pop_front(); +    } +      virtual BufferType GetEmptyBuffer(std::size_t size) = 0;  protected: @@ -316,6 +353,9 @@ private:          MapInterval new_map = CreateMap(new_start, new_end, new_gpu_addr);          if (modified_inheritance) {              new_map->MarkAsModified(true, GetModifiedTicks()); +            if (Settings::IsGPULevelHigh() && Settings::values.use_asynchronous_gpu_emulation) { +                AsyncFlushMap(new_map); +            }          }          Register(new_map, write_inheritance);          return new_map; @@ -502,6 +542,13 @@ private:          return false;      } +    void AsyncFlushMap(MapInterval& map) { +        if (!uncommited_flushes) { +            uncommited_flushes = std::make_shared<std::list<MapInterval>>(); +        } +        uncommited_flushes->push_back(map); +    } +      VideoCore::RasterizerInterface& rasterizer;      Core::System& system; @@ -533,6 +580,9 @@ private:      std::vector<u8> staging_buffer;      std::list<MapInterval> marked_for_unregister; +    std::shared_ptr<std::list<MapInterval>> uncommited_flushes{}; +    std::list<std::shared_ptr<std::list<MapInterval>>> commited_flushes; +      std::recursive_mutex mutex;  }; 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 @@  #include <algorithm>  #include <array> -#include <queue>  #include <memory> +#include <queue>  #include "common/assert.h"  #include "common/common_types.h" @@ -37,7 +37,7 @@ private:      u32 payload;  }; -template <typename TFence, typename TTextureCache> +template <typename TFence, typename TTextureCache, typename TTBufferCache>  class FenceManager {  public:      void SignalFence(GPUVAddr addr, u32 value) { @@ -46,6 +46,7 @@ public:          QueueFence(new_fence);          fences.push(new_fence);          texture_cache.CommitAsyncFlushes(); +        buffer_cache.CommitAsyncFlushes();          rasterizer.FlushCommands();          rasterizer.SyncGuestHost();      } @@ -54,10 +55,12 @@ public:          while (!fences.empty()) {              TFence& current_fence = fences.front();              bool should_wait = texture_cache.ShouldWaitAsyncFlushes(); +            should_wait |= buffer_cache.ShouldWaitAsyncFlushes();              if (should_wait) {                  WaitFence(current_fence);              }              texture_cache.PopAsyncFlushes(); +            buffer_cache.PopAsyncFlushes();              auto& gpu{system.GPU()};              auto& memory_manager{gpu.MemoryManager()};              memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload()); @@ -67,8 +70,9 @@ public:  protected:      FenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, -                 TTextureCache& texture_cache) -        : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache} {} +                 TTextureCache& texture_cache, TTBufferCache& buffer_cache) +        : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache}, buffer_cache{ +                                                                                    buffer_cache} {}      virtual TFence CreateFence(GPUVAddr addr, u32 value) = 0;      virtual void QueueFence(TFence& fence) = 0; @@ -78,16 +82,19 @@ protected:      Core::System& system;      VideoCore::RasterizerInterface& rasterizer;      TTextureCache& texture_cache; +    TTBufferCache& buffer_cache;  private:      void TryReleasePendingFences() {          while (!fences.empty()) {              TFence& current_fence = fences.front();              bool should_wait = texture_cache.ShouldWaitAsyncFlushes(); +            should_wait |= buffer_cache.ShouldWaitAsyncFlushes();              if (should_wait && !IsFenceSignaled(current_fence)) {                  return;              }              texture_cache.PopAsyncFlushes(); +            buffer_cache.PopAsyncFlushes();              auto& gpu{system.GPU()};              auto& memory_manager{gpu.MemoryManager()};              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) {  }  void ThreadManager::FlushRegion(VAddr addr, u64 size) { -    if (!Settings::IsGPULevelExtreme()) { +    if (!Settings::IsGPULevelHigh()) {          return;      }      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() {  }  FenceManagerOpenGL::FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, -                               TextureCacheOpenGL& texture_cache) -    : GenericFenceManager(system, rasterizer, texture_cache) {} +                               TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache) +    : GenericFenceManager(system, rasterizer, texture_cache, buffer_cache) {}  Fence FenceManagerOpenGL::CreateFence(GPUVAddr addr, u32 value) {      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 @@  #include "common/common_types.h"  #include "video_core/fence_manager.h" +#include "video_core/renderer_opengl/gl_buffer_cache.h"  #include "video_core/renderer_opengl/gl_resource_manager.h"  #include "video_core/renderer_opengl/gl_texture_cache.h" @@ -30,12 +31,12 @@ private:  };  using Fence = std::shared_ptr<GLInnerFence>; -using GenericFenceManager = VideoCommon::FenceManager<Fence, TextureCacheOpenGL>; +using GenericFenceManager = VideoCommon::FenceManager<Fence, TextureCacheOpenGL, OGLBufferCache>;  class FenceManagerOpenGL final : public GenericFenceManager {  public:      FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, -                   TextureCacheOpenGL& texture_cache); +                       TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache);  protected:      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        shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system},        screen_info{info}, program_manager{program_manager}, state_tracker{state_tracker},        buffer_cache{*this, system, device, STREAM_BUFFER_SIZE}, fence_manager{system, *this, -                                                                             texture_cache} { +                                                                             texture_cache, +                                                                             buffer_cache} {      CheckExtensions();  } | 
