Skip to content

Swapchain resize doesn't work in Wayland #10449

Description

@AlexRamallo

⚠️ Issues not using this template will be systematically closed.

Describe the bug
The function VulkanPlatformSurfaceSwapChain::hasResized is used to detect when to resize the swapchain, which doesn't work under Wayland (background info here). The result is that when window geometry changes, the output is warped. It seems vkGetPhysicalDeviceSurfaceCapabilitiesKHR always returns undefined values for the extent, and there's an mFallbackExtent variable to deal with it, but that's fixed at swapchain creation time.

I hacked together a simple workaround and can at least confirm that specifying the extent manually fixes the issue. Snippet:

// filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp
extern "C"
{
    // these are set in SDLDisplayManager during SDL_WINDOWEVENT_RESIZED
    bool g_vkSWHasResized = false;
    int g_vkSWHasResized_Width = 1024;
    int g_vkSWHasResized_Height = 768;
}

bool VulkanPlatformSurfaceSwapChain::hasResized() const {
    if(g_vkSWHasResized)
    {
        g_vkSWHasResized = false;
        const_cast<VkExtent2D&>(mFallbackExtent).width = g_vkSWHasResized_Width;
        const_cast<VkExtent2D&>(mFallbackExtent).height = g_vkSWHasResized_Height;
        return true;
    }

    VkSurfaceCapabilitiesKHR caps;
    vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDevice, mSurface, &caps);
    VkExtent2D perceivedExtent = caps.currentExtent;
    // Create the low-level swap chain.
    if (perceivedExtent.width == VULKAN_UNDEFINED_EXTENT
            || perceivedExtent.height == VULKAN_UNDEFINED_EXTENT) {
        perceivedExtent = mFallbackExtent;
    }
    return !fvkutils::equivalent(mSwapChainBundle.extent, perceivedExtent);
}

Since this class already has a handle to the mNativeWindow, I think the easiest solution that wouldn't break any APIs would be to similar to the above hack, except have it read the size from the native window structure. Since the client already owns this object, it's trivial for them to update it in response to window events.

To Reproduce
Steps to reproduce the behavior:

  1. Replace the built in SDL2 with a system version (filament's SDL is old and crashes with wayland)
  2. Build any sample app with -DFILAMENT_SUPPORTS_WAYLAND=ON
  3. Run it with the environment variable SDL_VIDEODRIVER=wayland

Expected behavior
Resizing the window also resizes the swapchain

Screenshots
Scaling the window down:
Image

Same, but with the hack shown above:

Image

Logs
N/A

Desktop (please complete the following information):

  • OS: Linux (KDE)
  • GPU: Nvidia RTX 4090
  • Backend: Vulkan

Smartphone (please complete the following information):

  • Device: N/A
  • OS: N/A

Additional context
I also tested this using SDL3 (in a separate Filament-based project, not the sample apps), and the behavior is exactly the same.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions