From 05cb10530fbd34635b06f75dea488a8896a763ac Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 29 Jun 2018 14:10:16 -0400 Subject: [PATCH] OpenGL: Use MakeCurrent/DoneCurrent for multithreaded rendering. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 ++++++ .../renderer_opengl/renderer_opengl.cpp | 15 ++++++++++++++- src/video_core/renderer_opengl/renderer_opengl.h | 7 +++++++ src/yuzu/bootmanager.cpp | 5 ++++- src/yuzu/main.cpp | 3 +++ src/yuzu_cmd/yuzu.cpp | 5 +++++ 6 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 4072a12b4..2e91a43e3 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -15,6 +15,7 @@ #include "common/microprofile.h" #include "common/scope_exit.h" #include "core/core.h" +#include "core/frontend/emu_window.h" #include "core/hle/kernel/process.h" #include "core/settings.h" #include "video_core/engines/maxwell_3d.h" @@ -22,6 +23,7 @@ #include "video_core/renderer_opengl/gl_shader_gen.h" #include "video_core/renderer_opengl/maxwell_to_gl.h" #include "video_core/renderer_opengl/renderer_opengl.h" +#include "video_core/video_core.h" using Maxwell = Tegra::Engines::Maxwell3D::Regs; using PixelFormat = SurfaceParams::PixelFormat; @@ -394,6 +396,8 @@ void RasterizerOpenGL::Clear() { if (clear_mask == 0) return; + ScopeAcquireGLContext acquire_context; + auto [dirty_color_surface, dirty_depth_surface] = ConfigureFramebuffers(use_color_fb, use_depth_fb); @@ -420,6 +424,8 @@ void RasterizerOpenGL::DrawArrays() { MICROPROFILE_SCOPE(OpenGL_Drawing); const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + ScopeAcquireGLContext acquire_context; + auto [dirty_color_surface, dirty_depth_surface] = ConfigureFramebuffers(true, regs.zeta.Address() != 0); diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 00841e937..1930fa6ef 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -92,11 +92,24 @@ static std::array MakeOrthographicMatrix(const float width, cons return matrix; } +ScopeAcquireGLContext::ScopeAcquireGLContext() { + if (Settings::values.use_multi_core) { + VideoCore::g_emu_window->MakeCurrent(); + } +} +ScopeAcquireGLContext::~ScopeAcquireGLContext() { + if (Settings::values.use_multi_core) { + VideoCore::g_emu_window->DoneCurrent(); + } +} + RendererOpenGL::RendererOpenGL() = default; RendererOpenGL::~RendererOpenGL() = default; /// Swap buffers (render frame) void RendererOpenGL::SwapBuffers(boost::optional framebuffer) { + ScopeAcquireGLContext acquire_context; + Core::System::GetInstance().perf_stats.EndSystemFrame(); // Maintain the rasterizer's state as a priority @@ -418,7 +431,7 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum /// Initialize the renderer bool RendererOpenGL::Init() { - render_window->MakeCurrent(); + ScopeAcquireGLContext acquire_context; if (GLAD_GL_KHR_debug) { glEnable(GL_DEBUG_OUTPUT); diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 21f0d298c..fd0267cf5 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -31,6 +31,13 @@ struct ScreenInfo { TextureInfo texture; }; +/// Helper class to acquire/release OpenGL context within a given scope +class ScopeAcquireGLContext : NonCopyable { +public: + ScopeAcquireGLContext(); + ~ScopeAcquireGLContext(); +}; + class RendererOpenGL : public RendererBase { public: RendererOpenGL(); diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 833085559..159b2c32b 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -20,7 +20,10 @@ EmuThread::EmuThread(GRenderWindow* render_window) : render_window(render_window) {} void EmuThread::run() { - render_window->MakeCurrent(); + if (!Settings::values.use_multi_core) { + // Single core mode must acquire OpenGL context for entire emulation session + render_window->MakeCurrent(); + } MicroProfileOnThreadCreate("EmuThread"); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 9ce8d7c27..16812e077 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -374,6 +374,8 @@ bool GMainWindow::LoadROM(const QString& filename) { const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())}; + render_window->DoneCurrent(); + if (result != Core::System::ResultStatus::Success) { switch (result) { case Core::System::ResultStatus::ErrorGetLoader: @@ -916,6 +918,7 @@ int main(int argc, char* argv[]) { QCoreApplication::setApplicationName("yuzu"); QApplication::setAttribute(Qt::AA_X11InitThreads); + QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity); QApplication app(argc, argv); // Qt changes the locale and causes issues in float conversion using std::to_string() when diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index f126bd277..24db1065a 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -148,6 +148,11 @@ int main(int argc, char** argv) { std::unique_ptr emu_window{std::make_unique(fullscreen)}; + if (!Settings::values.use_multi_core) { + // Single core mode must acquire OpenGL context for entire emulation session + emu_window->MakeCurrent(); + } + Core::System& system{Core::System::GetInstance()}; SCOPE_EXIT({ system.Shutdown(); });