summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp129
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h7
2 files changed, 78 insertions, 58 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 0e4904733..9d6cef6e8 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/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
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index cf74d34e4..e0c5a06d8 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/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