From 31a76410e8fa09462d960c10148c075125dc385a Mon Sep 17 00:00:00 2001 From: ameerj Date: Sun, 2 Aug 2020 13:05:41 -0400 Subject: Address feedback, add shader compile notifier, update setting text --- src/video_core/renderer_vulkan/vk_device.h | 5 +- .../renderer_vulkan/vk_graphics_pipeline.cpp | 9 ++-- .../renderer_vulkan/vk_graphics_pipeline.h | 30 ++++++++--- .../renderer_vulkan/vk_pipeline_cache.cpp | 23 ++++----- src/video_core/renderer_vulkan/vk_pipeline_cache.h | 58 ---------------------- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 19 +++---- 6 files changed, 51 insertions(+), 93 deletions(-) (limited to 'src/video_core/renderer_vulkan') diff --git a/src/video_core/renderer_vulkan/vk_device.h b/src/video_core/renderer_vulkan/vk_device.h index 30cd3e189..26a233db1 100644 --- a/src/video_core/renderer_vulkan/vk_device.h +++ b/src/video_core/renderer_vulkan/vk_device.h @@ -202,6 +202,7 @@ public: return reported_extensions; } + /// Returns true if the setting for async shader compilation is enabled. bool UseAsynchronousShaders() const { return use_asynchronous_shaders; } @@ -255,7 +256,9 @@ private: bool ext_custom_border_color{}; ///< Support for VK_EXT_custom_border_color. bool ext_extended_dynamic_state{}; ///< Support for VK_EXT_extended_dynamic_state. bool nv_device_diagnostics_config{}; ///< Support for VK_NV_device_diagnostics_config. - bool use_asynchronous_shaders{}; + + // Asynchronous Graphics Pipeline setting + bool use_asynchronous_shaders{}; ///< Setting to use asynchronous shaders/graphics pipeline // Telemetry parameters std::string vendor_name; ///< Device's driver name. diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 7d51b9836..5dc4cd5af 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -78,14 +78,15 @@ VKGraphicsPipeline::VKGraphicsPipeline(const VKDevice& device, VKScheduler& sche const GraphicsPipelineCacheKey& key, vk::Span bindings, const SPIRVProgram& program) - : device{device}, scheduler{scheduler}, fixed_state{key.fixed_state}, hash{key.Hash()}, + : device{device}, scheduler{scheduler}, hash{key.Hash()}, cache_key{key}, descriptor_set_layout{CreateDescriptorSetLayout(bindings)}, descriptor_allocator{descriptor_pool, *descriptor_set_layout}, update_descriptor_queue{update_descriptor_queue}, layout{CreatePipelineLayout()}, descriptor_template{CreateDescriptorUpdateTemplate(program)}, modules{CreateShaderModules( program)}, - renderpass{renderpass_cache.GetRenderPass(key.renderpass_params)}, - pipeline{CreatePipeline(key.renderpass_params, program)}, m_key{key} {} + renderpass{renderpass_cache.GetRenderPass(key.renderpass_params)}, pipeline{CreatePipeline( + key.renderpass_params, + program)} {} VKGraphicsPipeline::~VKGraphicsPipeline() = default; @@ -180,7 +181,7 @@ std::vector VKGraphicsPipeline::CreateShaderModules( vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpass_params, const SPIRVProgram& program) const { - const auto& state = fixed_state; + const auto& state = cache_key.fixed_state; const auto& viewport_swizzles = state.viewport_swizzles; 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 d50bd347c..9d462db0a 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 { using Maxwell = Tegra::Engines::Maxwell3D::Regs; -struct GraphicsPipelineCacheKey; +struct GraphicsPipelineCacheKey { + RenderPassParams renderpass_params; + u32 padding; + std::array shaders; + FixedPipelineState fixed_state; + + std::size_t Hash() const noexcept; + + bool operator==(const GraphicsPipelineCacheKey& rhs) const noexcept; + + bool operator!=(const GraphicsPipelineCacheKey& rhs) const noexcept { + return !operator==(rhs); + } + + std::size_t Size() const noexcept { + return sizeof(renderpass_params) + sizeof(padding) + sizeof(shaders) + fixed_state.Size(); + } +}; +static_assert(std::has_unique_object_representations_v); +static_assert(std::is_trivially_copyable_v); +static_assert(std::is_trivially_constructible_v); class VKDescriptorPool; class VKDevice; @@ -54,8 +74,8 @@ public: return renderpass; } - const GraphicsPipelineCacheKey& GetCacheKey() const { - return m_key; + GraphicsPipelineCacheKey GetCacheKey() const { + return cache_key; } private: @@ -74,8 +94,8 @@ private: const VKDevice& device; VKScheduler& scheduler; - const FixedPipelineState fixed_state; const u64 hash; + GraphicsPipelineCacheKey cache_key; vk::DescriptorSetLayout descriptor_set_layout; DescriptorAllocator descriptor_allocator; @@ -86,8 +106,6 @@ private: VkRenderPass renderpass; vk::Pipeline pipeline; - - const GraphicsPipelineCacheKey& m_key; }; } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 1a8b2c62b..20ffbeb38 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 @@ #include "video_core/shader/compiler_settings.h" #include "video_core/shader/memory_util.h" #include "video_core/shader_cache.h" +#include "video_core/shader_notify.h" namespace Vulkan { @@ -214,27 +215,31 @@ VKGraphicsPipeline* VKPipelineCache::GetGraphicsPipeline( } last_graphics_key = key; - if (device.UseAsynchronousShaders()) { + if (device.UseAsynchronousShaders() && async_shaders.IsShaderAsync(system.GPU())) { std::unique_lock lock{pipeline_cache}; const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); if (is_cache_miss) { + system.GPU().ShaderNotify().MarkSharderBuilding(); LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); const auto [program, bindings] = DecompileShaders(key.fixed_state); - async_shaders.QueueVulkanShader(this, bindings, program, key.renderpass_params, - key.padding, key.shaders, key.fixed_state); + async_shaders.QueueVulkanShader(this, device, scheduler, descriptor_pool, + update_descriptor_queue, renderpass_cache, bindings, + program, key); } - last_graphics_pipeline = graphics_cache.at(key).get(); + last_graphics_pipeline = pair->second.get(); return last_graphics_pipeline; } const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); auto& entry = pair->second; if (is_cache_miss) { + system.GPU().ShaderNotify().MarkSharderBuilding(); LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); const auto [program, bindings] = DecompileShaders(key.fixed_state); entry = std::make_unique(device, scheduler, descriptor_pool, update_descriptor_queue, renderpass_cache, key, bindings, program); + system.GPU().ShaderNotify().MarkShaderComplete(); } last_graphics_pipeline = entry.get(); return last_graphics_pipeline; @@ -294,14 +299,8 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach void VKPipelineCache::EmplacePipeline(std::unique_ptr 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); - } + graphics_cache.at(pipeline->GetCacheKey()) = std::move(pipeline); + system.GPU().ShaderNotify().MarkShaderComplete(); } void VKPipelineCache::OnShaderRemoval(Shader* shader) { diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 777ef2038..c04829e77 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -44,28 +44,6 @@ class VKUpdateDescriptorQueue; using Maxwell = Tegra::Engines::Maxwell3D::Regs; -struct GraphicsPipelineCacheKey { - RenderPassParams renderpass_params; - u32 padding; - std::array shaders; - FixedPipelineState fixed_state; - - std::size_t Hash() const noexcept; - - bool operator==(const GraphicsPipelineCacheKey& rhs) const noexcept; - - bool operator!=(const GraphicsPipelineCacheKey& rhs) const noexcept { - return !operator==(rhs); - } - - std::size_t Size() const noexcept { - return sizeof(renderpass_params) + sizeof(padding) + sizeof(shaders) + fixed_state.Size(); - } -}; -static_assert(std::has_unique_object_representations_v); -static_assert(std::is_trivially_copyable_v); -static_assert(std::is_trivially_constructible_v); - struct ComputePipelineCacheKey { GPUVAddr shader; u32 shared_memory_size; @@ -158,41 +136,6 @@ public: VKComputePipeline& GetComputePipeline(const ComputePipelineCacheKey& key); - const VKDevice& GetDevice() const { - return device; - } - - VKScheduler& GetScheduler() { - return scheduler; - } - const VKScheduler& GetScheduler() const { - return scheduler; - } - - VKDescriptorPool& GetDescriptorPool() { - return descriptor_pool; - } - - const VKDescriptorPool& GetDescriptorPool() const { - return descriptor_pool; - } - - VKUpdateDescriptorQueue& GetUpdateDescriptorQueue() { - return update_descriptor_queue; - } - - const VKUpdateDescriptorQueue& GetUpdateDescriptorQueue() const { - return update_descriptor_queue; - } - - VKRenderPassCache& GetRenderpassCache() { - return renderpass_cache; - } - - const VKRenderPassCache& GetRenderpassCache() const { - return renderpass_cache; - } - void EmplacePipeline(std::unique_ptr pipeline); protected: @@ -216,7 +159,6 @@ private: GraphicsPipelineCacheKey last_graphics_key; VKGraphicsPipeline* last_graphics_pipeline = nullptr; - std::vector> duplicates; std::mutex pipeline_cache; std::unordered_map> diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index fc1b51a96..720802ad5 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -14,6 +14,7 @@ #include "common/assert.h" #include "common/logging/log.h" #include "common/microprofile.h" +#include "common/scope_exit.h" #include "core/core.h" #include "core/settings.h" #include "video_core/engines/kepler_compute.h" @@ -408,15 +409,10 @@ RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWind // Max worker threads we should allow constexpr u32 MAX_THREADS = 4; - // Amount of threads we should reserve for other parts of yuzu - constexpr u32 RESERVED_THREADS = 6; - // Get the amount of threads we can use(this can return zero) - const auto cpu_thread_count = - std::max(RESERVED_THREADS, std::thread::hardware_concurrency()); - // Deduce how many "extra" threads we have to use. - const auto max_threads_unused = cpu_thread_count - RESERVED_THREADS; + // Deduce how many threads we can use + const auto threads_used = std::thread::hardware_concurrency() / 4; // Always allow at least 1 thread regardless of our settings - const auto max_worker_count = std::max(1u, max_threads_unused); + const auto max_worker_count = std::max(1U, threads_used); // Don't use more than MAX_THREADS const auto worker_count = std::min(max_worker_count, MAX_THREADS); async_shaders.AllocateWorkers(worker_count); @@ -432,6 +428,8 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { query_cache.UpdateCounters(); + SCOPE_EXIT({ system.GPU().TickWork(); }); + const auto& gpu = system.GPU().Maxwell3D(); GraphicsPipelineCacheKey key; key.fixed_state.Fill(gpu.regs, device.IsExtExtendedDynamicStateSupported()); @@ -458,10 +456,9 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { key.renderpass_params = GetRenderPassParams(texceptions); key.padding = 0; - auto pipeline = pipeline_cache.GetGraphicsPipeline(key, async_shaders); + auto* pipeline = pipeline_cache.GetGraphicsPipeline(key, async_shaders); if (pipeline == nullptr || pipeline->GetHandle() == VK_NULL_HANDLE) { // Async graphics pipeline was not ready. - system.GPU().TickWork(); return; } @@ -488,8 +485,6 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { }); EndTransformFeedback(); - - system.GPU().TickWork(); } void RasterizerVulkan::Clear() { -- cgit v1.2.3