diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 26 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.h | 4 |
3 files changed, 33 insertions, 3 deletions
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index 8c81c28a8..3f8895927 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h | |||
| @@ -87,7 +87,7 @@ public: | |||
| 87 | configure_func(this, is_indexed); | 87 | configure_func(this, is_indexed); |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | GraphicsPipeline* Next(const GraphicsPipelineCacheKey& current_key) noexcept { | 90 | [[nodiscard]] GraphicsPipeline* Next(const GraphicsPipelineCacheKey& current_key) noexcept { |
| 91 | if (key == current_key) { | 91 | if (key == current_key) { |
| 92 | return this; | 92 | return this; |
| 93 | } | 93 | } |
| @@ -96,6 +96,10 @@ public: | |||
| 96 | : nullptr; | 96 | : nullptr; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | [[nodiscard]] bool IsBuilt() const noexcept { | ||
| 100 | return is_built.load(std::memory_order::relaxed); | ||
| 101 | } | ||
| 102 | |||
| 99 | template <typename Spec> | 103 | template <typename Spec> |
| 100 | static auto MakeConfigureSpecFunc() { | 104 | static auto MakeConfigureSpecFunc() { |
| 101 | return [](GraphicsPipeline* pipeline, bool is_indexed) { | 105 | return [](GraphicsPipeline* pipeline, bool is_indexed) { |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index a7f3619a5..741ed1a98 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -240,6 +240,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::Engines::Maxw | |||
| 240 | device{device_}, scheduler{scheduler_}, descriptor_pool{descriptor_pool_}, | 240 | device{device_}, scheduler{scheduler_}, descriptor_pool{descriptor_pool_}, |
| 241 | update_descriptor_queue{update_descriptor_queue_}, render_pass_cache{render_pass_cache_}, | 241 | update_descriptor_queue{update_descriptor_queue_}, render_pass_cache{render_pass_cache_}, |
| 242 | buffer_cache{buffer_cache_}, texture_cache{texture_cache_}, | 242 | buffer_cache{buffer_cache_}, texture_cache{texture_cache_}, |
| 243 | use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()}, | ||
| 243 | workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "yuzu:PipelineBuilder"), | 244 | workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "yuzu:PipelineBuilder"), |
| 244 | serialization_thread(1, "yuzu:PipelineSerialization") { | 245 | serialization_thread(1, "yuzu:PipelineSerialization") { |
| 245 | const auto& float_control{device.FloatControlProperties()}; | 246 | const auto& float_control{device.FloatControlProperties()}; |
| @@ -303,7 +304,7 @@ GraphicsPipeline* PipelineCache::CurrentGraphicsPipeline() { | |||
| 303 | GraphicsPipeline* const next{current_pipeline->Next(graphics_key)}; | 304 | GraphicsPipeline* const next{current_pipeline->Next(graphics_key)}; |
| 304 | if (next) { | 305 | if (next) { |
| 305 | current_pipeline = next; | 306 | current_pipeline = next; |
| 306 | return current_pipeline; | 307 | return BuiltPipeline(current_pipeline); |
| 307 | } | 308 | } |
| 308 | } | 309 | } |
| 309 | const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)}; | 310 | const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)}; |
| @@ -318,7 +319,7 @@ GraphicsPipeline* PipelineCache::CurrentGraphicsPipeline() { | |||
| 318 | current_pipeline->AddTransition(pipeline.get()); | 319 | current_pipeline->AddTransition(pipeline.get()); |
| 319 | } | 320 | } |
| 320 | current_pipeline = pipeline.get(); | 321 | current_pipeline = pipeline.get(); |
| 321 | return current_pipeline; | 322 | return BuiltPipeline(current_pipeline); |
| 322 | } | 323 | } |
| 323 | 324 | ||
| 324 | ComputePipeline* PipelineCache::CurrentComputePipeline() { | 325 | ComputePipeline* PipelineCache::CurrentComputePipeline() { |
| @@ -415,6 +416,27 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading | |||
| 415 | workers.WaitForRequests(); | 416 | workers.WaitForRequests(); |
| 416 | } | 417 | } |
| 417 | 418 | ||
| 419 | GraphicsPipeline* PipelineCache::BuiltPipeline(GraphicsPipeline* pipeline) const noexcept { | ||
| 420 | if (pipeline->IsBuilt()) { | ||
| 421 | return pipeline; | ||
| 422 | } | ||
| 423 | if (!use_asynchronous_shaders) { | ||
| 424 | return pipeline; | ||
| 425 | } | ||
| 426 | // If something is using depth, we can assume that games are not rendering anything which | ||
| 427 | // will be used one time. | ||
| 428 | if (maxwell3d.regs.zeta_enable) { | ||
| 429 | return nullptr; | ||
| 430 | } | ||
| 431 | // If games are using a small index count, we can assume these are full screen quads. | ||
| 432 | // Usually these shaders are only used once for building textures so we can assume they | ||
| 433 | // can't be built async | ||
| 434 | if (maxwell3d.regs.index_array.count <= 6 || maxwell3d.regs.vertex_buffer.count <= 6) { | ||
| 435 | return pipeline; | ||
| 436 | } | ||
| 437 | return nullptr; | ||
| 438 | } | ||
| 439 | |||
| 418 | std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( | 440 | std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( |
| 419 | ShaderPools& pools, const GraphicsPipelineCacheKey& key, | 441 | ShaderPools& pools, const GraphicsPipelineCacheKey& key, |
| 420 | std::span<Shader::Environment* const> envs, bool build_in_parallel) try { | 442 | std::span<Shader::Environment* const> envs, bool build_in_parallel) try { |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 4116cc73f..869c63baf 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h | |||
| @@ -115,6 +115,8 @@ public: | |||
| 115 | const VideoCore::DiskResourceLoadCallback& callback); | 115 | const VideoCore::DiskResourceLoadCallback& callback); |
| 116 | 116 | ||
| 117 | private: | 117 | private: |
| 118 | [[nodiscard]] GraphicsPipeline* BuiltPipeline(GraphicsPipeline* pipeline) const noexcept; | ||
| 119 | |||
| 118 | std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(); | 120 | std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(); |
| 119 | 121 | ||
| 120 | std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline( | 122 | std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline( |
| @@ -140,6 +142,8 @@ private: | |||
| 140 | GraphicsPipelineCacheKey graphics_key{}; | 142 | GraphicsPipelineCacheKey graphics_key{}; |
| 141 | GraphicsPipeline* current_pipeline{}; | 143 | GraphicsPipeline* current_pipeline{}; |
| 142 | 144 | ||
| 145 | bool use_asynchronous_shaders{}; | ||
| 146 | |||
| 143 | std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<ComputePipeline>> compute_cache; | 147 | std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<ComputePipeline>> compute_cache; |
| 144 | std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<GraphicsPipeline>> graphics_cache; | 148 | std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<GraphicsPipeline>> graphics_cache; |
| 145 | 149 | ||