diff options
| author | 2020-08-17 15:06:11 +1000 | |
|---|---|---|
| committer | 2020-08-17 15:06:11 +1000 | |
| commit | cbaf1bc711e79a9094f157d3e0327f3a2c707462 (patch) | |
| tree | 084010b04064d06dc17716962df430e2bd213e7e /src/video_core/renderer_vulkan | |
| parent | Merge pull request #4515 from lat9nq/pgs-menubar-config (diff) | |
| parent | Remove unneeded newlines, optional Registry in shader params (diff) | |
| download | yuzu-cbaf1bc711e79a9094f157d3e0327f3a2c707462.tar.gz yuzu-cbaf1bc711e79a9094f157d3e0327f3a2c707462.tar.xz yuzu-cbaf1bc711e79a9094f157d3e0327f3a2c707462.zip | |
Merge pull request #4443 from ameerj/vk-async-shaders
vulkan_renderer: Async shader/graphics pipeline compilation
Diffstat (limited to 'src/video_core/renderer_vulkan')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_device.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_device.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_fence_manager.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.h | 28 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 37 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.h | 31 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 26 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/wrapper.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/wrapper.h | 2 |
11 files changed, 109 insertions, 48 deletions
diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp index 0c03e4d83..ebcfaa0e3 100644 --- a/src/video_core/renderer_vulkan/vk_device.cpp +++ b/src/video_core/renderer_vulkan/vk_device.cpp | |||
| @@ -382,6 +382,8 @@ bool VKDevice::Create() { | |||
| 382 | 382 | ||
| 383 | graphics_queue = logical.GetQueue(graphics_family); | 383 | graphics_queue = logical.GetQueue(graphics_family); |
| 384 | present_queue = logical.GetQueue(present_family); | 384 | present_queue = logical.GetQueue(present_family); |
| 385 | |||
| 386 | use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue(); | ||
| 385 | return true; | 387 | return true; |
| 386 | } | 388 | } |
| 387 | 389 | ||
diff --git a/src/video_core/renderer_vulkan/vk_device.h b/src/video_core/renderer_vulkan/vk_device.h index 529744f2d..26a233db1 100644 --- a/src/video_core/renderer_vulkan/vk_device.h +++ b/src/video_core/renderer_vulkan/vk_device.h | |||
| @@ -202,6 +202,11 @@ public: | |||
| 202 | return reported_extensions; | 202 | return reported_extensions; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | /// Returns true if the setting for async shader compilation is enabled. | ||
| 206 | bool UseAsynchronousShaders() const { | ||
| 207 | return use_asynchronous_shaders; | ||
| 208 | } | ||
| 209 | |||
| 205 | /// Checks if the physical device is suitable. | 210 | /// Checks if the physical device is suitable. |
| 206 | static bool IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface); | 211 | static bool IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface); |
| 207 | 212 | ||
| @@ -252,6 +257,9 @@ private: | |||
| 252 | bool ext_extended_dynamic_state{}; ///< Support for VK_EXT_extended_dynamic_state. | 257 | bool ext_extended_dynamic_state{}; ///< Support for VK_EXT_extended_dynamic_state. |
| 253 | bool nv_device_diagnostics_config{}; ///< Support for VK_NV_device_diagnostics_config. | 258 | bool nv_device_diagnostics_config{}; ///< Support for VK_NV_device_diagnostics_config. |
| 254 | 259 | ||
| 260 | // Asynchronous Graphics Pipeline setting | ||
| 261 | bool use_asynchronous_shaders{}; ///< Setting to use asynchronous shaders/graphics pipeline | ||
| 262 | |||
| 255 | // Telemetry parameters | 263 | // Telemetry parameters |
| 256 | std::string vendor_name; ///< Device's driver name. | 264 | std::string vendor_name; ///< Device's driver name. |
| 257 | std::vector<std::string> reported_extensions; ///< Reported Vulkan extensions. | 265 | std::vector<std::string> reported_extensions; ///< Reported Vulkan extensions. |
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.cpp b/src/video_core/renderer_vulkan/vk_fence_manager.cpp index a02be5487..d7f65d435 100644 --- a/src/video_core/renderer_vulkan/vk_fence_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_fence_manager.cpp | |||
| @@ -29,7 +29,7 @@ void InnerFence::Queue() { | |||
| 29 | } | 29 | } |
| 30 | ASSERT(!event); | 30 | ASSERT(!event); |
| 31 | 31 | ||
| 32 | event = device.GetLogical().CreateEvent(); | 32 | event = device.GetLogical().CreateNewEvent(); |
| 33 | ticks = scheduler.Ticks(); | 33 | ticks = scheduler.Ticks(); |
| 34 | 34 | ||
| 35 | scheduler.RequestOutsideRenderPassOperationContext(); | 35 | scheduler.RequestOutsideRenderPassOperationContext(); |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index aaf930b90..2e46c6278 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -78,15 +78,14 @@ VKGraphicsPipeline::VKGraphicsPipeline(const VKDevice& device, VKScheduler& sche | |||
| 78 | const GraphicsPipelineCacheKey& key, | 78 | const GraphicsPipelineCacheKey& key, |
| 79 | vk::Span<VkDescriptorSetLayoutBinding> bindings, | 79 | vk::Span<VkDescriptorSetLayoutBinding> bindings, |
| 80 | const SPIRVProgram& program) | 80 | const SPIRVProgram& program) |
| 81 | : device{device}, scheduler{scheduler}, fixed_state{key.fixed_state}, hash{key.Hash()}, | 81 | : device{device}, scheduler{scheduler}, cache_key{key}, hash{cache_key.Hash()}, |
| 82 | descriptor_set_layout{CreateDescriptorSetLayout(bindings)}, | 82 | descriptor_set_layout{CreateDescriptorSetLayout(bindings)}, |
| 83 | descriptor_allocator{descriptor_pool, *descriptor_set_layout}, | 83 | descriptor_allocator{descriptor_pool, *descriptor_set_layout}, |
| 84 | update_descriptor_queue{update_descriptor_queue}, layout{CreatePipelineLayout()}, | 84 | update_descriptor_queue{update_descriptor_queue}, layout{CreatePipelineLayout()}, |
| 85 | descriptor_template{CreateDescriptorUpdateTemplate(program)}, modules{CreateShaderModules( | 85 | descriptor_template{CreateDescriptorUpdateTemplate(program)}, modules{CreateShaderModules( |
| 86 | program)}, | 86 | program)}, |
| 87 | renderpass{renderpass_cache.GetRenderPass(key.renderpass_params)}, pipeline{CreatePipeline( | 87 | renderpass{renderpass_cache.GetRenderPass(cache_key.renderpass_params)}, |
| 88 | key.renderpass_params, | 88 | pipeline{CreatePipeline(cache_key.renderpass_params, program)} {} |
| 89 | program)} {} | ||
| 90 | 89 | ||
| 91 | VKGraphicsPipeline::~VKGraphicsPipeline() = default; | 90 | VKGraphicsPipeline::~VKGraphicsPipeline() = default; |
| 92 | 91 | ||
| @@ -181,7 +180,7 @@ std::vector<vk::ShaderModule> VKGraphicsPipeline::CreateShaderModules( | |||
| 181 | 180 | ||
| 182 | vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpass_params, | 181 | vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpass_params, |
| 183 | const SPIRVProgram& program) const { | 182 | const SPIRVProgram& program) const { |
| 184 | const auto& state = fixed_state; | 183 | const auto& state = cache_key.fixed_state; |
| 185 | const auto& viewport_swizzles = state.viewport_swizzles; | 184 | const auto& viewport_swizzles = state.viewport_swizzles; |
| 186 | 185 | ||
| 187 | FixedPipelineState::DynamicState dynamic; | 186 | FixedPipelineState::DynamicState dynamic; |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index a1d699a6c..58aa35efd 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h | |||
| @@ -19,7 +19,27 @@ namespace Vulkan { | |||
| 19 | 19 | ||
| 20 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | 20 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; |
| 21 | 21 | ||
| 22 | struct GraphicsPipelineCacheKey; | 22 | struct GraphicsPipelineCacheKey { |
| 23 | RenderPassParams renderpass_params; | ||
| 24 | u32 padding; | ||
| 25 | std::array<GPUVAddr, Maxwell::MaxShaderProgram> shaders; | ||
| 26 | FixedPipelineState fixed_state; | ||
| 27 | |||
| 28 | std::size_t Hash() const noexcept; | ||
| 29 | |||
| 30 | bool operator==(const GraphicsPipelineCacheKey& rhs) const noexcept; | ||
| 31 | |||
| 32 | bool operator!=(const GraphicsPipelineCacheKey& rhs) const noexcept { | ||
| 33 | return !operator==(rhs); | ||
| 34 | } | ||
| 35 | |||
| 36 | std::size_t Size() const noexcept { | ||
| 37 | return sizeof(renderpass_params) + sizeof(padding) + sizeof(shaders) + fixed_state.Size(); | ||
| 38 | } | ||
| 39 | }; | ||
| 40 | static_assert(std::has_unique_object_representations_v<GraphicsPipelineCacheKey>); | ||
| 41 | static_assert(std::is_trivially_copyable_v<GraphicsPipelineCacheKey>); | ||
| 42 | static_assert(std::is_trivially_constructible_v<GraphicsPipelineCacheKey>); | ||
| 23 | 43 | ||
| 24 | class VKDescriptorPool; | 44 | class VKDescriptorPool; |
| 25 | class VKDevice; | 45 | class VKDevice; |
| @@ -54,6 +74,10 @@ public: | |||
| 54 | return renderpass; | 74 | return renderpass; |
| 55 | } | 75 | } |
| 56 | 76 | ||
| 77 | GraphicsPipelineCacheKey GetCacheKey() const { | ||
| 78 | return cache_key; | ||
| 79 | } | ||
| 80 | |||
| 57 | private: | 81 | private: |
| 58 | vk::DescriptorSetLayout CreateDescriptorSetLayout( | 82 | vk::DescriptorSetLayout CreateDescriptorSetLayout( |
| 59 | vk::Span<VkDescriptorSetLayoutBinding> bindings) const; | 83 | vk::Span<VkDescriptorSetLayoutBinding> bindings) const; |
| @@ -70,7 +94,7 @@ private: | |||
| 70 | 94 | ||
| 71 | const VKDevice& device; | 95 | const VKDevice& device; |
| 72 | VKScheduler& scheduler; | 96 | VKScheduler& scheduler; |
| 73 | const FixedPipelineState fixed_state; | 97 | const GraphicsPipelineCacheKey cache_key; |
| 74 | const u64 hash; | 98 | const u64 hash; |
| 75 | 99 | ||
| 76 | vk::DescriptorSetLayout descriptor_set_layout; | 100 | vk::DescriptorSetLayout descriptor_set_layout; |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 418c62bc4..cfdcdd6ab 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include "video_core/shader/compiler_settings.h" | 28 | #include "video_core/shader/compiler_settings.h" |
| 29 | #include "video_core/shader/memory_util.h" | 29 | #include "video_core/shader/memory_util.h" |
| 30 | #include "video_core/shader_cache.h" | 30 | #include "video_core/shader_cache.h" |
| 31 | #include "video_core/shader_notify.h" | ||
| 31 | 32 | ||
| 32 | namespace Vulkan { | 33 | namespace Vulkan { |
| 33 | 34 | ||
| @@ -205,24 +206,43 @@ std::array<Shader*, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() { | |||
| 205 | return last_shaders = shaders; | 206 | return last_shaders = shaders; |
| 206 | } | 207 | } |
| 207 | 208 | ||
| 208 | VKGraphicsPipeline& VKPipelineCache::GetGraphicsPipeline(const GraphicsPipelineCacheKey& key) { | 209 | VKGraphicsPipeline* VKPipelineCache::GetGraphicsPipeline( |
| 210 | const GraphicsPipelineCacheKey& key, VideoCommon::Shader::AsyncShaders& async_shaders) { | ||
| 209 | MICROPROFILE_SCOPE(Vulkan_PipelineCache); | 211 | MICROPROFILE_SCOPE(Vulkan_PipelineCache); |
| 210 | 212 | ||
| 211 | if (last_graphics_pipeline && last_graphics_key == key) { | 213 | if (last_graphics_pipeline && last_graphics_key == key) { |
| 212 | return *last_graphics_pipeline; | 214 | return last_graphics_pipeline; |
| 213 | } | 215 | } |
| 214 | last_graphics_key = key; | 216 | last_graphics_key = key; |
| 215 | 217 | ||
| 218 | if (device.UseAsynchronousShaders() && async_shaders.IsShaderAsync(system.GPU())) { | ||
| 219 | std::unique_lock lock{pipeline_cache}; | ||
| 220 | const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); | ||
| 221 | if (is_cache_miss) { | ||
| 222 | system.GPU().ShaderNotify().MarkSharderBuilding(); | ||
| 223 | LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); | ||
| 224 | const auto [program, bindings] = DecompileShaders(key.fixed_state); | ||
| 225 | async_shaders.QueueVulkanShader(this, device, scheduler, descriptor_pool, | ||
| 226 | update_descriptor_queue, renderpass_cache, bindings, | ||
| 227 | program, key); | ||
| 228 | } | ||
| 229 | last_graphics_pipeline = pair->second.get(); | ||
| 230 | return last_graphics_pipeline; | ||
| 231 | } | ||
| 232 | |||
| 216 | const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); | 233 | const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); |
| 217 | auto& entry = pair->second; | 234 | auto& entry = pair->second; |
| 218 | if (is_cache_miss) { | 235 | if (is_cache_miss) { |
| 236 | system.GPU().ShaderNotify().MarkSharderBuilding(); | ||
| 219 | LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); | 237 | LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); |
| 220 | const auto [program, bindings] = DecompileShaders(key); | 238 | const auto [program, bindings] = DecompileShaders(key.fixed_state); |
| 221 | entry = std::make_unique<VKGraphicsPipeline>(device, scheduler, descriptor_pool, | 239 | entry = std::make_unique<VKGraphicsPipeline>(device, scheduler, descriptor_pool, |
| 222 | update_descriptor_queue, renderpass_cache, key, | 240 | update_descriptor_queue, renderpass_cache, key, |
| 223 | bindings, program); | 241 | bindings, program); |
| 242 | system.GPU().ShaderNotify().MarkShaderComplete(); | ||
| 224 | } | 243 | } |
| 225 | return *(last_graphics_pipeline = entry.get()); | 244 | last_graphics_pipeline = entry.get(); |
| 245 | return last_graphics_pipeline; | ||
| 226 | } | 246 | } |
| 227 | 247 | ||
| 228 | VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCacheKey& key) { | 248 | VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCacheKey& key) { |
| @@ -277,6 +297,12 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach | |||
| 277 | return *entry; | 297 | return *entry; |
| 278 | } | 298 | } |
| 279 | 299 | ||
| 300 | void VKPipelineCache::EmplacePipeline(std::unique_ptr<VKGraphicsPipeline> pipeline) { | ||
| 301 | system.GPU().ShaderNotify().MarkShaderComplete(); | ||
| 302 | std::unique_lock lock{pipeline_cache}; | ||
| 303 | graphics_cache.at(pipeline->GetCacheKey()) = std::move(pipeline); | ||
| 304 | } | ||
| 305 | |||
| 280 | void VKPipelineCache::OnShaderRemoval(Shader* shader) { | 306 | void VKPipelineCache::OnShaderRemoval(Shader* shader) { |
| 281 | bool finished = false; | 307 | bool finished = false; |
| 282 | const auto Finish = [&] { | 308 | const auto Finish = [&] { |
| @@ -312,8 +338,7 @@ void VKPipelineCache::OnShaderRemoval(Shader* shader) { | |||
| 312 | } | 338 | } |
| 313 | 339 | ||
| 314 | std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> | 340 | std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> |
| 315 | VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) { | 341 | VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) { |
| 316 | const auto& fixed_state = key.fixed_state; | ||
| 317 | auto& memory_manager = system.GPU().MemoryManager(); | 342 | auto& memory_manager = system.GPU().MemoryManager(); |
| 318 | const auto& gpu = system.GPU().Maxwell3D(); | 343 | const auto& gpu = system.GPU().Maxwell3D(); |
| 319 | 344 | ||
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 0a3fe65fb..c04829e77 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include "video_core/renderer_vulkan/vk_renderpass_cache.h" | 22 | #include "video_core/renderer_vulkan/vk_renderpass_cache.h" |
| 23 | #include "video_core/renderer_vulkan/vk_shader_decompiler.h" | 23 | #include "video_core/renderer_vulkan/vk_shader_decompiler.h" |
| 24 | #include "video_core/renderer_vulkan/wrapper.h" | 24 | #include "video_core/renderer_vulkan/wrapper.h" |
| 25 | #include "video_core/shader/async_shaders.h" | ||
| 25 | #include "video_core/shader/memory_util.h" | 26 | #include "video_core/shader/memory_util.h" |
| 26 | #include "video_core/shader/registry.h" | 27 | #include "video_core/shader/registry.h" |
| 27 | #include "video_core/shader/shader_ir.h" | 28 | #include "video_core/shader/shader_ir.h" |
| @@ -43,28 +44,6 @@ class VKUpdateDescriptorQueue; | |||
| 43 | 44 | ||
| 44 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | 45 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; |
| 45 | 46 | ||
| 46 | struct GraphicsPipelineCacheKey { | ||
| 47 | RenderPassParams renderpass_params; | ||
| 48 | u32 padding; | ||
| 49 | std::array<GPUVAddr, Maxwell::MaxShaderProgram> shaders; | ||
| 50 | FixedPipelineState fixed_state; | ||
| 51 | |||
| 52 | std::size_t Hash() const noexcept; | ||
| 53 | |||
| 54 | bool operator==(const GraphicsPipelineCacheKey& rhs) const noexcept; | ||
| 55 | |||
| 56 | bool operator!=(const GraphicsPipelineCacheKey& rhs) const noexcept { | ||
| 57 | return !operator==(rhs); | ||
| 58 | } | ||
| 59 | |||
| 60 | std::size_t Size() const noexcept { | ||
| 61 | return sizeof(renderpass_params) + sizeof(padding) + sizeof(shaders) + fixed_state.Size(); | ||
| 62 | } | ||
| 63 | }; | ||
| 64 | static_assert(std::has_unique_object_representations_v<GraphicsPipelineCacheKey>); | ||
| 65 | static_assert(std::is_trivially_copyable_v<GraphicsPipelineCacheKey>); | ||
| 66 | static_assert(std::is_trivially_constructible_v<GraphicsPipelineCacheKey>); | ||
| 67 | |||
| 68 | struct ComputePipelineCacheKey { | 47 | struct ComputePipelineCacheKey { |
| 69 | GPUVAddr shader; | 48 | GPUVAddr shader; |
| 70 | u32 shared_memory_size; | 49 | u32 shared_memory_size; |
| @@ -152,16 +131,19 @@ public: | |||
| 152 | 131 | ||
| 153 | std::array<Shader*, Maxwell::MaxShaderProgram> GetShaders(); | 132 | std::array<Shader*, Maxwell::MaxShaderProgram> GetShaders(); |
| 154 | 133 | ||
| 155 | VKGraphicsPipeline& GetGraphicsPipeline(const GraphicsPipelineCacheKey& key); | 134 | VKGraphicsPipeline* GetGraphicsPipeline(const GraphicsPipelineCacheKey& key, |
| 135 | VideoCommon::Shader::AsyncShaders& async_shaders); | ||
| 156 | 136 | ||
| 157 | VKComputePipeline& GetComputePipeline(const ComputePipelineCacheKey& key); | 137 | VKComputePipeline& GetComputePipeline(const ComputePipelineCacheKey& key); |
| 158 | 138 | ||
| 139 | void EmplacePipeline(std::unique_ptr<VKGraphicsPipeline> pipeline); | ||
| 140 | |||
| 159 | protected: | 141 | protected: |
| 160 | void OnShaderRemoval(Shader* shader) final; | 142 | void OnShaderRemoval(Shader* shader) final; |
| 161 | 143 | ||
| 162 | private: | 144 | private: |
| 163 | std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> DecompileShaders( | 145 | std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> DecompileShaders( |
| 164 | const GraphicsPipelineCacheKey& key); | 146 | const FixedPipelineState& fixed_state); |
| 165 | 147 | ||
| 166 | Core::System& system; | 148 | Core::System& system; |
| 167 | const VKDevice& device; | 149 | const VKDevice& device; |
| @@ -178,6 +160,7 @@ private: | |||
| 178 | GraphicsPipelineCacheKey last_graphics_key; | 160 | GraphicsPipelineCacheKey last_graphics_key; |
| 179 | VKGraphicsPipeline* last_graphics_pipeline = nullptr; | 161 | VKGraphicsPipeline* last_graphics_pipeline = nullptr; |
| 180 | 162 | ||
| 163 | std::mutex pipeline_cache; | ||
| 181 | std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<VKGraphicsPipeline>> | 164 | std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<VKGraphicsPipeline>> |
| 182 | graphics_cache; | 165 | graphics_cache; |
| 183 | std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<VKComputePipeline>> compute_cache; | 166 | std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<VKComputePipeline>> compute_cache; |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 7500e8244..936f76195 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "common/assert.h" | 14 | #include "common/assert.h" |
| 15 | #include "common/logging/log.h" | 15 | #include "common/logging/log.h" |
| 16 | #include "common/microprofile.h" | 16 | #include "common/microprofile.h" |
| 17 | #include "common/scope_exit.h" | ||
| 17 | #include "core/core.h" | 18 | #include "core/core.h" |
| 18 | #include "core/settings.h" | 19 | #include "core/settings.h" |
| 19 | #include "video_core/engines/kepler_compute.h" | 20 | #include "video_core/engines/kepler_compute.h" |
| @@ -400,8 +401,12 @@ RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWind | |||
| 400 | buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool), | 401 | buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool), |
| 401 | sampler_cache(device), | 402 | sampler_cache(device), |
| 402 | fence_manager(system, *this, device, scheduler, texture_cache, buffer_cache, query_cache), | 403 | fence_manager(system, *this, device, scheduler, texture_cache, buffer_cache, query_cache), |
| 403 | query_cache(system, *this, device, scheduler), wfi_event{device.GetLogical().CreateEvent()} { | 404 | query_cache(system, *this, device, scheduler), |
| 405 | wfi_event{device.GetLogical().CreateNewEvent()}, async_shaders{renderer} { | ||
| 404 | scheduler.SetQueryCache(query_cache); | 406 | scheduler.SetQueryCache(query_cache); |
| 407 | if (device.UseAsynchronousShaders()) { | ||
| 408 | async_shaders.AllocateWorkers(); | ||
| 409 | } | ||
| 405 | } | 410 | } |
| 406 | 411 | ||
| 407 | RasterizerVulkan::~RasterizerVulkan() = default; | 412 | RasterizerVulkan::~RasterizerVulkan() = default; |
| @@ -413,6 +418,8 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { | |||
| 413 | 418 | ||
| 414 | query_cache.UpdateCounters(); | 419 | query_cache.UpdateCounters(); |
| 415 | 420 | ||
| 421 | SCOPE_EXIT({ system.GPU().TickWork(); }); | ||
| 422 | |||
| 416 | const auto& gpu = system.GPU().Maxwell3D(); | 423 | const auto& gpu = system.GPU().Maxwell3D(); |
| 417 | GraphicsPipelineCacheKey key; | 424 | GraphicsPipelineCacheKey key; |
| 418 | key.fixed_state.Fill(gpu.regs, device.IsExtExtendedDynamicStateSupported()); | 425 | key.fixed_state.Fill(gpu.regs, device.IsExtExtendedDynamicStateSupported()); |
| @@ -439,10 +446,15 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { | |||
| 439 | key.renderpass_params = GetRenderPassParams(texceptions); | 446 | key.renderpass_params = GetRenderPassParams(texceptions); |
| 440 | key.padding = 0; | 447 | key.padding = 0; |
| 441 | 448 | ||
| 442 | auto& pipeline = pipeline_cache.GetGraphicsPipeline(key); | 449 | auto* pipeline = pipeline_cache.GetGraphicsPipeline(key, async_shaders); |
| 443 | scheduler.BindGraphicsPipeline(pipeline.GetHandle()); | 450 | if (pipeline == nullptr || pipeline->GetHandle() == VK_NULL_HANDLE) { |
| 451 | // Async graphics pipeline was not ready. | ||
| 452 | return; | ||
| 453 | } | ||
| 454 | |||
| 455 | scheduler.BindGraphicsPipeline(pipeline->GetHandle()); | ||
| 444 | 456 | ||
| 445 | const auto renderpass = pipeline.GetRenderPass(); | 457 | const auto renderpass = pipeline->GetRenderPass(); |
| 446 | const auto [framebuffer, render_area] = ConfigureFramebuffers(renderpass); | 458 | const auto [framebuffer, render_area] = ConfigureFramebuffers(renderpass); |
| 447 | scheduler.RequestRenderpass(renderpass, framebuffer, render_area); | 459 | scheduler.RequestRenderpass(renderpass, framebuffer, render_area); |
| 448 | 460 | ||
| @@ -452,8 +464,8 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { | |||
| 452 | 464 | ||
| 453 | BeginTransformFeedback(); | 465 | BeginTransformFeedback(); |
| 454 | 466 | ||
| 455 | const auto pipeline_layout = pipeline.GetLayout(); | 467 | const auto pipeline_layout = pipeline->GetLayout(); |
| 456 | const auto descriptor_set = pipeline.CommitDescriptorSet(); | 468 | const auto descriptor_set = pipeline->CommitDescriptorSet(); |
| 457 | scheduler.Record([pipeline_layout, descriptor_set, draw_params](vk::CommandBuffer cmdbuf) { | 469 | scheduler.Record([pipeline_layout, descriptor_set, draw_params](vk::CommandBuffer cmdbuf) { |
| 458 | if (descriptor_set) { | 470 | if (descriptor_set) { |
| 459 | cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, | 471 | cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, |
| @@ -463,8 +475,6 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { | |||
| 463 | }); | 475 | }); |
| 464 | 476 | ||
| 465 | EndTransformFeedback(); | 477 | EndTransformFeedback(); |
| 466 | |||
| 467 | system.GPU().TickWork(); | ||
| 468 | } | 478 | } |
| 469 | 479 | ||
| 470 | void RasterizerVulkan::Clear() { | 480 | void RasterizerVulkan::Clear() { |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 923178b0b..f640ba649 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include "video_core/renderer_vulkan/vk_texture_cache.h" | 32 | #include "video_core/renderer_vulkan/vk_texture_cache.h" |
| 33 | #include "video_core/renderer_vulkan/vk_update_descriptor.h" | 33 | #include "video_core/renderer_vulkan/vk_update_descriptor.h" |
| 34 | #include "video_core/renderer_vulkan/wrapper.h" | 34 | #include "video_core/renderer_vulkan/wrapper.h" |
| 35 | #include "video_core/shader/async_shaders.h" | ||
| 35 | 36 | ||
| 36 | namespace Core { | 37 | namespace Core { |
| 37 | class System; | 38 | class System; |
| @@ -136,6 +137,14 @@ public: | |||
| 136 | u32 pixel_stride) override; | 137 | u32 pixel_stride) override; |
| 137 | void SetupDirtyFlags() override; | 138 | void SetupDirtyFlags() override; |
| 138 | 139 | ||
| 140 | VideoCommon::Shader::AsyncShaders& GetAsyncShaders() { | ||
| 141 | return async_shaders; | ||
| 142 | } | ||
| 143 | |||
| 144 | const VideoCommon::Shader::AsyncShaders& GetAsyncShaders() const { | ||
| 145 | return async_shaders; | ||
| 146 | } | ||
| 147 | |||
| 139 | /// Maximum supported size that a constbuffer can have in bytes. | 148 | /// Maximum supported size that a constbuffer can have in bytes. |
| 140 | static constexpr std::size_t MaxConstbufferSize = 0x10000; | 149 | static constexpr std::size_t MaxConstbufferSize = 0x10000; |
| 141 | static_assert(MaxConstbufferSize % (4 * sizeof(float)) == 0, | 150 | static_assert(MaxConstbufferSize % (4 * sizeof(float)) == 0, |
| @@ -297,6 +306,7 @@ private: | |||
| 297 | vk::Buffer default_buffer; | 306 | vk::Buffer default_buffer; |
| 298 | VKMemoryCommit default_buffer_commit; | 307 | VKMemoryCommit default_buffer_commit; |
| 299 | vk::Event wfi_event; | 308 | vk::Event wfi_event; |
| 309 | VideoCommon::Shader::AsyncShaders async_shaders; | ||
| 300 | 310 | ||
| 301 | std::array<View, Maxwell::NumRenderTargets> color_attachments; | 311 | std::array<View, Maxwell::NumRenderTargets> color_attachments; |
| 302 | View zeta_attachment; | 312 | View zeta_attachment; |
diff --git a/src/video_core/renderer_vulkan/wrapper.cpp b/src/video_core/renderer_vulkan/wrapper.cpp index 14cac38ea..c43d60adf 100644 --- a/src/video_core/renderer_vulkan/wrapper.cpp +++ b/src/video_core/renderer_vulkan/wrapper.cpp | |||
| @@ -644,7 +644,7 @@ ShaderModule Device::CreateShaderModule(const VkShaderModuleCreateInfo& ci) cons | |||
| 644 | return ShaderModule(object, handle, *dld); | 644 | return ShaderModule(object, handle, *dld); |
| 645 | } | 645 | } |
| 646 | 646 | ||
| 647 | Event Device::CreateEvent() const { | 647 | Event Device::CreateNewEvent() const { |
| 648 | static constexpr VkEventCreateInfo ci{ | 648 | static constexpr VkEventCreateInfo ci{ |
| 649 | .sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, | 649 | .sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| 650 | .pNext = nullptr, | 650 | .pNext = nullptr, |
diff --git a/src/video_core/renderer_vulkan/wrapper.h b/src/video_core/renderer_vulkan/wrapper.h index 31885ef42..b9d3fedc1 100644 --- a/src/video_core/renderer_vulkan/wrapper.h +++ b/src/video_core/renderer_vulkan/wrapper.h | |||
| @@ -721,7 +721,7 @@ public: | |||
| 721 | 721 | ||
| 722 | ShaderModule CreateShaderModule(const VkShaderModuleCreateInfo& ci) const; | 722 | ShaderModule CreateShaderModule(const VkShaderModuleCreateInfo& ci) const; |
| 723 | 723 | ||
| 724 | Event CreateEvent() const; | 724 | Event CreateNewEvent() const; |
| 725 | 725 | ||
| 726 | SwapchainKHR CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const; | 726 | SwapchainKHR CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const; |
| 727 | 727 | ||