From 811d2e6d3b63f7660645e2064e5162f661ba012c Mon Sep 17 00:00:00 2001 From: e2dk4r <43293320+e2dk4r@users.noreply.github.com> Date: Fri, 27 Sep 2024 22:04:08 +0300 Subject: [PATCH] headless: fix vulkan exclusive fullscreen ignored Running in headless mode under wayland (e.g. Sway) compositor, it's not possible to set any resolution other than 1280x720. This is because Ryujinx was not updating default surface dimension when creating swapchain. --- src/Ryujinx.Graphics.Vulkan/Window.cs | 19 +++++++++------ .../Vulkan/VulkanWindow.cs | 24 +++++++++++++++---- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/Ryujinx.Graphics.Vulkan/Window.cs b/src/Ryujinx.Graphics.Vulkan/Window.cs index 3dc6d4e191..65b59dae4e 100644 --- a/src/Ryujinx.Graphics.Vulkan/Window.cs +++ b/src/Ryujinx.Graphics.Vulkan/Window.cs @@ -10,8 +10,8 @@ namespace Ryujinx.Graphics.Vulkan { class Window : WindowBase, IDisposable { - private const int SurfaceWidth = 1280; - private const int SurfaceHeight = 720; + private uint _surfaceWidth = 1280; + private uint _surfaceHeight = 720; private readonly VulkanRenderer _gd; private readonly SurfaceKHR _surface; @@ -295,15 +295,15 @@ namespace Ryujinx.Graphics.Vulkan } } - public static Extent2D ChooseSwapExtent(SurfaceCapabilitiesKHR capabilities) + public Extent2D ChooseSwapExtent(SurfaceCapabilitiesKHR capabilities) { if (capabilities.CurrentExtent.Width != uint.MaxValue) { return capabilities.CurrentExtent; } - uint width = Math.Max(capabilities.MinImageExtent.Width, Math.Min(capabilities.MaxImageExtent.Width, SurfaceWidth)); - uint height = Math.Max(capabilities.MinImageExtent.Height, Math.Min(capabilities.MaxImageExtent.Height, SurfaceHeight)); + uint width = Math.Max(capabilities.MinImageExtent.Width, Math.Min(capabilities.MaxImageExtent.Width, _surfaceWidth)); + uint height = Math.Max(capabilities.MinImageExtent.Height, Math.Min(capabilities.MaxImageExtent.Height, _surfaceHeight)); return new Extent2D(width, height); } @@ -630,8 +630,13 @@ namespace Ryujinx.Graphics.Vulkan public override void SetSize(int width, int height) { - // We don't need to use width and height as we can get the size from the surface. - _swapchainIsDirty = true; + if (width > 0 && height > 0) + { + _surfaceWidth = (uint)width; + _surfaceHeight = (uint)height; + + _swapchainIsDirty = true; + } } public override void ChangeVSyncMode(bool vsyncEnabled) diff --git a/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs b/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs index e5572c936b..f4cdfbeb94 100644 --- a/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs +++ b/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs @@ -29,16 +29,30 @@ namespace Ryujinx.Headless.SDL2.Vulkan protected override void InitializeRenderer() { + int width = DefaultWidth; + int height = DefaultHeight; + if (IsExclusiveFullscreen) { - Renderer?.Window.SetSize(ExclusiveFullscreenWidth, ExclusiveFullscreenHeight); - MouseDriver.SetClientSize(ExclusiveFullscreenWidth, ExclusiveFullscreenHeight); + width = ExclusiveFullscreenWidth; + height = ExclusiveFullscreenHeight; } - else + else if (IsFullscreen) { - Renderer?.Window.SetSize(DefaultWidth, DefaultHeight); - MouseDriver.SetClientSize(DefaultWidth, DefaultHeight); + // NOTE: grabbing the main display's dimensions directly as OpenGL doesn't scale along like the VulkanWindow. + if (SDL_GetDisplayBounds(DisplayId, out SDL_Rect displayBounds) < 0) + { + Logger.Warning?.Print(LogClass.Application, $"Could not retrieve display bounds: {SDL_GetError()}"); + } + else + { + width = displayBounds.w; + height = displayBounds.h; + } } + + Renderer?.Window.SetSize(width, height); + MouseDriver.SetClientSize(width, height); } private static void BasicInvoke(Action action)