Просмотр исходного кода

gl_shader_cache: Store workers in shader cache object

ReinUsesLisp 5 лет назад
Родитель
Сommit
12fe7210d2

+ 71 - 58
src/video_core/renderer_opengl/gl_shader_cache.cpp

@@ -239,6 +239,15 @@ void SetXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs
 }
 } // Anonymous namespace
 
+struct ShaderCache::Context {
+    explicit Context(Core::Frontend::EmuWindow& emu_window)
+        : gl_context{emu_window.CreateSharedContext()}, scoped{*gl_context} {}
+
+    std::unique_ptr<Core::Frontend::GraphicsContext> gl_context;
+    Core::Frontend::GraphicsContext::Scoped scoped;
+    ShaderPools pools;
+};
+
 ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_,
                          Tegra::Engines::Maxwell3D& maxwell3d_,
                          Tegra::Engines::KeplerCompute& kepler_compute_,
@@ -247,46 +256,49 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
                          ProgramManager& program_manager_, StateTracker& state_tracker_)
     : VideoCommon::ShaderCache{rasterizer_, gpu_memory_, maxwell3d_, kepler_compute_},
       emu_window{emu_window_}, device{device_}, texture_cache{texture_cache_},
-      buffer_cache{buffer_cache_}, program_manager{program_manager_}, state_tracker{
-                                                                          state_tracker_} {
-    profile = Shader::Profile{
-        .supported_spirv = 0x00010000,
-
-        .unified_descriptor_binding = false,
-        .support_descriptor_aliasing = false,
-        .support_int8 = false,
-        .support_int16 = false,
-        .support_vertex_instance_id = true,
-        .support_float_controls = false,
-        .support_separate_denorm_behavior = false,
-        .support_separate_rounding_mode = false,
-        .support_fp16_denorm_preserve = false,
-        .support_fp32_denorm_preserve = false,
-        .support_fp16_denorm_flush = false,
-        .support_fp32_denorm_flush = false,
-        .support_fp16_signed_zero_nan_preserve = false,
-        .support_fp32_signed_zero_nan_preserve = false,
-        .support_fp64_signed_zero_nan_preserve = false,
-        .support_explicit_workgroup_layout = false,
-        .support_vote = true,
-        .support_viewport_index_layer_non_geometry =
-            device.HasNvViewportArray2() || device.HasVertexViewportLayer(),
-        .support_viewport_mask = device.HasNvViewportArray2(),
-        .support_typeless_image_loads = device.HasImageLoadFormatted(),
-        .support_demote_to_helper_invocation = false,
-        .support_int64_atomics = false,
-        .support_derivative_control = device.HasDerivativeControl(),
-
-        .warp_size_potentially_larger_than_guest = true,
-
-        .lower_left_origin_mode = true,
-        .need_declared_frag_colors = true,
-
-        .has_broken_spirv_clamp = true,
-        .has_broken_unsigned_image_offsets = true,
-        .has_broken_signed_operations = true,
-        .ignore_nan_fp_comparisons = true,
-    };
+      buffer_cache{buffer_cache_}, program_manager{program_manager_}, state_tracker{state_tracker_},
+      use_asynchronous_shaders{device.UseAsynchronousShaders()},
+      profile{
+          .supported_spirv = 0x00010000,
+
+          .unified_descriptor_binding = false,
+          .support_descriptor_aliasing = false,
+          .support_int8 = false,
+          .support_int16 = false,
+          .support_vertex_instance_id = true,
+          .support_float_controls = false,
+          .support_separate_denorm_behavior = false,
+          .support_separate_rounding_mode = false,
+          .support_fp16_denorm_preserve = false,
+          .support_fp32_denorm_preserve = false,
+          .support_fp16_denorm_flush = false,
+          .support_fp32_denorm_flush = false,
+          .support_fp16_signed_zero_nan_preserve = false,
+          .support_fp32_signed_zero_nan_preserve = false,
+          .support_fp64_signed_zero_nan_preserve = false,
+          .support_explicit_workgroup_layout = false,
+          .support_vote = true,
+          .support_viewport_index_layer_non_geometry =
+              device.HasNvViewportArray2() || device.HasVertexViewportLayer(),
+          .support_viewport_mask = device.HasNvViewportArray2(),
+          .support_typeless_image_loads = device.HasImageLoadFormatted(),
+          .support_demote_to_helper_invocation = false,
+          .support_int64_atomics = false,
+          .support_derivative_control = device.HasDerivativeControl(),
+
+          .warp_size_potentially_larger_than_guest = true,
+
+          .lower_left_origin_mode = true,
+          .need_declared_frag_colors = true,
+
+          .has_broken_spirv_clamp = true,
+          .has_broken_unsigned_image_offsets = true,
+          .has_broken_signed_operations = true,
+          .ignore_nan_fp_comparisons = true,
+      } {
+    if (use_asynchronous_shaders) {
+        workers = CreateWorkers();
+    }
 }
 
 ShaderCache::~ShaderCache() = default;
@@ -307,29 +319,20 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
     }
     shader_cache_filename = transferable_dir / fmt::format("{:016x}.bin", title_id);
 
-    struct Context {
-        explicit Context(Core::Frontend::EmuWindow& emu_window)
-            : gl_context{emu_window.CreateSharedContext()}, scoped{*gl_context} {}
-
-        std::unique_ptr<Core::Frontend::GraphicsContext> gl_context;
-        Core::Frontend::GraphicsContext::Scoped scoped;
-        ShaderPools pools;
-    };
-    Common::StatefulThreadWorker<Context> workers(
-        std::max(std::thread::hardware_concurrency(), 2U) - 1, "yuzu:ShaderBuilder",
-        [this] { return Context{emu_window}; });
-
+    if (!workers) {
+        workers = CreateWorkers();
+    }
     struct {
         std::mutex mutex;
-        size_t total{0};
-        size_t built{0};
-        bool has_loaded{false};
+        size_t total{};
+        size_t built{};
+        bool has_loaded{};
     } state;
 
     const auto load_compute{[&](std::ifstream& file, FileEnvironment env) {
         ComputePipelineKey key;
         file.read(reinterpret_cast<char*>(&key), sizeof(key));
-        workers.QueueWork(
+        workers->QueueWork(
             [this, key, env = std::move(env), &state, &callback](Context* ctx) mutable {
                 ctx->pools.ReleaseContents();
                 auto pipeline{CreateComputePipeline(ctx->pools, key, env)};
@@ -347,7 +350,7 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
     const auto load_graphics{[&](std::ifstream& file, std::vector<FileEnvironment> envs) {
         GraphicsPipelineKey key;
         file.read(reinterpret_cast<char*>(&key), sizeof(key));
-        workers.QueueWork(
+        workers->QueueWork(
             [this, key, envs = std::move(envs), &state, &callback](Context* ctx) mutable {
                 boost::container::static_vector<Shader::Environment*, 5> env_ptrs;
                 for (auto& env : envs) {
@@ -373,7 +376,10 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
     state.has_loaded = true;
     lock.unlock();
 
-    workers.WaitForRequests();
+    workers->WaitForRequests();
+    if (!use_asynchronous_shaders) {
+        workers.reset();
+    }
 }
 
 GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
@@ -570,4 +576,11 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools&
     return nullptr;
 }
 
+std::unique_ptr<Common::StatefulThreadWorker<ShaderCache::Context>> ShaderCache::CreateWorkers()
+    const {
+    return std::make_unique<Common::StatefulThreadWorker<Context>>(
+        std::max(std::thread::hardware_concurrency(), 2U) - 1, "yuzu:ShaderBuilder",
+        [this] { return Context{emu_window}; });
+}
+
 } // namespace OpenGL

+ 7 - 0
src/video_core/renderer_opengl/gl_shader_cache.h

@@ -12,6 +12,7 @@
 #include <glad/glad.h>
 
 #include "common/common_types.h"
+#include "common/thread_worker.h"
 #include "shader_recompiler/frontend/ir/basic_block.h"
 #include "shader_recompiler/frontend/ir/value.h"
 #include "shader_recompiler/frontend/maxwell/control_flow.h"
@@ -44,6 +45,8 @@ struct ShaderPools {
 };
 
 class ShaderCache : public VideoCommon::ShaderCache {
+    struct Context;
+
 public:
     explicit ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_,
                          Tegra::Engines::Maxwell3D& maxwell3d_,
@@ -74,6 +77,8 @@ private:
                                                            const ComputePipelineKey& key,
                                                            Shader::Environment& env);
 
+    std::unique_ptr<Common::StatefulThreadWorker<Context>> CreateWorkers() const;
+
     Core::Frontend::EmuWindow& emu_window;
     const Device& device;
     TextureCache& texture_cache;
@@ -82,6 +87,7 @@ private:
     StateTracker& state_tracker;
 
     GraphicsPipelineKey graphics_key{};
+    const bool use_asynchronous_shaders;
 
     ShaderPools main_pools;
     std::unordered_map<GraphicsPipelineKey, std::unique_ptr<GraphicsPipeline>> graphics_cache;
@@ -89,6 +95,7 @@ private:
 
     Shader::Profile profile;
     std::filesystem::path shader_cache_filename;
+    std::unique_ptr<Common::StatefulThreadWorker<Context>> workers;
 };
 
 } // namespace OpenGL