From ff81fb04b40649febff6ed986c33d79a856868dc Mon Sep 17 00:00:00 2001 From: pawelniegowski Date: Fri, 29 Jul 2022 12:26:18 +0200 Subject: [PATCH] Fix MakeCurrent and shader issues with AMD 22.7 driver --- src/citra/emu_window/emu_window_sdl2.cpp | 10 +++++++++- src/citra/emu_window/emu_window_sdl2.h | 8 ++++++++ src/citra_qt/bootmanager.cpp | 2 ++ src/core/frontend/emu_window.h | 10 ++++++++++ src/video_core/renderer_opengl/gl_shader_manager.cpp | 5 +++++ src/video_core/renderer_opengl/gl_shader_util.cpp | 2 +- 6 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/citra/emu_window/emu_window_sdl2.cpp b/src/citra/emu_window/emu_window_sdl2.cpp index 98045c3c6..e5a0594c4 100644 --- a/src/citra/emu_window/emu_window_sdl2.cpp +++ b/src/citra/emu_window/emu_window_sdl2.cpp @@ -30,7 +30,6 @@ SharedContext_SDL2::SharedContext_SDL2() { } SharedContext_SDL2::~SharedContext_SDL2() { - DoneCurrent(); SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); } @@ -185,6 +184,7 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) { window_context = SDL_GL_CreateContext(render_window); core_context = CreateSharedContext(); + last_saved_context = nullptr; if (window_context == nullptr) { LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context: {}", SDL_GetError()); @@ -222,6 +222,14 @@ std::unique_ptr EmuWindow_SDL2::CreateSharedContext() return std::make_unique(); } +void EmuWindow_SDL2::SaveContext() { + last_saved_context = SDL_GL_GetCurrentContext(); +} + +void EmuWindow_SDL2::RestoreContext() { + SDL_GL_MakeCurrent(render_window, last_saved_context); +} + void EmuWindow_SDL2::Present() { SDL_GL_MakeCurrent(render_window, window_context); SDL_GL_SetSwapInterval(1); diff --git a/src/citra/emu_window/emu_window_sdl2.h b/src/citra/emu_window/emu_window_sdl2.h index b0834fd06..64dec5381 100644 --- a/src/citra/emu_window/emu_window_sdl2.h +++ b/src/citra/emu_window/emu_window_sdl2.h @@ -49,6 +49,11 @@ public: /// Creates a new context that is shared with the current context std::unique_ptr CreateSharedContext() const override; + /// Saves the current context, for the purpose of e.g. creating new shared contexts + void SaveContext() override; + /// Restores the context previously saved + void RestoreContext() override; + private: /// Called by PollEvents when a key is pressed or released. void OnKeyEvent(int key, u8 state); @@ -94,6 +99,9 @@ private: /// The OpenGL context associated with the window SDL_GLContext window_context; + /// Used by SaveContext and RestoreContext + SDL_GLContext last_saved_context; + /// The OpenGL context associated with the core std::unique_ptr core_context; diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 8b4c145bf..3a3eeb322 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -53,6 +53,8 @@ void EmuThread::run() { emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); + core_context.MakeCurrent(); + if (Core::System::GetInstance().frame_limiter.IsFrameAdvancing()) { // Usually the loading screen is hidden after the first frame is drawn. In this case // we hide it immediately as we need to wait for user input to start the emulation. diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index 326563655..0bf3b5115 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -111,6 +111,16 @@ public: return nullptr; } + /** + * Save current GraphicsContext. + */ + virtual void SaveContext() {}; + + /** + * Restore saved GraphicsContext. + */ + virtual void RestoreContext() {}; + /** * Signal that a touch pressed event has occurred (e.g. mouse click pressed) * @param framebuffer_x Framebuffer x-coordinate that was pressed diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 7f49e9b73..f019bc80e 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp @@ -706,6 +706,8 @@ void ShaderProgramManager::LoadDiskCache(const std::atomic_bool& stop_loading, const std::size_t bucket_size{load_raws_size / num_workers}; std::vector> contexts(num_workers); std::vector threads(num_workers); + + emu_window.SaveContext(); for (std::size_t i = 0; i < num_workers; ++i) { const bool is_last_worker = i + 1 == num_workers; const std::size_t start{bucket_size * i}; @@ -713,11 +715,14 @@ void ShaderProgramManager::LoadDiskCache(const std::atomic_bool& stop_loading, // On some platforms the shared context has to be created from the GUI thread contexts[i] = emu_window.CreateSharedContext(); + // Release the context, so it can be immediately used by the spawned thread + contexts[i]->DoneCurrent(); threads[i] = std::thread(LoadRawSepareble, contexts[i].get(), start, end); } for (auto& thread : threads) { thread.join(); } + emu_window.RestoreContext(); if (compilation_failed) { disk_cache.InvalidateAll(); diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp index 036cd49a3..ff75e1eab 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.cpp +++ b/src/video_core/renderer_opengl/gl_shader_util.cpp @@ -26,7 +26,7 @@ GLuint LoadShader(const char* source, GLenum type) { #extension GL_EXT_clip_cull_distance : enable #endif // defined(GL_EXT_clip_cull_distance) )" - : "#version 330\n"; + : "#version 430\n"; const char* debug_type; switch (type) {