mirror of
				https://git.h3cjp.net/H3cJP/citra.git
				synced 2025-10-31 06:55:03 +00:00 
			
		
		
		
	Address Feedback.
This commit is contained in:
		
							parent
							
								
									ec2f3e48e1
								
							
						
					
					
						commit
						f616dc0b59
					
				|  | @ -154,12 +154,9 @@ public: | |||
|         std::lock_guard lock{mutex}; | ||||
| 
 | ||||
|         std::vector<MapInterval> objects = GetMapsInRange(addr, size); | ||||
|         for (auto& object : objects) { | ||||
|             if (object->IsModified() && object->IsRegistered()) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|         return std::any_of(objects.begin(), objects.end(), [](const MapInterval& map) { | ||||
|             return map->IsModified() && map->IsRegistered(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /// Mark the specified region as being invalidated
 | ||||
|  | @ -199,9 +196,9 @@ public: | |||
|     } | ||||
| 
 | ||||
|     void CommitAsyncFlushes() { | ||||
|         if (uncommited_flushes) { | ||||
|         if (uncommitted_flushes) { | ||||
|             auto commit_list = std::make_shared<std::list<MapInterval>>(); | ||||
|             for (auto& map : *uncommited_flushes) { | ||||
|             for (auto& map : *uncommitted_flushes) { | ||||
|                 if (map->IsRegistered() && map->IsModified()) { | ||||
|                     // TODO(Blinkhawk): Implement backend asynchronous flushing
 | ||||
|                     // AsyncFlushMap(map)
 | ||||
|  | @ -209,41 +206,34 @@ public: | |||
|                 } | ||||
|             } | ||||
|             if (!commit_list->empty()) { | ||||
|                 commited_flushes.push_back(commit_list); | ||||
|                 committed_flushes.push_back(commit_list); | ||||
|             } else { | ||||
|                 commited_flushes.emplace_back(); | ||||
|                 committed_flushes.emplace_back(); | ||||
|             } | ||||
|         } else { | ||||
|             commited_flushes.emplace_back(); | ||||
|             committed_flushes.emplace_back(); | ||||
|         } | ||||
|         uncommited_flushes.reset(); | ||||
|         uncommitted_flushes.reset(); | ||||
|     } | ||||
| 
 | ||||
|     bool ShouldWaitAsyncFlushes() { | ||||
|         if (commited_flushes.empty()) { | ||||
|     bool ShouldWaitAsyncFlushes() const { | ||||
|         if (committed_flushes.empty()) { | ||||
|             return false; | ||||
|         } | ||||
|         auto& flush_list = commited_flushes.front(); | ||||
|         if (!flush_list) { | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|         return committed_flushes.front() != nullptr; | ||||
|     } | ||||
| 
 | ||||
|     bool HasUncommitedFlushes() { | ||||
|         if (uncommited_flushes) { | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|     bool HasUncommittedFlushes() const { | ||||
|         return uncommitted_flushes != nullptr; | ||||
|     } | ||||
| 
 | ||||
|     void PopAsyncFlushes() { | ||||
|         if (commited_flushes.empty()) { | ||||
|         if (committed_flushes.empty()) { | ||||
|             return; | ||||
|         } | ||||
|         auto& flush_list = commited_flushes.front(); | ||||
|         auto& flush_list = committed_flushes.front(); | ||||
|         if (!flush_list) { | ||||
|             commited_flushes.pop_front(); | ||||
|             committed_flushes.pop_front(); | ||||
|             return; | ||||
|         } | ||||
|         for (MapInterval& map : *flush_list) { | ||||
|  | @ -252,7 +242,7 @@ public: | |||
|                 FlushMap(map); | ||||
|             } | ||||
|         } | ||||
|         commited_flushes.pop_front(); | ||||
|         committed_flushes.pop_front(); | ||||
|     } | ||||
| 
 | ||||
|     virtual BufferType GetEmptyBuffer(std::size_t size) = 0; | ||||
|  | @ -568,10 +558,10 @@ private: | |||
|     } | ||||
| 
 | ||||
|     void MarkForAsyncFlush(MapInterval& map) { | ||||
|         if (!uncommited_flushes) { | ||||
|             uncommited_flushes = std::make_shared<std::unordered_set<MapInterval>>(); | ||||
|         if (!uncommitted_flushes) { | ||||
|             uncommitted_flushes = std::make_shared<std::unordered_set<MapInterval>>(); | ||||
|         } | ||||
|         uncommited_flushes->insert(map); | ||||
|         uncommitted_flushes->insert(map); | ||||
|     } | ||||
| 
 | ||||
|     VideoCore::RasterizerInterface& rasterizer; | ||||
|  | @ -605,8 +595,8 @@ private: | |||
|     std::vector<u8> staging_buffer; | ||||
|     std::list<MapInterval> marked_for_unregister; | ||||
| 
 | ||||
|     std::shared_ptr<std::unordered_set<MapInterval>> uncommited_flushes{}; | ||||
|     std::list<std::shared_ptr<std::list<MapInterval>>> commited_flushes; | ||||
|     std::shared_ptr<std::unordered_set<MapInterval>> uncommitted_flushes{}; | ||||
|     std::list<std::shared_ptr<std::list<MapInterval>>> committed_flushes; | ||||
| 
 | ||||
|     std::recursive_mutex mutex; | ||||
| }; | ||||
|  |  | |||
|  | @ -28,15 +28,15 @@ public: | |||
|     FenceBase(GPUVAddr address, u32 payload, bool is_stubbed) | ||||
|         : address{address}, payload{payload}, is_semaphore{true}, is_stubbed{is_stubbed} {} | ||||
| 
 | ||||
|     constexpr GPUVAddr GetAddress() const { | ||||
|     GPUVAddr GetAddress() const { | ||||
|         return address; | ||||
|     } | ||||
| 
 | ||||
|     constexpr u32 GetPayload() const { | ||||
|     u32 GetPayload() const { | ||||
|         return payload; | ||||
|     } | ||||
| 
 | ||||
|     constexpr bool IsSemaphore() const { | ||||
|     bool IsSemaphore() const { | ||||
|         return is_semaphore; | ||||
|     } | ||||
| 
 | ||||
|  | @ -54,12 +54,8 @@ class FenceManager { | |||
| public: | ||||
|     void SignalSemaphore(GPUVAddr addr, u32 value) { | ||||
|         TryReleasePendingFences(); | ||||
|         bool should_flush = texture_cache.HasUncommitedFlushes(); | ||||
|         should_flush |= buffer_cache.HasUncommitedFlushes(); | ||||
|         should_flush |= query_cache.HasUncommitedFlushes(); | ||||
|         texture_cache.CommitAsyncFlushes(); | ||||
|         buffer_cache.CommitAsyncFlushes(); | ||||
|         query_cache.CommitAsyncFlushes(); | ||||
|         bool should_flush = ShouldFlush(); | ||||
|         CommitAsyncFlushes(); | ||||
|         TFence new_fence = CreateFence(addr, value, !should_flush); | ||||
|         fences.push(new_fence); | ||||
|         QueueFence(new_fence); | ||||
|  | @ -71,12 +67,8 @@ public: | |||
| 
 | ||||
|     void SignalSyncPoint(u32 value) { | ||||
|         TryReleasePendingFences(); | ||||
|         bool should_flush = texture_cache.HasUncommitedFlushes(); | ||||
|         should_flush |= buffer_cache.HasUncommitedFlushes(); | ||||
|         should_flush |= query_cache.HasUncommitedFlushes(); | ||||
|         texture_cache.CommitAsyncFlushes(); | ||||
|         buffer_cache.CommitAsyncFlushes(); | ||||
|         query_cache.CommitAsyncFlushes(); | ||||
|         bool should_flush = ShouldFlush(); | ||||
|         CommitAsyncFlushes(); | ||||
|         TFence new_fence = CreateFence(value, !should_flush); | ||||
|         fences.push(new_fence); | ||||
|         QueueFence(new_fence); | ||||
|  | @ -89,15 +81,10 @@ public: | |||
|     void WaitPendingFences() { | ||||
|         while (!fences.empty()) { | ||||
|             TFence& current_fence = fences.front(); | ||||
|             bool should_wait = texture_cache.ShouldWaitAsyncFlushes(); | ||||
|             should_wait |= buffer_cache.ShouldWaitAsyncFlushes(); | ||||
|             should_wait |= query_cache.ShouldWaitAsyncFlushes(); | ||||
|             if (should_wait) { | ||||
|             if (ShouldWait()) { | ||||
|                 WaitFence(current_fence); | ||||
|             } | ||||
|             texture_cache.PopAsyncFlushes(); | ||||
|             buffer_cache.PopAsyncFlushes(); | ||||
|             query_cache.PopAsyncFlushes(); | ||||
|             PopAsyncFlushes(); | ||||
|             auto& gpu{system.GPU()}; | ||||
|             if (current_fence->IsSemaphore()) { | ||||
|                 auto& memory_manager{gpu.MemoryManager()}; | ||||
|  | @ -116,10 +103,18 @@ protected: | |||
|         : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache}, | ||||
|           buffer_cache{buffer_cache}, query_cache{query_cache} {} | ||||
| 
 | ||||
|     virtual ~FenceManager() {} | ||||
| 
 | ||||
|     /// Creates a Sync Point Fence Interface, does not create a backend fence if 'is_stubbed' is
 | ||||
|     /// true
 | ||||
|     virtual TFence CreateFence(u32 value, bool is_stubbed) = 0; | ||||
|     /// Creates a Semaphore Fence Interface, does not create a backend fence if 'is_stubbed' is true
 | ||||
|     virtual TFence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) = 0; | ||||
|     /// Queues a fence into the backend if the fence isn't stubbed.
 | ||||
|     virtual void QueueFence(TFence& fence) = 0; | ||||
|     virtual bool IsFenceSignaled(TFence& fence) = 0; | ||||
|     /// Notifies that the backend fence has been signaled/reached in host GPU.
 | ||||
|     virtual bool IsFenceSignaled(TFence& fence) const = 0; | ||||
|     /// Waits until a fence has been signalled by the host GPU.
 | ||||
|     virtual void WaitFence(TFence& fence) = 0; | ||||
| 
 | ||||
|     Core::System& system; | ||||
|  | @ -132,15 +127,10 @@ private: | |||
|     void TryReleasePendingFences() { | ||||
|         while (!fences.empty()) { | ||||
|             TFence& current_fence = fences.front(); | ||||
|             bool should_wait = texture_cache.ShouldWaitAsyncFlushes(); | ||||
|             should_wait |= buffer_cache.ShouldWaitAsyncFlushes(); | ||||
|             should_wait |= query_cache.ShouldWaitAsyncFlushes(); | ||||
|             if (should_wait && !IsFenceSignaled(current_fence)) { | ||||
|             if (ShouldWait() && !IsFenceSignaled(current_fence)) { | ||||
|                 return; | ||||
|             } | ||||
|             texture_cache.PopAsyncFlushes(); | ||||
|             buffer_cache.PopAsyncFlushes(); | ||||
|             query_cache.PopAsyncFlushes(); | ||||
|             PopAsyncFlushes(); | ||||
|             auto& gpu{system.GPU()}; | ||||
|             if (current_fence->IsSemaphore()) { | ||||
|                 auto& memory_manager{gpu.MemoryManager()}; | ||||
|  | @ -152,6 +142,28 @@ private: | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     bool ShouldWait() const { | ||||
|         return texture_cache.ShouldWaitAsyncFlushes() || buffer_cache.ShouldWaitAsyncFlushes() || | ||||
|                query_cache.ShouldWaitAsyncFlushes(); | ||||
|     } | ||||
| 
 | ||||
|     bool ShouldFlush() const { | ||||
|         return texture_cache.HasUncommittedFlushes() || buffer_cache.HasUncommittedFlushes() || | ||||
|                query_cache.HasUncommittedFlushes(); | ||||
|     } | ||||
| 
 | ||||
|     void PopAsyncFlushes() { | ||||
|         texture_cache.PopAsyncFlushes(); | ||||
|         buffer_cache.PopAsyncFlushes(); | ||||
|         query_cache.PopAsyncFlushes(); | ||||
|     } | ||||
| 
 | ||||
|     void CommitAsyncFlushes() { | ||||
|         texture_cache.CommitAsyncFlushes(); | ||||
|         buffer_cache.CommitAsyncFlushes(); | ||||
|         query_cache.CommitAsyncFlushes(); | ||||
|     } | ||||
| 
 | ||||
|     std::queue<TFence> fences; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -125,7 +125,7 @@ bool GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) { | |||
|     return true; | ||||
| } | ||||
| 
 | ||||
| u64 GPU::RequestFlush(CacheAddr addr, std::size_t size) { | ||||
| u64 GPU::RequestFlush(VAddr addr, std::size_t size) { | ||||
|     std::unique_lock lck{flush_request_mutex}; | ||||
|     const u64 fence = ++last_flush_fence; | ||||
|     flush_requests.emplace_back(fence, addr, size); | ||||
|  | @ -137,7 +137,7 @@ void GPU::TickWork() { | |||
|     while (!flush_requests.empty()) { | ||||
|         auto& request = flush_requests.front(); | ||||
|         const u64 fence = request.fence; | ||||
|         const CacheAddr addr = request.addr; | ||||
|         const VAddr addr = request.addr; | ||||
|         const std::size_t size = request.size; | ||||
|         flush_requests.pop_front(); | ||||
|         flush_request_mutex.unlock(); | ||||
|  |  | |||
|  | @ -155,16 +155,22 @@ public: | |||
|     /// Calls a GPU method.
 | ||||
|     void CallMethod(const MethodCall& method_call); | ||||
| 
 | ||||
|     /// Flush all current written commands into the host GPU for execution.
 | ||||
|     void FlushCommands(); | ||||
|     /// Synchronizes CPU writes with Host GPU memory.
 | ||||
|     void SyncGuestHost(); | ||||
|     /// Signal the ending of command list.
 | ||||
|     virtual void OnCommandListEnd(); | ||||
| 
 | ||||
|     u64 RequestFlush(CacheAddr addr, std::size_t size); | ||||
|     /// Request a host GPU memory flush from the CPU.
 | ||||
|     u64 RequestFlush(VAddr addr, std::size_t size); | ||||
| 
 | ||||
|     /// Obtains current flush request fence id.
 | ||||
|     u64 CurrentFlushRequestFence() const { | ||||
|         return current_flush_fence.load(std::memory_order_relaxed); | ||||
|     } | ||||
| 
 | ||||
|     /// Tick pending requests within the GPU.
 | ||||
|     void TickWork(); | ||||
| 
 | ||||
|     /// Returns a reference to the Maxwell3D GPU engine.
 | ||||
|  | @ -336,10 +342,10 @@ private: | |||
|     std::condition_variable sync_cv; | ||||
| 
 | ||||
|     struct FlushRequest { | ||||
|         FlushRequest(u64 fence, CacheAddr addr, std::size_t size) | ||||
|         FlushRequest(u64 fence, VAddr addr, std::size_t size) | ||||
|             : fence{fence}, addr{addr}, size{size} {} | ||||
|         u64 fence; | ||||
|         CacheAddr addr; | ||||
|         VAddr addr; | ||||
|         std::size_t size; | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -176,41 +176,34 @@ public: | |||
|     } | ||||
| 
 | ||||
|     void CommitAsyncFlushes() { | ||||
|         commited_flushes.push_back(uncommited_flushes); | ||||
|         uncommited_flushes.reset(); | ||||
|         committed_flushes.push_back(uncommitted_flushes); | ||||
|         uncommitted_flushes.reset(); | ||||
|     } | ||||
| 
 | ||||
|     bool HasUncommitedFlushes() { | ||||
|         if (uncommited_flushes) { | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|     bool HasUncommittedFlushes() const { | ||||
|         return uncommitted_flushes != nullptr; | ||||
|     } | ||||
| 
 | ||||
|     bool ShouldWaitAsyncFlushes() { | ||||
|         if (commited_flushes.empty()) { | ||||
|     bool ShouldWaitAsyncFlushes() const { | ||||
|         if (committed_flushes.empty()) { | ||||
|             return false; | ||||
|         } | ||||
|         auto& flush_list = commited_flushes.front(); | ||||
|         if (!flush_list) { | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|         return committed_flushes.front() != nullptr; | ||||
|     } | ||||
| 
 | ||||
|     void PopAsyncFlushes() { | ||||
|         if (commited_flushes.empty()) { | ||||
|         if (committed_flushes.empty()) { | ||||
|             return; | ||||
|         } | ||||
|         auto& flush_list = commited_flushes.front(); | ||||
|         auto& flush_list = committed_flushes.front(); | ||||
|         if (!flush_list) { | ||||
|             commited_flushes.pop_front(); | ||||
|             committed_flushes.pop_front(); | ||||
|             return; | ||||
|         } | ||||
|         for (VAddr query_address : *flush_list) { | ||||
|             FlushAndRemoveRegion(query_address, 4); | ||||
|         } | ||||
|         commited_flushes.pop_front(); | ||||
|         committed_flushes.pop_front(); | ||||
|     } | ||||
| 
 | ||||
| protected: | ||||
|  | @ -268,10 +261,10 @@ private: | |||
|     } | ||||
| 
 | ||||
|     void AsyncFlushQuery(VAddr addr) { | ||||
|         if (!uncommited_flushes) { | ||||
|             uncommited_flushes = std::make_shared<std::unordered_set<VAddr>>(); | ||||
|         if (!uncommitted_flushes) { | ||||
|             uncommitted_flushes = std::make_shared<std::unordered_set<VAddr>>(); | ||||
|         } | ||||
|         uncommited_flushes->insert(addr); | ||||
|         uncommitted_flushes->insert(addr); | ||||
|     } | ||||
| 
 | ||||
|     static constexpr std::uintptr_t PAGE_SIZE = 4096; | ||||
|  | @ -286,8 +279,8 @@ private: | |||
| 
 | ||||
|     std::array<CounterStream, VideoCore::NumQueryTypes> streams; | ||||
| 
 | ||||
|     std::shared_ptr<std::unordered_set<VAddr>> uncommited_flushes{}; | ||||
|     std::list<std::shared_ptr<std::unordered_set<VAddr>>> commited_flushes; | ||||
|     std::shared_ptr<std::unordered_set<VAddr>> uncommitted_flushes{}; | ||||
|     std::list<std::shared_ptr<std::unordered_set<VAddr>>> committed_flushes; | ||||
| }; | ||||
| 
 | ||||
| template <class QueryCache, class HostCounter> | ||||
|  |  | |||
|  | @ -64,6 +64,7 @@ public: | |||
|     /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
 | ||||
|     virtual void FlushRegion(VAddr addr, u64 size) = 0; | ||||
| 
 | ||||
|     /// Check if the the specified memory area requires flushing to CPU Memory.
 | ||||
|     virtual bool MustFlushRegion(VAddr addr, u64 size) = 0; | ||||
| 
 | ||||
|     /// Notify rasterizer that any caches of the specified region should be invalidated
 | ||||
|  |  | |||
|  | @ -62,7 +62,7 @@ void FenceManagerOpenGL::QueueFence(Fence& fence) { | |||
|     fence->Queue(); | ||||
| } | ||||
| 
 | ||||
| bool FenceManagerOpenGL::IsFenceSignaled(Fence& fence) { | ||||
| bool FenceManagerOpenGL::IsFenceSignaled(Fence& fence) const { | ||||
|     return fence->IsSignaled(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -46,7 +46,7 @@ protected: | |||
|     Fence CreateFence(u32 value, bool is_stubbed) override; | ||||
|     Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override; | ||||
|     void QueueFence(Fence& fence) override; | ||||
|     bool IsFenceSignaled(Fence& fence) override; | ||||
|     bool IsFenceSignaled(Fence& fence) const override; | ||||
|     void WaitFence(Fence& fence) override; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -653,9 +653,6 @@ void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) { | |||
| } | ||||
| 
 | ||||
| bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size) { | ||||
|     if (!Settings::IsGPULevelExtreme()) { | ||||
|         return buffer_cache.MustFlushRegion(addr, size); | ||||
|     } | ||||
|     return texture_cache.MustFlushRegion(addr, size) || buffer_cache.MustFlushRegion(addr, size); | ||||
| } | ||||
| 
 | ||||
|  | @ -672,7 +669,7 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { | |||
| 
 | ||||
| void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { | ||||
|     MICROPROFILE_SCOPE(OpenGL_CacheManagement); | ||||
|     if (!addr || !size) { | ||||
|     if (addr == 0 || size == 0) { | ||||
|         return; | ||||
|     } | ||||
|     texture_cache.OnCPUWrite(addr, size); | ||||
|  |  | |||
|  | @ -90,7 +90,7 @@ void VKFenceManager::QueueFence(Fence& fence) { | |||
|     fence->Queue(); | ||||
| } | ||||
| 
 | ||||
| bool VKFenceManager::IsFenceSignaled(Fence& fence) { | ||||
| bool VKFenceManager::IsFenceSignaled(Fence& fence) const { | ||||
|     return fence->IsSignaled(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -63,7 +63,7 @@ protected: | |||
|     Fence CreateFence(u32 value, bool is_stubbed) override; | ||||
|     Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override; | ||||
|     void QueueFence(Fence& fence) override; | ||||
|     bool IsFenceSignaled(Fence& fence) override; | ||||
|     bool IsFenceSignaled(Fence& fence) const override; | ||||
|     void WaitFence(Fence& fence) override; | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -533,7 +533,7 @@ void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { | |||
| } | ||||
| 
 | ||||
| void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) { | ||||
|     if (!addr || !size) { | ||||
|     if (addr == 0 || size == 0) { | ||||
|         return; | ||||
|     } | ||||
|     texture_cache.OnCPUWrite(addr, size); | ||||
|  |  | |||
|  | @ -120,15 +120,8 @@ public: | |||
|         std::lock_guard lock{mutex}; | ||||
| 
 | ||||
|         auto surfaces = GetSurfacesInRegion(addr, size); | ||||
|         if (surfaces.empty()) { | ||||
|             return false; | ||||
|         } | ||||
|         for (const auto& surface : surfaces) { | ||||
|             if (surface->IsModified()) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|         return std::any_of(surfaces.begin(), surfaces.end(), | ||||
|                            [](const TSurface& surface) { return surface->IsModified(); }); | ||||
|     } | ||||
| 
 | ||||
|     TView GetTextureSurface(const Tegra::Texture::TICEntry& tic, | ||||
|  | @ -333,41 +326,34 @@ public: | |||
|     } | ||||
| 
 | ||||
|     void CommitAsyncFlushes() { | ||||
|         commited_flushes.push_back(uncommited_flushes); | ||||
|         uncommited_flushes.reset(); | ||||
|         committed_flushes.push_back(uncommitted_flushes); | ||||
|         uncommitted_flushes.reset(); | ||||
|     } | ||||
| 
 | ||||
|     bool HasUncommitedFlushes() { | ||||
|         if (uncommited_flushes) { | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|     bool HasUncommittedFlushes() const { | ||||
|         return uncommitted_flushes != nullptr; | ||||
|     } | ||||
| 
 | ||||
|     bool ShouldWaitAsyncFlushes() { | ||||
|         if (commited_flushes.empty()) { | ||||
|     bool ShouldWaitAsyncFlushes() const { | ||||
|         if (committed_flushes.empty()) { | ||||
|             return false; | ||||
|         } | ||||
|         auto& flush_list = commited_flushes.front(); | ||||
|         if (!flush_list) { | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|         return committed_flushes.front() != nullptr; | ||||
|     } | ||||
| 
 | ||||
|     void PopAsyncFlushes() { | ||||
|         if (commited_flushes.empty()) { | ||||
|         if (committed_flushes.empty()) { | ||||
|             return; | ||||
|         } | ||||
|         auto& flush_list = commited_flushes.front(); | ||||
|         auto& flush_list = committed_flushes.front(); | ||||
|         if (!flush_list) { | ||||
|             commited_flushes.pop_front(); | ||||
|             committed_flushes.pop_front(); | ||||
|             return; | ||||
|         } | ||||
|         for (TSurface& surface : *flush_list) { | ||||
|             FlushSurface(surface); | ||||
|         } | ||||
|         commited_flushes.pop_front(); | ||||
|         committed_flushes.pop_front(); | ||||
|     } | ||||
| 
 | ||||
| protected: | ||||
|  | @ -1206,10 +1192,10 @@ private: | |||
|     }; | ||||
| 
 | ||||
|     void AsyncFlushSurface(TSurface& surface) { | ||||
|         if (!uncommited_flushes) { | ||||
|             uncommited_flushes = std::make_shared<std::list<TSurface>>(); | ||||
|         if (!uncommitted_flushes) { | ||||
|             uncommitted_flushes = std::make_shared<std::list<TSurface>>(); | ||||
|         } | ||||
|         uncommited_flushes->push_back(surface); | ||||
|         uncommitted_flushes->push_back(surface); | ||||
|     } | ||||
| 
 | ||||
|     VideoCore::RasterizerInterface& rasterizer; | ||||
|  | @ -1258,8 +1244,8 @@ private: | |||
| 
 | ||||
|     std::list<TSurface> marked_for_unregister; | ||||
| 
 | ||||
|     std::shared_ptr<std::list<TSurface>> uncommited_flushes{}; | ||||
|     std::list<std::shared_ptr<std::list<TSurface>>> commited_flushes; | ||||
|     std::shared_ptr<std::list<TSurface>> uncommitted_flushes{}; | ||||
|     std::list<std::shared_ptr<std::list<TSurface>>> committed_flushes; | ||||
| 
 | ||||
|     StagingCache staging_cache; | ||||
|     std::recursive_mutex mutex; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue