mirror of
				https://git.eden-emu.dev/eden-emu/eden.git
				synced 2025-10-25 19:03:17 +00:00 
			
		
		
		
	GPU: Refactor synchronization on Async GPU
This commit is contained in:
		
							parent
							
								
									0a62525e65
								
							
						
					
					
						commit
						c689dc6804
					
				
					 11 changed files with 56 additions and 7 deletions
				
			
		|  | @ -32,6 +32,7 @@ void DmaPusher::DispatchCalls() { | |||
|         } | ||||
|     } | ||||
|     gpu.FlushCommands(); | ||||
|     gpu.SyncGuestHost(); | ||||
| } | ||||
| 
 | ||||
| bool DmaPusher::Step() { | ||||
|  |  | |||
|  | @ -403,9 +403,13 @@ void Maxwell3D::ProcessQueryGet() { | |||
|                "Units other than CROP are unimplemented"); | ||||
| 
 | ||||
|     switch (regs.query.query_get.operation) { | ||||
|     case Regs::QueryOperation::Release: | ||||
|         StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); | ||||
|     case Regs::QueryOperation::Release: { | ||||
|         rasterizer.FlushCommands(); | ||||
|         rasterizer.SyncGuestHost(); | ||||
|         const u64 result = regs.query.query_sequence; | ||||
|         StampQueryResult(result, regs.query.query_get.short_query == 0); | ||||
|         break; | ||||
|     } | ||||
|     case Regs::QueryOperation::Acquire: | ||||
|         // TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that
 | ||||
|         // matches the current payload.
 | ||||
|  |  | |||
|  | @ -142,6 +142,9 @@ void GPU::FlushCommands() { | |||
|     renderer->Rasterizer().FlushCommands(); | ||||
| } | ||||
| 
 | ||||
| void GPU::SyncGuestHost() { | ||||
|     renderer->Rasterizer().SyncGuestHost(); | ||||
| } | ||||
| // Note that, traditionally, methods are treated as 4-byte addressable locations, and hence
 | ||||
| // their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4.
 | ||||
| // So the values you see in docs might be multiplied by 4.
 | ||||
|  |  | |||
|  | @ -156,6 +156,7 @@ public: | |||
|     void CallMethod(const MethodCall& method_call); | ||||
| 
 | ||||
|     void FlushCommands(); | ||||
|     void SyncGuestHost(); | ||||
| 
 | ||||
|     /// Returns a reference to the Maxwell3D GPU engine.
 | ||||
|     Engines::Maxwell3D& Maxwell3D(); | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ static void RunThread(VideoCore::RendererBase& renderer, Core::Frontend::Graphic | |||
|         } else if (const auto data = std::get_if<FlushRegionCommand>(&next.data)) { | ||||
|             renderer.Rasterizer().FlushRegion(data->addr, data->size); | ||||
|         } else if (const auto data = std::get_if<InvalidateRegionCommand>(&next.data)) { | ||||
|             renderer.Rasterizer().InvalidateRegion(data->addr, data->size); | ||||
|             renderer.Rasterizer().OnCPUWrite(data->addr, data->size); | ||||
|         } else if (std::holds_alternative<EndProcessingCommand>(next.data)) { | ||||
|             return; | ||||
|         } else { | ||||
|  | @ -82,12 +82,12 @@ void ThreadManager::FlushRegion(VAddr addr, u64 size) { | |||
| } | ||||
| 
 | ||||
| void ThreadManager::InvalidateRegion(VAddr addr, u64 size) { | ||||
|     system.Renderer().Rasterizer().InvalidateRegion(addr, size); | ||||
|     system.Renderer().Rasterizer().OnCPUWrite(addr, size); | ||||
| } | ||||
| 
 | ||||
| void ThreadManager::FlushAndInvalidateRegion(VAddr addr, u64 size) { | ||||
|     // Skip flush on asynch mode, as FlushAndInvalidateRegion is not used for anything too important
 | ||||
|     InvalidateRegion(addr, size); | ||||
|     system.Renderer().Rasterizer().OnCPUWrite(addr, size); | ||||
| } | ||||
| 
 | ||||
| void ThreadManager::WaitIdle() const { | ||||
|  |  | |||
|  | @ -58,6 +58,12 @@ public: | |||
|     /// Notify rasterizer that any caches of the specified region should be invalidated
 | ||||
|     virtual void InvalidateRegion(VAddr addr, u64 size) = 0; | ||||
| 
 | ||||
|     /// Notify rasterizer that any caches of the specified region are desync with guest
 | ||||
|     virtual void OnCPUWrite(VAddr addr, u64 size) = 0; | ||||
| 
 | ||||
|     /// Sync memory between guest and host.
 | ||||
|     virtual void SyncGuestHost() = 0; | ||||
| 
 | ||||
|     /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
 | ||||
|     /// and invalidated
 | ||||
|     virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; | ||||
|  |  | |||
|  | @ -660,6 +660,22 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { | |||
|     query_cache.InvalidateRegion(addr, size); | ||||
| } | ||||
| 
 | ||||
| void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { | ||||
|     MICROPROFILE_SCOPE(OpenGL_CacheManagement); | ||||
|     if (!addr || !size) { | ||||
|         return; | ||||
|     } | ||||
|     texture_cache.OnCPUWrite(addr, size); | ||||
|     shader_cache.InvalidateRegion(addr, size); | ||||
|     buffer_cache.InvalidateRegion(addr, size); | ||||
| } | ||||
| 
 | ||||
| void RasterizerOpenGL::SyncGuestHost() { | ||||
|     MICROPROFILE_SCOPE(OpenGL_CacheManagement); | ||||
|     texture_cache.SyncGuestHost(); | ||||
|     // buffer_cache.SyncGuestHost();
 | ||||
| } | ||||
| 
 | ||||
| void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { | ||||
|     if (Settings::IsGPULevelExtreme()) { | ||||
|         FlushRegion(addr, size); | ||||
|  |  | |||
|  | @ -67,6 +67,8 @@ public: | |||
|     void FlushAll() override; | ||||
|     void FlushRegion(VAddr addr, u64 size) override; | ||||
|     void InvalidateRegion(VAddr addr, u64 size) override; | ||||
|     void OnCPUWrite(VAddr addr, u64 size) override; | ||||
|     void SyncGuestHost() override; | ||||
|     void FlushAndInvalidateRegion(VAddr addr, u64 size) override; | ||||
|     void FlushCommands() override; | ||||
|     void TickFrame() override; | ||||
|  |  | |||
|  | @ -524,6 +524,20 @@ void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { | |||
|     query_cache.InvalidateRegion(addr, size); | ||||
| } | ||||
| 
 | ||||
| void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) { | ||||
|     if (!addr || !size) { | ||||
|         return; | ||||
|     } | ||||
|     texture_cache.OnCPUWrite(addr, size); | ||||
|     pipeline_cache.InvalidateRegion(addr, size); | ||||
|     buffer_cache.InvalidateRegion(addr, size); | ||||
| } | ||||
| 
 | ||||
| void RasterizerVulkan::SyncGuestHost() { | ||||
|     texture_cache.SyncGuestHost(); | ||||
|     // buffer_cache.SyncGuestHost();
 | ||||
| } | ||||
| 
 | ||||
| void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { | ||||
|     FlushRegion(addr, size); | ||||
|     InvalidateRegion(addr, size); | ||||
|  |  | |||
|  | @ -119,6 +119,8 @@ public: | |||
|     void FlushAll() override; | ||||
|     void FlushRegion(VAddr addr, u64 size) override; | ||||
|     void InvalidateRegion(VAddr addr, u64 size) override; | ||||
|     void OnCPUWrite(VAddr addr, u64 size) override; | ||||
|     void SyncGuestHost() override; | ||||
|     void FlushAndInvalidateRegion(VAddr addr, u64 size) override; | ||||
|     void FlushCommands() override; | ||||
|     void TickFrame() override; | ||||
|  |  | |||
|  | @ -63,7 +63,7 @@ public: | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void OnCPUWrite(CacheAddr addr, std::size_t size) { | ||||
|     void OnCPUWrite(VAddr addr, std::size_t size) { | ||||
|         std::lock_guard lock{mutex}; | ||||
| 
 | ||||
|         for (const auto& surface : GetSurfacesInRegion(addr, size)) { | ||||
|  | @ -549,7 +549,7 @@ private: | |||
|         } | ||||
|         const auto& final_params = new_surface->GetSurfaceParams(); | ||||
|         if (cr_params.type != final_params.type) { | ||||
|             if (Settings::values.use_accurate_gpu_emulation) { | ||||
|             if (Settings::IsGPULevelExtreme()) { | ||||
|                 BufferCopy(current_surface, new_surface); | ||||
|             } | ||||
|         } else { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Fernando Sahmkow
						Fernando Sahmkow