mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-15 03:08:36 +12:00
rsx: Use multithreaded shader compiler backend
This commit is contained in:
parent
e89a568765
commit
3ddfa288cf
30 changed files with 1065 additions and 580 deletions
149
rpcs3/Emu/RSX/GL/GLPipelineCompiler.cpp
Normal file
149
rpcs3/Emu/RSX/GL/GLPipelineCompiler.cpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
#include "stdafx.h"
|
||||
#include "GLPipelineCompiler.h"
|
||||
#include "Utilities/Thread.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace gl
|
||||
{
|
||||
// Global list of worker threads
|
||||
std::unique_ptr<named_thread_group<pipe_compiler>> g_pipe_compilers;
|
||||
int g_num_pipe_compilers = 0;
|
||||
atomic_t<int> g_compiler_index{};
|
||||
|
||||
pipe_compiler::pipe_compiler()
|
||||
{
|
||||
}
|
||||
|
||||
pipe_compiler::~pipe_compiler()
|
||||
{
|
||||
if (m_context_destroy_func)
|
||||
{
|
||||
m_context_destroy_func(m_context);
|
||||
}
|
||||
}
|
||||
|
||||
void pipe_compiler::initialize(
|
||||
std::function<draw_context_t()> context_create_func,
|
||||
std::function<void(draw_context_t)> context_bind_func,
|
||||
std::function<void(draw_context_t)> context_destroy_func)
|
||||
{
|
||||
m_context_bind_func = context_bind_func;
|
||||
m_context_destroy_func = context_destroy_func;
|
||||
|
||||
m_context = context_create_func();
|
||||
}
|
||||
|
||||
void pipe_compiler::operator()()
|
||||
{
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
for (auto&& job : m_work_queue.pop_all())
|
||||
{
|
||||
if (m_context_ready.compare_and_swap_test(false, true))
|
||||
{
|
||||
// Bind context on first use
|
||||
m_context_bind_func(m_context);
|
||||
}
|
||||
|
||||
auto result = int_compile_graphics_pipe(
|
||||
job.vp_handle, job.fp_handle,
|
||||
job.post_create_func,
|
||||
job.post_link_func);
|
||||
|
||||
job.completion_callback(result);
|
||||
}
|
||||
|
||||
m_work_queue.wait();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<glsl::program> pipe_compiler::compile(
|
||||
GLuint vp_handle, GLuint fp_handle,
|
||||
op_flags flags,
|
||||
callback_t post_create_func,
|
||||
callback_t post_link_func,
|
||||
callback_t completion_callback_func)
|
||||
{
|
||||
if (flags == COMPILE_INLINE)
|
||||
{
|
||||
return int_compile_graphics_pipe(vp_handle, fp_handle, post_create_func, post_link_func);
|
||||
}
|
||||
|
||||
m_work_queue.push(vp_handle, fp_handle, post_create_func, post_link_func, completion_callback_func);
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<glsl::program> pipe_compiler::int_compile_graphics_pipe(
|
||||
GLuint vp_handle, GLuint fp_handle,
|
||||
callback_t post_create_func,
|
||||
callback_t post_link_func)
|
||||
{
|
||||
auto result = std::make_unique<glsl::program>();
|
||||
result->create();
|
||||
|
||||
if (post_create_func)
|
||||
{
|
||||
post_create_func(result);
|
||||
}
|
||||
|
||||
result->link();
|
||||
|
||||
if (post_link_func)
|
||||
{
|
||||
post_link_func(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void initialize_pipe_compiler(
|
||||
std::function<draw_context_t()> context_create_func,
|
||||
std::function<void(draw_context_t)> context_bind_func,
|
||||
std::function<void(draw_context_t)> context_destroy_func,
|
||||
int num_worker_threads)
|
||||
{
|
||||
if (num_worker_threads == -1)
|
||||
{
|
||||
// Select optimal number of compiler threads
|
||||
const auto hw_threads = std::thread::hardware_concurrency();
|
||||
if (hw_threads >= 12)
|
||||
{
|
||||
num_worker_threads = 4;
|
||||
}
|
||||
else if (hw_threads >= 8)
|
||||
{
|
||||
num_worker_threads = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_worker_threads = 1;
|
||||
}
|
||||
}
|
||||
|
||||
verify(HERE), num_worker_threads >= 1;
|
||||
|
||||
// Create the thread pool
|
||||
g_pipe_compilers = std::make_unique<named_thread_group<pipe_compiler>>("RSX.W", num_worker_threads);
|
||||
g_num_pipe_compilers = num_worker_threads;
|
||||
|
||||
// Initialize the workers. At least one inline compiler shall exist (doesn't actually run)
|
||||
for (pipe_compiler& compiler : *g_pipe_compilers.get())
|
||||
{
|
||||
compiler.initialize(context_create_func, context_bind_func, context_destroy_func);
|
||||
}
|
||||
}
|
||||
|
||||
void destroy_pipe_compiler()
|
||||
{
|
||||
g_pipe_compilers.reset();
|
||||
}
|
||||
|
||||
pipe_compiler* get_pipe_compiler()
|
||||
{
|
||||
verify(HERE), g_pipe_compilers;
|
||||
int thread_index = g_compiler_index++;
|
||||
|
||||
return g_pipe_compilers.get()->begin() + (thread_index % g_num_pipe_compilers);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue