mirror of
https://github.com/ublue-os/bazzite.git
synced 2024-12-29 03:20:57 +00:00
feat(gamescope): Add Ally display patch and bicubic filter patch, use master branch for now
This commit is contained in:
parent
3e4e162956
commit
a6f0015327
@ -1,239 +0,0 @@
|
||||
From ab115896be1a448bde0eb7673c26300ea4ca5040 Mon Sep 17 00:00:00 2001
|
||||
From: sharkautarch <128002472+sharkautarch@users.noreply.github.com>
|
||||
Date: Sun, 19 May 2024 20:15:36 -0400
|
||||
Subject: [PATCH 1/2] QueuePresent: canBypassXWayland(): fetch multiple xcb
|
||||
cookies initially before waiting on any of them
|
||||
|
||||
---
|
||||
layer/VkLayer_FROG_gamescope_wsi.cpp | 1 +
|
||||
layer/xcb_helpers.hpp | 105 +++++++++++++++++++++++----
|
||||
2 files changed, 93 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/layer/VkLayer_FROG_gamescope_wsi.cpp b/layer/VkLayer_FROG_gamescope_wsi.cpp
|
||||
index 5844c2a63..ca44849f2 100644
|
||||
--- a/layer/VkLayer_FROG_gamescope_wsi.cpp
|
||||
+++ b/layer/VkLayer_FROG_gamescope_wsi.cpp
|
||||
@@ -975,6 +975,7 @@ namespace GamescopeWSILayer {
|
||||
continue;
|
||||
}
|
||||
|
||||
+ xcb::Prefetcher prefetcher(gamescopeSurface->connection, gamescopeSurface->window);
|
||||
const bool canBypass = gamescopeSurface->canBypassXWayland();
|
||||
if (canBypass != gamescopeSwapchain->isBypassingXWayland)
|
||||
UpdateSwapchainResult(canBypass ? VK_SUBOPTIMAL_KHR : VK_ERROR_OUT_OF_DATE_KHR);
|
||||
diff --git a/layer/xcb_helpers.hpp b/layer/xcb_helpers.hpp
|
||||
index 8fac5635b..72d0ec092 100644
|
||||
--- a/layer/xcb_helpers.hpp
|
||||
+++ b/layer/xcb_helpers.hpp
|
||||
@@ -4,22 +4,106 @@
|
||||
#include <xcb/composite.h>
|
||||
#include <cstdio>
|
||||
#include <optional>
|
||||
+#include <pthread.h>
|
||||
|
||||
namespace xcb {
|
||||
+ inline static constinit pthread_t g_cache_tid; //incase g_cache could otherwise be accessed by one thread, while it is being deleted by another thread
|
||||
+ inline static constinit struct cookie_cache_t {
|
||||
+ xcb_window_t window;
|
||||
+ std::tuple<xcb_get_geometry_cookie_t, xcb_query_tree_cookie_t> cached_cookies;
|
||||
+ std::tuple<xcb_get_geometry_reply_t*, xcb_query_tree_reply_t*> cached_replies;
|
||||
+ } g_cache = {};
|
||||
+
|
||||
+ //Note: this class is currently only meant to be used within GamescopeWSILayer::VkDeviceOverrides::QueuePresentKHR:
|
||||
+ struct Prefetcher {
|
||||
+ explicit Prefetcher(xcb_connection_t* connection, const xcb_window_t window) {
|
||||
+ g_cache = {
|
||||
+ .window = window,
|
||||
+ .cached_cookies = {
|
||||
+ xcb_get_geometry(connection, window),
|
||||
+ xcb_query_tree(connection, window)
|
||||
+ }
|
||||
+ };
|
||||
+ g_cache_tid = pthread_self();
|
||||
+ }
|
||||
|
||||
+ ~Prefetcher() {
|
||||
+ g_cache_tid = {};
|
||||
+ free(std::get<0>(g_cache.cached_replies));
|
||||
+ free(std::get<1>(g_cache.cached_replies));
|
||||
+ g_cache.cached_replies = {nullptr,nullptr};
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
struct ReplyDeleter {
|
||||
+ const bool m_bOwning = true;
|
||||
+ consteval ReplyDeleter(bool bOwning = true) : m_bOwning{bOwning} {}
|
||||
template <typename T>
|
||||
void operator()(T* ptr) const {
|
||||
- free(const_cast<std::remove_const_t<T>*>(ptr));
|
||||
+ if (m_bOwning)
|
||||
+ free(const_cast<std::remove_const_t<T>*>(ptr));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using Reply = std::unique_ptr<T, ReplyDeleter>;
|
||||
+
|
||||
+ template <typename Cookie_RetType, typename Reply_RetType, typename XcbConn=xcb_connection_t*, typename... Args>
|
||||
+ class XcbFetch {
|
||||
+ using cookie_f_ptr_t = Cookie_RetType (*)(XcbConn, Args...);
|
||||
+ using reply_f_ptr_t = Reply_RetType* (*)(XcbConn, Cookie_RetType, xcb_generic_error_t**);
|
||||
+
|
||||
+ const cookie_f_ptr_t m_cookieFunc;
|
||||
+ const reply_f_ptr_t m_replyFunc;
|
||||
+
|
||||
+ public:
|
||||
+ consteval XcbFetch(cookie_f_ptr_t cookieFunc, reply_f_ptr_t replyFunc) : m_cookieFunc{cookieFunc}, m_replyFunc{replyFunc} {}
|
||||
+
|
||||
+ inline Reply<Reply_RetType> operator()(XcbConn conn, auto... args) { //have to use auto for argsTwo, since otherwise there'd be a type deduction conflict
|
||||
+ return Reply<Reply_RetType> { m_replyFunc(conn, m_cookieFunc(conn, args...), nullptr) };
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ template <typename CookieType>
|
||||
+ concept CacheableCookie = std::is_same<CookieType, xcb_get_geometry_cookie_t>::value
|
||||
+ || std::is_same<CookieType, xcb_query_tree_cookie_t>::value;
|
||||
+
|
||||
+ template <CacheableCookie Cookie_RetType, typename Reply_RetType>
|
||||
+ class XcbFetch<Cookie_RetType, Reply_RetType, xcb_connection_t*, xcb_window_t> {
|
||||
+ using cookie_f_ptr_t = Cookie_RetType (*)(xcb_connection_t*, xcb_window_t);
|
||||
+ using reply_f_ptr_t = Reply_RetType* (*)(xcb_connection_t*, Cookie_RetType, xcb_generic_error_t**);
|
||||
+
|
||||
+ const cookie_f_ptr_t m_cookieFunc;
|
||||
+ const reply_f_ptr_t m_replyFunc;
|
||||
+
|
||||
+ inline Reply<Reply_RetType> getCachedReply(xcb_connection_t* connection) {
|
||||
+ if (std::get<Reply_RetType*>(g_cache.cached_replies) == nullptr) {
|
||||
+ std::get<Reply_RetType*>(g_cache.cached_replies) = m_replyFunc(connection, std::get<Cookie_RetType>(g_cache.cached_cookies), nullptr);
|
||||
+ }
|
||||
|
||||
+ return Reply<Reply_RetType>{std::get<Reply_RetType*>(g_cache.cached_replies), ReplyDeleter{false}}; // return 'non-owning' unique_ptr
|
||||
+ }
|
||||
+
|
||||
+ public:
|
||||
+ consteval XcbFetch(cookie_f_ptr_t cookieFunc, reply_f_ptr_t replyFunc) : m_cookieFunc{cookieFunc}, m_replyFunc{replyFunc} {}
|
||||
+
|
||||
+ inline Reply<Reply_RetType> operator()(xcb_connection_t* conn, xcb_window_t window) {
|
||||
+ const bool tryCached = pthread_equal(g_cache_tid, pthread_self())
|
||||
+ && g_cache.window == window;
|
||||
+ if (!tryCached) [[unlikely]]
|
||||
+ return Reply<Reply_RetType> { m_replyFunc(conn, m_cookieFunc(conn, window), nullptr) };
|
||||
+
|
||||
+ auto ret = getCachedReply(conn);
|
||||
+ #if !defined(NDEBUG) || NDEBUG == 0
|
||||
+ if (!ret)
|
||||
+ fprintf(stderr, "[Gamescope WSI] getCachedReply() failed.\n");
|
||||
+ #endif
|
||||
+ return ret;
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
static std::optional<xcb_atom_t> getAtom(xcb_connection_t* connection, std::string_view name) {
|
||||
- xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, false, name.length(), name.data());
|
||||
- auto reply = Reply<xcb_intern_atom_reply_t>{ xcb_intern_atom_reply(connection, cookie, nullptr) };
|
||||
+ auto reply = XcbFetch{xcb_intern_atom, xcb_intern_atom_reply}(connection, false, name.length(), name.data());
|
||||
if (!reply) {
|
||||
fprintf(stderr, "[Gamescope WSI] Failed to get xcb atom.\n");
|
||||
return std::nullopt;
|
||||
@@ -34,8 +118,7 @@ namespace xcb {
|
||||
|
||||
xcb_screen_t* screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
|
||||
|
||||
- xcb_get_property_cookie_t cookie = xcb_get_property(connection, false, screen->root, atom, XCB_ATOM_CARDINAL, 0, sizeof(T) / sizeof(uint32_t));
|
||||
- auto reply = Reply<xcb_get_property_reply_t>{ xcb_get_property_reply(connection, cookie, nullptr) };
|
||||
+ auto reply = XcbFetch{xcb_get_property, xcb_get_property_reply}(connection, false, screen->root, atom, XCB_ATOM_CARDINAL, 0, sizeof(T) / sizeof(uint32_t));
|
||||
if (!reply) {
|
||||
fprintf(stderr, "[Gamescope WSI] Failed to read T root window property.\n");
|
||||
return std::nullopt;
|
||||
@@ -61,8 +144,7 @@ namespace xcb {
|
||||
|
||||
static std::optional<xcb_window_t> getToplevelWindow(xcb_connection_t* connection, xcb_window_t window) {
|
||||
for (;;) {
|
||||
- xcb_query_tree_cookie_t cookie = xcb_query_tree(connection, window);
|
||||
- auto reply = Reply<xcb_query_tree_reply_t>{ xcb_query_tree_reply(connection, cookie, nullptr) };
|
||||
+ auto reply = XcbFetch{xcb_query_tree, xcb_query_tree_reply}(connection, window);
|
||||
|
||||
if (!reply) {
|
||||
fprintf(stderr, "[Gamescope WSI] getToplevelWindow: xcb_query_tree failed for window 0x%x.\n", window);
|
||||
@@ -77,8 +159,7 @@ namespace xcb {
|
||||
}
|
||||
|
||||
static std::optional<VkRect2D> getWindowRect(xcb_connection_t* connection, xcb_window_t window) {
|
||||
- xcb_get_geometry_cookie_t cookie = xcb_get_geometry(connection, window);
|
||||
- auto reply = Reply<xcb_get_geometry_reply_t>{ xcb_get_geometry_reply(connection, cookie, nullptr) };
|
||||
+ auto reply = XcbFetch{xcb_get_geometry, xcb_get_geometry_reply}(connection, window);
|
||||
if (!reply) {
|
||||
fprintf(stderr, "[Gamescope WSI] getWindowRect: xcb_get_geometry failed for window 0x%x.\n", window);
|
||||
return std::nullopt;
|
||||
@@ -112,8 +193,7 @@ namespace xcb {
|
||||
static std::optional<VkExtent2D> getLargestObscuringChildWindowSize(xcb_connection_t* connection, xcb_window_t window) {
|
||||
VkExtent2D largestExtent = {};
|
||||
|
||||
- xcb_query_tree_cookie_t cookie = xcb_query_tree(connection, window);
|
||||
- auto reply = Reply<xcb_query_tree_reply_t>{ xcb_query_tree_reply(connection, cookie, nullptr) };
|
||||
+ auto reply = XcbFetch{xcb_query_tree, xcb_query_tree_reply}(connection, window);
|
||||
|
||||
if (!reply) {
|
||||
fprintf(stderr, "[Gamescope WSI] getLargestObscuringWindowSize: xcb_query_tree failed for window 0x%x.\n", window);
|
||||
@@ -130,8 +210,7 @@ namespace xcb {
|
||||
for (uint32_t i = 0; i < reply->children_len; i++) {
|
||||
xcb_window_t child = children[i];
|
||||
|
||||
- xcb_get_window_attributes_cookie_t attributeCookie = xcb_get_window_attributes(connection, child);
|
||||
- auto attributeReply = Reply<xcb_get_window_attributes_reply_t>{ xcb_get_window_attributes_reply(connection, attributeCookie, nullptr) };
|
||||
+ auto attributeReply = XcbFetch{xcb_get_window_attributes, xcb_get_window_attributes_reply}(connection, child);
|
||||
|
||||
const bool obscuring =
|
||||
attributeReply &&
|
||||
|
||||
From 1b59621f4de5c05096d1f279cba2e04264124154 Mon Sep 17 00:00:00 2001
|
||||
From: sharkautarch <128002472+sharkautarch@users.noreply.github.com>
|
||||
Date: Tue, 18 Jun 2024 22:21:23 -0400
|
||||
Subject: [PATCH 2/2] WSI: prefetcher: fix issue w/ attempting to prefetch xcb
|
||||
stuff for pure wayland surfaces
|
||||
|
||||
---
|
||||
layer/VkLayer_FROG_gamescope_wsi.cpp | 2 +-
|
||||
layer/xcb_helpers.hpp | 9 ++++++++-
|
||||
2 files changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/layer/VkLayer_FROG_gamescope_wsi.cpp b/layer/VkLayer_FROG_gamescope_wsi.cpp
|
||||
index f26819a60..ce011dcd7 100644
|
||||
--- a/layer/VkLayer_FROG_gamescope_wsi.cpp
|
||||
+++ b/layer/VkLayer_FROG_gamescope_wsi.cpp
|
||||
@@ -1234,7 +1234,7 @@ namespace GamescopeWSILayer {
|
||||
continue;
|
||||
}
|
||||
|
||||
- xcb::Prefetcher prefetcher(gamescopeSurface->connection, gamescopeSurface->window);
|
||||
+ auto prefetcher = xcb::Prefetcher::GetPrefetcherIf(!gamescopeSurface->isWayland(), gamescopeSurface->connection, gamescopeSurface->window);
|
||||
const bool canBypass = gamescopeSurface->canBypassXWayland();
|
||||
if (canBypass != gamescopeSwapchain->isBypassingXWayland)
|
||||
UpdateSwapchainResult(canBypass ? VK_SUBOPTIMAL_KHR : VK_ERROR_OUT_OF_DATE_KHR);
|
||||
diff --git a/layer/xcb_helpers.hpp b/layer/xcb_helpers.hpp
|
||||
index 72d0ec092..f26aef38b 100644
|
||||
--- a/layer/xcb_helpers.hpp
|
||||
+++ b/layer/xcb_helpers.hpp
|
||||
@@ -16,6 +16,13 @@ namespace xcb {
|
||||
|
||||
//Note: this class is currently only meant to be used within GamescopeWSILayer::VkDeviceOverrides::QueuePresentKHR:
|
||||
struct Prefetcher {
|
||||
+ static std::optional<Prefetcher> GetPrefetcherIf(bool bCond, xcb_connection_t* connection, const xcb_window_t window) {
|
||||
+ if (bCond)
|
||||
+ return std::optional<Prefetcher>(std::in_place_t{}, connection, window);
|
||||
+
|
||||
+ return std::nullopt;
|
||||
+ }
|
||||
+
|
||||
explicit Prefetcher(xcb_connection_t* connection, const xcb_window_t window) {
|
||||
g_cache = {
|
||||
.window = window,
|
||||
@@ -90,7 +97,7 @@ namespace xcb {
|
||||
inline Reply<Reply_RetType> operator()(xcb_connection_t* conn, xcb_window_t window) {
|
||||
const bool tryCached = pthread_equal(g_cache_tid, pthread_self())
|
||||
&& g_cache.window == window;
|
||||
- if (!tryCached) [[unlikely]]
|
||||
+ if (!tryCached)
|
||||
return Reply<Reply_RetType> { m_replyFunc(conn, m_cookieFunc(conn, window), nullptr) };
|
||||
|
||||
auto ret = getCachedReply(conn);
|
1012
spec_files/gamescope/740.patch
Normal file
1012
spec_files/gamescope/740.patch
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@
|
||||
|
||||
Name: gamescope
|
||||
Version: 100.%{gamescope_tag}
|
||||
Release: 3.bazzite
|
||||
Release: 6.bazzite
|
||||
Summary: Micro-compositor for video games on Wayland
|
||||
|
||||
License: BSD
|
||||
@ -24,11 +24,8 @@ Patch1: chimeraos.patch
|
||||
Patch2: disable-steam-touch-click-atom.patch
|
||||
Patch3: v2-0001-steam-overlay-hotkeys.patch
|
||||
|
||||
# https://github.com/ValveSoftware/gamescope/issues/1369
|
||||
Patch4: revert-299bc34.patch
|
||||
|
||||
# https://github.com/ValveSoftware/gamescope/pull/1231
|
||||
Patch5: 1231.patch
|
||||
# https://github.com/ValveSoftware/gamescope/pull/740
|
||||
Patch4: 740.patch
|
||||
|
||||
BuildRequires: meson >= 0.54.0
|
||||
BuildRequires: ninja-build
|
||||
@ -66,6 +63,7 @@ BuildRequires: (pkgconfig(libliftoff) >= 0.4.1 with pkgconfig(libliftoff) < 0.5
|
||||
BuildRequires: pkgconfig(libcap)
|
||||
BuildRequires: pkgconfig(hwdata)
|
||||
BuildRequires: pkgconfig(lcms2)
|
||||
BuildRequires: pkgconfig(luajit)
|
||||
BuildRequires: spirv-headers-devel
|
||||
# Enforce the the minimum EVR to contain fixes for all of:
|
||||
# CVE-2021-28021 CVE-2021-42715 CVE-2021-42716 CVE-2022-28041 CVE-2023-43898
|
||||
@ -101,7 +99,8 @@ Summary: libs for %{name}
|
||||
%summary
|
||||
|
||||
%prep
|
||||
git clone --depth 1 --branch %{gamescope_tag} %{url}.git
|
||||
# git clone --depth 1 --branch %%{gamescope_tag} %%{url}.git
|
||||
git clone --depth 1 --branch master %{url}.git
|
||||
cd gamescope
|
||||
git submodule update --init --recursive
|
||||
mkdir -p pkgconfig
|
||||
|
@ -1,65 +0,0 @@
|
||||
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
||||
index 4216555..48c017d 100644
|
||||
--- a/src/steamcompmgr.cpp
|
||||
+++ b/src/steamcompmgr.cpp
|
||||
@@ -3236,7 +3236,7 @@ found:;
|
||||
if ( window_has_commits( focus ) )
|
||||
out->focusWindow = focus;
|
||||
else
|
||||
- focus->outdatedInteractiveFocus = true;
|
||||
+ out->outdatedInteractiveFocus = true;
|
||||
|
||||
// Always update X's idea of focus, but still dirty
|
||||
// the it being outdated so we can resolve that globally later.
|
||||
@@ -5963,28 +5963,37 @@ bool handle_done_commit( steamcompmgr_win_t *w, xwayland_ctx_t *ctx, uint64_t co
|
||||
// Window just got a new available commit, determine if that's worth a repaint
|
||||
|
||||
// If this is an overlay that we're presenting, repaint
|
||||
- if ( w == global_focus.overlayWindow && w->opacity != TRANSLUCENT )
|
||||
+ if ( gameFocused )
|
||||
{
|
||||
- hasRepaintNonBasePlane = true;
|
||||
- }
|
||||
+ if ( w == global_focus.overlayWindow && w->opacity != TRANSLUCENT )
|
||||
+ {
|
||||
+ hasRepaintNonBasePlane = true;
|
||||
+ }
|
||||
|
||||
- if ( w == global_focus.notificationWindow && w->opacity != TRANSLUCENT )
|
||||
- {
|
||||
- hasRepaintNonBasePlane = true;
|
||||
+ if ( w == global_focus.notificationWindow && w->opacity != TRANSLUCENT )
|
||||
+ {
|
||||
+ hasRepaintNonBasePlane = true;
|
||||
+ }
|
||||
}
|
||||
-
|
||||
- // If this is an external overlay, repaint
|
||||
- if ( w == global_focus.externalOverlayWindow && w->opacity != TRANSLUCENT )
|
||||
+ if ( ctx )
|
||||
{
|
||||
- hasRepaintNonBasePlane = true;
|
||||
+ if ( ctx->focus.outdatedInteractiveFocus )
|
||||
+ {
|
||||
+ MakeFocusDirty();
|
||||
+ ctx->focus.outdatedInteractiveFocus = false;
|
||||
+ }
|
||||
}
|
||||
-
|
||||
- if ( w->outdatedInteractiveFocus )
|
||||
+ if ( global_focus.outdatedInteractiveFocus )
|
||||
{
|
||||
MakeFocusDirty();
|
||||
- w->outdatedInteractiveFocus = false;
|
||||
- }
|
||||
+ global_focus.outdatedInteractiveFocus = false;
|
||||
|
||||
+ // If this is an external overlay, repaint
|
||||
+ if ( w == global_focus.externalOverlayWindow && w->opacity != TRANSLUCENT )
|
||||
+ {
|
||||
+ hasRepaintNonBasePlane = true;
|
||||
+ }
|
||||
+ }
|
||||
// If this is the main plane, repaint
|
||||
if ( w == global_focus.focusWindow && !w->isSteamStreamingClient )
|
||||
{
|
Loading…
Reference in New Issue
Block a user