OpenGL: Use MakeCurrent/DoneCurrent for multithreaded rendering.

This commit is contained in:
bunnei 2018-06-29 14:10:16 -04:00
parent 9fc0d1d701
commit 05cb10530f
6 changed files with 39 additions and 2 deletions

View File

@ -15,6 +15,7 @@
#include "common/microprofile.h" #include "common/microprofile.h"
#include "common/scope_exit.h" #include "common/scope_exit.h"
#include "core/core.h" #include "core/core.h"
#include "core/frontend/emu_window.h"
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/settings.h" #include "core/settings.h"
#include "video_core/engines/maxwell_3d.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/gl_shader_gen.h"
#include "video_core/renderer_opengl/maxwell_to_gl.h" #include "video_core/renderer_opengl/maxwell_to_gl.h"
#include "video_core/renderer_opengl/renderer_opengl.h" #include "video_core/renderer_opengl/renderer_opengl.h"
#include "video_core/video_core.h"
using Maxwell = Tegra::Engines::Maxwell3D::Regs; using Maxwell = Tegra::Engines::Maxwell3D::Regs;
using PixelFormat = SurfaceParams::PixelFormat; using PixelFormat = SurfaceParams::PixelFormat;
@ -394,6 +396,8 @@ void RasterizerOpenGL::Clear() {
if (clear_mask == 0) if (clear_mask == 0)
return; return;
ScopeAcquireGLContext acquire_context;
auto [dirty_color_surface, dirty_depth_surface] = auto [dirty_color_surface, dirty_depth_surface] =
ConfigureFramebuffers(use_color_fb, use_depth_fb); ConfigureFramebuffers(use_color_fb, use_depth_fb);
@ -420,6 +424,8 @@ void RasterizerOpenGL::DrawArrays() {
MICROPROFILE_SCOPE(OpenGL_Drawing); MICROPROFILE_SCOPE(OpenGL_Drawing);
const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
ScopeAcquireGLContext acquire_context;
auto [dirty_color_surface, dirty_depth_surface] = auto [dirty_color_surface, dirty_depth_surface] =
ConfigureFramebuffers(true, regs.zeta.Address() != 0); ConfigureFramebuffers(true, regs.zeta.Address() != 0);

View File

@ -92,11 +92,24 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons
return matrix; 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;
RendererOpenGL::~RendererOpenGL() = default; RendererOpenGL::~RendererOpenGL() = default;
/// Swap buffers (render frame) /// Swap buffers (render frame)
void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) { void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) {
ScopeAcquireGLContext acquire_context;
Core::System::GetInstance().perf_stats.EndSystemFrame(); Core::System::GetInstance().perf_stats.EndSystemFrame();
// Maintain the rasterizer's state as a priority // 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 /// Initialize the renderer
bool RendererOpenGL::Init() { bool RendererOpenGL::Init() {
render_window->MakeCurrent(); ScopeAcquireGLContext acquire_context;
if (GLAD_GL_KHR_debug) { if (GLAD_GL_KHR_debug) {
glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT);

View File

@ -31,6 +31,13 @@ struct ScreenInfo {
TextureInfo texture; TextureInfo texture;
}; };
/// Helper class to acquire/release OpenGL context within a given scope
class ScopeAcquireGLContext : NonCopyable {
public:
ScopeAcquireGLContext();
~ScopeAcquireGLContext();
};
class RendererOpenGL : public RendererBase { class RendererOpenGL : public RendererBase {
public: public:
RendererOpenGL(); RendererOpenGL();

View File

@ -20,7 +20,10 @@
EmuThread::EmuThread(GRenderWindow* render_window) : render_window(render_window) {} EmuThread::EmuThread(GRenderWindow* render_window) : render_window(render_window) {}
void EmuThread::run() { 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"); MicroProfileOnThreadCreate("EmuThread");

View File

@ -374,6 +374,8 @@ bool GMainWindow::LoadROM(const QString& filename) {
const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())}; const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())};
render_window->DoneCurrent();
if (result != Core::System::ResultStatus::Success) { if (result != Core::System::ResultStatus::Success) {
switch (result) { switch (result) {
case Core::System::ResultStatus::ErrorGetLoader: case Core::System::ResultStatus::ErrorGetLoader:
@ -916,6 +918,7 @@ int main(int argc, char* argv[]) {
QCoreApplication::setApplicationName("yuzu"); QCoreApplication::setApplicationName("yuzu");
QApplication::setAttribute(Qt::AA_X11InitThreads); QApplication::setAttribute(Qt::AA_X11InitThreads);
QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
QApplication app(argc, argv); QApplication app(argc, argv);
// Qt changes the locale and causes issues in float conversion using std::to_string() when // Qt changes the locale and causes issues in float conversion using std::to_string() when

View File

@ -148,6 +148,11 @@ int main(int argc, char** argv) {
std::unique_ptr<EmuWindow_SDL2> emu_window{std::make_unique<EmuWindow_SDL2>(fullscreen)}; std::unique_ptr<EmuWindow_SDL2> emu_window{std::make_unique<EmuWindow_SDL2>(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()}; Core::System& system{Core::System::GetInstance()};
SCOPE_EXIT({ system.Shutdown(); }); SCOPE_EXIT({ system.Shutdown(); });