forked from eden-emu/eden
		
	Vk Async Worker directly emplace in cache
This commit is contained in:
		
							parent
							
								
									4539073ce1
								
							
						
					
					
						commit
						c02464f64e
					
				
					 3 changed files with 41 additions and 58 deletions
				
			
		|  | @ -215,11 +215,7 @@ VKGraphicsPipeline* VKPipelineCache::GetGraphicsPipeline( | ||||||
|     last_graphics_key = key; |     last_graphics_key = key; | ||||||
| 
 | 
 | ||||||
|     if (device.UseAsynchronousShaders()) { |     if (device.UseAsynchronousShaders()) { | ||||||
|         auto work = async_shaders.GetCompletedWork(); |         std::unique_lock lock{pipeline_cache}; | ||||||
|         for (auto& w : work) { |  | ||||||
|             auto& entry = graphics_cache.at(w.pipeline->GetCacheKey()); |  | ||||||
|             entry = std::move(w.pipeline); |  | ||||||
|         } |  | ||||||
|         const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); |         const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); | ||||||
|         if (is_cache_miss) { |         if (is_cache_miss) { | ||||||
|             LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); |             LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); | ||||||
|  | @ -296,6 +292,18 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach | ||||||
|     return *entry; |     return *entry; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void VKPipelineCache::EmplacePipeline(std::unique_ptr<VKGraphicsPipeline> pipeline) { | ||||||
|  |     std::unique_lock lock{pipeline_cache}; | ||||||
|  |     const auto [pair, is_cache_miss] = graphics_cache.try_emplace(pipeline->GetCacheKey()); | ||||||
|  |     auto& entry = pair->second; | ||||||
|  |     if (entry) { | ||||||
|  |         LOG_INFO(Render_Vulkan, "Pipeline already here 0x{:016X}", pipeline->GetCacheKey().Hash()); | ||||||
|  |         duplicates.push_back(std::move(pipeline)); | ||||||
|  |     } else { | ||||||
|  |         entry = std::move(pipeline); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void VKPipelineCache::OnShaderRemoval(Shader* shader) { | void VKPipelineCache::OnShaderRemoval(Shader* shader) { | ||||||
|     bool finished = false; |     bool finished = false; | ||||||
|     const auto Finish = [&] { |     const auto Finish = [&] { | ||||||
|  |  | ||||||
|  | @ -193,6 +193,8 @@ public: | ||||||
|         return renderpass_cache; |         return renderpass_cache; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void EmplacePipeline(std::unique_ptr<VKGraphicsPipeline> pipeline); | ||||||
|  | 
 | ||||||
| protected: | protected: | ||||||
|     void OnShaderRemoval(Shader* shader) final; |     void OnShaderRemoval(Shader* shader) final; | ||||||
| 
 | 
 | ||||||
|  | @ -216,6 +218,7 @@ private: | ||||||
|     VKGraphicsPipeline* last_graphics_pipeline = nullptr; |     VKGraphicsPipeline* last_graphics_pipeline = nullptr; | ||||||
|     std::vector<std::unique_ptr<VKGraphicsPipeline>> duplicates; |     std::vector<std::unique_ptr<VKGraphicsPipeline>> duplicates; | ||||||
| 
 | 
 | ||||||
|  |     std::mutex pipeline_cache; | ||||||
|     std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<VKGraphicsPipeline>> |     std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<VKGraphicsPipeline>> | ||||||
|         graphics_cache; |         graphics_cache; | ||||||
|     std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<VKComputePipeline>> compute_cache; |     std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<VKComputePipeline>> compute_cache; | ||||||
|  |  | ||||||
|  | @ -111,19 +111,19 @@ void AsyncShaders::QueueOpenGLShader(const OpenGL::Device& device, | ||||||
|                                      VideoCommon::Shader::CompilerSettings compiler_settings, |                                      VideoCommon::Shader::CompilerSettings compiler_settings, | ||||||
|                                      const VideoCommon::Shader::Registry& registry, |                                      const VideoCommon::Shader::Registry& registry, | ||||||
|                                      VAddr cpu_addr) { |                                      VAddr cpu_addr) { | ||||||
|     auto p = std::make_unique<WorkerParams>(); |     auto params = std::make_unique<WorkerParams>(); | ||||||
|     p->backend = device.UseAssemblyShaders() ? Backend::GLASM : Backend::OpenGL; |     params->backend = device.UseAssemblyShaders() ? Backend::GLASM : Backend::OpenGL; | ||||||
|     p->device = &device; |     params->device = &device; | ||||||
|     p->shader_type = shader_type; |     params->shader_type = shader_type; | ||||||
|     p->uid = uid; |     params->uid = uid; | ||||||
|     p->code = std::move(code); |     params->code = std::move(code); | ||||||
|     p->code_b = std::move(code_b); |     params->code_b = std::move(code_b); | ||||||
|     p->main_offset = main_offset; |     params->main_offset = main_offset; | ||||||
|     p->compiler_settings = compiler_settings; |     params->compiler_settings = compiler_settings; | ||||||
|     p->registry = ®istry; |     params->registry = ®istry; | ||||||
|     p->cpu_address = cpu_addr; |     params->cpu_address = cpu_addr; | ||||||
|     std::unique_lock lock(queue_mutex); |     std::unique_lock lock(queue_mutex); | ||||||
|     pending_queue.push(std::move(p)); |     pending_queue.push(std::move(params)); | ||||||
|     cv.notify_one(); |     cv.notify_one(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -133,19 +133,19 @@ void AsyncShaders::QueueVulkanShader( | ||||||
|     std::array<GPUVAddr, Vulkan::Maxwell::MaxShaderProgram> shaders, |     std::array<GPUVAddr, Vulkan::Maxwell::MaxShaderProgram> shaders, | ||||||
|     Vulkan::FixedPipelineState fixed_state) { |     Vulkan::FixedPipelineState fixed_state) { | ||||||
| 
 | 
 | ||||||
|     auto p = std::make_unique<WorkerParams>(); |     auto params = std::make_unique<WorkerParams>(); | ||||||
| 
 | 
 | ||||||
|     p->backend = Backend::Vulkan; |     params->backend = Backend::Vulkan; | ||||||
|     p->pp_cache = pp_cache; |     params->pp_cache = pp_cache; | ||||||
|     p->bindings = bindings; |     params->bindings = bindings; | ||||||
|     p->program = program; |     params->program = program; | ||||||
|     p->renderpass_params = renderpass_params; |     params->renderpass_params = renderpass_params; | ||||||
|     p->padding = padding; |     params->padding = padding; | ||||||
|     p->shaders = shaders; |     params->shaders = shaders; | ||||||
|     p->fixed_state = fixed_state; |     params->fixed_state = fixed_state; | ||||||
| 
 | 
 | ||||||
|     std::unique_lock lock(queue_mutex); |     std::unique_lock lock(queue_mutex); | ||||||
|     pending_queue.push(std::move(p)); |     pending_queue.push(std::move(params)); | ||||||
|     cv.notify_one(); |     cv.notify_one(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -162,7 +162,6 @@ void AsyncShaders::ShaderCompilerThread(Core::Frontend::GraphicsContext* context | ||||||
|         if (!HasWorkQueued()) { |         if (!HasWorkQueued()) { | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
| 
 |  | ||||||
|         // Another thread beat us, just unlock and wait for the next load
 |         // Another thread beat us, just unlock and wait for the next load
 | ||||||
|         if (pending_queue.empty()) { |         if (pending_queue.empty()) { | ||||||
|             continue; |             continue; | ||||||
|  | @ -186,8 +185,6 @@ void AsyncShaders::ShaderCompilerThread(Core::Frontend::GraphicsContext* context | ||||||
|             result.code = std::move(work->code); |             result.code = std::move(work->code); | ||||||
|             result.code_b = std::move(work->code_b); |             result.code_b = std::move(work->code_b); | ||||||
|             result.shader_type = work->shader_type; |             result.shader_type = work->shader_type; | ||||||
|             // LOG_CRITICAL(Render_Vulkan, "Shader hast been Compiled \t0x{:016X} id {}",
 |  | ||||||
|             // result.uid, id);
 |  | ||||||
| 
 | 
 | ||||||
|             if (work->backend == Backend::OpenGL) { |             if (work->backend == Backend::OpenGL) { | ||||||
|                 result.program.opengl = std::move(program->source_program); |                 result.program.opengl = std::move(program->source_program); | ||||||
|  | @ -208,40 +205,15 @@ void AsyncShaders::ShaderCompilerThread(Core::Frontend::GraphicsContext* context | ||||||
|                 .fixed_state = work->fixed_state, |                 .fixed_state = work->fixed_state, | ||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|             { |  | ||||||
|                 std::unique_lock find_lock{completed_mutex}; |  | ||||||
|                 for (size_t i = 0; i < finished_work.size(); ++i) { |  | ||||||
|                     // This loop deletes duplicate pipelines in finished_work
 |  | ||||||
|                     // in favor of the pipeline about to be created
 |  | ||||||
| 
 |  | ||||||
|                     if (finished_work[i].pipeline && |  | ||||||
|                         finished_work[i].pipeline->GetCacheKey().Hash() == params_key.Hash()) { |  | ||||||
|                         LOG_CRITICAL(Render_Vulkan, |  | ||||||
|                                      "Pipeliene was already here \t0x{:016X} matches 0x{:016X} ", |  | ||||||
|                                      params_key.Hash(), |  | ||||||
|                                      finished_work[i].pipeline->GetCacheKey().Hash()); |  | ||||||
|                         finished_work.erase(finished_work.begin() + i); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 find_lock.unlock(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             auto pipeline = std::make_unique<Vulkan::VKGraphicsPipeline>( |             auto pipeline = std::make_unique<Vulkan::VKGraphicsPipeline>( | ||||||
|                 work->pp_cache->GetDevice(), work->pp_cache->GetScheduler(), |                 work->pp_cache->GetDevice(), work->pp_cache->GetScheduler(), | ||||||
|                 work->pp_cache->GetDescriptorPool(), work->pp_cache->GetUpdateDescriptorQueue(), |                 work->pp_cache->GetDescriptorPool(), work->pp_cache->GetUpdateDescriptorQueue(), | ||||||
|                 work->pp_cache->GetRenderpassCache(), params_key, work->bindings, work->program); |                 work->pp_cache->GetRenderpassCache(), params_key, work->bindings, work->program); | ||||||
| 
 | 
 | ||||||
|             { |             work->pp_cache->EmplacePipeline(std::move(pipeline)); | ||||||
|                 std::unique_lock complete_lock(completed_mutex); |             work.reset(); | ||||||
|                 Result result{ |  | ||||||
|                     .backend = Backend::Vulkan, |  | ||||||
|                     .pipeline = std::move(pipeline), |  | ||||||
|                 }; |  | ||||||
|                 finished_work.push_back(std::move(result)); |  | ||||||
|                 complete_lock.unlock(); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|         // Give a chance for another thread to get work. Lessens duplicates
 |         // Give a chance for another thread to get work.
 | ||||||
|         std::this_thread::yield(); |         std::this_thread::yield(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 ameerj
						ameerj