From d5f53da79d944869eb88416494ecf10a47eee90d Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 13 Dec 2022 12:30:15 -0500 Subject: [PATCH 1/7] renderer_opengl: refactor context acquire --- src/video_core/gpu.cpp | 5 +- src/video_core/renderer_opengl/gl_device.cpp | 10 ++- src/video_core/renderer_opengl/gl_device.h | 5 ++ .../renderer_opengl/gl_shader_cache.cpp | 76 +++++++++++-------- .../renderer_opengl/gl_shader_cache.h | 1 + src/yuzu/bootmanager.cpp | 3 +- 6 files changed, 62 insertions(+), 38 deletions(-) diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 28b38273e8..c6d54be638 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -223,8 +223,6 @@ struct GPU::Impl { /// core timing events. void Start() { gpu_thread.StartThread(*renderer, renderer->Context(), *scheduler); - cpu_context = renderer->GetRenderWindow().CreateSharedContext(); - cpu_context->MakeCurrent(); } void NotifyShutdown() { @@ -235,6 +233,9 @@ struct GPU::Impl { /// Obtain the CPU Context void ObtainContext() { + if (!cpu_context) { + cpu_context = renderer->GetRenderWindow().CreateSharedContext(); + } cpu_context->MakeCurrent(); } diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index e2e3dac345..4c5020defc 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp @@ -126,9 +126,11 @@ Device::Device() { const bool is_intel = vendor_name == "Intel"; #ifdef __unix__ - const bool is_linux = true; + constexpr bool is_linux = true; + const bool is_wayland = strcasecmp(getenv("XDG_SESSION_TYPE"), "wayland") == 0; #else - const bool is_linux = false; + constexpr bool is_linux = false; + constexpr bool is_wayland = false; #endif bool disable_fast_buffer_sub_data = false; @@ -194,9 +196,11 @@ Device::Device() { } // Blocks AMD and Intel OpenGL drivers on Windows from using asynchronous shader compilation. + // Blocks EGL on Wayland from using asynchronous shader compilation. use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() && - !(is_amd || (is_intel && !is_linux)); + !(is_amd || (is_intel && !is_linux)) && !is_wayland; use_driver_cache = is_nvidia; + strict_context_required = is_wayland; LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index 5ef51ebcf3..adb79c56e8 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h @@ -173,6 +173,10 @@ public: return can_report_memory; } + bool StrictContextRequired() const { + return strict_context_required; + } + private: static bool TestVariableAoffi(); static bool TestPreciseBug(); @@ -216,6 +220,7 @@ private: bool has_cbuf_ftou_bug{}; bool has_bool_ref_bug{}; bool can_report_memory{}; + bool strict_context_required{}; std::string vendor_name; }; diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index a59d0d24e0..fff55d585e 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -174,6 +174,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, program_manager{program_manager_}, state_tracker{state_tracker_}, shader_notify{shader_notify_}, use_asynchronous_shaders{device.UseAsynchronousShaders()}, + strict_context_required{device.StrictContextRequired()}, profile{ .supported_spirv = 0x00010000, @@ -255,9 +256,14 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading, } shader_cache_filename = base_dir / "opengl.bin"; - if (!workers) { + if (!workers && !strict_context_required) { workers = CreateWorkers(); } + std::optional strict_context; + if (strict_context_required) { + strict_context.emplace(emu_window); + } + struct { std::mutex mutex; size_t total{}; @@ -265,44 +271,49 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading, bool has_loaded{}; } state; + const auto queue_work{[&](Common::UniqueFunction&& work) { + if (strict_context_required) { + work(&strict_context.value()); + } else { + workers->QueueWork(std::move(work)); + } + }}; const auto load_compute{[&](std::ifstream& file, FileEnvironment env) { ComputePipelineKey key; file.read(reinterpret_cast(&key), sizeof(key)); - workers->QueueWork( - [this, key, env = std::move(env), &state, &callback](Context* ctx) mutable { - ctx->pools.ReleaseContents(); - auto pipeline{CreateComputePipeline(ctx->pools, key, env)}; - std::scoped_lock lock{state.mutex}; - if (pipeline) { - compute_cache.emplace(key, std::move(pipeline)); - } - ++state.built; - if (state.has_loaded) { - callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); - } - }); + queue_work([this, key, env = std::move(env), &state, &callback](Context* ctx) mutable { + ctx->pools.ReleaseContents(); + auto pipeline{CreateComputePipeline(ctx->pools, key, env)}; + std::scoped_lock lock{state.mutex}; + if (pipeline) { + compute_cache.emplace(key, std::move(pipeline)); + } + ++state.built; + if (state.has_loaded) { + callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); + } + }); ++state.total; }}; const auto load_graphics{[&](std::ifstream& file, std::vector envs) { GraphicsPipelineKey key; file.read(reinterpret_cast(&key), sizeof(key)); - workers->QueueWork( - [this, key, envs = std::move(envs), &state, &callback](Context* ctx) mutable { - boost::container::static_vector env_ptrs; - for (auto& env : envs) { - env_ptrs.push_back(&env); - } - ctx->pools.ReleaseContents(); - auto pipeline{CreateGraphicsPipeline(ctx->pools, key, MakeSpan(env_ptrs), false)}; - std::scoped_lock lock{state.mutex}; - if (pipeline) { - graphics_cache.emplace(key, std::move(pipeline)); - } - ++state.built; - if (state.has_loaded) { - callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); - } - }); + queue_work([this, key, envs = std::move(envs), &state, &callback](Context* ctx) mutable { + boost::container::static_vector env_ptrs; + for (auto& env : envs) { + env_ptrs.push_back(&env); + } + ctx->pools.ReleaseContents(); + auto pipeline{CreateGraphicsPipeline(ctx->pools, key, MakeSpan(env_ptrs), false)}; + std::scoped_lock lock{state.mutex}; + if (pipeline) { + graphics_cache.emplace(key, std::move(pipeline)); + } + ++state.built; + if (state.has_loaded) { + callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); + } + }); ++state.total; }}; LoadPipelines(stop_loading, shader_cache_filename, CACHE_VERSION, load_compute, load_graphics); @@ -314,6 +325,9 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading, state.has_loaded = true; lock.unlock(); + if (strict_context_required) { + return; + } workers->WaitForRequests(stop_loading); if (!use_asynchronous_shaders) { workers.reset(); diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 53ffea904d..f824205922 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h @@ -69,6 +69,7 @@ private: StateTracker& state_tracker; VideoCore::ShaderNotify& shader_notify; const bool use_asynchronous_shaders; + const bool strict_context_required; GraphicsPipelineKey graphics_key{}; GraphicsPipeline* current_pipeline{}; diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 5b5b6fed86..1437dec88f 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -61,8 +61,6 @@ void EmuThread::run() { // Main process has been loaded. Make the context current to this thread and begin GPU and CPU // execution. - gpu.Start(); - gpu.ObtainContext(); emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); @@ -77,6 +75,7 @@ void EmuThread::run() { emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); gpu.ReleaseContext(); + gpu.Start(); system.GetCpuManager().OnGpuReady(); From 3cc3176ad6549c412f2370f496f00f1f6849275c Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Tue, 13 Dec 2022 13:08:02 -0500 Subject: [PATCH 2/7] video_core/vulkan: Explicity check swapchain size when deciding to recreate Vulkan for whatever reason does not return VK_ERROR_OUT_OF_DATE_KHR when the swapchain is the wrong size. Explicity make sure the size is indeed up to date to workaround this. --- .../renderer_vulkan/renderer_vulkan.cpp | 14 ++++++++------ src/video_core/renderer_vulkan/vk_swapchain.cpp | 15 ++++++++------- src/video_core/renderer_vulkan/vk_swapchain.h | 14 ++++++++++++-- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 18be547294..f502a7d09a 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -139,23 +139,25 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { RenderScreenshot(*framebuffer, use_accelerated); bool has_been_recreated = false; - const auto recreate_swapchain = [&] { + const auto recreate_swapchain = [&](u32 width, u32 height) { if (!has_been_recreated) { has_been_recreated = true; scheduler.Finish(); } - const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout(); - swapchain.Create(layout.width, layout.height, is_srgb); + swapchain.Create(width, height, is_srgb); }; - if (swapchain.NeedsRecreation(is_srgb)) { - recreate_swapchain(); + + const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout(); + if (swapchain.NeedsRecreation(is_srgb) || swapchain.GetWidth() != layout.width || + swapchain.GetHeight() != layout.height) { + recreate_swapchain(layout.width, layout.height); } bool is_outdated; do { swapchain.AcquireNextImage(); is_outdated = swapchain.IsOutDated(); if (is_outdated) { - recreate_swapchain(); + recreate_swapchain(layout.width, layout.height); } } while (is_outdated); if (has_been_recreated) { diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index d7be417f5c..b6810eef9a 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -67,17 +67,19 @@ VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 wi } // Anonymous namespace -Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, u32 width, - u32 height, bool srgb) +Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, + u32 width_, u32 height_, bool srgb) : surface{surface_}, device{device_}, scheduler{scheduler_} { - Create(width, height, srgb); + Create(width_, height_, srgb); } Swapchain::~Swapchain() = default; -void Swapchain::Create(u32 width, u32 height, bool srgb) { +void Swapchain::Create(u32 width_, u32 height_, bool srgb) { is_outdated = false; is_suboptimal = false; + width = width_; + height = height_; const auto physical_device = device.GetPhysical(); const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)}; @@ -88,7 +90,7 @@ void Swapchain::Create(u32 width, u32 height, bool srgb) { device.GetLogical().WaitIdle(); Destroy(); - CreateSwapchain(capabilities, width, height, srgb); + CreateSwapchain(capabilities, srgb); CreateSemaphores(); CreateImageViews(); @@ -148,8 +150,7 @@ void Swapchain::Present(VkSemaphore render_semaphore) { } } -void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height, - bool srgb) { +void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bool srgb) { const auto physical_device{device.GetPhysical()}; const auto formats{physical_device.GetSurfaceFormatsKHR(surface)}; const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h index 111b3902d6..caf1ff32b8 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.h +++ b/src/video_core/renderer_vulkan/vk_swapchain.h @@ -80,9 +80,16 @@ public: return *present_semaphores[frame_index]; } + u32 GetWidth() const { + return width; + } + + u32 GetHeight() const { + return height; + } + private: - void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height, - bool srgb); + void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bool srgb); void CreateSemaphores(); void CreateImageViews(); @@ -105,6 +112,9 @@ private: std::vector resource_ticks; std::vector present_semaphores; + u32 width; + u32 height; + u32 image_index{}; u32 frame_index{}; From 5754456292e920810e3b036b851c05c5332353ce Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Sun, 20 Nov 2022 17:46:53 -0500 Subject: [PATCH 3/7] emu_window_sdl2: Respect hidpi Use SDL_GL_GetDrawableSize instead of SDL_GetWindowSize which will return the true size our swapchain needs to be in even for hidpi displays. --- src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 37dd1747c1..31f28a5075 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -115,7 +115,7 @@ bool EmuWindow_SDL2::IsShown() const { void EmuWindow_SDL2::OnResize() { int width, height; - SDL_GetWindowSize(render_window, &width, &height); + SDL_GL_GetDrawableSize(render_window, &width, &height); UpdateCurrentFramebufferLayout(width, height); } From 29fbce9fe6007ca0d7aafebb47fe9c5edbfe9393 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Mon, 12 Dec 2022 22:18:26 -0500 Subject: [PATCH 4/7] RenderWidget: Set WA_DontCreateNativeAncestors Some windowing systems like wayland are designed to show hardware accellerated surfaces as subsurfaces and not native windows. --- src/yuzu/bootmanager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 1437dec88f..d2103e86f9 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -223,6 +223,7 @@ class RenderWidget : public QWidget { public: explicit RenderWidget(GRenderWindow* parent) : QWidget(parent), render_window(parent) { setAttribute(Qt::WA_NativeWindow); + setAttribute(Qt::WA_DontCreateNativeAncestors); setAttribute(Qt::WA_PaintOnScreen); } From 45fcde817e0455b2e92ee86417688e53a6742b4b Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Tue, 13 Dec 2022 13:17:19 -0500 Subject: [PATCH 5/7] wayland: Always use exclusive fullscreen Wayland does not allow clients to choose their own size and position on the screen. The concept of fullscreening an application by sizing it to the screen and removing decorations does not exist. Use exclusive fullscreen instead. --- src/yuzu/main.cpp | 13 +++++++++---- src/yuzu/main.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 6c204416fa..885e24990c 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -2915,9 +2915,14 @@ static QScreen* GuessCurrentScreen(QWidget* window) { }); } +bool GMainWindow::UsingExclusiveFullscreen() { + return Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive || + QGuiApplication::platformName() == QStringLiteral("wayland"); +} + void GMainWindow::ShowFullscreen() { - const auto show_fullscreen = [](QWidget* window) { - if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { + const auto show_fullscreen = [this](QWidget* window) { + if (UsingExclusiveFullscreen()) { window->showFullScreen(); return; } @@ -2945,7 +2950,7 @@ void GMainWindow::ShowFullscreen() { void GMainWindow::HideFullscreen() { if (ui->action_Single_Window_Mode->isChecked()) { - if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { + if (UsingExclusiveFullscreen()) { showNormal(); restoreGeometry(UISettings::values.geometry); } else { @@ -2959,7 +2964,7 @@ void GMainWindow::HideFullscreen() { statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked()); ui->menubar->show(); } else { - if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { + if (UsingExclusiveFullscreen()) { render_window->showNormal(); render_window->restoreGeometry(UISettings::values.renderwindow_geometry); } else { diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 62d629973a..27644fae5f 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -320,6 +320,7 @@ private slots: void OnDisplayTitleBars(bool); void InitializeHotkeys(); void ToggleFullscreen(); + bool UsingExclusiveFullscreen(); void ShowFullscreen(); void HideFullscreen(); void ToggleWindowMode(); From 2221afaf265c15d0d3a2e551f172bed6567fc11a Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Tue, 13 Dec 2022 13:17:44 -0500 Subject: [PATCH 6/7] OpenGL: Check for threading support We need this. --- src/yuzu/bootmanager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index d2103e86f9..0ba7fff7a3 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -952,6 +952,12 @@ void GRenderWindow::OnMinimalClientAreaChangeRequest(std::pair minimal bool GRenderWindow::InitializeOpenGL() { #ifdef HAS_OPENGL + if (!QOpenGLContext::supportsThreadedOpenGL()) { + QMessageBox::warning(this, tr("OpenGL not available!"), + tr("OpenGL shared contexts are not supported.")); + return false; + } + // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground, // WA_DontShowOnScreen, WA_DeleteOnClose auto child = new OpenGLRenderWidget(this); From 09e3029c1118616394e5e9c45dfcdd4adcdf86ad Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Tue, 13 Dec 2022 14:39:03 -0500 Subject: [PATCH 7/7] gl_device: Use a more robust way to use strict context mode Instead of checking a environment variable which may not actually exist or is just wrong, ask QT if it's running on the wayland platform. --- src/core/frontend/emu_window.h | 6 ++++++ src/video_core/renderer_opengl/gl_device.cpp | 8 +++----- src/video_core/renderer_opengl/gl_device.h | 3 ++- src/video_core/renderer_opengl/renderer_opengl.cpp | 4 ++-- src/yuzu/bootmanager.cpp | 2 ++ src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp | 2 ++ 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index 95363b645e..cf85ba29eb 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -131,6 +131,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. @@ -207,6 +211,8 @@ protected: WindowSystemInfo window_info; + bool strict_context_required = false; + private: /** * Handler called when the minimal client area was requested to be changed via SetConfig. diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index 4c5020defc..cee5c32470 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp @@ -112,7 +112,7 @@ bool IsASTCSupported() { } } // Anonymous namespace -Device::Device() { +Device::Device(Core::Frontend::EmuWindow& emu_window) { if (!GLAD_GL_VERSION_4_6) { LOG_ERROR(Render_OpenGL, "OpenGL 4.6 is not available"); throw std::runtime_error{"Insufficient version"}; @@ -127,10 +127,8 @@ Device::Device() { #ifdef __unix__ constexpr bool is_linux = true; - const bool is_wayland = strcasecmp(getenv("XDG_SESSION_TYPE"), "wayland") == 0; #else constexpr bool is_linux = false; - constexpr bool is_wayland = false; #endif bool disable_fast_buffer_sub_data = false; @@ -195,12 +193,12 @@ Device::Device() { } } + strict_context_required = emu_window.StrictContextRequired(); // Blocks AMD and Intel OpenGL drivers on Windows from using asynchronous shader compilation. // Blocks EGL on Wayland from using asynchronous shader compilation. use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() && - !(is_amd || (is_intel && !is_linux)) && !is_wayland; + !(is_amd || (is_intel && !is_linux)) && !strict_context_required; use_driver_cache = is_nvidia; - strict_context_required = is_wayland; LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index adb79c56e8..2a72d84be0 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h @@ -5,6 +5,7 @@ #include #include "common/common_types.h" +#include "core/frontend/emu_window.h" #include "shader_recompiler/stage.h" namespace Settings { @@ -15,7 +16,7 @@ namespace OpenGL { class Device { public: - explicit Device(); + explicit Device(Core::Frontend::EmuWindow& emu_window); [[nodiscard]] std::string GetVendorName() const; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 5b5e178adf..bc75680f0a 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -140,8 +140,8 @@ RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_, Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, std::unique_ptr context_) : RendererBase{emu_window_, std::move(context_)}, telemetry_session{telemetry_session_}, - emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, state_tracker{}, - program_manager{device}, + emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, device{emu_window_}, + state_tracker{}, program_manager{device}, rasterizer(emu_window, gpu, cpu_memory, device, screen_info, program_manager, state_tracker) { if (Settings::values.renderer_debug && GLAD_GL_KHR_debug) { glEnable(GL_DEBUG_OUTPUT); diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 0ba7fff7a3..1a47fb9c96 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -314,6 +314,8 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_, input_subsystem->Initialize(); this->setMouseTracking(true); + strict_context_required = QGuiApplication::platformName() == QStringLiteral("wayland"); + connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete); connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram, Qt::QueuedConnection); diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 9b660c13ce..ddcb048d64 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -104,6 +104,8 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste exit(1); } + strict_context_required = strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0; + SetWindowIcon(); if (fullscreen) {