gl: Implement async optimized interpreter build

This commit is contained in:
kd-11
2026-04-12 20:39:55 +03:00
committed by kd-11
parent 97c7d069ac
commit f3d0c3ba28
2 changed files with 30 additions and 15 deletions
+21 -8
View File
@@ -59,7 +59,7 @@ namespace gl
dlg->set_limit(1, limit2); dlg->set_limit(1, limit2);
atomic_t<u32> ctr = 0; atomic_t<u32> ctr = 0;
auto progress_hook = [&](interpreter::cached_program*) { ctr++; }; auto progress_hook = [&](const std::shared_ptr<interpreter::cached_program>&) { ctr++; };
auto update_progress = [&](u32 stage) auto update_progress = [&](u32 stage)
{ {
@@ -188,10 +188,23 @@ namespace gl
std::lock_guard lock(m_program_cache_lock); std::lock_guard lock(m_program_cache_lock);
if (auto it = m_program_cache.find(opt); it != m_program_cache.end()) [[likely]] if (auto it = m_program_cache.find(opt); it != m_program_cache.end()) [[likely]]
{ {
m_current_interpreter = it->second.get(); m_current_interpreter = it->second;
}
if (m_current_interpreter)
{
constexpr u32 test_mask = (interpreter::CACHED_PIPE_UNOPTIMIZED | interpreter::CACHED_PIPE_RECOMPILING);
constexpr u32 unoptimized_mask = interpreter::CACHED_PIPE_UNOPTIMIZED;
if ((m_current_interpreter->flags & test_mask) == unoptimized_mask)
{
// Interpreter is unoptimized and we haven't tried to recompile it
// NOTE: This operation effectively orphans the current interpreter, but since unoptimized pipelines just have a non-owning reference then it's actually fine and we don't really leak anything.
m_current_interpreter->flags |= interpreter::CACHED_PIPE_RECOMPILING;
build_program_async(opt, {});
} }
return m_current_interpreter->prog.get(); return m_current_interpreter->prog.get();
} }
}
m_current_interpreter = build_program(opt); m_current_interpreter = build_program(opt);
return m_current_interpreter->prog.get(); return m_current_interpreter->prog.get();
@@ -465,9 +478,9 @@ namespace gl
} }
} }
interpreter::cached_program* shader_interpreter::build_program(u64 compiler_options) std::shared_ptr<interpreter::cached_program> shader_interpreter::build_program(u64 compiler_options)
{ {
auto data = new interpreter::cached_program(); auto data = std::make_shared<interpreter::cached_program>();
build_fs(compiler_options, *data); build_fs(compiler_options, *data);
build_vs(compiler_options, *data); build_vs(compiler_options, *data);
@@ -481,9 +494,9 @@ namespace gl
return data; return data;
} }
void shader_interpreter::build_program_async(u64 compiler_options, std::function<void(interpreter::cached_program*)> callback) void shader_interpreter::build_program_async(u64 compiler_options, async_build_callback_t callback)
{ {
auto data = new interpreter::cached_program(); auto data = std::make_shared<interpreter::cached_program>();
auto post_create_hook = [=](glsl::program* prog) auto post_create_hook = [=](glsl::program* prog)
{ {
@@ -514,7 +527,7 @@ namespace gl
); );
} }
void shader_interpreter::post_init_hook(interpreter::cached_program* data, u64 compiler_options) void shader_interpreter::post_init_hook(const std::shared_ptr<interpreter::cached_program>& data, u64 compiler_options)
{ {
data->prog->uniforms[0] = GL_STREAM_BUFFER_START + 0; data->prog->uniforms[0] = GL_STREAM_BUFFER_START + 0;
data->prog->uniforms[1] = GL_STREAM_BUFFER_START + 1; data->prog->uniforms[1] = GL_STREAM_BUFFER_START + 1;
@@ -538,7 +551,7 @@ namespace gl
} }
std::lock_guard lock(m_program_cache_lock); std::lock_guard lock(m_program_cache_lock);
m_program_cache[compiler_options].reset(data); m_program_cache[compiler_options] = data;
} }
bool shader_interpreter::is_interpreter(const glsl::program* program) const bool shader_interpreter::is_interpreter(const glsl::program* program) const
+8 -6
View File
@@ -64,7 +64,8 @@ namespace gl
enum cached_program_flags enum cached_program_flags
{ {
CACHED_PIPE_UNOPTIMIZED = 1 CACHED_PIPE_UNOPTIMIZED = (1 << 0),
CACHED_PIPE_RECOMPILING = (1 << 1),
}; };
struct cached_program struct cached_program
@@ -81,7 +82,8 @@ namespace gl
class shader_interpreter class shader_interpreter
{ {
using shader_cache_t = std::unordered_map<u64, std::shared_ptr<glsl::shader>>; using shader_cache_t = std::unordered_map<u64, std::shared_ptr<glsl::shader>>;
using pipeline_cache_t = std::unordered_map<u64, std::unique_ptr<interpreter::cached_program>>; using pipeline_cache_t = std::unordered_map<u64, std::shared_ptr<interpreter::cached_program>>;
using async_build_callback_t = std::function<void(const std::shared_ptr<interpreter::cached_program>&)>;
shared_mutex m_vs_cache_lock; shared_mutex m_vs_cache_lock;
shared_mutex m_fs_cache_lock; shared_mutex m_fs_cache_lock;
@@ -94,11 +96,11 @@ namespace gl
void build_vs(u64 compiler_options, interpreter::cached_program& prog_data); void build_vs(u64 compiler_options, interpreter::cached_program& prog_data);
void build_fs(u64 compiler_options, interpreter::cached_program& prog_data); void build_fs(u64 compiler_options, interpreter::cached_program& prog_data);
interpreter::cached_program* build_program(u64 compiler_options); std::shared_ptr<interpreter::cached_program> build_program(u64 compiler_options);
void build_program_async(u64 compiler_options, std::function<void(interpreter::cached_program*)> callback); void build_program_async(u64 compiler_options, async_build_callback_t callback);
void post_init_hook(interpreter::cached_program* data, u64 compiler_options); void post_init_hook(const std::shared_ptr<interpreter::cached_program>& data, u64 compiler_options);
interpreter::cached_program* m_current_interpreter = nullptr; std::shared_ptr<interpreter::cached_program> m_current_interpreter;
public: public:
void create(rsx::shader_loading_dialog* dlg); void create(rsx::shader_loading_dialog* dlg);