Skip to content

Commit

Permalink
layer: Send VK_ERROR_OUT_OF_DATE when window size changes on X11
Browse files Browse the repository at this point in the history
As currentExtent will have changed...
  • Loading branch information
misyltoad committed Sep 10, 2024
1 parent 7d4ff16 commit 6f516c3
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 1 deletion.
24 changes: 23 additions & 1 deletion layer/VkLayer_FROG_gamescope_wsi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#define VK_USE_PLATFORM_XLIB_KHR
#include "vkroots.h"
#include "xcb_helpers.hpp"
#include "vulkan_operators.hpp"
#include "gamescope-swapchain-client-protocol.h"
#include "../src/color_helpers.h"
#include "../src/layer_defines.h"
Expand Down Expand Up @@ -209,7 +210,11 @@ namespace GamescopeWSILayer {
GamescopeLayerClient::Flags flags;
bool hdrOutput;

// Cached for comparison.
std::optional<VkRect2D> cachedWindowRect;

bool isWayland() const {
// Is native Wayland?
return connection == nullptr;
}

Expand All @@ -222,7 +227,7 @@ namespace GamescopeWSILayer {
return hdrOutput && hdrAllowed;
}

bool canBypassXWayland() const {
bool canBypassXWayland() {
if (isWayland())
return true;

Expand All @@ -234,6 +239,8 @@ namespace GamescopeWSILayer {
return false;
}

cachedWindowRect = *rect;

auto toplevelRect = xcb::getWindowRect(connection, *toplevelWindow);
if (!toplevelRect) {
fprintf(stderr, "[Gamescope WSI] canBypassXWayland: failed to get window info for window 0x%x.\n", window);
Expand Down Expand Up @@ -294,6 +301,7 @@ namespace GamescopeWSILayer {
bool isBypassingXWayland;
bool forceFifo;
VkPresentModeKHR presentMode;
VkExtent2D extent;
uint32_t serverId = 0;
bool retired = false;

Expand Down Expand Up @@ -1046,6 +1054,7 @@ namespace GamescopeWSILayer {
.isBypassingXWayland = canBypass,
.forceFifo = gamescopeIsForcingFifo(), // Were we forcing fifo when this swapchain was made?
.presentMode = pCreateInfo->presentMode, // The new present mode.
.extent = pCreateInfo->imageExtent,
.serverId = serverId,
});
gamescopeSwapchain->pastPresentTimings.reserve(MaxPastPresentationTimes);
Expand Down Expand Up @@ -1238,6 +1247,19 @@ namespace GamescopeWSILayer {
const bool canBypass = gamescopeSurface->canBypassXWayland();
if (canBypass != gamescopeSwapchain->isBypassingXWayland)
UpdateSwapchainResult(canBypass ? VK_SUBOPTIMAL_KHR : VK_ERROR_OUT_OF_DATE_KHR);

// Emulate behaviour when currentExtent changes in X11 swapchain.
if (!gamescopeSurface->isWayland()) {
// gamescopeSurface->cachedWindowSize is set by canBypassXWayland.
// TODO: Rename that to be some update cached vars thing, then read back canBypassXWayland.
if (gamescopeSurface->cachedWindowRect) {
const bool windowSizeChanged = gamescopeSurface->cachedWindowRect->extent != gamescopeSwapchain->extent;
if (windowSizeChanged)
UpdateSwapchainResult(VK_ERROR_OUT_OF_DATE_KHR);
} else {
fprintf(stderr, "[Gamescope WSI] QueuePresentKHR: Failed to get cached window size for swapchain %u\n", i);
}
}
}
}

Expand Down
90 changes: 90 additions & 0 deletions layer/vulkan_operators.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#pragma once

#include <vulkan/vulkan_core.h>

inline bool operator == (
const VkImageSubresourceRange& a,
const VkImageSubresourceRange& b) {
return a.aspectMask == b.aspectMask
&& a.baseMipLevel == b.baseMipLevel
&& a.levelCount == b.levelCount
&& a.baseArrayLayer == b.baseArrayLayer
&& a.layerCount == b.layerCount;
}


inline bool operator != (
const VkImageSubresourceRange& a,
const VkImageSubresourceRange& b) {
return !operator == (a, b);
}


inline bool operator == (
const VkImageSubresourceLayers& a,
const VkImageSubresourceLayers& b) {
return a.aspectMask == b.aspectMask
&& a.mipLevel == b.mipLevel
&& a.baseArrayLayer == b.baseArrayLayer
&& a.layerCount == b.layerCount;
}


inline bool operator != (
const VkImageSubresourceLayers& a,
const VkImageSubresourceLayers& b) {
return !operator == (a, b);
}


inline bool operator == (VkExtent3D a, VkExtent3D b) {
return a.width == b.width
&& a.height == b.height
&& a.depth == b.depth;
}


inline bool operator != (VkExtent3D a, VkExtent3D b) {
return a.width != b.width
|| a.height != b.height
|| a.depth != b.depth;
}


inline bool operator == (VkExtent2D a, VkExtent2D b) {
return a.width == b.width
&& a.height == b.height;
}


inline bool operator != (VkExtent2D a, VkExtent2D b) {
return a.width != b.width
|| a.height != b.height;
}


inline bool operator == (VkOffset3D a, VkOffset3D b) {
return a.x == b.x
&& a.y == b.y
&& a.z == b.z;
}


inline bool operator != (VkOffset3D a, VkOffset3D b) {
return a.x != b.x
|| a.y != b.y
|| a.z != b.z;
}


inline bool operator == (VkOffset2D a, VkOffset2D b) {
return a.x == b.x
&& a.y == b.y;
}


inline bool operator != (VkOffset2D a, VkOffset2D b) {
return a.x != b.x
|| a.y != b.y;
}

0 comments on commit 6f516c3

Please sign in to comment.