summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader/async_shaders.h
diff options
context:
space:
mode:
authorDavid Marcec <dmarcecguzman@gmail.com>2020-07-10 05:36:38 +0200
committerDavid Marcec <dmarcecguzman@gmail.com>2020-07-17 06:24:57 +0200
commit468bd9c1b0f9e74f7c096b127a94a94e4ed7caec (patch)
tree50a0f28b7c817222247369400bedf5de1ccc4e19 /src/video_core/shader/async_shaders.h
parentMerge pull request #4347 from lioncash/logging (diff)
downloadyuzu-468bd9c1b0f9e74f7c096b127a94a94e4ed7caec.tar
yuzu-468bd9c1b0f9e74f7c096b127a94a94e4ed7caec.tar.gz
yuzu-468bd9c1b0f9e74f7c096b127a94a94e4ed7caec.tar.bz2
yuzu-468bd9c1b0f9e74f7c096b127a94a94e4ed7caec.tar.lz
yuzu-468bd9c1b0f9e74f7c096b127a94a94e4ed7caec.tar.xz
yuzu-468bd9c1b0f9e74f7c096b127a94a94e4ed7caec.tar.zst
yuzu-468bd9c1b0f9e74f7c096b127a94a94e4ed7caec.zip
Diffstat (limited to 'src/video_core/shader/async_shaders.h')
-rw-r--r--src/video_core/shader/async_shaders.h107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/video_core/shader/async_shaders.h b/src/video_core/shader/async_shaders.h
new file mode 100644
index 000000000..26bc38326
--- /dev/null
+++ b/src/video_core/shader/async_shaders.h
@@ -0,0 +1,107 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <deque>
+#include <memory>
+#include <shared_mutex>
+#include <thread>
+#include "common/bit_field.h"
+#include "common/common_types.h"
+#include "video_core/renderer_opengl/gl_device.h"
+#include "video_core/renderer_opengl/gl_resource_manager.h"
+#include "video_core/renderer_opengl/gl_shader_decompiler.h"
+
+namespace Core::Frontend {
+class EmuWindow;
+class GraphicsContext;
+} // namespace Core::Frontend
+
+namespace Tegra {
+class GPU;
+}
+
+namespace VideoCommon::Shader {
+
+class AsyncShaders {
+public:
+ enum class Backend {
+ OpenGL,
+ GLASM,
+ };
+
+ struct ResultPrograms {
+ OpenGL::OGLProgram opengl;
+ OpenGL::OGLAssemblyProgram glasm;
+ };
+
+ struct Result {
+ u64 uid;
+ VAddr cpu_address;
+ Backend backend;
+ ResultPrograms program;
+ std::vector<u64> code;
+ std::vector<u64> code_b;
+ Tegra::Engines::ShaderType shader_type;
+ };
+
+ explicit AsyncShaders(Core::Frontend::EmuWindow& emu_window);
+ ~AsyncShaders();
+
+ /// Start up shader worker threads
+ void AllocateWorkers(std::size_t num_workers);
+
+ /// Clear the shader queue and kill all worker threads
+ void FreeWorkers();
+
+ // Force end all threads
+ void KillWorkers();
+
+ /// Check our worker queue to see if we have any work queued already
+ bool HasWorkQueued();
+
+ /// Check to see if any shaders have actually been compiled
+ bool HasCompletedWork();
+
+ /// Deduce if a shader can be build on another thread of MUST be built in sync. We cannot build
+ /// every shader async as some shaders are only built and executed once. We try to "guess" which
+ /// shader would be used only once
+ bool IsShaderAsync(const Tegra::GPU& gpu) const;
+
+ /// Pulls completed compiled shaders
+ std::vector<Result> GetCompletedWork();
+
+ void QueueOpenGLShader(const OpenGL::Device& device, Tegra::Engines::ShaderType shader_type,
+ u64 uid, std::vector<u64> code, std::vector<u64> code_b, u32 main_offset,
+ VideoCommon::Shader::CompilerSettings compiler_settings,
+ const VideoCommon::Shader::Registry& registry, VAddr cpu_addr);
+
+private:
+ void ShaderCompilerThread(Core::Frontend::GraphicsContext* context);
+
+ struct WorkerParams {
+ AsyncShaders::Backend backend;
+ OpenGL::Device device;
+ Tegra::Engines::ShaderType shader_type;
+ u64 uid;
+ std::vector<u64> code;
+ std::vector<u64> code_b;
+ u32 main_offset;
+ VideoCommon::Shader::CompilerSettings compiler_settings;
+ VideoCommon::Shader::Registry registry;
+ VAddr cpu_address;
+ };
+
+ std::shared_mutex queue_mutex;
+ std::shared_mutex completed_mutex;
+ std::atomic<bool> is_thread_exiting{};
+ std::vector<std::unique_ptr<Core::Frontend::GraphicsContext>> context_list;
+ std::vector<std::thread> worker_threads;
+ std::deque<WorkerParams> pending_queue;
+ std::vector<AsyncShaders::Result> finished_work;
+ Core::Frontend::EmuWindow& emu_window;
+};
+
+} // namespace VideoCommon::Shader