summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp26
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h4
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
324ComputePipeline* PipelineCache::CurrentComputePipeline() { 325ComputePipeline* 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
419GraphicsPipeline* 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
418std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( 440std::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
117private: 117private:
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