summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-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
239} 239}
240} // Anonymous namespace 240} // Anonymous namespace
241 241
242struct ShaderCache::Context {
243 explicit Context(Core::Frontend::EmuWindow& emu_window)
244 : gl_context{emu_window.CreateSharedContext()}, scoped{*gl_context} {}
245
246 std::unique_ptr<Core::Frontend::GraphicsContext> gl_context;
247 Core::Frontend::GraphicsContext::Scoped scoped;
248 ShaderPools pools;
249};
250
242ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_, 251ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_,
243 Tegra::Engines::Maxwell3D& maxwell3d_, 252 Tegra::Engines::Maxwell3D& maxwell3d_,
244 Tegra::Engines::KeplerCompute& kepler_compute_, 253 Tegra::Engines::KeplerCompute& kepler_compute_,
@@ -247,46 +256,49 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
247 ProgramManager& program_manager_, StateTracker& state_tracker_) 256 ProgramManager& program_manager_, StateTracker& state_tracker_)
248 : VideoCommon::ShaderCache{rasterizer_, gpu_memory_, maxwell3d_, kepler_compute_}, 257 : VideoCommon::ShaderCache{rasterizer_, gpu_memory_, maxwell3d_, kepler_compute_},
249 emu_window{emu_window_}, device{device_}, texture_cache{texture_cache_}, 258 emu_window{emu_window_}, device{device_}, texture_cache{texture_cache_},
250 buffer_cache{buffer_cache_}, program_manager{program_manager_}, state_tracker{ 259 buffer_cache{buffer_cache_}, program_manager{program_manager_}, state_tracker{state_tracker_},
251 state_tracker_} { 260 use_asynchronous_shaders{device.UseAsynchronousShaders()},
252 profile = Shader::Profile{ 261 profile{
253 .supported_spirv = 0x00010000, 262 .supported_spirv = 0x00010000,
254 263
255 .unified_descriptor_binding = false, 264 .unified_descriptor_binding = false,
256 .support_descriptor_aliasing = false, 265 .support_descriptor_aliasing = false,
257 .support_int8 = false, 266 .support_int8 = false,
258 .support_int16 = false, 267 .support_int16 = false,
259 .support_vertex_instance_id = true, 268 .support_vertex_instance_id = true,
260 .support_float_controls = false, 269 .support_float_controls = false,
261 .support_separate_denorm_behavior = false, 270 .support_separate_denorm_behavior = false,
262 .support_separate_rounding_mode = false, 271 .support_separate_rounding_mode = false,
263 .support_fp16_denorm_preserve = false, 272 .support_fp16_denorm_preserve = false,
264 .support_fp32_denorm_preserve = false, 273 .support_fp32_denorm_preserve = false,
265 .support_fp16_denorm_flush = false, 274 .support_fp16_denorm_flush = false,
266 .support_fp32_denorm_flush = false, 275 .support_fp32_denorm_flush = false,
267 .support_fp16_signed_zero_nan_preserve = false, 276 .support_fp16_signed_zero_nan_preserve = false,
268 .support_fp32_signed_zero_nan_preserve = false, 277 .support_fp32_signed_zero_nan_preserve = false,
269 .support_fp64_signed_zero_nan_preserve = false, 278 .support_fp64_signed_zero_nan_preserve = false,
270 .support_explicit_workgroup_layout = false, 279 .support_explicit_workgroup_layout = false,
271 .support_vote = true, 280 .support_vote = true,
272 .support_viewport_index_layer_non_geometry = 281 .support_viewport_index_layer_non_geometry =
273 device.HasNvViewportArray2() || device.HasVertexViewportLayer(), 282 device.HasNvViewportArray2() || device.HasVertexViewportLayer(),
274 .support_viewport_mask = device.HasNvViewportArray2(), 283 .support_viewport_mask = device.HasNvViewportArray2(),
275 .support_typeless_image_loads = device.HasImageLoadFormatted(), 284 .support_typeless_image_loads = device.HasImageLoadFormatted(),
276 .support_demote_to_helper_invocation = false, 285 .support_demote_to_helper_invocation = false,
277 .support_int64_atomics = false, 286 .support_int64_atomics = false,
278 .support_derivative_control = device.HasDerivativeControl(), 287 .support_derivative_control = device.HasDerivativeControl(),
279 288
280 .warp_size_potentially_larger_than_guest = true, 289 .warp_size_potentially_larger_than_guest = true,
281 290
282 .lower_left_origin_mode = true, 291 .lower_left_origin_mode = true,
283 .need_declared_frag_colors = true, 292 .need_declared_frag_colors = true,
284 293
285 .has_broken_spirv_clamp = true, 294 .has_broken_spirv_clamp = true,
286 .has_broken_unsigned_image_offsets = true, 295 .has_broken_unsigned_image_offsets = true,
287 .has_broken_signed_operations = true, 296 .has_broken_signed_operations = true,
288 .ignore_nan_fp_comparisons = true, 297 .ignore_nan_fp_comparisons = true,
289 }; 298 } {
299 if (use_asynchronous_shaders) {
300 workers = CreateWorkers();
301 }
290} 302}
291 303
292ShaderCache::~ShaderCache() = default; 304ShaderCache::~ShaderCache() = default;
@@ -307,29 +319,20 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
307 } 319 }
308 shader_cache_filename = transferable_dir / fmt::format("{:016x}.bin", title_id); 320 shader_cache_filename = transferable_dir / fmt::format("{:016x}.bin", title_id);
309 321
310 struct Context { 322 if (!workers) {
311 explicit Context(Core::Frontend::EmuWindow& emu_window) 323 workers = CreateWorkers();
312 : gl_context{emu_window.CreateSharedContext()}, scoped{*gl_context} {} 324 }
313
314 std::unique_ptr<Core::Frontend::GraphicsContext> gl_context;
315 Core::Frontend::GraphicsContext::Scoped scoped;
316 ShaderPools pools;
317 };
318 Common::StatefulThreadWorker<Context> workers(
319 std::max(std::thread::hardware_concurrency(), 2U) - 1, "yuzu:ShaderBuilder",
320 [this] { return Context{emu_window}; });
321
322 struct { 325 struct {
323 std::mutex mutex; 326 std::mutex mutex;
324 size_t total{0}; 327 size_t total{};
325 size_t built{0}; 328 size_t built{};
326 bool has_loaded{false}; 329 bool has_loaded{};
327 } state; 330 } state;
328 331
329 const auto load_compute{[&](std::ifstream& file, FileEnvironment env) { 332 const auto load_compute{[&](std::ifstream& file, FileEnvironment env) {
330 ComputePipelineKey key; 333 ComputePipelineKey key;
331 file.read(reinterpret_cast<char*>(&key), sizeof(key)); 334 file.read(reinterpret_cast<char*>(&key), sizeof(key));
332 workers.QueueWork( 335 workers->QueueWork(
333 [this, key, env = std::move(env), &state, &callback](Context* ctx) mutable { 336 [this, key, env = std::move(env), &state, &callback](Context* ctx) mutable {
334 ctx->pools.ReleaseContents(); 337 ctx->pools.ReleaseContents();
335 auto pipeline{CreateComputePipeline(ctx->pools, key, env)}; 338 auto pipeline{CreateComputePipeline(ctx->pools, key, env)};
@@ -347,7 +350,7 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
347 const auto load_graphics{[&](std::ifstream& file, std::vector<FileEnvironment> envs) { 350 const auto load_graphics{[&](std::ifstream& file, std::vector<FileEnvironment> envs) {
348 GraphicsPipelineKey key; 351 GraphicsPipelineKey key;
349 file.read(reinterpret_cast<char*>(&key), sizeof(key)); 352 file.read(reinterpret_cast<char*>(&key), sizeof(key));
350 workers.QueueWork( 353 workers->QueueWork(
351 [this, key, envs = std::move(envs), &state, &callback](Context* ctx) mutable { 354 [this, key, envs = std::move(envs), &state, &callback](Context* ctx) mutable {
352 boost::container::static_vector<Shader::Environment*, 5> env_ptrs; 355 boost::container::static_vector<Shader::Environment*, 5> env_ptrs;
353 for (auto& env : envs) { 356 for (auto& env : envs) {
@@ -373,7 +376,10 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
373 state.has_loaded = true; 376 state.has_loaded = true;
374 lock.unlock(); 377 lock.unlock();
375 378
376 workers.WaitForRequests(); 379 workers->WaitForRequests();
380 if (!use_asynchronous_shaders) {
381 workers.reset();
382 }
377} 383}
378 384
379GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() { 385GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
@@ -570,4 +576,11 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools&
570 return nullptr; 576 return nullptr;
571} 577}
572 578
579std::unique_ptr<Common::StatefulThreadWorker<ShaderCache::Context>> ShaderCache::CreateWorkers()
580 const {
581 return std::make_unique<Common::StatefulThreadWorker<Context>>(
582 std::max(std::thread::hardware_concurrency(), 2U) - 1, "yuzu:ShaderBuilder",
583 [this] { return Context{emu_window}; });
584}
585
573} // namespace OpenGL 586} // 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 @@
12#include <glad/glad.h> 12#include <glad/glad.h>
13 13
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "common/thread_worker.h"
15#include "shader_recompiler/frontend/ir/basic_block.h" 16#include "shader_recompiler/frontend/ir/basic_block.h"
16#include "shader_recompiler/frontend/ir/value.h" 17#include "shader_recompiler/frontend/ir/value.h"
17#include "shader_recompiler/frontend/maxwell/control_flow.h" 18#include "shader_recompiler/frontend/maxwell/control_flow.h"
@@ -44,6 +45,8 @@ struct ShaderPools {
44}; 45};
45 46
46class ShaderCache : public VideoCommon::ShaderCache { 47class ShaderCache : public VideoCommon::ShaderCache {
48 struct Context;
49
47public: 50public:
48 explicit ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_, 51 explicit ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_,
49 Tegra::Engines::Maxwell3D& maxwell3d_, 52 Tegra::Engines::Maxwell3D& maxwell3d_,
@@ -74,6 +77,8 @@ private:
74 const ComputePipelineKey& key, 77 const ComputePipelineKey& key,
75 Shader::Environment& env); 78 Shader::Environment& env);
76 79
80 std::unique_ptr<Common::StatefulThreadWorker<Context>> CreateWorkers() const;
81
77 Core::Frontend::EmuWindow& emu_window; 82 Core::Frontend::EmuWindow& emu_window;
78 const Device& device; 83 const Device& device;
79 TextureCache& texture_cache; 84 TextureCache& texture_cache;
@@ -82,6 +87,7 @@ private:
82 StateTracker& state_tracker; 87 StateTracker& state_tracker;
83 88
84 GraphicsPipelineKey graphics_key{}; 89 GraphicsPipelineKey graphics_key{};
90 const bool use_asynchronous_shaders;
85 91
86 ShaderPools main_pools; 92 ShaderPools main_pools;
87 std::unordered_map<GraphicsPipelineKey, std::unique_ptr<GraphicsPipeline>> graphics_cache; 93 std::unordered_map<GraphicsPipelineKey, std::unique_ptr<GraphicsPipeline>> graphics_cache;
@@ -89,6 +95,7 @@ private:
89 95
90 Shader::Profile profile; 96 Shader::Profile profile;
91 std::filesystem::path shader_cache_filename; 97 std::filesystem::path shader_cache_filename;
98 std::unique_ptr<Common::StatefulThreadWorker<Context>> workers;
92}; 99};
93 100
94} // namespace OpenGL 101} // namespace OpenGL