summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp5
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp69
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h10
3 files changed, 36 insertions, 48 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index e3d31c3eb..8f59e0442 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -305,7 +305,6 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
305 } 305 }
306 306
307 const std::vector gl_cache = disk_cache.LoadPrecompiled(); 307 const std::vector gl_cache = disk_cache.LoadPrecompiled();
308 const auto supported_formats = GetSupportedFormats();
309 308
310 // Track if precompiled cache was altered during loading to know if we have to 309 // Track if precompiled cache was altered during loading to know if we have to
311 // serialize the virtual precompiled cache file back to the hard drive 310 // serialize the virtual precompiled cache file back to the hard drive
@@ -327,8 +326,8 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
327 326
328 const auto worker = [&](Core::Frontend::GraphicsContext* context, std::size_t begin, 327 const auto worker = [&](Core::Frontend::GraphicsContext* context, std::size_t begin,
329 std::size_t end) { 328 std::size_t end) {
330 context->MakeCurrent(); 329 const auto scope = context->Acquire();
331 SCOPE_EXIT({ return context->DoneCurrent(); }); 330 const auto supported_formats = GetSupportedFormats();
332 331
333 for (std::size_t i = begin; i < end; ++i) { 332 for (std::size_t i = begin; i < end; ++i) {
334 if (stop_loading) { 333 if (stop_loading) {
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index fca5e3ec0..6f08803c1 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -7,9 +7,7 @@
7#include <cstdlib> 7#include <cstdlib>
8#include <cstring> 8#include <cstring>
9#include <memory> 9#include <memory>
10
11#include <glad/glad.h> 10#include <glad/glad.h>
12
13#include "common/assert.h" 11#include "common/assert.h"
14#include "common/logging/log.h" 12#include "common/logging/log.h"
15#include "common/microprofile.h" 13#include "common/microprofile.h"
@@ -30,8 +28,6 @@ namespace OpenGL {
30 28
31namespace { 29namespace {
32 30
33// If the size of this is too small, it ends up creating a soft cap on FPS as the renderer will have
34// to wait on available presentation frames.
35constexpr std::size_t SWAP_CHAIN_SIZE = 3; 31constexpr std::size_t SWAP_CHAIN_SIZE = 3;
36 32
37struct Frame { 33struct Frame {
@@ -214,7 +210,7 @@ public:
214 std::deque<Frame*> present_queue; 210 std::deque<Frame*> present_queue;
215 Frame* previous_frame{}; 211 Frame* previous_frame{};
216 212
217 FrameMailbox() : has_debug_tool{HasDebugTool()} { 213 FrameMailbox() {
218 for (auto& frame : swap_chain) { 214 for (auto& frame : swap_chain) {
219 free_queue.push(&frame); 215 free_queue.push(&frame);
220 } 216 }
@@ -285,13 +281,9 @@ public:
285 std::unique_lock lock{swap_chain_lock}; 281 std::unique_lock lock{swap_chain_lock};
286 present_queue.push_front(frame); 282 present_queue.push_front(frame);
287 present_cv.notify_one(); 283 present_cv.notify_one();
288
289 DebugNotifyNextFrame();
290 } 284 }
291 285
292 Frame* TryGetPresentFrame(int timeout_ms) { 286 Frame* TryGetPresentFrame(int timeout_ms) {
293 DebugWaitForNextFrame();
294
295 std::unique_lock lock{swap_chain_lock}; 287 std::unique_lock lock{swap_chain_lock};
296 // wait for new entries in the present_queue 288 // wait for new entries in the present_queue
297 present_cv.wait_for(lock, std::chrono::milliseconds(timeout_ms), 289 present_cv.wait_for(lock, std::chrono::milliseconds(timeout_ms),
@@ -317,38 +309,12 @@ public:
317 previous_frame = frame; 309 previous_frame = frame;
318 return frame; 310 return frame;
319 } 311 }
320
321private:
322 std::mutex debug_synch_mutex;
323 std::condition_variable debug_synch_condition;
324 std::atomic_int frame_for_debug{};
325 const bool has_debug_tool; // When true, using a GPU debugger, so keep frames in lock-step
326
327 /// Signal that a new frame is available (called from GPU thread)
328 void DebugNotifyNextFrame() {
329 if (!has_debug_tool) {
330 return;
331 }
332 frame_for_debug++;
333 std::lock_guard lock{debug_synch_mutex};
334 debug_synch_condition.notify_one();
335 }
336
337 /// Wait for a new frame to be available (called from presentation thread)
338 void DebugWaitForNextFrame() {
339 if (!has_debug_tool) {
340 return;
341 }
342 const int last_frame = frame_for_debug;
343 std::unique_lock lock{debug_synch_mutex};
344 debug_synch_condition.wait(lock,
345 [this, last_frame] { return frame_for_debug > last_frame; });
346 }
347}; 312};
348 313
349RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system) 314RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system,
350 : VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system}, 315 Core::Frontend::GraphicsContext& context)
351 frame_mailbox{std::make_unique<FrameMailbox>()} {} 316 : VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system}, frame_mailbox{},
317 has_debug_tool{HasDebugTool()}, context{context} {}
352 318
353RendererOpenGL::~RendererOpenGL() = default; 319RendererOpenGL::~RendererOpenGL() = default;
354 320
@@ -356,8 +322,6 @@ MICROPROFILE_DEFINE(OpenGL_RenderFrame, "OpenGL", "Render Frame", MP_RGB(128, 12
356MICROPROFILE_DEFINE(OpenGL_WaitPresent, "OpenGL", "Wait For Present", MP_RGB(128, 128, 128)); 322MICROPROFILE_DEFINE(OpenGL_WaitPresent, "OpenGL", "Wait For Present", MP_RGB(128, 128, 128));
357 323
358void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { 324void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
359 render_window.PollEvents();
360
361 if (!framebuffer) { 325 if (!framebuffer) {
362 return; 326 return;
363 } 327 }
@@ -413,6 +377,13 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
413 m_current_frame++; 377 m_current_frame++;
414 rasterizer->TickFrame(); 378 rasterizer->TickFrame();
415 } 379 }
380
381 render_window.PollEvents();
382 if (has_debug_tool) {
383 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
384 Present(0);
385 context.SwapBuffers();
386 }
416} 387}
417 388
418void RendererOpenGL::PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer) { 389void RendererOpenGL::PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer) {
@@ -480,6 +451,8 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color
480} 451}
481 452
482void RendererOpenGL::InitOpenGLObjects() { 453void RendererOpenGL::InitOpenGLObjects() {
454 frame_mailbox = std::make_unique<FrameMailbox>();
455
483 glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, 456 glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
484 0.0f); 457 0.0f);
485 458
@@ -692,12 +665,21 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
692 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 665 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
693} 666}
694 667
695void RendererOpenGL::TryPresent(int timeout_ms) { 668bool RendererOpenGL::TryPresent(int timeout_ms) {
669 if (has_debug_tool) {
670 LOG_DEBUG(Render_OpenGL,
671 "Skipping presentation because we are presenting on the main context");
672 return false;
673 }
674 return Present(timeout_ms);
675}
676
677bool RendererOpenGL::Present(int timeout_ms) {
696 const auto& layout = render_window.GetFramebufferLayout(); 678 const auto& layout = render_window.GetFramebufferLayout();
697 auto frame = frame_mailbox->TryGetPresentFrame(timeout_ms); 679 auto frame = frame_mailbox->TryGetPresentFrame(timeout_ms);
698 if (!frame) { 680 if (!frame) {
699 LOG_DEBUG(Render_OpenGL, "TryGetPresentFrame returned no frame to present"); 681 LOG_DEBUG(Render_OpenGL, "TryGetPresentFrame returned no frame to present");
700 return; 682 return false;
701 } 683 }
702 684
703 // Clearing before a full overwrite of a fbo can signal to drivers that they can avoid a 685 // Clearing before a full overwrite of a fbo can signal to drivers that they can avoid a
@@ -725,6 +707,7 @@ void RendererOpenGL::TryPresent(int timeout_ms) {
725 glFlush(); 707 glFlush();
726 708
727 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); 709 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
710 return true;
728} 711}
729 712
730void RendererOpenGL::RenderScreenshot() { 713void RendererOpenGL::RenderScreenshot() {
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 33073ce5b..50b647661 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -55,13 +55,14 @@ class FrameMailbox;
55 55
56class RendererOpenGL final : public VideoCore::RendererBase { 56class RendererOpenGL final : public VideoCore::RendererBase {
57public: 57public:
58 explicit RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system); 58 explicit RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system,
59 Core::Frontend::GraphicsContext& context);
59 ~RendererOpenGL() override; 60 ~RendererOpenGL() override;
60 61
61 bool Init() override; 62 bool Init() override;
62 void ShutDown() override; 63 void ShutDown() override;
63 void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override; 64 void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
64 void TryPresent(int timeout_ms) override; 65 bool TryPresent(int timeout_ms) override;
65 66
66private: 67private:
67 /// Initializes the OpenGL state and creates persistent objects. 68 /// Initializes the OpenGL state and creates persistent objects.
@@ -89,8 +90,11 @@ private:
89 90
90 void PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer); 91 void PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer);
91 92
93 bool Present(int timeout_ms);
94
92 Core::Frontend::EmuWindow& emu_window; 95 Core::Frontend::EmuWindow& emu_window;
93 Core::System& system; 96 Core::System& system;
97 Core::Frontend::GraphicsContext& context;
94 98
95 StateTracker state_tracker{system}; 99 StateTracker state_tracker{system};
96 100
@@ -115,6 +119,8 @@ private:
115 119
116 /// Frame presentation mailbox 120 /// Frame presentation mailbox
117 std::unique_ptr<FrameMailbox> frame_mailbox; 121 std::unique_ptr<FrameMailbox> frame_mailbox;
122
123 bool has_debug_tool = false;
118}; 124};
119 125
120} // namespace OpenGL 126} // namespace OpenGL