fix gamescope for older GPUs (#1930)

* gamescope: make the SDL backend the default backend for all builds

* add back funny patches

* Obsolete gamescope-legacy with wrapper script, fix multiarch subpackage

* fix dependency issue

* terra downstream script patches

* add the ctrl patch properly

* revert

* update to 3.15.0

* simplify wrapper script

* handle calling gamescope-legacy from non-gamescope session

* Use my PR patch for gamescope fallback

* format patch from github

* update patch

---------

Signed-off-by: Cappy Ishihara <cappy@cappuchino.xyz>
This commit is contained in:
Cappy Ishihara
2024-08-25 16:42:06 +07:00
committed by GitHub
parent 36362e035c
commit e334d5d927
13 changed files with 395 additions and 671 deletions
+36
View File
@@ -0,0 +1,36 @@
From 5529e8ac8f3232ec6233e33286834548e1d8018d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franti=C5=A1ek=20Zatloukal?= <fzatlouk@redhat.com>
Date: Sun, 8 Oct 2023 22:10:33 +0200
Subject: [PATCH] <cstdint>
---
src/reshade/source/effect_parser_stmt.cpp | 1 +
src/reshade/source/effect_token.hpp | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/reshade/source/effect_parser_stmt.cpp b/src/reshade/source/effect_parser_stmt.cpp
index 7829729..f126be2 100644
--- a/src/reshade/source/effect_parser_stmt.cpp
+++ b/src/reshade/source/effect_parser_stmt.cpp
@@ -9,6 +9,7 @@
#include <cctype> // std::toupper
#include <cassert>
#include <functional>
+#include <limits>
#include <string_view>
struct on_scope_exit
diff --git a/src/reshade/source/effect_token.hpp b/src/reshade/source/effect_token.hpp
index 072d439..e4bb633 100644
--- a/src/reshade/source/effect_token.hpp
+++ b/src/reshade/source/effect_token.hpp
@@ -5,6 +5,7 @@
#pragma once
+#include <cstdint>
#include <string>
#include <vector>
--
2.41.0
+21
View File
@@ -0,0 +1,21 @@
From 88ce1e5de62886aa14c74421cde6130e16e70d7d Mon Sep 17 00:00:00 2001
From: psykose <alice@ayaya.dev>
Date: Sat, 6 Jul 2024 20:52:50 +0200
Subject: [PATCH] utils: include limits.h for PATH_MAX
---
src/Utils/Process.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Utils/Process.cpp b/src/Utils/Process.cpp
index e71786f75..3e748e0d3 100644
--- a/src/Utils/Process.cpp
+++ b/src/Utils/Process.cpp
@@ -21,6 +21,7 @@
#include <pthread.h>
#include <stdlib.h>
#include <dirent.h>
+#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
-239
View File
@@ -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);
+34
View File
@@ -0,0 +1,34 @@
From ca58cb2453e6d9ef44d799e394ee9950b7a35b30 Mon Sep 17 00:00:00 2001
From: Cappy Ishihara <cappy@cappuchino.xyz>
Date: Wed, 21 Aug 2024 03:56:53 +0700
Subject: [PATCH] Check if current GPU supports Vulkan DRM modifiers when
`--backend=auto` is used.
This works around #1218 by making use of the new backend option added in #1321,
but adds a check to automatically fall back to the SDL backend if the current
GPU does not support Vulkan DRM modifiers.
---
src/main.cpp | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/main.cpp b/src/main.cpp
index ca4001249..bc6b16904 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -817,9 +817,13 @@ int main(int argc, char **argv)
if ( eCurrentBackend == gamescope::GamescopeBackend::Auto )
{
if ( g_pOriginalWaylandDisplay != NULL )
- eCurrentBackend = gamescope::GamescopeBackend::Wayland;
- else if ( g_pOriginalDisplay != NULL )
- eCurrentBackend = gamescope::GamescopeBackend::SDL;
+ // Additional check if the current GPU supports Vulkan DRM modifiers
+ // Fallback to SDL if not supported (e.g Older AMD GPUs like Polaris 10/20)
+ if ( vulkan_supports_modifiers() )
+ eCurrentBackend = gamescope::GamescopeBackend::Wayland;
+ else
+ eCurrentBackend = gamescope::GamescopeBackend::SDL;
+
else
eCurrentBackend = gamescope::GamescopeBackend::DRM;
}
File diff suppressed because it is too large Load Diff
-136
View File
@@ -1,136 +0,0 @@
diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
index 85e5126..be418b4 100644
--- a/src/Backends/DRMBackend.cpp
+++ b/src/Backends/DRMBackend.cpp
@@ -2149,6 +2149,7 @@ namespace gamescope
( m_Mutable.szMakePNP == "WLC"sv && m_Mutable.szModel == "ANX7530 U"sv ) ||
( m_Mutable.szMakePNP == "ANX"sv && m_Mutable.szModel == "ANX7530 U"sv ) ||
( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "ANX7530 U"sv ) ||
+ ( m_Mutable.szMakePNP == "DHD"sv && m_Mutable.szModel == "DeckHD-1200p"sv ) ||
( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Jupiter"sv ) ||
( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Galileo"sv );
@@ -2160,6 +2161,7 @@ namespace gamescope
{
static constexpr uint32_t kPIDGalileoSDC = 0x3003;
static constexpr uint32_t kPIDGalileoBOE = 0x3004;
+ static constexpr uint32_t kPIDJupiterDHD = 0x4001;
if ( pProduct->product == kPIDGalileoSDC )
{
@@ -2171,6 +2173,10 @@ namespace gamescope
m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE;
m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDRates );
}
+ else if (pProduct-> product == kPIDJupiterDHD ) {
+ m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD;
+ m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckLCDRates );
+ }
else
{
m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD;
@@ -2200,7 +2206,8 @@ namespace gamescope
drm_log.infof( "[colorimetry]: Steam Deck LCD detected. Using known colorimetry" );
m_Mutable.DisplayColorimetry = displaycolorimetry_steamdeck_measured;
}
- else
+ else if (m_Mutable.eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE ||
+ m_Mutable.eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC )
{
// Steam Deck OLED has calibrated chromaticity coordinates in the EDID
// for each unit.
@@ -2330,7 +2337,7 @@ namespace gamescope
.uMinContentLightLevel = nits_to_u16_dark( 0 ),
};
}
- else if ( eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD )
+ else if ( eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD || eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD )
{
// Set up some HDR fallbacks for undocking
return BackendConnectorHDRInfo
diff --git a/src/gamescope_shared.h b/src/gamescope_shared.h
index ed30d8c..3b60774 100644
--- a/src/gamescope_shared.h
+++ b/src/gamescope_shared.h
@@ -8,6 +8,7 @@ namespace gamescope
{
GAMESCOPE_KNOWN_DISPLAY_UNKNOWN,
GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD, // Jupiter
+ GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD, // Jupiter Deck HD
GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC, // Galileo SDC
GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE, // Galileo BOE
};
diff --git a/src/modegen.cpp b/src/modegen.cpp
index d174c2d..5dd1136 100644
--- a/src/modegen.cpp
+++ b/src/modegen.cpp
@@ -293,13 +293,32 @@ unsigned int galileo_boe_vfp[] =
172,152,136,120,100,84,68,52,36,20,8
};
-#define GALILEO_MIN_REFRESH 45
+//SD LCD Stock Timings
+#define JUPITER_BOE_PID 0x3001
+#define JUPITER_B_PID 0x3002
+#define JUPITER_HFP 40
+#define JUPITER_HSYNC 4
+#define JUPITER_HBP 40
+#define JUPITER_VFP 30
+#define JUPITER_VSYNC 4
+#define JUPITER_VBP 8
+//SD LCD DeckHD Timings
+#define JUPITER_DHD_PID 0x4001
+#define JUPITER_DHD_HFP 40
+#define JUPITER_DHD_HSYNC 20
+#define JUPITER_DHD_HBP 40
+#define JUPITER_DHD_VFP 18
+#define JUPITER_DHD_VSYNC 2
+#define JUPITER_DHD_VBP 20
+//SD OLED SDC Timings
#define GALILEO_SDC_PID 0x3003
#define GALILEO_SDC_VSYNC 1
#define GALILEO_SDC_VBP 22
+//SD OLED BOE Timings
#define GALILEO_BOE_PID 0x3004
#define GALILEO_BOE_VSYNC 2
#define GALILEO_BOE_VBP 30
+#define GALILEO_MIN_REFRESH 45
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
unsigned int get_galileo_vfp( int vrefresh, unsigned int * vfp_array, unsigned int num_rates )
@@ -344,17 +363,28 @@ void generate_fixed_mode(drmModeModeInfo *mode, const drmModeModeInfo *base, int
mode->vsync_end = mode->vsync_start + vsync;
mode->vtotal = mode->vsync_end + vbp;
} else {
- if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD )
+ if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD ) {
+ mode->hdisplay = 1200;
+ mode->hsync_start = mode->hdisplay + JUPITER_DHD_HFP;
+ mode->hsync_end = mode->hsync_start + JUPITER_DHD_HSYNC;
+ mode->htotal = mode->hsync_end + JUPITER_DHD_HBP;
+
+ mode->vdisplay = 1920;
+ mode->vsync_start = mode->vdisplay + JUPITER_DHD_VFP;
+ mode->vsync_end = mode->vsync_start + JUPITER_DHD_VSYNC;
+ mode->vtotal = mode->vsync_end + JUPITER_DHD_VBP;
+ }
+ else if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD )
{
mode->hdisplay = 800;
- mode->hsync_start = 840;
- mode->hsync_end = 844;
- mode->htotal = 884;
+ mode->hsync_start = mode->hdisplay + JUPITER_HFP;
+ mode->hsync_end = mode->hsync_start + JUPITER_HSYNC;
+ mode->htotal = mode->hsync_end + JUPITER_HBP;
mode->vdisplay = 1280;
- mode->vsync_start = 1310;
- mode->vsync_end = 1314;
- mode->vtotal = 1322;
+ mode->vsync_start = mode->vdisplay + JUPITER_VFP;
+ mode->vsync_end = mode->vsync_start + JUPITER_VSYNC;
+ mode->vtotal = mode->vsync_end + JUPITER_VBP;
}
mode->clock = ( ( mode->htotal * mode->vtotal * vrefresh ) + 999 ) / 1000;
@@ -48,4 +48,4 @@ index 92bf617..d7498e5 100644
+ cv_disable_touch_click = true;
}
break;
case '?':
case '?':
@@ -1,63 +0,0 @@
From 2e4d7ad1bf2cb98eb67ff8f9385cf6657cf2e912 Mon Sep 17 00:00:00 2001
From: Matthew Schwartz <njtransit215@gmail.com>
Date: Wed, 3 Jul 2024 15:20:08 -0700
Subject: [PATCH] drm: Separate BOE and SDC OLED Deck panel valid refresh rates
OLED Decks with BOE panels seem to struggle with a few different
specific modesets (51hz/55hz/65hz) that SDC panels have no issues with.
To work around this, let's make use of Gamescope recognizing each
display manufacturer to correct the bad modesets while leaving
SDC panel units alone. This can be reverted if an underlying cause can
be found in the kernel in the future.
---
src/Backends/DRMBackend.cpp | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
index 97ef446..9f93c7f 100644
--- a/src/Backends/DRMBackend.cpp
+++ b/src/Backends/DRMBackend.cpp
@@ -554,7 +554,7 @@ static constexpr uint32_t s_kSteamDeckLCDRates[] =
60,
};
-static constexpr uint32_t s_kSteamDeckOLEDRates[] =
+static constexpr uint32_t s_kSteamDeckOLEDSDCRates[] =
{
45, 47, 48, 49,
50, 51, 53, 55, 56, 59,
@@ -564,6 +564,16 @@ static constexpr uint32_t s_kSteamDeckOLEDRates[] =
90,
};
+static constexpr uint32_t s_kSteamDeckOLEDBOERates[] =
+{
+ 45, 47, 48, 49,
+ 50, 53, 56, 59,
+ 60, 62, 64, 66, 68,
+ 72, 73, 76, 77, 78,
+ 80, 81, 82, 84, 85, 86, 87, 88,
+ 90,
+};
+
static void update_connector_display_info_wl(struct drm_t *drm)
{
wlserver_lock();
@@ -2128,12 +2138,12 @@ namespace gamescope
if ( pProduct->product == kPIDGalileoSDC )
{
m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC;
- m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDRates );
+ m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDSDCRates );
}
else if ( pProduct->product == kPIDGalileoBOE )
{
m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE;
- m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDRates );
+ m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDBOERates );
}
else
{
--
2.45.2
+29
View File
@@ -0,0 +1,29 @@
#!/bin/sh
# Wrapper script to run Gamescope with legacy options for older GPUs
gamescope_path="/usr/bin/gamescope"
# check if $BACKEND is already defined
# todo: Probably want to patch gamescope-session-plus for this instead meow
# For compatibility, let's add the argument for nested backends too
LEGACY_BACKEND_ARGS=""
NESTED_BACKEND_ARGS=""
if [ -z "$BACKEND" ]; then
LEGACY_BACKEND_ARGS="--backend=sdl"
NESTED_BACKEND_ARGS="--backend=sdl"
else
# Only added for nested sessions, as $BACKEND should be defined only for legacy
NESTED_BACKEND_ARGS="--backend=$BACKEND"
fi
if [ -z "$DISPLAY" ]; then
$gamescope_path $LEGACY_BACKEND_ARGS $@
else
$gamescope_path $NESTED_BACKEND_ARGS $@
fi
+1 -1
View File
@@ -4,4 +4,4 @@ includedir=${prefix}/include/stb
Name: stb
Description: Single-file public domain libraries for C/C++
Version: 0.1.0
Cflags: -I${includedir}
Cflags: -I${includedir}
+46 -27
View File
@@ -1,37 +1,43 @@
%if 0%{?fedora} >= 41
%global libliftoff_minver 0.5.0
%else
%global libliftoff_minver 0.4.1
%endif
%global toolchain clang
%global _default_patch_fuzz 2
%global gamescope_tag 3.15.1
Name: terra-gamescope
Version: 100.%{gamescope_tag}
Release: 1%?dist
Summary: Micro-compositor for video games on Wayland
Summary: Micro-compositor for video games on Wayland - Terra patch, please read the full description
License: BSD
URL: https://github.com/ValveSoftware/gamescope
# Create stb.pc to satisfy dependency('stb')
Source0: stb.pc
Source1: gamescope-legacy.sh
Patch0: 0001-cstdint.patch
# https://github.com/ChimeraOS/gamescope
#Patch0: chimeraos.patch
Patch1: chimeraos.patch
# https://hhd.dev/
#Patch1: disable-steam-touch-click-atom.patch
# https://github.com/ValveSoftware/gamescope/pull/1281
# Patch2: deckhd.patch
# https://github.com/ValveSoftware/gamescope/issues/1398
Patch3: drm-Separate-BOE-and-SDC-OLED-Deck-panel-rates.patch
# https://github.com/ValveSoftware/gamescope/issues/1369
Patch4: revert-299bc34.patch
# https://github.com/ValveSoftware/gamescope/pull/1231
Patch5: 1231.patch
Patch2: disable-steam-touch-click-atom.patch
Patch3: v2-0001-always-send-ctrl-1-2-to-steam-s-wayland-session.patch
# Set default backend to SDL instead of Wayland, to avoid issues with GPUs that do not support
# Vulkan DRM modifiers.
# See also: gamescope-legacy package
# https://github.com/ValveSoftware/gamescope/issues/1218#issuecomment-2123801764
Patch6: 1483.patch
BuildRequires: meson >= 0.54.0
BuildRequires: ninja-build
BuildRequires: cmake
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: clang
BuildRequires: glm-devel
BuildRequires: google-benchmark-devel
BuildRequires: libXmu-devel
@@ -52,22 +58,16 @@ BuildRequires: pkgconfig(xres)
BuildRequires: pkgconfig(libdrm)
BuildRequires: pkgconfig(vulkan)
BuildRequires: pkgconfig(wayland-scanner)
BuildRequires: pkgconfig(wayland-server)
BuildRequires: pkgconfig(wayland-server) >= 1.23.0
BuildRequires: pkgconfig(wayland-protocols) >= 1.17
BuildRequires: pkgconfig(xkbcommon)
BuildRequires: pkgconfig(sdl2)
BuildRequires: pkgconfig(libpipewire-0.3)
BuildRequires: pkgconfig(libavif)
#BuildRequires: (pkgconfig(wlroots) >= 0.18.0 with pkgconfig(wlroots) < 0.19.0)
#BuildRequires: (pkgconfig(libliftoff) >= 0.4.1 with pkgconfig(libliftoff) < 0.5)
BuildRequires: pkgconfig(libliftoff)
BuildRequires: pkgconfig(wlroots)
BuildRequires: pkgconfig(libliftoff) >= 0.4.1
BuildRequires: pkgconfig(libcap)
BuildRequires: pkgconfig(hwdata)
BuildRequires: pkgconfig(libudev)
BuildRequires: pkgconfig(libseat)
BuildRequires: pkgconfig(libinput)
BuildRequires: xcb-util-wm-devel
BuildRequires: pkgconfig(xcb-errors)
BuildRequires: pkgconfig(lcms2)
BuildRequires: spirv-headers-devel
# Enforce the the minimum EVR to contain fixes for all of:
@@ -90,16 +90,21 @@ BuildRequires: git
# libliftoff hasn't bumped soname, but API/ABI has changed for 0.2.0 release
Requires: libliftoff%{?_isa} >= %{libliftoff_minver}
Requires: xorg-x11-server-Xwayland
Requires: %{name}-libs = %{version}-%{release}
%ifarch %{ix86}
Requires: %{name}-libs(x86-32) = %{version}-%{release}
%endif
Requires: terra-gamescope-libs = %{version}-%{release}
Requires: terra-gamescope-libs(x86-32) = %{version}-%{release}
Recommends: mesa-dri-drivers
Recommends: mesa-vulkan-drivers
Provides: gamescope-legacy
Obsoletes: gamescope-legacy < 3.14.2
%description
Gamescope is the micro-compositor optimized for running video games on Wayland.
This specific build of Gamescope is patched to use SDL as the default backend instead of Wayland, and
includes a legacy wrapper script for older GPUs and extra configuration options. Please see
https://developer.fyralabs.com/terra/gamescope for more information.
%package libs
Summary: libs for Gamescope
%description libs
@@ -120,21 +125,35 @@ sed -i 's^../thirdparty/SPIRV-Headers/include/spirv/^/usr/include/spirv/^' src/m
%build
cd gamescope
export PKG_CONFIG_PATH=pkgconfig
%meson -Dpipewire=enabled -Dinput_emulation=enabled -Ddrm_backend=enabled -Drt_cap=enabled -Davif_screenshots=enabled -Dsdl2_backend=enabled
%if %{__isa_bits} == 64
%meson --auto-features=enabled -Dforce_fallback_for=vkroots,wlroots,libliftoff
%else
%meson -Denable_gamescope=false -Denable_gamescope_wsi_layer=true
%endif
%meson_build
%install
cd gamescope
%meson_install --skip-subprojects
%if %{__isa_bits} == 64
install -Dm755 %{SOURCE1} %{buildroot}%{_bindir}/gamescope-legacy
%endif
%files
%license gamescope/LICENSE
%doc gamescope/README.md
%if %{__isa_bits} == 64
%caps(cap_sys_nice=eip) %{_bindir}/gamescope
%{_bindir}/gamescopectl
%{_bindir}/gamescopestream
%{_bindir}/gamescopereaper
%{_bindir}/gamescope-legacy
%endif
%files libs
%{_libdir}/libVkLayer_FROG_gamescope_wsi_*.so
%{_datadir}/vulkan/implicit_layer.d/VkLayer_FROG_gamescope_wsi.*.json
%changelog
%autochangelog
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
curl -o ./1483.patch https://patch-diff.githubusercontent.com/raw/ValveSoftware/gamescope/pull/1483.patch
@@ -0,0 +1,39 @@
From 35e001dc59a44227d670c667a85a6ef5472eee58 Mon Sep 17 00:00:00 2001
From: antheas <git@antheas.dev>
Date: Sat, 20 Jul 2024 01:23:19 +0300
Subject: [PATCH v2] always send ctrl+1/2 to steam's wayland session
---
src/wlserver.cpp | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/wlserver.cpp b/src/wlserver.cpp
index 1852be9..7de737d 100644
--- a/src/wlserver.cpp
+++ b/src/wlserver.cpp
@@ -369,7 +369,12 @@ static void wlserver_handle_key(struct wl_listener *listener, void *data)
keysym == XKB_KEY_XF86AudioLowerVolume ||
keysym == XKB_KEY_XF86AudioRaiseVolume ||
keysym == XKB_KEY_XF86PowerOff;
- if ( ( event->state == WL_KEYBOARD_KEY_STATE_PRESSED || event->state == WL_KEYBOARD_KEY_STATE_RELEASED ) && forbidden_key )
+
+ // Check for steam keys (ctrl + 1/2)
+ bool is_steamshortcut = (keyboard->wlr->modifiers.depressed & WLR_MODIFIER_CTRL) && (keysym == XKB_KEY_1 ||
+ keysym == XKB_KEY_2);
+
+ if ( ( event->state == WL_KEYBOARD_KEY_STATE_PRESSED || event->state == WL_KEYBOARD_KEY_STATE_RELEASED ) && (forbidden_key || is_steamshortcut) )
{
// Always send volume+/- to root server only, to avoid it reaching the game.
struct wlr_surface *old_kb_surf = wlserver.kb_focus_surface;
@@ -378,6 +383,9 @@ static void wlserver_handle_key(struct wl_listener *listener, void *data)
{
wlserver_keyboardfocus( new_kb_surf, false );
wlr_seat_set_keyboard( wlserver.wlr.seat, keyboard->wlr );
+ // Send modifiers to steam for it to work
+ if (is_steamshortcut)
+ wlr_seat_keyboard_notify_modifiers(wlserver.wlr.seat, &keyboard->wlr->modifiers);
wlr_seat_keyboard_notify_key( wlserver.wlr.seat, event->time_msec, event->keycode, event->state );
wlserver_keyboardfocus( old_kb_surf, false );
return;
--
2.45.2