layer: Fixup currentExtent surface cap + minImageCount
This commit is contained in:
parent
1d8ce1c634
commit
83392e2afb
3 changed files with 57 additions and 5 deletions
|
@ -2,6 +2,7 @@
|
|||
#define VK_USE_PLATFORM_XCB_KHR
|
||||
#define VK_USE_PLATFORM_XLIB_KHR
|
||||
#include "vkroots.h"
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include "gamescope-xwayland-client-protocol.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
@ -27,7 +28,9 @@ namespace GamescopeWSILayer {
|
|||
struct GamescopeSurfaceData {
|
||||
VkInstance instance;
|
||||
wl_surface* surface;
|
||||
uint32_t window_xid;
|
||||
|
||||
xcb_connection_t* xcb_conn;
|
||||
xcb_window_t window_xid;
|
||||
};
|
||||
VKROOTS_DEFINE_SYNCHRONIZED_MAP_TYPE(GamescopeSurface, VkSurfaceKHR);
|
||||
|
||||
|
@ -130,7 +133,7 @@ namespace GamescopeWSILayer {
|
|||
if (!gamescopeInstance)
|
||||
return pDispatch->CreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
|
||||
|
||||
return CreateGamescopeSurface(pDispatch, *gamescopeInstance, instance, uint32_t(pCreateInfo->window), pAllocator, pSurface);
|
||||
return CreateGamescopeSurface(pDispatch, *gamescopeInstance, instance, pCreateInfo->connection, uint32_t(pCreateInfo->window), pAllocator, pSurface);
|
||||
}
|
||||
|
||||
static VkResult CreateXlibSurfaceKHR(
|
||||
|
@ -143,7 +146,7 @@ namespace GamescopeWSILayer {
|
|||
if (!gamescopeInstance)
|
||||
return pDispatch->CreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
|
||||
|
||||
return CreateGamescopeSurface(pDispatch, *gamescopeInstance, instance, uint32_t(pCreateInfo->window), pAllocator, pSurface);
|
||||
return CreateGamescopeSurface(pDispatch, *gamescopeInstance, instance, XGetXCBConnection(pCreateInfo->dpy), uint32_t(pCreateInfo->window), pAllocator, pSurface);
|
||||
}
|
||||
|
||||
static VkResult GetPhysicalDeviceSurfaceFormatsKHR(
|
||||
|
@ -184,6 +187,29 @@ namespace GamescopeWSILayer {
|
|||
pSurfaceInfo);
|
||||
}
|
||||
|
||||
static VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
const vkroots::VkInstanceDispatch* pDispatch,
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkSurfaceKHR surface,
|
||||
VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) {
|
||||
auto gamescopeSurface = GamescopeSurface::get(surface);
|
||||
if (!gamescopeSurface)
|
||||
return pDispatch->GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities);
|
||||
|
||||
VkResult res = VK_SUCCESS;
|
||||
if ((res = pDispatch->GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities)) != VK_SUCCESS)
|
||||
return res;
|
||||
|
||||
VkExtent2D currentExtent = {};
|
||||
if ((res = getCurrentExtent((*gamescopeSurface)->xcb_conn, (*gamescopeSurface)->window_xid, ¤tExtent)) != VK_SUCCESS)
|
||||
return res;
|
||||
|
||||
pSurfaceCapabilities->currentExtent = currentExtent;
|
||||
pSurfaceCapabilities->minImageCount = getMinImageCount();
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static void DestroySurfaceKHR(
|
||||
const vkroots::VkInstanceDispatch* pDispatch,
|
||||
VkInstance instance,
|
||||
|
@ -229,6 +255,7 @@ namespace GamescopeWSILayer {
|
|||
const vkroots::VkInstanceDispatch* pDispatch,
|
||||
GamescopeInstance& gamescopeInstance,
|
||||
VkInstance instance,
|
||||
xcb_connection_t* xcb_conn,
|
||||
uint32_t window_xid,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface) {
|
||||
|
@ -262,7 +289,8 @@ namespace GamescopeWSILayer {
|
|||
GamescopeSurface::create(*pSurface, GamescopeSurfaceData {
|
||||
.instance = instance,
|
||||
.surface = waylandSurface,
|
||||
.window_xid = window_xid,
|
||||
.xcb_conn = xcb_conn,
|
||||
.window_xid = xcb_window_t(window_xid),
|
||||
});
|
||||
|
||||
return result;
|
||||
|
@ -306,6 +334,29 @@ namespace GamescopeWSILayer {
|
|||
return s_isRunningUnderGamescope;
|
||||
}
|
||||
|
||||
static VkResult getCurrentExtent(xcb_connection_t* xcb_conn, xcb_window_t window_xid, VkExtent2D *pExtent) {
|
||||
xcb_generic_error_t *err = nullptr;
|
||||
xcb_get_geometry_cookie_t geom_cookie = xcb_get_geometry(xcb_conn, window_xid);
|
||||
xcb_get_geometry_reply_t* geom = xcb_get_geometry_reply(xcb_conn, geom_cookie, &err);
|
||||
if (!geom) {
|
||||
free(err);
|
||||
return VK_ERROR_SURFACE_LOST_KHR;
|
||||
}
|
||||
|
||||
*pExtent = VkExtent2D{ geom->width, geom->height };
|
||||
free(geom);
|
||||
free(err);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t getMinImageCount() {
|
||||
const char *overrideStr = std::getenv("GAMESCOPE_WSI_MIN_IMAGE_COUNT");
|
||||
if (overrideStr && *overrideStr)
|
||||
return uint32_t(std::atoi(overrideStr));
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
static constexpr wl_registry_listener s_registryListener = {
|
||||
.global = [](void* data, wl_registry* registry, uint32_t name, const char* interface, uint32_t version) {
|
||||
auto instance = reinterpret_cast<GamescopeInstanceData *>(data);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
gamescope_wsi_layer = shared_library('VkLayer_FROG_gamescope_wsi', 'VkLayer_FROG_gamescope_wsi.cpp', protocols_client_src,
|
||||
dependencies : [ vkroots_dep, dep_xcb, dep_x11, wayland_client ],
|
||||
dependencies : [ vkroots_dep, dep_xcb, dep_x11, dep_x11_xcb, wayland_client ],
|
||||
override_options : [ 'cpp_std=c++20' ],
|
||||
install : true )
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ dep_xxf86vm = dependency('xxf86vm')
|
|||
dep_xtst = dependency('xtst')
|
||||
dep_xres = dependency('xres')
|
||||
dep_xcb = dependency('xcb')
|
||||
dep_x11_xcb = dependency('x11-xcb')
|
||||
|
||||
drm_dep = dependency('libdrm', version: '>= 2.4.113')
|
||||
vulkan_dep = dependency('vulkan')
|
||||
|
|
Loading…
Reference in a new issue