OpenGL: Use MakeCurrent/DoneCurrent for multithreaded rendering.
This commit is contained in:
parent
9fc0d1d701
commit
05cb10530f
6 changed files with 39 additions and 2 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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() {
|
||||||
|
if (!Settings::values.use_multi_core) {
|
||||||
|
// Single core mode must acquire OpenGL context for entire emulation session
|
||||||
render_window->MakeCurrent();
|
render_window->MakeCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
MicroProfileOnThreadCreate("EmuThread");
|
MicroProfileOnThreadCreate("EmuThread");
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(); });
|
||||||
|
|
Loading…
Reference in a new issue