layer, wlserver: Implement swapchain feedback
This commit is contained in:
parent
1064ddcce7
commit
2aa4791ba0
5 changed files with 96 additions and 5 deletions
|
@ -25,6 +25,7 @@ namespace GamescopeWSILayer {
|
|||
VKROOTS_DEFINE_SYNCHRONIZED_MAP_TYPE(GamescopeInstance, VkInstance);
|
||||
|
||||
struct GamescopeSurfaceData {
|
||||
VkInstance instance;
|
||||
wl_surface* surface;
|
||||
};
|
||||
VKROOTS_DEFINE_SYNCHRONIZED_MAP_TYPE(GamescopeSurface, VkSurfaceKHR);
|
||||
|
@ -258,6 +259,7 @@ namespace GamescopeWSILayer {
|
|||
|
||||
printf("Made gamescope surface for xid: 0x%x\n", window_xid);
|
||||
GamescopeSurface::create(*pSurface, GamescopeSurfaceData {
|
||||
.instance = instance,
|
||||
.surface = waylandSurface,
|
||||
});
|
||||
|
||||
|
@ -311,7 +313,7 @@ namespace GamescopeWSILayer {
|
|||
wl_registry_bind(registry, name, &wl_compositor_interface, version));
|
||||
} else if (!std::strcmp(interface, gamescope_xwayland_interface.name)) {
|
||||
instance->gamescope = reinterpret_cast<gamescope_xwayland *>(
|
||||
wl_registry_bind(registry, name, &gamescope_xwayland_interface, 1));
|
||||
wl_registry_bind(registry, name, &gamescope_xwayland_interface, version));
|
||||
}
|
||||
},
|
||||
.global_remove = [](void* data, wl_registry* registry, uint32_t name) {
|
||||
|
@ -351,6 +353,23 @@ namespace GamescopeWSILayer {
|
|||
GamescopeSwapchain::create(*pSwapchain, GamescopeSwapchainData{
|
||||
.surface = pCreateInfo->surface,
|
||||
});
|
||||
|
||||
auto gamescopeInstance = GamescopeInstance::get((*gamescopeSurface)->instance);
|
||||
if (gamescopeInstance) {
|
||||
uint32_t imageCount = 0;
|
||||
pDispatch->GetSwapchainImagesKHR(device, *pSwapchain, &imageCount, nullptr);
|
||||
|
||||
gamescope_xwayland_swapchain_feedback(
|
||||
(*gamescopeInstance)->gamescope,
|
||||
(*gamescopeSurface)->surface,
|
||||
imageCount,
|
||||
uint32_t(pCreateInfo->imageFormat),
|
||||
uint32_t(pCreateInfo->imageColorSpace),
|
||||
uint32_t(pCreateInfo->compositeAlpha),
|
||||
uint32_t(pCreateInfo->preTransform),
|
||||
uint32_t(pCreateInfo->presentMode),
|
||||
uint32_t(pCreateInfo->clipped));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -369,7 +388,8 @@ namespace GamescopeWSILayer {
|
|||
|
||||
VKROOTS_DEFINE_LAYER_INTERFACES(GamescopeWSILayer::VkInstanceOverrides,
|
||||
vkroots::NoOverrides,
|
||||
vkroots::NoOverrides);
|
||||
GamescopeWSILayer::VkDeviceOverrides);
|
||||
|
||||
VKROOTS_IMPLEMENT_SYNCHRONIZED_MAP_TYPE(GamescopeWSILayer::GamescopeInstance);
|
||||
VKROOTS_IMPLEMENT_SYNCHRONIZED_MAP_TYPE(GamescopeWSILayer::GamescopeSurface);
|
||||
VKROOTS_IMPLEMENT_SYNCHRONIZED_MAP_TYPE(GamescopeWSILayer::GamescopeSwapchain);
|
||||
|
|
|
@ -4,7 +4,7 @@ project(
|
|||
'cpp',
|
||||
meson_version: '>=0.58.0',
|
||||
default_options: [
|
||||
'cpp_std=c++14',
|
||||
'cpp_std=c++17',
|
||||
'warning_level=2',
|
||||
'force_fallback_for=wlroots,libliftoff',
|
||||
],
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
it.
|
||||
</description>
|
||||
|
||||
<interface name="gamescope_xwayland" version="1">
|
||||
<interface name="gamescope_xwayland" version="2">
|
||||
<request name="destroy" type="destructor"></request>
|
||||
|
||||
<request name="override_window_content">
|
||||
|
@ -46,5 +46,34 @@
|
|||
<arg name="surface" type="object" interface="wl_surface" summary="Wayland surface"/>
|
||||
<arg name="x11_window" type="uint" summary="X11 window ID"/>
|
||||
</request>
|
||||
|
||||
<request name="swapchain_feedback" since="2">
|
||||
<description summary="provide swapchain feedback">
|
||||
Provide swapchain feedback to the compositor.
|
||||
|
||||
This is what the useless tearing protocol should have been.
|
||||
Absolutely not enough information in the final protocol to do what we want for SteamOS --
|
||||
which is have the Allow Tearing toggle apply to *both* Mailbox + Immediate and NOT fifo,
|
||||
essentially acting as an override for tearing on/off for games.
|
||||
The upstream protocol is very useless for our usecase here.
|
||||
|
||||
Provides image count ahead of time instead of needing to try and calculate it from
|
||||
an initial stall if we are doing low latency.
|
||||
|
||||
Provides colorspace info for us to do HDR for both HDR10 PQ and scRGB.
|
||||
The upstream HDR efforts seem to have no interest in supporting scRGB but we *need* that so /shrug
|
||||
We can do it here now! Yipee!
|
||||
|
||||
Swapchain feedback solves so many problems! :D
|
||||
</description>
|
||||
<arg name="surface" type="object" interface="wl_surface" summary="Wayland surface"/>
|
||||
<arg name="image_count" type="uint" summary="image count of swapchain"/>
|
||||
<arg name="vk_format" type="uint" summary="VkFormat of swapchain"/>
|
||||
<arg name="vk_colorspace" type="uint" summary="VkColorSpaceKHR of swapchain"/>
|
||||
<arg name="vk_composite_alpha" type="uint" summary="VkCompositeAlphaFlagBitsKHR of swapchain"/>
|
||||
<arg name="vk_pre_transform" type="uint" summary="VkSurfaceTransformFlagBitsKHR of swapchain"/>
|
||||
<arg name="vk_present_mode" type="uint" summary="VkPresentModeKHR of swapchain"/>
|
||||
<arg name="vk_clipped" type="uint" summary="clipped (VkBool32) of swapchain"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
||||
|
|
|
@ -515,6 +515,32 @@ static void gamescope_xwayland_handle_override_window_content( struct wl_client
|
|||
server->handle_override_window_content(client, resource, surface_resource, x11_window);
|
||||
}
|
||||
|
||||
static void gamescope_xwayland_handle_swapchain_feedback( struct wl_client *client, struct wl_resource *resource,
|
||||
struct wl_resource *surface_resource,
|
||||
uint32_t image_count,
|
||||
uint32_t vk_format,
|
||||
uint32_t vk_colorspace,
|
||||
uint32_t vk_composite_alpha,
|
||||
uint32_t vk_pre_transform,
|
||||
uint32_t vk_present_mode,
|
||||
uint32_t vk_clipped)
|
||||
{
|
||||
struct wlr_surface *surface = wlr_surface_from_resource( surface_resource );
|
||||
wlserver_wl_surface_info *wl_info = get_wl_surface_info( surface );
|
||||
if ( wl_info )
|
||||
{
|
||||
wl_info->swapchain_feedback = wlserver_vk_swapchain_feedback {
|
||||
.image_count = image_count,
|
||||
.vk_format = VkFormat(vk_format),
|
||||
.vk_colorspace = VkColorSpaceKHR(vk_colorspace),
|
||||
.vk_composite_alpha = VkCompositeAlphaFlagBitsKHR(vk_composite_alpha),
|
||||
.vk_pre_transform = VkSurfaceTransformFlagBitsKHR(vk_pre_transform),
|
||||
.vk_present_mode = VkPresentModeKHR(vk_present_mode),
|
||||
.vk_clipped = VkBool32(vk_clipped),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static void gamescope_xwayland_handle_destroy( struct wl_client *client, struct wl_resource *resource )
|
||||
{
|
||||
wl_resource_destroy( resource );
|
||||
|
@ -523,6 +549,7 @@ static void gamescope_xwayland_handle_destroy( struct wl_client *client, struct
|
|||
static const struct gamescope_xwayland_interface gamescope_xwayland_impl = {
|
||||
.destroy = gamescope_xwayland_handle_destroy,
|
||||
.override_window_content = gamescope_xwayland_handle_override_window_content,
|
||||
.swapchain_feedback = gamescope_xwayland_handle_swapchain_feedback,
|
||||
};
|
||||
|
||||
static void gamescope_xwayland_bind( struct wl_client *client, void *data, uint32_t version, uint32_t id )
|
||||
|
@ -533,7 +560,7 @@ static void gamescope_xwayland_bind( struct wl_client *client, void *data, uint3
|
|||
|
||||
static void create_gamescope_xwayland( void )
|
||||
{
|
||||
uint32_t version = 1;
|
||||
uint32_t version = 2;
|
||||
wl_global_create( wlserver.display, &gamescope_xwayland_interface, version, NULL, gamescope_xwayland_bind );
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <mutex>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <optional>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#define WLSERVER_BUTTON_COUNT 4
|
||||
|
||||
|
@ -199,6 +201,17 @@ struct wlserver_x11_surface_info
|
|||
gamescope_xwayland_server_t *xwayland_server;
|
||||
};
|
||||
|
||||
struct wlserver_vk_swapchain_feedback
|
||||
{
|
||||
uint32_t image_count;
|
||||
VkFormat vk_format;
|
||||
VkColorSpaceKHR vk_colorspace;
|
||||
VkCompositeAlphaFlagBitsKHR vk_composite_alpha;
|
||||
VkSurfaceTransformFlagBitsKHR vk_pre_transform;
|
||||
VkPresentModeKHR vk_present_mode;
|
||||
VkBool32 vk_clipped;
|
||||
};
|
||||
|
||||
struct wlserver_wl_surface_info
|
||||
{
|
||||
wlserver_x11_surface_info *x11_surface = nullptr;
|
||||
|
@ -207,6 +220,8 @@ struct wlserver_wl_surface_info
|
|||
struct wl_listener destroy;
|
||||
|
||||
uint32_t presentation_hint = 0;
|
||||
|
||||
std::optional<wlserver_vk_swapchain_feedback> swapchain_feedback = std::nullopt;
|
||||
};
|
||||
|
||||
void wlserver_x11_surface_info_init( struct wlserver_x11_surface_info *surf, gamescope_xwayland_server_t *server, uint32_t x11_id );
|
||||
|
|
Loading…
Reference in a new issue