diff options
Diffstat (limited to 'src/video_core/renderer_opengl')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 69 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 10 |
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 | ||
| 31 | namespace { | 29 | namespace { |
| 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. | ||
| 35 | constexpr std::size_t SWAP_CHAIN_SIZE = 3; | 31 | constexpr std::size_t SWAP_CHAIN_SIZE = 3; |
| 36 | 32 | ||
| 37 | struct Frame { | 33 | struct 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 | |||
| 321 | private: | ||
| 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 | ||
| 349 | RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system) | 314 | RendererOpenGL::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 | ||
| 353 | RendererOpenGL::~RendererOpenGL() = default; | 319 | RendererOpenGL::~RendererOpenGL() = default; |
| 354 | 320 | ||
| @@ -356,8 +322,6 @@ MICROPROFILE_DEFINE(OpenGL_RenderFrame, "OpenGL", "Render Frame", MP_RGB(128, 12 | |||
| 356 | MICROPROFILE_DEFINE(OpenGL_WaitPresent, "OpenGL", "Wait For Present", MP_RGB(128, 128, 128)); | 322 | MICROPROFILE_DEFINE(OpenGL_WaitPresent, "OpenGL", "Wait For Present", MP_RGB(128, 128, 128)); |
| 357 | 323 | ||
| 358 | void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | 324 | void 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 | ||
| 418 | void RendererOpenGL::PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer) { | 389 | void 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 | ||
| 482 | void RendererOpenGL::InitOpenGLObjects() { | 453 | void 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 | ||
| 695 | void RendererOpenGL::TryPresent(int timeout_ms) { | 668 | bool 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 | |||
| 677 | bool 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 | ||
| 730 | void RendererOpenGL::RenderScreenshot() { | 713 | void 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 | ||
| 56 | class RendererOpenGL final : public VideoCore::RendererBase { | 56 | class RendererOpenGL final : public VideoCore::RendererBase { |
| 57 | public: | 57 | public: |
| 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 | ||
| 66 | private: | 67 | private: |
| 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 |