diff options
| author | 2020-07-31 17:30:05 -0400 | |
|---|---|---|
| committer | 2020-08-16 12:02:22 -0400 | |
| commit | c02464f64e302b8c9ea0f310e6fd85834d26cca5 (patch) | |
| tree | ddf37cedd4f779690a677a89770b394905da7196 /src | |
| parent | Address feedback. Bruteforce delete duplicates (diff) | |
| download | yuzu-c02464f64e302b8c9ea0f310e6fd85834d26cca5.tar.gz yuzu-c02464f64e302b8c9ea0f310e6fd85834d26cca5.tar.xz yuzu-c02464f64e302b8c9ea0f310e6fd85834d26cca5.zip | |
Vk Async Worker directly emplace in cache
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.h | 3 | ||||
| -rw-r--r-- | src/video_core/shader/async_shaders.cpp | 78 |
3 files changed, 41 insertions, 58 deletions
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index a7ce621ca..1a8b2c62b 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -215,11 +215,7 @@ VKGraphicsPipeline* VKPipelineCache::GetGraphicsPipeline( | |||
| 215 | last_graphics_key = key; | 215 | last_graphics_key = key; |
| 216 | 216 | ||
| 217 | if (device.UseAsynchronousShaders()) { | 217 | if (device.UseAsynchronousShaders()) { |
| 218 | auto work = async_shaders.GetCompletedWork(); | 218 | std::unique_lock lock{pipeline_cache}; |
| 219 | for (auto& w : work) { | ||
| 220 | auto& entry = graphics_cache.at(w.pipeline->GetCacheKey()); | ||
| 221 | entry = std::move(w.pipeline); | ||
| 222 | } | ||
| 223 | const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); | 219 | const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); |
| 224 | if (is_cache_miss) { | 220 | if (is_cache_miss) { |
| 225 | LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); | 221 | LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); |
| @@ -296,6 +292,18 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach | |||
| 296 | return *entry; | 292 | return *entry; |
| 297 | } | 293 | } |
| 298 | 294 | ||
| 295 | void VKPipelineCache::EmplacePipeline(std::unique_ptr<VKGraphicsPipeline> pipeline) { | ||
| 296 | std::unique_lock lock{pipeline_cache}; | ||
| 297 | const auto [pair, is_cache_miss] = graphics_cache.try_emplace(pipeline->GetCacheKey()); | ||
| 298 | auto& entry = pair->second; | ||
| 299 | if (entry) { | ||
| 300 | LOG_INFO(Render_Vulkan, "Pipeline already here 0x{:016X}", pipeline->GetCacheKey().Hash()); | ||
| 301 | duplicates.push_back(std::move(pipeline)); | ||
| 302 | } else { | ||
| 303 | entry = std::move(pipeline); | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 299 | void VKPipelineCache::OnShaderRemoval(Shader* shader) { | 307 | void VKPipelineCache::OnShaderRemoval(Shader* shader) { |
| 300 | bool finished = false; | 308 | bool finished = false; |
| 301 | const auto Finish = [&] { | 309 | const auto Finish = [&] { |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 404f2b3f7..777ef2038 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h | |||
| @@ -193,6 +193,8 @@ public: | |||
| 193 | return renderpass_cache; | 193 | return renderpass_cache; |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | void EmplacePipeline(std::unique_ptr<VKGraphicsPipeline> pipeline); | ||
| 197 | |||
| 196 | protected: | 198 | protected: |
| 197 | void OnShaderRemoval(Shader* shader) final; | 199 | void OnShaderRemoval(Shader* shader) final; |
| 198 | 200 | ||
| @@ -216,6 +218,7 @@ private: | |||
| 216 | VKGraphicsPipeline* last_graphics_pipeline = nullptr; | 218 | VKGraphicsPipeline* last_graphics_pipeline = nullptr; |
| 217 | std::vector<std::unique_ptr<VKGraphicsPipeline>> duplicates; | 219 | std::vector<std::unique_ptr<VKGraphicsPipeline>> duplicates; |
| 218 | 220 | ||
| 221 | std::mutex pipeline_cache; | ||
| 219 | std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<VKGraphicsPipeline>> | 222 | std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<VKGraphicsPipeline>> |
| 220 | graphics_cache; | 223 | graphics_cache; |
| 221 | std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<VKComputePipeline>> compute_cache; | 224 | std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<VKComputePipeline>> compute_cache; |
diff --git a/src/video_core/shader/async_shaders.cpp b/src/video_core/shader/async_shaders.cpp index c536b025b..54a81460b 100644 --- a/src/video_core/shader/async_shaders.cpp +++ b/src/video_core/shader/async_shaders.cpp | |||
| @@ -111,19 +111,19 @@ void AsyncShaders::QueueOpenGLShader(const OpenGL::Device& device, | |||
| 111 | VideoCommon::Shader::CompilerSettings compiler_settings, | 111 | VideoCommon::Shader::CompilerSettings compiler_settings, |
| 112 | const VideoCommon::Shader::Registry& registry, | 112 | const VideoCommon::Shader::Registry& registry, |
| 113 | VAddr cpu_addr) { | 113 | VAddr cpu_addr) { |
| 114 | auto p = std::make_unique<WorkerParams>(); | 114 | auto params = std::make_unique<WorkerParams>(); |
| 115 | p->backend = device.UseAssemblyShaders() ? Backend::GLASM : Backend::OpenGL; | 115 | params->backend = device.UseAssemblyShaders() ? Backend::GLASM : Backend::OpenGL; |
| 116 | p->device = &device; | 116 | params->device = &device; |
| 117 | p->shader_type = shader_type; | 117 | params->shader_type = shader_type; |
| 118 | p->uid = uid; | 118 | params->uid = uid; |
| 119 | p->code = std::move(code); | 119 | params->code = std::move(code); |
| 120 | p->code_b = std::move(code_b); | 120 | params->code_b = std::move(code_b); |
| 121 | p->main_offset = main_offset; | 121 | params->main_offset = main_offset; |
| 122 | p->compiler_settings = compiler_settings; | 122 | params->compiler_settings = compiler_settings; |
| 123 | p->registry = ®istry; | 123 | params->registry = ®istry; |
| 124 | p->cpu_address = cpu_addr; | 124 | params->cpu_address = cpu_addr; |
| 125 | std::unique_lock lock(queue_mutex); | 125 | std::unique_lock lock(queue_mutex); |
| 126 | pending_queue.push(std::move(p)); | 126 | pending_queue.push(std::move(params)); |
| 127 | cv.notify_one(); | 127 | cv.notify_one(); |
| 128 | } | 128 | } |
| 129 | 129 | ||
| @@ -133,19 +133,19 @@ void AsyncShaders::QueueVulkanShader( | |||
| 133 | std::array<GPUVAddr, Vulkan::Maxwell::MaxShaderProgram> shaders, | 133 | std::array<GPUVAddr, Vulkan::Maxwell::MaxShaderProgram> shaders, |
| 134 | Vulkan::FixedPipelineState fixed_state) { | 134 | Vulkan::FixedPipelineState fixed_state) { |
| 135 | 135 | ||
| 136 | auto p = std::make_unique<WorkerParams>(); | 136 | auto params = std::make_unique<WorkerParams>(); |
| 137 | 137 | ||
| 138 | p->backend = Backend::Vulkan; | 138 | params->backend = Backend::Vulkan; |
| 139 | p->pp_cache = pp_cache; | 139 | params->pp_cache = pp_cache; |
| 140 | p->bindings = bindings; | 140 | params->bindings = bindings; |
| 141 | p->program = program; | 141 | params->program = program; |
| 142 | p->renderpass_params = renderpass_params; | 142 | params->renderpass_params = renderpass_params; |
| 143 | p->padding = padding; | 143 | params->padding = padding; |
| 144 | p->shaders = shaders; | 144 | params->shaders = shaders; |
| 145 | p->fixed_state = fixed_state; | 145 | params->fixed_state = fixed_state; |
| 146 | 146 | ||
| 147 | std::unique_lock lock(queue_mutex); | 147 | std::unique_lock lock(queue_mutex); |
| 148 | pending_queue.push(std::move(p)); | 148 | pending_queue.push(std::move(params)); |
| 149 | cv.notify_one(); | 149 | cv.notify_one(); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| @@ -162,7 +162,6 @@ void AsyncShaders::ShaderCompilerThread(Core::Frontend::GraphicsContext* context | |||
| 162 | if (!HasWorkQueued()) { | 162 | if (!HasWorkQueued()) { |
| 163 | continue; | 163 | continue; |
| 164 | } | 164 | } |
| 165 | |||
| 166 | // Another thread beat us, just unlock and wait for the next load | 165 | // Another thread beat us, just unlock and wait for the next load |
| 167 | if (pending_queue.empty()) { | 166 | if (pending_queue.empty()) { |
| 168 | continue; | 167 | continue; |
| @@ -186,8 +185,6 @@ void AsyncShaders::ShaderCompilerThread(Core::Frontend::GraphicsContext* context | |||
| 186 | result.code = std::move(work->code); | 185 | result.code = std::move(work->code); |
| 187 | result.code_b = std::move(work->code_b); | 186 | result.code_b = std::move(work->code_b); |
| 188 | result.shader_type = work->shader_type; | 187 | result.shader_type = work->shader_type; |
| 189 | // LOG_CRITICAL(Render_Vulkan, "Shader hast been Compiled \t0x{:016X} id {}", | ||
| 190 | // result.uid, id); | ||
| 191 | 188 | ||
| 192 | if (work->backend == Backend::OpenGL) { | 189 | if (work->backend == Backend::OpenGL) { |
| 193 | result.program.opengl = std::move(program->source_program); | 190 | result.program.opengl = std::move(program->source_program); |
| @@ -208,40 +205,15 @@ void AsyncShaders::ShaderCompilerThread(Core::Frontend::GraphicsContext* context | |||
| 208 | .fixed_state = work->fixed_state, | 205 | .fixed_state = work->fixed_state, |
| 209 | }; | 206 | }; |
| 210 | 207 | ||
| 211 | { | ||
| 212 | std::unique_lock find_lock{completed_mutex}; | ||
| 213 | for (size_t i = 0; i < finished_work.size(); ++i) { | ||
| 214 | // This loop deletes duplicate pipelines in finished_work | ||
| 215 | // in favor of the pipeline about to be created | ||
| 216 | |||
| 217 | if (finished_work[i].pipeline && | ||
| 218 | finished_work[i].pipeline->GetCacheKey().Hash() == params_key.Hash()) { | ||
| 219 | LOG_CRITICAL(Render_Vulkan, | ||
| 220 | "Pipeliene was already here \t0x{:016X} matches 0x{:016X} ", | ||
| 221 | params_key.Hash(), | ||
| 222 | finished_work[i].pipeline->GetCacheKey().Hash()); | ||
| 223 | finished_work.erase(finished_work.begin() + i); | ||
| 224 | } | ||
| 225 | } | ||
| 226 | find_lock.unlock(); | ||
| 227 | } | ||
| 228 | |||
| 229 | auto pipeline = std::make_unique<Vulkan::VKGraphicsPipeline>( | 208 | auto pipeline = std::make_unique<Vulkan::VKGraphicsPipeline>( |
| 230 | work->pp_cache->GetDevice(), work->pp_cache->GetScheduler(), | 209 | work->pp_cache->GetDevice(), work->pp_cache->GetScheduler(), |
| 231 | work->pp_cache->GetDescriptorPool(), work->pp_cache->GetUpdateDescriptorQueue(), | 210 | work->pp_cache->GetDescriptorPool(), work->pp_cache->GetUpdateDescriptorQueue(), |
| 232 | work->pp_cache->GetRenderpassCache(), params_key, work->bindings, work->program); | 211 | work->pp_cache->GetRenderpassCache(), params_key, work->bindings, work->program); |
| 233 | 212 | ||
| 234 | { | 213 | work->pp_cache->EmplacePipeline(std::move(pipeline)); |
| 235 | std::unique_lock complete_lock(completed_mutex); | 214 | work.reset(); |
| 236 | Result result{ | ||
| 237 | .backend = Backend::Vulkan, | ||
| 238 | .pipeline = std::move(pipeline), | ||
| 239 | }; | ||
| 240 | finished_work.push_back(std::move(result)); | ||
| 241 | complete_lock.unlock(); | ||
| 242 | } | ||
| 243 | } | 215 | } |
| 244 | // Give a chance for another thread to get work. Lessens duplicates | 216 | // Give a chance for another thread to get work. |
| 245 | std::this_thread::yield(); | 217 | std::this_thread::yield(); |
| 246 | } | 218 | } |
| 247 | } | 219 | } |