From 4da5e4a37560f9b3c85af2679330f9ec292c8ee1 Mon Sep 17 00:00:00 2001 From: Autumn Ashton Date: Mon, 16 Dec 2024 06:10:33 +0000 Subject: [PATCH] layer: Fix oldSwapchain when going in/out of XWayland bypassing We need to NULL this out if we are swapping here, as oldSwapchain in the driver can't handle the difference in underlying surface types here. --- layer/VkLayer_FROG_gamescope_wsi.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/layer/VkLayer_FROG_gamescope_wsi.cpp b/layer/VkLayer_FROG_gamescope_wsi.cpp index f692d9fcc2..718a2604f3 100644 --- a/layer/VkLayer_FROG_gamescope_wsi.cpp +++ b/layer/VkLayer_FROG_gamescope_wsi.cpp @@ -1076,7 +1076,9 @@ namespace GamescopeWSILayer { gamescope_swapchain_destroy(state->object); } GamescopeSwapchain::remove(swapchain); + fprintf(stderr, "[Gamescope WSI] Destroying swapchain: %p\n", swapchain); pDispatch->DestroySwapchainKHR(device, swapchain, pAllocator); + fprintf(stderr, "[Gamescope WSI] Destroyed swapchain: %p\n", swapchain); } static VkResult CreateSwapchainKHR( @@ -1103,14 +1105,20 @@ namespace GamescopeWSILayer { return pDispatch->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); } + const bool canBypass = gamescopeSurface->canBypassXWayland(); + + VkSwapchainCreateInfoKHR swapchainInfo = *pCreateInfo; + if (pCreateInfo->oldSwapchain) { if (auto gamescopeSwapchain = GamescopeSwapchain::get(pCreateInfo->oldSwapchain)) { gamescopeSwapchain->retired = true; + // If we are going to/from being able to bypass XWayland, make sure + // we NULL out oldSwapchain, as they'll be for different surfaces and swapchain types. + if (gamescopeSwapchain->isBypassingXWayland != canBypass) + swapchainInfo.oldSwapchain = VK_NULL_HANDLE; } } - VkSwapchainCreateInfoKHR swapchainInfo = *pCreateInfo; - if (gamescopeSurface->flags & GamescopeLayerClient::Flag::ForceSwapchainExtent) { if (!gamescopeSurface->isWayland()) { auto rect = xcb::getWindowRect(gamescopeSurface->connection, gamescopeSurface->window); @@ -1121,7 +1129,6 @@ namespace GamescopeWSILayer { } } - const bool canBypass = gamescopeSurface->canBypassXWayland(); // If we can't flip, fallback to the regular XCB surface on the XCB window. if (!canBypass) swapchainInfo.surface = gamescopeSurface->fallbackSurface; @@ -1151,8 +1158,9 @@ namespace GamescopeWSILayer { minImageCount = std::max(getMinImageCount(), minImageCount); swapchainInfo.minImageCount = minImageCount; - fprintf(stderr, "[Gamescope WSI] Creating swapchain for xid: 0x%0x - provided minImageCount: %u - minImageCount: %u - format: %s - colorspace: %s - flip: %s\n", + fprintf(stderr, "[Gamescope WSI] Creating swapchain for xid: 0x%0x - oldSwapchain: %p - provided minImageCount: %u - minImageCount: %u - format: %s - colorspace: %s - flip: %s\n", gamescopeSurface->window, + pCreateInfo->oldSwapchain, pCreateInfo->minImageCount, minImageCount, vkroots::helpers::enumString(pCreateInfo->imageFormat), @@ -1231,8 +1239,9 @@ namespace GamescopeWSILayer { uint32_t imageCount = 0; pDispatch->GetSwapchainImagesKHR(device, *pSwapchain, &imageCount, nullptr); - fprintf(stderr, "[Gamescope WSI] Created swapchain for xid: 0x%0x - imageCount: %u\n", + fprintf(stderr, "[Gamescope WSI] Created swapchain for xid: 0x%0x swapchain: %p - imageCount: %u\n", gamescopeSurface->window, + *pSwapchain, imageCount); gamescope_swapchain_swapchain_feedback(