video_core: Disable async shader loading with strict contexts
This commit is contained in:
		| @@ -82,6 +82,8 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(bool fullscreen, bool is_secondary) | ||||
|         exit(1); | ||||
|     } | ||||
|  | ||||
|     strict_context_required = std::strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0; | ||||
|  | ||||
|     dummy_window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, | ||||
|                                     SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); | ||||
|  | ||||
|   | ||||
| @@ -407,6 +407,7 @@ GRenderWindow::GRenderWindow(QWidget* parent_, EmuThread* emu_thread, bool is_se | ||||
|     setLayout(layout); | ||||
|  | ||||
|     this->setMouseTracking(true); | ||||
|     strict_context_required = QGuiApplication::platformName() == QStringLiteral("wayland"); | ||||
|  | ||||
|     GMainWindow* parent = GetMainWindow(); | ||||
|     connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete); | ||||
|   | ||||
| @@ -203,6 +203,10 @@ public: | ||||
|         return active_config; | ||||
|     } | ||||
|  | ||||
|     bool StrictContextRequired() const { | ||||
|         return strict_context_required; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Requests the internal configuration to be replaced by the specified argument at some point in | ||||
|      * the future. | ||||
| @@ -268,6 +272,7 @@ protected: | ||||
|     } | ||||
|  | ||||
|     bool is_secondary{}; | ||||
|     bool strict_context_required{}; | ||||
|     WindowSystemInfo window_info; | ||||
|  | ||||
| private: | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
| #include <thread> | ||||
| #include <unordered_map> | ||||
| #include <variant> | ||||
| #include "common/scope_exit.h" | ||||
| #include "video_core/renderer_opengl/gl_driver.h" | ||||
| #include "video_core/renderer_opengl/gl_resource_manager.h" | ||||
| #include "video_core/renderer_opengl/gl_shader_disk_cache.h" | ||||
| @@ -367,7 +368,9 @@ public: | ||||
|  | ||||
| ShaderProgramManager::ShaderProgramManager(Frontend::EmuWindow& emu_window_, const Driver& driver_, | ||||
|                                            bool separable) | ||||
|     : impl(std::make_unique<Impl>(separable)), emu_window{emu_window_}, driver{driver_} {} | ||||
|     : emu_window{emu_window_}, driver{driver_}, | ||||
|       strict_context_required{emu_window.StrictContextRequired()}, impl{std::make_unique<Impl>( | ||||
|                                                                        separable)} {} | ||||
|  | ||||
| ShaderProgramManager::~ShaderProgramManager() = default; | ||||
|  | ||||
| @@ -622,8 +625,8 @@ void ShaderProgramManager::LoadDiskCache(const std::atomic_bool& stop_loading, | ||||
|     compilation_failed = false; | ||||
|  | ||||
|     std::size_t built_shaders = 0; // It doesn't have be atomic since it's used behind a mutex | ||||
|     const auto LoadRawSepareble = [&](Frontend::GraphicsContext* context, std::size_t begin, | ||||
|                                       std::size_t end) { | ||||
|     const auto LoadRawSepareble = [&](std::size_t begin, std::size_t end, | ||||
|                                       Frontend::GraphicsContext* context = nullptr) { | ||||
|         const auto scope = context->Acquire(); | ||||
|         for (std::size_t i = begin; i < end; ++i) { | ||||
|             if (stop_loading || compilation_failed) { | ||||
| @@ -683,6 +686,7 @@ void ShaderProgramManager::LoadDiskCache(const std::atomic_bool& stop_loading, | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     if (!strict_context_required) { | ||||
|         const std::size_t num_workers{std::max(1U, std::thread::hardware_concurrency())}; | ||||
|         const std::size_t bucket_size{load_raws_size / num_workers}; | ||||
|         std::vector<std::unique_ptr<Frontend::GraphicsContext>> contexts(num_workers); | ||||
| @@ -698,12 +702,16 @@ void ShaderProgramManager::LoadDiskCache(const std::atomic_bool& stop_loading, | ||||
|             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); | ||||
|             threads[i] = std::thread(LoadRawSepareble, start, end, contexts[i].get()); | ||||
|         } | ||||
|         for (auto& thread : threads) { | ||||
|             thread.join(); | ||||
|         } | ||||
|         emu_window.RestoreContext(); | ||||
|     } else { | ||||
|         const auto dummy_context{std::make_unique<Frontend::GraphicsContext>()}; | ||||
|         LoadRawSepareble(0, load_raws_size, dummy_context.get()); | ||||
|     } | ||||
|  | ||||
|     if (compilation_failed) { | ||||
|         disk_cache.InvalidateAll(); | ||||
|   | ||||
| @@ -46,10 +46,10 @@ public: | ||||
|     void ApplyTo(OpenGLState& state); | ||||
|  | ||||
| private: | ||||
|     class Impl; | ||||
|     std::unique_ptr<Impl> impl; | ||||
|  | ||||
|     Frontend::EmuWindow& emu_window; | ||||
|     const Driver& driver; | ||||
|     bool strict_context_required; | ||||
|     class Impl; | ||||
|     std::unique_ptr<Impl> impl; | ||||
| }; | ||||
| } // namespace OpenGL | ||||
|   | ||||
		Reference in New Issue
	
	Block a user