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