From af99af20a4403523163a18f888f944facbcc55ba Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Tue, 8 Oct 2024 08:14:32 -0700 Subject: [PATCH 1/3] feat(gamescope): Add Ally display patch and bicubic filter patch, use master branch for now --- spec_files/gamescope/1231.patch | 239 ----- spec_files/gamescope/740.patch | 1012 +++++++++++++++++++++ spec_files/gamescope/chimeraos.patch | 579 +++++++----- spec_files/gamescope/gamescope.spec | 14 +- spec_files/gamescope/revert-299bc34.patch | 65 -- 5 files changed, 1351 insertions(+), 558 deletions(-) delete mode 100644 spec_files/gamescope/1231.patch create mode 100644 spec_files/gamescope/740.patch delete mode 100644 spec_files/gamescope/revert-299bc34.patch diff --git a/spec_files/gamescope/1231.patch b/spec_files/gamescope/1231.patch deleted file mode 100644 index e21cb0a8..00000000 --- a/spec_files/gamescope/1231.patch +++ /dev/null @@ -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 - #include - #include -+#include - - 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 cached_cookies; -+ std::tuple 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 - void operator()(T* ptr) const { -- free(const_cast*>(ptr)); -+ if (m_bOwning) -+ free(const_cast*>(ptr)); - } - }; - - template - using Reply = std::unique_ptr; -+ -+ template -+ 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 operator()(XcbConn conn, auto... args) { //have to use auto for argsTwo, since otherwise there'd be a type deduction conflict -+ return Reply { m_replyFunc(conn, m_cookieFunc(conn, args...), nullptr) }; -+ } -+ }; -+ -+ template -+ concept CacheableCookie = std::is_same::value -+ || std::is_same::value; -+ -+ template -+ class XcbFetch { -+ 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 getCachedReply(xcb_connection_t* connection) { -+ if (std::get(g_cache.cached_replies) == nullptr) { -+ std::get(g_cache.cached_replies) = m_replyFunc(connection, std::get(g_cache.cached_cookies), nullptr); -+ } - -+ return Reply{std::get(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 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 { 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 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(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(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 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(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 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(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 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(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(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 GetPrefetcherIf(bool bCond, xcb_connection_t* connection, const xcb_window_t window) { -+ if (bCond) -+ return std::optional(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 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 { m_replyFunc(conn, m_cookieFunc(conn, window), nullptr) }; - - auto ret = getCachedReply(conn); diff --git a/spec_files/gamescope/740.patch b/spec_files/gamescope/740.patch new file mode 100644 index 00000000..97a763f3 --- /dev/null +++ b/spec_files/gamescope/740.patch @@ -0,0 +1,1012 @@ +From 564a689c2b293d2e894bf1edb14eb0f78bde8725 Mon Sep 17 00:00:00 2001 +From: "Ruan E. Formigoni" +Date: Sat, 5 Oct 2024 14:40:23 -0300 +Subject: [PATCH 1/9] Partial bicubic code adaptation + +--- + src/Backends/SDLBackend.cpp | 4 + + src/Backends/WaylandBackend.cpp | 1 + + src/main.cpp | 29 ++++++ + src/main.hpp | 15 +++ + src/meson.build | 1 + + src/rendervulkan.cpp | 64 +++++++++++- + src/rendervulkan.hpp | 2 + + src/shaders/bicubic.h | 44 ++++++++ + src/shaders/cs_bicubic.comp | 176 ++++++++++++++++++++++++++++++++ + src/steamcompmgr.cpp | 6 ++ + 10 files changed, 341 insertions(+), 1 deletion(-) + create mode 100644 src/shaders/bicubic.h + create mode 100644 src/shaders/cs_bicubic.comp + +diff --git a/src/Backends/SDLBackend.cpp b/src/Backends/SDLBackend.cpp +index 6d50f8d34..c24b864c6 100644 +--- a/src/Backends/SDLBackend.cpp ++++ b/src/Backends/SDLBackend.cpp +@@ -719,6 +719,10 @@ namespace gamescope + case KEY_B: + g_wantedUpscaleFilter = GamescopeUpscaleFilter::LINEAR; + break; ++ case KEY_K: ++ g_wantedDownscaleFilter = (g_wantedDownscaleFilter == GamescopeDownscaleFilter::BICUBIC) ? ++ GamescopeDownscaleFilter::LINEAR : GamescopeDownscaleFilter::BICUBIC; ++ break; + case KEY_U: + g_wantedUpscaleFilter = (g_wantedUpscaleFilter == GamescopeUpscaleFilter::FSR) ? + GamescopeUpscaleFilter::LINEAR : GamescopeUpscaleFilter::FSR; +diff --git a/src/Backends/WaylandBackend.cpp b/src/Backends/WaylandBackend.cpp +index c53bf14df..d0abb2fa2 100644 +--- a/src/Backends/WaylandBackend.cpp ++++ b/src/Backends/WaylandBackend.cpp +@@ -1598,6 +1598,7 @@ namespace gamescope + bNeedsFullComposite |= cv_composite_force; + bNeedsFullComposite |= pFrameInfo->useFSRLayer0; + bNeedsFullComposite |= pFrameInfo->useNISLayer0; ++ bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0; + bNeedsFullComposite |= pFrameInfo->blurLayer0; + bNeedsFullComposite |= bNeedsCompositeFromFilter; + bNeedsFullComposite |= g_bColorSliderInUse; +diff --git a/src/main.cpp b/src/main.cpp +index a9cdaa2e2..ed7fd4fa7 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + #if defined(__linux__) + #include +@@ -63,6 +64,7 @@ const struct option *gamescope_options = (struct option[]){ + { "output-height", required_argument, nullptr, 'H' }, + { "sharpness", required_argument, nullptr, 0 }, + { "fsr-sharpness", required_argument, nullptr, 0 }, ++ { "bicubic", optional_argument, nullptr, 'D' }, + { "rt", no_argument, nullptr, 0 }, + { "prefer-vk-device", required_argument, 0 }, + { "expose-wayland", no_argument, 0 }, +@@ -288,11 +290,14 @@ bool g_bGrabbed = false; + float g_mouseSensitivity = 1.0; + + GamescopeUpscaleFilter g_upscaleFilter = GamescopeUpscaleFilter::LINEAR; ++GamescopeDownscaleFilter g_downscaleFilter = GamescopeDownscaleFilter::LINEAR; + GamescopeUpscaleScaler g_upscaleScaler = GamescopeUpscaleScaler::AUTO; + + GamescopeUpscaleFilter g_wantedUpscaleFilter = GamescopeUpscaleFilter::LINEAR; ++GamescopeDownscaleFilter g_wantedDownscaleFilter = GamescopeDownscaleFilter::LINEAR; + GamescopeUpscaleScaler g_wantedUpscaleScaler = GamescopeUpscaleScaler::AUTO; + int g_upscaleFilterSharpness = 2; ++GamescopeBicubicParams g_bicubicParams; + + gamescope::GamescopeModeGeneration g_eGamescopeModeGeneration = gamescope::GAMESCOPE_MODE_GENERATE_CVT; + +@@ -397,6 +402,27 @@ static enum GamescopeUpscaleFilter parse_upscaler_filter(const char *str) + } + } + ++static enum GamescopeDownscaleFilter parse_downscaling_filter(const char *str) ++{ ++ std::stringstream ss{optarg}; ++ ++ double b, c; ++ char comma; ++ if ((ss >> b >> comma >> c) && (comma == ',')) { ++ // clamp values ++ b = std::clamp(b, 0.0, 1.0); ++ c = std::clamp(c, 0.0, 1.0); ++ // Ovewrite default global parameters ++ g_bicubicParams.b = b; ++ g_bicubicParams.c = c; ++ // Set downscaling filters ++ return GamescopeDownscaleFilter::BICUBIC; ++ } ++ ++ fprintf( stderr, "gamescope: invalid value for --bicubic\n" ); ++ exit(1); ++} ++ + static enum gamescope::GamescopeBackend parse_backend_name(const char *str) + { + if (strcmp(str, "auto") == 0) { +@@ -704,6 +730,9 @@ int main(int argc, char **argv) + case 'F': + g_wantedUpscaleFilter = parse_upscaler_filter(optarg); + break; ++ case 'D': ++ g_wantedDownscaleFilter = parse_downscaling_filter(optarg); ++ break; + case 'b': + g_bBorderlessOutputWindow = true; + break; +diff --git a/src/main.hpp b/src/main.hpp +index 2e6fb833a..f8cc03053 100644 +--- a/src/main.hpp ++++ b/src/main.hpp +@@ -40,6 +40,18 @@ enum class GamescopeUpscaleFilter : uint32_t + FROM_VIEW = 0xF, // internal + }; + ++enum class GamescopeDownscaleFilter : uint32_t ++{ ++ LINEAR = 0, ++ BICUBIC, ++}; ++ ++struct GamescopeBicubicParams ++{ ++ float b = 0.3f; ++ float c = 0.3f; ++}; ++ + static constexpr bool DoesHardwareSupportUpscaleFilter( GamescopeUpscaleFilter eFilter ) + { + // Could do nearest someday... AMDGPU DC supports custom tap placement to an extent. +@@ -57,10 +69,13 @@ enum class GamescopeUpscaleScaler : uint32_t + }; + + extern GamescopeUpscaleFilter g_upscaleFilter; ++extern GamescopeDownscaleFilter g_downscaleFilter; + extern GamescopeUpscaleScaler g_upscaleScaler; + extern GamescopeUpscaleFilter g_wantedUpscaleFilter; ++extern GamescopeDownscaleFilter g_wantedDownscaleFilter; + extern GamescopeUpscaleScaler g_wantedUpscaleScaler; + extern int g_upscaleFilterSharpness; ++extern GamescopeBicubicParams g_bicubicParams; + + extern bool g_bBorderlessOutputWindow; + +diff --git a/src/meson.build b/src/meson.build +index 5174de670..907277a23 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -66,6 +66,7 @@ shader_src = [ + 'shaders/cs_composite_rcas.comp', + 'shaders/cs_easu.comp', + 'shaders/cs_easu_fp16.comp', ++ 'shaders/cs_bicubic.comp', + 'shaders/cs_gaussian_blur_horizontal.comp', + 'shaders/cs_nis.comp', + 'shaders/cs_nis_fp16.comp', +diff --git a/src/rendervulkan.cpp b/src/rendervulkan.cpp +index d61fd73ea..45f45deba 100644 +--- a/src/rendervulkan.cpp ++++ b/src/rendervulkan.cpp +@@ -44,6 +44,7 @@ + #include "cs_composite_rcas.h" + #include "cs_easu.h" + #include "cs_easu_fp16.h" ++#include "cs_bicubic.h" + #include "cs_gaussian_blur_horizontal.h" + #include "cs_nis.h" + #include "cs_nis_fp16.h" +@@ -52,6 +53,7 @@ + #define A_CPU + #include "shaders/ffx_a.h" + #include "shaders/ffx_fsr1.h" ++#include "shaders/bicubic.h" + + #include "reshade_effect_manager.hpp" + +@@ -890,11 +892,13 @@ bool CVulkanDevice::createShaders() + if (m_bSupportsFp16) + { + SHADER(EASU, cs_easu_fp16); ++ SHADER(BICUBIC, cs_bicubic); + SHADER(NIS, cs_nis_fp16); + } + else + { + SHADER(EASU, cs_easu); ++ SHADER(BICUBIC, cs_bicubic); + SHADER(NIS, cs_nis); + } + SHADER(RGB_TO_NV12, cs_rgb_to_nv12); +@@ -1126,6 +1130,7 @@ void CVulkanDevice::compileAllPipelines() + SHADER(BLUR_FIRST_PASS, 1, 2, 1); + SHADER(RCAS, k_nMaxLayers, k_nMaxYcbcrMask_ToPreCompile, 1); + SHADER(EASU, 1, 1, 1); ++ SHADER(BICUBIC, 1, 1, 1); + SHADER(NIS, 1, 1, 1); + SHADER(RGB_TO_NV12, 1, 1, 1); + #undef SHADER +@@ -3691,6 +3696,17 @@ struct EasuPushData_t + } + }; + ++struct BicubicPushData_t ++{ ++ uvec4_t Const0; ++ uvec4_t Const1; ++ ++ BicubicPushData_t(float B, float C, uint32_t inputX, uint32_t inputY, uint32_t tempX, uint32_t tempY, uint32_t winX, uint32_t winY) ++ { ++ BicubicCon(&Const0.x, &Const1.x, B*10, C*10, inputX, inputY, tempX, tempY, winX, winY); ++ } ++}; ++ + struct RcasPushData_t + { + uvec2_t u_layer0Offset; +@@ -3900,7 +3916,53 @@ std::optional vulkan_composite( struct FrameInfo_t *frameInfo, gamesco + for (uint32_t i = 0; i < EOTF_Count; i++) + cmdBuffer->bindColorMgmtLuts(i, frameInfo->shaperLut[i], frameInfo->lut3D[i]); + +- if ( frameInfo->useFSRLayer0 ) ++ if ( frameInfo->useBICUBICLayer0 ) ++ { ++ // fprintf(stderr, "-- Use bicubic\n"); ++ uint32_t inputX = frameInfo->layers[0].tex->width(); ++ uint32_t inputY = frameInfo->layers[0].tex->height(); ++ ++ uint32_t tempX = frameInfo->layers[0].integerWidth(); ++ uint32_t tempY = frameInfo->layers[0].integerHeight(); ++ ++ update_tmp_images(tempX, tempY); ++ ++ cmdBuffer->bindPipeline( g_device.pipeline(SHADER_TYPE_BICUBIC, frameInfo->layerCount, frameInfo->ycbcrMask())); ++ // cmdBuffer->bindTarget(compositeImage); ++ cmdBuffer->bindTarget(g_output.tmpOutput); ++ cmdBuffer->bindTexture(0, frameInfo->layers[0].tex); ++ cmdBuffer->setTextureSrgb(0, true); ++ cmdBuffer->setSamplerUnnormalized(0, false); ++ cmdBuffer->setSamplerNearest(0, false); ++ cmdBuffer->uploadConstants(g_bicubicParams.b ++ , g_bicubicParams.c ++ , inputX ++ , inputY ++ , tempX ++ , tempY ++ , currentOutputWidth ++ , currentOutputHeight ++ ); ++ ++ int pixelsPerGroup = 16; ++ ++ cmdBuffer->dispatch(div_roundup(tempX, pixelsPerGroup), div_roundup(tempY, pixelsPerGroup)); ++ ++ struct FrameInfo_t bicFrameInfo = *frameInfo; ++ bicFrameInfo.layers[0].tex = g_output.tmpOutput; ++ bicFrameInfo.layers[0].scale.x = 1.0f; ++ bicFrameInfo.layers[0].scale.y = 1.0f; ++ ++ cmdBuffer->bindPipeline( g_device.pipeline(SHADER_TYPE_BLIT, bicFrameInfo.layerCount, bicFrameInfo.ycbcrMask())); ++ bind_all_layers(cmdBuffer.get(), &bicFrameInfo); ++ cmdBuffer->bindTarget(compositeImage); ++ cmdBuffer->uploadConstants(&bicFrameInfo); ++ ++ pixelsPerGroup = 8; ++ ++ cmdBuffer->dispatch(div_roundup(currentOutputWidth, pixelsPerGroup), div_roundup(currentOutputHeight, pixelsPerGroup)); ++ } ++ else if ( frameInfo->useFSRLayer0 ) + { + uint32_t inputX = frameInfo->layers[0].tex->width(); + uint32_t inputY = frameInfo->layers[0].tex->height(); +diff --git a/src/rendervulkan.hpp b/src/rendervulkan.hpp +index b967e849f..f6b80c5a1 100644 +--- a/src/rendervulkan.hpp ++++ b/src/rendervulkan.hpp +@@ -269,6 +269,7 @@ struct FrameInfo_t + { + bool useFSRLayer0; + bool useNISLayer0; ++ bool useBICUBICLayer0; + bool bFadingOut; + BlurMode blurLayer0; + int blurRadius; +@@ -530,6 +531,7 @@ enum ShaderType { + SHADER_TYPE_EASU, + SHADER_TYPE_RCAS, + SHADER_TYPE_NIS, ++ SHADER_TYPE_BICUBIC, + SHADER_TYPE_RGB_TO_NV12, + + SHADER_TYPE_COUNT +diff --git a/src/shaders/bicubic.h b/src/shaders/bicubic.h +new file mode 100644 +index 000000000..8117e8783 +--- /dev/null ++++ b/src/shaders/bicubic.h +@@ -0,0 +1,44 @@ ++//_____________________________________________________________/\_______________________________________________________________ ++//============================================================================================================================== ++// ++// ++// BICUBIC IMAGE SCALING ++// ++// ++//------------------------------------------------------------------------------------------------------------------------------ ++//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++//_____________________________________________________________/\_______________________________________________________________ ++//============================================================================================================================== ++// CONSTANT SETUP ++//============================================================================================================================== ++// Call to setup required constant values (works on CPU or GPU). ++A_STATIC void BicubicCon( ++outAU4 con0, ++outAU4 con1, ++// Configurable parameters ++AU1 B, ++AU1 C, ++// This the rendered image resolution ++AF1 inputRenderedSizeX, ++AF1 inputRenderedSizeY, ++// This is the resolution of the resource containing the input image (useful for dynamic resolution) ++AF1 inputCurrentSizeX, ++AF1 inputCurrentSizeY, ++// This is the window width / height ++AF1 outputTargetSizeX, ++AF1 outputTargetSizeY) ++{ ++ // Input/Output size information ++ con0[0]=AU1_AF1(inputRenderedSizeX); ++ con0[1]=AU1_AF1(inputRenderedSizeY); ++ con0[2]=AU1_AF1(inputCurrentSizeX); ++ con0[3]=AU1_AF1(inputCurrentSizeY); ++ ++ // Viewport pixel position to normalized image space. ++ con1[0]=AU1_AF1(outputTargetSizeX); ++ con1[1]=AU1_AF1(outputTargetSizeY); ++ con1[2]=B; ++ con1[3]=C; ++} +diff --git a/src/shaders/cs_bicubic.comp b/src/shaders/cs_bicubic.comp +new file mode 100644 +index 000000000..4904433b5 +--- /dev/null ++++ b/src/shaders/cs_bicubic.comp +@@ -0,0 +1,176 @@ ++// References ++// https://www.codeproject.com/Articles/236394/Bi-Cubic-and-Bi-Linear-Interpolation-with-GLSL ++// https://stackoverflow.com/questions/13501081/efficient-bicubic-filtering-code-in-glsl ++// https://web.archive.org/web/20180927181721/http://www.java-gaming.org/index.php?topic=35123.0 ++// https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1 ++ ++#version 460 ++ ++#extension GL_GOOGLE_include_directive : require ++#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require ++ ++#include "descriptor_set.h" ++ ++layout( ++ local_size_x = 64, ++ local_size_y = 1, ++ local_size_z = 1) in; ++ ++// Push constant is a mechanism in modern OpenGL that allows passing small amounts of frequently ++// updated data to the shader without needing to bind a buffer ++layout(push_constant) ++uniform layers_t { ++ uvec4 c0, c1; ++}; ++ ++#define A_GPU 1 ++#define A_GLSL 1 ++#define A_HALF 1 ++#include "ffx_a.h" ++#include "bicubic.h" ++ ++// The Mitchell–Netravali filters or BC-splines ++// https://en.wikipedia.org/wiki/Mitchell%E2%80%93Netravali_filters ++// Conditionals are slow in GPU code, so to represent 0 <= f < 1 and 1 <= f < 2 ++// the P(d) form shown in the wikipedia page is used ++vec4 mitchellNetravaliWeights(float f, float B, float C) ++{ ++ float w0 = ((12.0 - 9.0 * B - 6.0 * C) * pow(f, 3.0)) + ++ ((-18.0 + 12.0 * B + 6.0 * C) * pow(f, 2.0)) + ++ (6.0 - 2.0 * B); ++ ++ float w1 = ((-B - 6.0 * C) * pow(f - 1.0, 3.0)) + ++ ((6.0 * B + 30.0 * C) * pow(f - 1.0, 2.0)) + ++ ((-12.0 * B - 48.0 * C) * (f - 1.0)) + ++ (8.0 * B + 24.0 * C); ++ ++ float w2 = ((12.0 - 9.0 * B - 6.0 * C) * pow(1.0 - f, 3.0)) + ++ ((-18.0 + 12.0 * B + 6.0 * C) * pow(1.0 - f, 2.0)) + ++ (6.0 - 2.0 * B); ++ ++ float w3 = ((-B - 6.0 * C) * pow(2.0 - f, 3.0)) + ++ ((6.0 * B + 30.0 * C) * pow(2.0 - f, 2.0)) + ++ ((-12.0 * B - 48.0 * C) * (2.0 - f)) + ++ (8.0 * B + 24.0 * C); ++ ++ return vec4(w0, w1, w2, w3); ++} ++ ++// https://stackoverflow.com/questions/13501081/efficient-bicubic-filtering-code-in-glsl ++// https://web.archive.org/web/20180927181721/http://www.java-gaming.org/index.php?topic=35123.0 ++// This is an efficient method to implement bicubic filtering, it takes ++// advantage of the fact that the bilinear approach gives the weighted average ++// of a 2x2 area. ++vec4 textureBicubic(sampler2D splr, vec2 texCoords) ++{ ++ vec2 texSize = textureSize(splr, 0); ++ vec2 invTexSize = 1.0 / texSize; ++ ++ // Converts normalized coordinates into pixel-space coordinate ++ // Example: If texCoords is (0.5, 0.5), and the texture size is (1920, 1080), the result will be ++ // (960, 540)—the center of the texture in pixel space. ++ // Subtracting 0.5 ensures that you're sampling from the center of the texel rather than its corner ++ // Example: Assume we have a 3x3 texture and texCoords = (0.5, 0.5): ++ // [0,0][1,0][2,0] ++ // [0,1][1,1][2,1] ++ // [0,2][1,2][2,2] ++ // texCoords * texSize - 0.5 maps to (1.5, 1.5), which is between (1,1) and (2,2), then ++ // subtracts 0.5 to move it to (1.0, 1.0)—the center of the texel ++ texCoords = texCoords * texSize - 0.5; ++ ++ // Get B and C that were pushed from the user input (or default values) ++ float B = c1[2] / 10.0f; ++ float C = c1[3] / 10.0f; ++ ++ // Get the fractional part of the coordinates ++ // They are used in Mitchell Netravali's strategy to calculate the interpolation weights, ++ // i.e., how much influence the neighboring vertices have on the final pixel value ++ vec2 fxy = fract(texCoords); ++ texCoords -= fxy; ++ ++ // Calculate bicubic weights ++ // These weights represent how much influence each neighboring texel in the 4x4 grid will have ++ // on the final interpolated pixel value ++ vec4 xweights = mitchellNetravaliWeights(fxy.x, B, C); ++ vec4 yweights = mitchellNetravaliWeights(fxy.y, B, C); ++ ++ // Modify the current texture coordinates to have an offset in texels for each coordinate ++ // E.g. texCoords + vec(-1.0, 0.0) is a texel to the left ++ // texCoords + vec(1.0, 0.0) is a texel to the right ++ // texCoords + vec(0.0, 1.0) is a texel downwards ++ // texCoords + vec(0.0, -1.0) is a texel upwards ++ vec4 offsetTexels = texCoords.xxyy; ++ offsetTexels += vec2 (-1.0, +1.0).xyxy; ++ // Normalize weights to range between (0,1) ++ // vec4 sumWeights = vec4(xweights.xz + xweights.yw, yweights.xz + yweights.yw); ++ // vec4 normalizedWeights = vec4 (xweights.yw, yweights.yw) / sumWeights; ++ vec4 sumWeights = vec4(xweights.x + xweights.y, xweights.z + xweights.w, yweights.x + yweights.y, yweights.z + yweights.w); ++ vec4 normalizedWeights = vec4 (xweights.y, xweights.w, yweights.y, yweights.w) / sumWeights; ++ // Use the weights to influence the sampling position inside each texel ++ // Each texel has a size from (0,1) ++ vec4 offsetSampler = offsetTexels + normalizedWeights; ++ // Go back to normalized space ++ offsetSampler *= invTexSize.xxyy; ++ // Perform the sampling ++ vec4 sample0 = texture(splr, offsetSampler.xz); ++ vec4 sample1 = texture(splr, offsetSampler.yz); ++ vec4 sample2 = texture(splr, offsetSampler.xw); ++ vec4 sample3 = texture(splr, offsetSampler.yw); ++ ++ // Now we perform linear interpolation in the selected points ++ // The mix(a, b, t) function in GLSL performs linear interpolation between a and b based on the ++ // parameter t, t is between 0 and 1 ++ // https://registry.khronos.org/OpenGL-Refpages/gl4/html/mix.xhtml ++ ++ // Here we want to normalize sx and sy to between 0 and 1 (t value) ++ float sx = sumWeights.x / (sumWeights.x + sumWeights.y); ++ float sy = sumWeights.z / (sumWeights.z + sumWeights.w); ++ ++ return mix( ++ mix(sample3, sample2, sx), mix(sample1, sample0, sx) ++ , sy); ++} ++ ++void bicPass(uvec2 pos) ++{ ++ // Retrieve pushed values ++ AF2 inputRenderedSize = AF2_AU2(c0.xy); ++ AF2 inputCurrentSize = AF2_AU2(c0.zw); ++ AF2 outputTargetSize = AF2_AU2(c1.xy); ++ ++ // ARcpF1(x) == 1.0 / x ++ // scaleFactor is the division between the rendered image and the size it should have at the end ++ // E.g.: Rendered 1920x1080, window size is 960x540, then scaleFactor is 2x2 ++ AF2 scaleFactor = inputRenderedSize * vec2(ARcpF1(inputCurrentSize.x), ARcpF1(inputCurrentSize.y)); ++ ++ // The parameter pos of this function is used to iterate over the output image (e.g. 960x540) ++ // The position of the processed pixel should be taken from the rendered image (e.g. 1920x1080) ++ // 10x10 in the output, corresponds to 20x20 in the original image ++ AF2 positionPixel=AF2(pos)*scaleFactor; ++ ++ // Normalize the image space to be between [0,1] ++ positionPixel=positionPixel*vec2(ARcpF1(inputRenderedSize.x),ARcpF1(inputRenderedSize.y)); ++ ++ // Apply the bicubic algorithm in the normalized pixel position ++ vec4 bicPass = textureBicubic(s_samplers[0], positionPixel); ++ ++ imageStore(dst, ivec2(pos), bicPass); ++} ++ ++ ++void main() ++{ ++ // AMD recommends to use this swizzle and to process 4 pixel per invocation ++ // for better cache utilisation ++ uvec2 pos = ARmp8x8(gl_LocalInvocationID.x) + uvec2(gl_WorkGroupID.x << 4u, gl_WorkGroupID.y << 4u); ++ ++ bicPass(pos); ++ pos.x += 8u; ++ bicPass(pos); ++ pos.y += 8u; ++ bicPass(pos); ++ pos.x -= 8u; ++ bicPass(pos); ++} ++ ++/* vim: set expandtab ft=cpp fdm=marker ts=4 sw=4 tw=100 et :*/ +diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp +index 02148f423..b33608707 100644 +--- a/src/steamcompmgr.cpp ++++ b/src/steamcompmgr.cpp +@@ -2356,6 +2356,10 @@ paint_all(bool async) + paint_window(w, w, &frameInfo, global_focus.cursor, PaintWindowFlag::BasePlane | PaintWindowFlag::DrawBorders, 1.0f, override); + + bool needsScaling = frameInfo.layers[0].scale.x < 0.999f && frameInfo.layers[0].scale.y < 0.999f; ++ // Temporarily allow upscaling as well ++ // bool needsDownScaling = frameInfo.layers[0].scale.x > 1.001f && frameInfo.layers[0].scale.y > 1.001f; ++ bool needsDownScaling = true; ++ frameInfo.useBICUBICLayer0 = g_downscaleFilter == GamescopeDownscaleFilter::BICUBIC && needsDownScaling; + frameInfo.useFSRLayer0 = g_upscaleFilter == GamescopeUpscaleFilter::FSR && needsScaling; + frameInfo.useNISLayer0 = g_upscaleFilter == GamescopeUpscaleFilter::NIS && needsScaling; + } +@@ -2488,6 +2492,7 @@ paint_all(bool async) + } + + frameInfo.useFSRLayer0 = false; ++ frameInfo.useBICUBICLayer0 = false; + frameInfo.useNISLayer0 = false; + } + +@@ -7846,6 +7851,7 @@ steamcompmgr_main(int argc, char **argv) + g_bSteamIsActiveWindow = false; + g_upscaleScaler = g_wantedUpscaleScaler; + g_upscaleFilter = g_wantedUpscaleFilter; ++ g_downscaleFilter = g_wantedDownscaleFilter; + } + + // If we're in the middle of a fade, then keep us + +From 6acfb50f09cc9fd8a16dd502d260b920a8ba02cb Mon Sep 17 00:00:00 2001 +From: "Ruan E. Formigoni" +Date: Sat, 5 Oct 2024 15:19:23 -0300 +Subject: [PATCH 2/9] Partial bicubic code adaptation [2] + +--- + src/Backends/DRMBackend.cpp | 1 + + src/Backends/OpenVRBackend.cpp | 1 + + src/main.cpp | 6 +++--- + src/rendervulkan.cpp | 3 +-- + src/shaders/descriptor_set.h | 1 + + src/steamcompmgr.cpp | 17 +++++++++++++++++ + src/steamcompmgr.hpp | 1 + + src/xwayland_ctx.hpp | 1 + + 8 files changed, 26 insertions(+), 5 deletions(-) + +diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp +index c62635f19..76c9f0514 100644 +--- a/src/Backends/DRMBackend.cpp ++++ b/src/Backends/DRMBackend.cpp +@@ -3211,6 +3211,7 @@ namespace gamescope + bNeedsFullComposite |= bWasFirstFrame; + bNeedsFullComposite |= pFrameInfo->useFSRLayer0; + bNeedsFullComposite |= pFrameInfo->useNISLayer0; ++ bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0; + bNeedsFullComposite |= pFrameInfo->blurLayer0; + bNeedsFullComposite |= bNeedsCompositeFromFilter; + bNeedsFullComposite |= !k_bUseCursorPlane && bDrewCursor; +diff --git a/src/Backends/OpenVRBackend.cpp b/src/Backends/OpenVRBackend.cpp +index c39caa54b..08640f853 100644 +--- a/src/Backends/OpenVRBackend.cpp ++++ b/src/Backends/OpenVRBackend.cpp +@@ -554,6 +554,7 @@ namespace gamescope + bNeedsFullComposite |= cv_composite_force; + bNeedsFullComposite |= pFrameInfo->useFSRLayer0; + bNeedsFullComposite |= pFrameInfo->useNISLayer0; ++ bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0; + bNeedsFullComposite |= pFrameInfo->blurLayer0; + bNeedsFullComposite |= bNeedsCompositeFromFilter; + bNeedsFullComposite |= g_bColorSliderInUse; +diff --git a/src/main.cpp b/src/main.cpp +index ed7fd4fa7..de25ddeab 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -402,7 +402,7 @@ static enum GamescopeUpscaleFilter parse_upscaler_filter(const char *str) + } + } + +-static enum GamescopeDownscaleFilter parse_downscaling_filter(const char *str) ++static enum GamescopeDownscaleFilter parse_downscaler_filter(const char *str) + { + std::stringstream ss{optarg}; + +@@ -415,7 +415,7 @@ static enum GamescopeDownscaleFilter parse_downscaling_filter(const char *str) + // Ovewrite default global parameters + g_bicubicParams.b = b; + g_bicubicParams.c = c; +- // Set downscaling filters ++ // Set downscaler filters + return GamescopeDownscaleFilter::BICUBIC; + } + +@@ -731,7 +731,7 @@ int main(int argc, char **argv) + g_wantedUpscaleFilter = parse_upscaler_filter(optarg); + break; + case 'D': +- g_wantedDownscaleFilter = parse_downscaling_filter(optarg); ++ g_wantedDownscaleFilter = parse_downscaler_filter(optarg); + break; + case 'b': + g_bBorderlessOutputWindow = true; +diff --git a/src/rendervulkan.cpp b/src/rendervulkan.cpp +index 45f45deba..e80afb68a 100644 +--- a/src/rendervulkan.cpp ++++ b/src/rendervulkan.cpp +@@ -889,16 +889,15 @@ bool CVulkanDevice::createShaders() + SHADER(BLUR_COND, cs_composite_blur_cond); + SHADER(BLUR_FIRST_PASS, cs_gaussian_blur_horizontal); + SHADER(RCAS, cs_composite_rcas); ++ SHADER(BICUBIC, cs_bicubic); + if (m_bSupportsFp16) + { + SHADER(EASU, cs_easu_fp16); +- SHADER(BICUBIC, cs_bicubic); + SHADER(NIS, cs_nis_fp16); + } + else + { + SHADER(EASU, cs_easu); +- SHADER(BICUBIC, cs_bicubic); + SHADER(NIS, cs_nis); + } + SHADER(RGB_TO_NV12, cs_rgb_to_nv12); +diff --git a/src/shaders/descriptor_set.h b/src/shaders/descriptor_set.h +index f2b8527c8..64cc1c9c3 100644 +--- a/src/shaders/descriptor_set.h ++++ b/src/shaders/descriptor_set.h +@@ -21,6 +21,7 @@ const int filter_nearest = 1; + const int filter_fsr = 2; + const int filter_nis = 3; + const int filter_pixel = 4; ++const int filter_bicubic = 5; + const int filter_from_view = 255; + + const int EOTF_Gamma22 = 0; +diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp +index b33608707..86a815f06 100644 +--- a/src/steamcompmgr.cpp ++++ b/src/steamcompmgr.cpp +@@ -874,6 +874,7 @@ gamescope::ConCommand cc_debug_set_fps_limit( "debug_set_fps_limit", "Set refres + static int g_nRuntimeInfoFd = -1; + + bool g_bFSRActive = false; ++bool g_bBicubicActive = false; + + BlurMode g_BlurMode = BLUR_MODE_OFF; + BlurMode g_BlurModeOld = BLUR_MODE_OFF; +@@ -2497,6 +2498,7 @@ paint_all(bool async) + } + + g_bFSRActive = frameInfo.useFSRLayer0; ++ g_bBicubicActive = frameInfo.useBICUBICLayer0; + + g_bFirstFrame = false; + +@@ -5417,6 +5419,9 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev) + g_wantedUpscaleScaler = GamescopeUpscaleScaler::AUTO; + g_wantedUpscaleFilter = GamescopeUpscaleFilter::NIS; + break; ++ case 5: ++ g_wantedDownscaleFilter = GamescopeDownscaleFilter::BICUBIC; ++ break; + } + hasRepaint = true; + } +@@ -6969,6 +6974,7 @@ void init_xwayland_ctx(uint32_t serverId, gamescope_xwayland_server_t *xwayland_ + ctx->atoms.gamescopeLowLatency = XInternAtom( ctx->dpy, "GAMESCOPE_LOW_LATENCY", false ); + + ctx->atoms.gamescopeFSRFeedback = XInternAtom( ctx->dpy, "GAMESCOPE_FSR_FEEDBACK", false ); ++ ctx->atoms.gamescopeBicubicFeedback = XInternAtom( ctx->dpy, "GAMESCOPE_BICUBIC_FEEDBACK", false ); + + ctx->atoms.gamescopeBlurMode = XInternAtom( ctx->dpy, "GAMESCOPE_BLUR_MODE", false ); + ctx->atoms.gamescopeBlurRadius = XInternAtom( ctx->dpy, "GAMESCOPE_BLUR_RADIUS", false ); +@@ -7224,6 +7230,7 @@ extern int g_nPreferredOutputWidth; + extern int g_nPreferredOutputHeight; + + static bool g_bWasFSRActive = false; ++static bool g_bWasBicubicActive = false; + + bool g_bAppWantsHDRCached = false; + +@@ -7615,6 +7622,16 @@ steamcompmgr_main(int argc, char **argv) + flush_root = true; + } + ++ if ( g_bBicubicActive != g_bWasBicubicActive ) ++ { ++ uint32_t active = g_bBicubicActive ? 1 : 0; ++ XChangeProperty( root_ctx->dpy, root_ctx->root, root_ctx->atoms.gamescopeBicubicFeedback, XA_CARDINAL, 32, PropModeReplace, ++ (unsigned char *)&active, 1 ); ++ ++ g_bWasBicubicActive = g_bBicubicActive; ++ flush_root = true; ++ } ++ + if (global_focus.IsDirty()) + determine_and_apply_focus(); + +diff --git a/src/steamcompmgr.hpp b/src/steamcompmgr.hpp +index 9f384c461..ea0746860 100644 +--- a/src/steamcompmgr.hpp ++++ b/src/steamcompmgr.hpp +@@ -128,6 +128,7 @@ extern float focusedWindowOffsetX; + extern float focusedWindowOffsetY; + + extern bool g_bFSRActive; ++extern bool g_bBicubicActive; + + extern uint32_t inputCounter; + extern uint64_t g_lastWinSeq; +diff --git a/src/xwayland_ctx.hpp b/src/xwayland_ctx.hpp +index df2af70d1..e212a119e 100644 +--- a/src/xwayland_ctx.hpp ++++ b/src/xwayland_ctx.hpp +@@ -164,6 +164,7 @@ struct xwayland_ctx_t final : public gamescope::IWaitable + Atom gamescopeLowLatency; + + Atom gamescopeFSRFeedback; ++ Atom gamescopeBicubicFeedback; + + Atom gamescopeBlurMode; + Atom gamescopeBlurRadius; + +From fceb9b90021e0abf2da6e8cff71034dc204afb24 Mon Sep 17 00:00:00 2001 +From: "Ruan E. Formigoni" +Date: Mon, 7 Oct 2024 00:37:49 -0300 +Subject: [PATCH 3/9] Fix indentation + +--- + src/Backends/OpenVRBackend.cpp | 2 +- + src/Backends/WaylandBackend.cpp | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/Backends/OpenVRBackend.cpp b/src/Backends/OpenVRBackend.cpp +index 08640f853..96a3d0166 100644 +--- a/src/Backends/OpenVRBackend.cpp ++++ b/src/Backends/OpenVRBackend.cpp +@@ -554,7 +554,7 @@ namespace gamescope + bNeedsFullComposite |= cv_composite_force; + bNeedsFullComposite |= pFrameInfo->useFSRLayer0; + bNeedsFullComposite |= pFrameInfo->useNISLayer0; +- bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0; ++ bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0; + bNeedsFullComposite |= pFrameInfo->blurLayer0; + bNeedsFullComposite |= bNeedsCompositeFromFilter; + bNeedsFullComposite |= g_bColorSliderInUse; +diff --git a/src/Backends/WaylandBackend.cpp b/src/Backends/WaylandBackend.cpp +index d0abb2fa2..d9d213e85 100644 +--- a/src/Backends/WaylandBackend.cpp ++++ b/src/Backends/WaylandBackend.cpp +@@ -1598,7 +1598,7 @@ namespace gamescope + bNeedsFullComposite |= cv_composite_force; + bNeedsFullComposite |= pFrameInfo->useFSRLayer0; + bNeedsFullComposite |= pFrameInfo->useNISLayer0; +- bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0; ++ bNeedsFullComposite |= pFrameInfo->useBICUBICLayer0; + bNeedsFullComposite |= pFrameInfo->blurLayer0; + bNeedsFullComposite |= bNeedsCompositeFromFilter; + bNeedsFullComposite |= g_bColorSliderInUse; + +From 514c7c243730e6f4cae719cd5a662bc5ee68dc6c Mon Sep 17 00:00:00 2001 +From: "Ruan E. Formigoni" +Date: Mon, 7 Oct 2024 00:43:10 -0300 +Subject: [PATCH 4/9] Fix black screen on bicubic filter + +--- + src/shaders/cs_bicubic.comp | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/shaders/cs_bicubic.comp b/src/shaders/cs_bicubic.comp +index 4904433b5..2b6dfb824 100644 +--- a/src/shaders/cs_bicubic.comp ++++ b/src/shaders/cs_bicubic.comp +@@ -8,6 +8,7 @@ + + #extension GL_GOOGLE_include_directive : require + #extension GL_EXT_shader_explicit_arithmetic_types_float16 : require ++#extension GL_EXT_scalar_block_layout : require + + #include "descriptor_set.h" + +@@ -18,7 +19,7 @@ layout( + + // Push constant is a mechanism in modern OpenGL that allows passing small amounts of frequently + // updated data to the shader without needing to bind a buffer +-layout(push_constant) ++layout(binding = 0, scalar) + uniform layers_t { + uvec4 c0, c1; + }; + +From 8fa17e48fa07210f03d2643f3fe8811e2e6aa9a4 Mon Sep 17 00:00:00 2001 +From: "Ruan E. Formigoni" +Date: Mon, 7 Oct 2024 01:27:35 -0300 +Subject: [PATCH 5/9] Use bicubic as an option of --filter + +--- + src/main.cpp | 39 ++++++++++++++++++++++++++++++++------- + 1 file changed, 32 insertions(+), 7 deletions(-) + +diff --git a/src/main.cpp b/src/main.cpp +index de25ddeab..b7f5985b9 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -64,7 +64,6 @@ const struct option *gamescope_options = (struct option[]){ + { "output-height", required_argument, nullptr, 'H' }, + { "sharpness", required_argument, nullptr, 0 }, + { "fsr-sharpness", required_argument, nullptr, 0 }, +- { "bicubic", optional_argument, nullptr, 'D' }, + { "rt", no_argument, nullptr, 0 }, + { "prefer-vk-device", required_argument, 0 }, + { "expose-wayland", no_argument, 0 }, +@@ -404,8 +403,26 @@ static enum GamescopeUpscaleFilter parse_upscaler_filter(const char *str) + + static enum GamescopeDownscaleFilter parse_downscaler_filter(const char *str) + { +- std::stringstream ss{optarg}; ++ std::string_view arg{str}; + ++ // If the string is just 'bicubic' use default values ++ if ( arg == "bicubic" ) { ++ return GamescopeDownscaleFilter::BICUBIC; ++ } ++ ++ // Arguments start after ':' ++ if ( auto search = arg.find(':'); search == std::string::npos ) { ++ fprintf( stderr, "gamescope: invalid argument for --filter=bicubic:float,float\n" ); ++ exit(1); ++ } else { ++ arg = std::string_view(arg.data() + search + 1); ++ } ++ ++ // Push arguments to stream ++ std::stringstream ss; ++ ss << arg; ++ ++ // Validate arguments from stream + double b, c; + char comma; + if ((ss >> b >> comma >> c) && (comma == ',')) { +@@ -419,10 +436,21 @@ static enum GamescopeDownscaleFilter parse_downscaler_filter(const char *str) + return GamescopeDownscaleFilter::BICUBIC; + } + +- fprintf( stderr, "gamescope: invalid value for --bicubic\n" ); ++ fprintf( stderr, "gamescope: invalid value for --filter\n" ); + exit(1); + } + ++static void parse_filter(const char *str) ++{ ++ fprintf(stderr, "str: %s\n", str); ++ if (std::string_view{str}.starts_with("bicubic")) { ++ fprintf(stderr, "Startswith\n"); ++ g_wantedDownscaleFilter = parse_downscaler_filter(str); ++ } else { ++ g_wantedUpscaleFilter = parse_upscaler_filter(str); ++ } ++} ++ + static enum gamescope::GamescopeBackend parse_backend_name(const char *str) + { + if (strcmp(str, "auto") == 0) { +@@ -728,10 +756,7 @@ int main(int argc, char **argv) + g_wantedUpscaleScaler = parse_upscaler_scaler(optarg); + break; + case 'F': +- g_wantedUpscaleFilter = parse_upscaler_filter(optarg); +- break; +- case 'D': +- g_wantedDownscaleFilter = parse_downscaler_filter(optarg); ++ parse_filter(optarg); + break; + case 'b': + g_bBorderlessOutputWindow = true; + +From 5e50b2f931abe251e656138ba7bd0e5694dcc671 Mon Sep 17 00:00:00 2001 +From: "Ruan E. Formigoni" +Date: Mon, 7 Oct 2024 01:44:06 -0300 +Subject: [PATCH 6/9] Updated README with bicubic info + +--- + README.md | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/README.md b/README.md +index 8aa0227bf..cfae48017 100644 +--- a/README.md ++++ b/README.md +@@ -66,6 +66,7 @@ See `gamescope --help` for a full list of options. + * `-o`: set a frame-rate limit for the game when unfocused. Specified in frames per second. Defaults to unlimited. + * `-F fsr`: use AMD FidelityFX™ Super Resolution 1.0 for upscaling + * `-F nis`: use NVIDIA Image Scaling v1.0.3 for upscaling ++* `-F bicubic`: use a bicubic filter for downscaling + * `-S integer`: use integer scaling. + * `-S stretch`: use stretch scaling, the game will fill the window. (e.g. 4:3 to 16:9) + * `-b`: create a border-less window. + +From c1832fc5a44df8fc4c30c47b45638694e51bfa53 Mon Sep 17 00:00:00 2001 +From: "Ruan E. Formigoni" +Date: Mon, 7 Oct 2024 01:45:55 -0300 +Subject: [PATCH 7/9] Fix indentation in meson.build + +--- + src/meson.build | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/meson.build b/src/meson.build +index 907277a23..90096979a 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -66,7 +66,7 @@ shader_src = [ + 'shaders/cs_composite_rcas.comp', + 'shaders/cs_easu.comp', + 'shaders/cs_easu_fp16.comp', +- 'shaders/cs_bicubic.comp', ++ 'shaders/cs_bicubic.comp', + 'shaders/cs_gaussian_blur_horizontal.comp', + 'shaders/cs_nis.comp', + 'shaders/cs_nis_fp16.comp', + +From 7ad3fc2a5e0ce35758fec6a8fb51fb4306cbc6e1 Mon Sep 17 00:00:00 2001 +From: "Ruan E. Formigoni" +Date: Mon, 7 Oct 2024 05:31:33 -0300 +Subject: [PATCH 8/9] Remove debug print + +--- + src/main.cpp | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/main.cpp b/src/main.cpp +index b7f5985b9..32a20cbd5 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -442,9 +442,7 @@ static enum GamescopeDownscaleFilter parse_downscaler_filter(const char *str) + + static void parse_filter(const char *str) + { +- fprintf(stderr, "str: %s\n", str); + if (std::string_view{str}.starts_with("bicubic")) { +- fprintf(stderr, "Startswith\n"); + g_wantedDownscaleFilter = parse_downscaler_filter(str); + } else { + g_wantedUpscaleFilter = parse_upscaler_filter(str); + +From 6649fd8f0e7d2bce465855221f30eafc06f9a4ce Mon Sep 17 00:00:00 2001 +From: "Ruan E. Formigoni" +Date: Mon, 7 Oct 2024 05:34:15 -0300 +Subject: [PATCH 9/9] Remove outdated comments + +--- + src/rendervulkan.cpp | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/rendervulkan.cpp b/src/rendervulkan.cpp +index e80afb68a..33f999101 100644 +--- a/src/rendervulkan.cpp ++++ b/src/rendervulkan.cpp +@@ -3917,7 +3917,6 @@ std::optional vulkan_composite( struct FrameInfo_t *frameInfo, gamesco + + if ( frameInfo->useBICUBICLayer0 ) + { +- // fprintf(stderr, "-- Use bicubic\n"); + uint32_t inputX = frameInfo->layers[0].tex->width(); + uint32_t inputY = frameInfo->layers[0].tex->height(); + +@@ -3927,7 +3926,6 @@ std::optional vulkan_composite( struct FrameInfo_t *frameInfo, gamesco + update_tmp_images(tempX, tempY); + + cmdBuffer->bindPipeline( g_device.pipeline(SHADER_TYPE_BICUBIC, frameInfo->layerCount, frameInfo->ycbcrMask())); +- // cmdBuffer->bindTarget(compositeImage); + cmdBuffer->bindTarget(g_output.tmpOutput); + cmdBuffer->bindTexture(0, frameInfo->layers[0].tex); + cmdBuffer->setTextureSrgb(0, true); diff --git a/spec_files/gamescope/chimeraos.patch b/spec_files/gamescope/chimeraos.patch index 74a57612..3105f655 100644 --- a/spec_files/gamescope/chimeraos.patch +++ b/spec_files/gamescope/chimeraos.patch @@ -1,7 +1,7 @@ -From 646446c157d55d8508c734cddfc3025834f7cf50 Mon Sep 17 00:00:00 2001 +From 342d51127c33b38d95605eecb824089fb85f831e Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Fri, 17 May 2024 19:43:49 -0500 -Subject: [PATCH 01/21] Add touch-gestures to open up Steam menus +Subject: [PATCH 01/23] Add touch-gestures to open up Steam menus --- src/main.cpp | 5 +++++ @@ -10,10 +10,10 @@ Subject: [PATCH 01/21] Add touch-gestures to open up Steam menus 3 files changed, 34 insertions(+) diff --git a/src/main.cpp b/src/main.cpp -index ca40012..3a1b1ae 100644 +index c074f82..a39922c 100644 --- a/src/main.cpp +++ b/src/main.cpp -@@ -108,6 +108,8 @@ const struct option *gamescope_options = (struct option[]){ +@@ -110,6 +110,8 @@ const struct option *gamescope_options = (struct option[]){ // wlserver options { "xwayland-count", required_argument, nullptr, 0 }, @@ -22,7 +22,7 @@ index ca40012..3a1b1ae 100644 // steamcompmgr options { "cursor", required_argument, nullptr, 0 }, -@@ -185,6 +187,7 @@ const char usage[] = +@@ -187,6 +189,7 @@ const char usage[] = " -T, --stats-path write statistics to path\n" " -C, --hide-cursor-delay hide cursor image after delay\n" " -e, --steam enable Steam integration\n" @@ -30,7 +30,7 @@ index ca40012..3a1b1ae 100644 " --xwayland-count create N xwayland servers\n" " --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n" " --force-orientation rotate the internal display (left, right, normal, upsidedown)\n" -@@ -734,6 +737,8 @@ int main(int argc, char **argv) +@@ -736,6 +739,8 @@ int main(int argc, char **argv) g_bDebugLayers = true; } else if (strcmp(opt_name, "disable-color-management") == 0) { g_bForceDisableColorMgmt = true; @@ -40,10 +40,10 @@ index ca40012..3a1b1ae 100644 g_nXWaylandCount = atoi( optarg ); } else if (strcmp(opt_name, "composite-debug") == 0) { diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index ccbd512..26b953a 100644 +index 78a86ee..ceeef24 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp -@@ -81,6 +81,7 @@ using namespace std::literals; +@@ -82,6 +82,7 @@ using namespace std::literals; extern gamescope::ConVar cv_drm_debug_disable_explicit_sync; //#define GAMESCOPE_SWAPCHAIN_DEBUG @@ -51,7 +51,7 @@ index ccbd512..26b953a 100644 struct wlserver_t wlserver = { .touch_down_ids = {} -@@ -2526,6 +2527,33 @@ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool +@@ -2537,6 +2538,33 @@ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool if ( bAlwaysWarpCursor ) wlserver_mousewarp( tx, ty, time, false ); @@ -98,13 +98,13 @@ index 0569472..3304c18 100644 void wlserver_open_steam_menu( bool qam ); -- -2.46.0 +2.46.2 -From 97c2ed0ea6a5cd43b450e0952db20c08d82bbe60 Mon Sep 17 00:00:00 2001 +From 438d40cbd225a6a2ca7c66e6ac6be2ef0a238a62 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Fri, 17 May 2024 20:16:20 -0500 -Subject: [PATCH 02/21] Add bypass_steam_resolution to workaround the 720p/800p +Subject: [PATCH 02/23] Add bypass_steam_resolution to workaround the 720p/800p restrictions Steam has for games --- @@ -113,10 +113,10 @@ Subject: [PATCH 02/21] Add bypass_steam_resolution to workaround the 720p/800p 2 files changed, 14 insertions(+) diff --git a/src/main.cpp b/src/main.cpp -index 3a1b1ae..534779d 100644 +index a39922c..503f837 100644 --- a/src/main.cpp +++ b/src/main.cpp -@@ -129,6 +129,8 @@ const struct option *gamescope_options = (struct option[]){ +@@ -131,6 +131,8 @@ const struct option *gamescope_options = (struct option[]){ { "fade-out-duration", required_argument, nullptr, 0 }, { "force-orientation", required_argument, nullptr, 0 }, { "force-windows-fullscreen", no_argument, nullptr, 0 }, @@ -125,7 +125,7 @@ index 3a1b1ae..534779d 100644 { "disable-color-management", no_argument, nullptr, 0 }, { "sdr-gamut-wideness", required_argument, nullptr, 0 }, -@@ -187,6 +189,7 @@ const char usage[] = +@@ -189,6 +191,7 @@ const char usage[] = " -T, --stats-path write statistics to path\n" " -C, --hide-cursor-delay hide cursor image after delay\n" " -e, --steam enable Steam integration\n" @@ -134,10 +134,10 @@ index 3a1b1ae..534779d 100644 " --xwayland-count create N xwayland servers\n" " --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n" diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp -index e997c85..952a5f8 100644 +index 11a7cad..2e0e297 100644 --- a/src/steamcompmgr.cpp +++ b/src/steamcompmgr.cpp -@@ -356,6 +356,8 @@ bool g_bForceHDR10OutputDebug = false; +@@ -359,6 +359,8 @@ bool g_bForceHDR10OutputDebug = false; gamescope::ConVar cv_hdr_enabled{ "hdr_enabled", false, "Whether or not HDR is enabled if it is available." }; bool g_bHDRItmEnable = false; int g_nCurrentRefreshRate_CachedValue = 0; @@ -146,7 +146,7 @@ index e997c85..952a5f8 100644 static void update_color_mgmt() -@@ -5387,6 +5389,13 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev) +@@ -5430,6 +5432,13 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev) size_t server_idx = size_t{ xwayland_mode_ctl[ 0 ] }; int width = xwayland_mode_ctl[ 1 ]; int height = xwayland_mode_ctl[ 2 ]; @@ -160,9 +160,9 @@ index e997c85..952a5f8 100644 bool allowSuperRes = !!xwayland_mode_ctl[ 3 ]; if ( !allowSuperRes ) -@@ -7370,6 +7379,8 @@ steamcompmgr_main(int argc, char **argv) +@@ -7445,6 +7454,8 @@ steamcompmgr_main(int argc, char **argv) bForceWindowsFullscreen = true; - } else if (strcmp(opt_name, "hdr-enabled") == 0) { + } else if (strcmp(opt_name, "hdr-enabled") == 0 || strcmp(opt_name, "hdr-enable") == 0) { cv_hdr_enabled = true; + } else if (strcmp(opt_name, "bypass_steam_resolution") == 0) { + cv_bypass_steam_resolution = true; @@ -170,13 +170,13 @@ index e997c85..952a5f8 100644 g_bForceHDRSupportDebug = true; } else if (strcmp(opt_name, "hdr-debug-force-output") == 0) { -- -2.46.0 +2.46.2 -From 234e3bb0369b7ed45a8e2f3c41f3c1e900be9d34 Mon Sep 17 00:00:00 2001 +From 1f40e410d662cd0041764b738067037e45df2192 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Wed, 26 Jul 2023 20:46:29 -0500 -Subject: [PATCH 03/21] Add force external orientation. +Subject: [PATCH 03/23] Add force external orientation. Co-authored-by: Bouke Sybren Haarsma --- @@ -187,10 +187,10 @@ Co-authored-by: Bouke Sybren Haarsma 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp -index 799fd39..3815b98 100644 +index 3a996af..6bc64fa 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp -@@ -537,6 +537,7 @@ bool g_bSupportsSyncObjs = false; +@@ -532,6 +532,7 @@ bool g_bSupportsSyncObjs = false; extern gamescope::GamescopeModeGeneration g_eGamescopeModeGeneration; extern GamescopePanelOrientation g_DesiredInternalOrientation; @@ -198,7 +198,7 @@ index 799fd39..3815b98 100644 extern bool g_bForceDisableColorMgmt; -@@ -2031,6 +2032,10 @@ namespace gamescope +@@ -2026,6 +2027,10 @@ namespace gamescope { m_ChosenOrientation = g_DesiredInternalOrientation; } @@ -210,10 +210,10 @@ index 799fd39..3815b98 100644 { if ( this->GetProperties().panel_orientation ) diff --git a/src/main.cpp b/src/main.cpp -index 534779d..f9be05e 100644 +index 503f837..1e0b71e 100644 --- a/src/main.cpp +++ b/src/main.cpp -@@ -128,6 +128,7 @@ const struct option *gamescope_options = (struct option[]){ +@@ -130,6 +130,7 @@ const struct option *gamescope_options = (struct option[]){ { "disable-xres", no_argument, nullptr, 'x' }, { "fade-out-duration", required_argument, nullptr, 0 }, { "force-orientation", required_argument, nullptr, 0 }, @@ -221,7 +221,7 @@ index 534779d..f9be05e 100644 { "force-windows-fullscreen", no_argument, nullptr, 0 }, { "bypass-steam-resolution", no_argument, nullptr, 0 }, -@@ -194,6 +195,7 @@ const char usage[] = +@@ -196,6 +197,7 @@ const char usage[] = " --xwayland-count create N xwayland servers\n" " --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n" " --force-orientation rotate the internal display (left, right, normal, upsidedown)\n" @@ -229,7 +229,7 @@ index 534779d..f9be05e 100644 " --force-windows-fullscreen force windows inside of gamescope to be the size of the nested display (fullscreen)\n" " --cursor-scale-height if specified, sets a base output height to linearly scale the cursor against.\n" " --hdr-enabled enable HDR output (needs Gamescope WSI layer enabled for support from clients)\n" -@@ -289,6 +291,8 @@ bool g_bOutputHDREnabled = false; +@@ -291,6 +293,8 @@ bool g_bOutputHDREnabled = false; bool g_bFullscreen = false; bool g_bForceRelativeMouse = false; @@ -238,7 +238,7 @@ index 534779d..f9be05e 100644 bool g_bGrabbed = false; float g_mouseSensitivity = 1.0; -@@ -362,7 +366,24 @@ static GamescopePanelOrientation force_orientation(const char *str) +@@ -364,7 +368,24 @@ static GamescopePanelOrientation force_orientation(const char *str) } else if (strcmp(str, "upsidedown") == 0) { return GAMESCOPE_PANEL_ORIENTATION_180; } else { @@ -264,7 +264,7 @@ index 534779d..f9be05e 100644 exit(1); } } -@@ -755,6 +776,8 @@ int main(int argc, char **argv) +@@ -757,6 +778,8 @@ int main(int argc, char **argv) g_eGamescopeModeGeneration = parse_gamescope_mode_generation( optarg ); } else if (strcmp(opt_name, "force-orientation") == 0) { g_DesiredInternalOrientation = force_orientation( optarg ); @@ -286,10 +286,10 @@ index 2e6fb83..ebd018a 100644 enum class GamescopeUpscaleFilter : uint32_t { diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index 26b953a..837079a 100644 +index ceeef24..62876c2 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp -@@ -2488,6 +2488,29 @@ static void apply_touchscreen_orientation(double *x, double *y ) +@@ -2499,6 +2499,29 @@ static void apply_touchscreen_orientation(double *x, double *y ) break; } @@ -320,13 +320,13 @@ index 26b953a..837079a 100644 *y = ty; } -- -2.46.0 +2.46.2 -From bc0ddd46fd9db62fbc3fe14e0b1493e35ceb2be8 Mon Sep 17 00:00:00 2001 +From 5ecd89b45675fd4f648a454884db2f970e17894f Mon Sep 17 00:00:00 2001 From: Bouke Sybren Haarsma Date: Tue, 12 Mar 2024 00:07:57 +0100 -Subject: [PATCH 04/21] implement force-panel-type +Subject: [PATCH 04/23] implement force-panel-type --- src/backend.h | 3 +++ @@ -335,10 +335,10 @@ Subject: [PATCH 04/21] implement force-panel-type 3 files changed, 20 insertions(+) diff --git a/src/backend.h b/src/backend.h -index 7d9fb46..08e8268 100644 +index dd295f4..71c41a7 100644 --- a/src/backend.h +++ b/src/backend.h -@@ -18,6 +18,7 @@ struct wlr_buffer; +@@ -20,6 +20,7 @@ struct wlr_buffer; struct wlr_dmabuf_attributes; struct FrameInfo_t; @@ -346,7 +346,7 @@ index 7d9fb46..08e8268 100644 namespace gamescope { -@@ -221,6 +222,8 @@ namespace gamescope +@@ -228,6 +229,8 @@ namespace gamescope // Dumb helper we should remove to support multi display someday. gamescope::GamescopeScreenType GetScreenType() { @@ -356,10 +356,10 @@ index 7d9fb46..08e8268 100644 return GetCurrentConnector()->GetScreenType(); diff --git a/src/gamescope_shared.h b/src/gamescope_shared.h -index 5ce8591..d1b7a6e 100644 +index 1ff54bd..feffdc1 100644 --- a/src/gamescope_shared.h +++ b/src/gamescope_shared.h -@@ -25,6 +25,7 @@ namespace gamescope +@@ -16,6 +16,7 @@ namespace gamescope { GAMESCOPE_SCREEN_TYPE_INTERNAL, GAMESCOPE_SCREEN_TYPE_EXTERNAL, @@ -368,10 +368,10 @@ index 5ce8591..d1b7a6e 100644 GAMESCOPE_SCREEN_TYPE_COUNT }; diff --git a/src/main.cpp b/src/main.cpp -index f9be05e..dc3e9c8 100644 +index 1e0b71e..967d402 100644 --- a/src/main.cpp +++ b/src/main.cpp -@@ -129,6 +129,7 @@ const struct option *gamescope_options = (struct option[]){ +@@ -131,6 +131,7 @@ const struct option *gamescope_options = (struct option[]){ { "fade-out-duration", required_argument, nullptr, 0 }, { "force-orientation", required_argument, nullptr, 0 }, { "force-external-orientation", required_argument, nullptr, 0 }, @@ -379,7 +379,7 @@ index f9be05e..dc3e9c8 100644 { "force-windows-fullscreen", no_argument, nullptr, 0 }, { "bypass-steam-resolution", no_argument, nullptr, 0 }, -@@ -196,6 +197,7 @@ const char usage[] = +@@ -198,6 +199,7 @@ const char usage[] = " --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n" " --force-orientation rotate the internal display (left, right, normal, upsidedown)\n" " --force-external-orientation rotate the external display (left, right, normal, upsidedown)\n" @@ -387,7 +387,7 @@ index f9be05e..dc3e9c8 100644 " --force-windows-fullscreen force windows inside of gamescope to be the size of the nested display (fullscreen)\n" " --cursor-scale-height if specified, sets a base output height to linearly scale the cursor against.\n" " --hdr-enabled enable HDR output (needs Gamescope WSI layer enabled for support from clients)\n" -@@ -387,6 +389,18 @@ static GamescopePanelOrientation force_external_orientation(const char *str) +@@ -389,6 +391,18 @@ static GamescopePanelOrientation force_external_orientation(const char *str) exit(1); } } @@ -406,7 +406,7 @@ index f9be05e..dc3e9c8 100644 static enum GamescopeUpscaleScaler parse_upscaler_scaler(const char *str) { -@@ -778,6 +792,8 @@ int main(int argc, char **argv) +@@ -780,6 +794,8 @@ int main(int argc, char **argv) g_DesiredInternalOrientation = force_orientation( optarg ); } else if (strcmp(opt_name, "force-external-orientation") == 0) { g_DesiredExternalOrientation = force_external_orientation( optarg ); @@ -416,13 +416,13 @@ index f9be05e..dc3e9c8 100644 strcmp(opt_name, "fsr-sharpness") == 0) { g_upscaleFilterSharpness = atoi( optarg ); -- -2.46.0 +2.46.2 -From 2a0c92febded984bc0d610eaedc9e8cc4d4ce51a Mon Sep 17 00:00:00 2001 +From 9f4fe80258fdb8405a02bf35ea2d849c32c8baa0 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Fri, 17 May 2024 21:11:34 -0500 -Subject: [PATCH 05/21] wlserver: Fix an issue that would cause gamescope to +Subject: [PATCH 05/23] wlserver: Fix an issue that would cause gamescope to crash when the touchscreen was used --- @@ -430,10 +430,10 @@ Subject: [PATCH 05/21] wlserver: Fix an issue that would cause gamescope to 1 file changed, 23 deletions(-) diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index 837079a..26b953a 100644 +index 62876c2..ceeef24 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp -@@ -2488,29 +2488,6 @@ static void apply_touchscreen_orientation(double *x, double *y ) +@@ -2499,29 +2499,6 @@ static void apply_touchscreen_orientation(double *x, double *y ) break; } @@ -464,40 +464,39 @@ index 837079a..26b953a 100644 *y = ty; } -- -2.46.0 +2.46.2 -From 69bae3bffa954251d6a857b1b6928fc4755e40bf Mon Sep 17 00:00:00 2001 +From 295762788cd549879f700527bdda8a2f1cdab829 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Fri, 17 May 2024 21:56:55 -0500 -Subject: [PATCH 06/21] Add --custom-refresh-rates +Subject: [PATCH 06/23] Add --custom-refresh-rates --- - src/Backends/DRMBackend.cpp | 4 ++++ + src/Backends/DRMBackend.cpp | 3 +++ src/main.cpp | 30 ++++++++++++++++++++++++++++++ src/main.hpp | 2 ++ - 3 files changed, 36 insertions(+) + 3 files changed, 35 insertions(+) diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp -index 3815b98..e3512a1 100644 +index 6bc64fa..8fffcb7 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp -@@ -2135,6 +2135,10 @@ namespace gamescope - ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Jupiter"sv ) || - ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Galileo"sv ); +@@ -2224,6 +2224,9 @@ namespace gamescope + + bHasKnownHDRInfo = true; + } ++ } else if ( g_customRefreshRates.size() > 0 ) { ++ m_Mutable.ValidDynamicRefreshRates = g_customRefreshRates; ++ return; + } + } -+ if ( g_customRefreshRates.size() > 0 ) { -+ m_Mutable.ValidDynamicRefreshRates = std::span(g_customRefreshRates); -+ return; -+ } - if ( bSteamDeckDisplay ) - { - static constexpr uint32_t kPIDGalileoSDC = 0x3003; diff --git a/src/main.cpp b/src/main.cpp -index dc3e9c8..18eb399 100644 +index 967d402..a227936 100644 --- a/src/main.cpp +++ b/src/main.cpp -@@ -132,6 +132,7 @@ const struct option *gamescope_options = (struct option[]){ +@@ -134,6 +134,7 @@ const struct option *gamescope_options = (struct option[]){ { "force-panel-type", required_argument, nullptr, 0 }, { "force-windows-fullscreen", no_argument, nullptr, 0 }, { "bypass-steam-resolution", no_argument, nullptr, 0 }, @@ -505,7 +504,7 @@ index dc3e9c8..18eb399 100644 { "disable-color-management", no_argument, nullptr, 0 }, -@@ -210,6 +211,7 @@ const char usage[] = +@@ -212,6 +213,7 @@ const char usage[] = " --hdr-itm-target-nits set the target luminace of the inverse tone mapping process.\n" " Default: 1000 nits, Max: 10000 nits\n" " --framerate-limit Set a simple framerate limit. Used as a divisor of the refresh rate, rounds down eg 60 / 59 -> 60fps, 60 / 25 -> 30fps. Default: 0, disabled.\n" @@ -513,7 +512,7 @@ index dc3e9c8..18eb399 100644 " --mangoapp Launch with the mangoapp (mangohud) performance overlay enabled. You should use this instead of using mangohud on the game or gamescope.\n" "\n" "Nested mode options:\n" -@@ -462,6 +464,32 @@ static enum gamescope::GamescopeBackend parse_backend_name(const char *str) +@@ -464,6 +466,32 @@ static enum gamescope::GamescopeBackend parse_backend_name(const char *str) fprintf( stderr, "gamescope: invalid value for --backend\n" ); exit(1); } @@ -546,7 +545,7 @@ index dc3e9c8..18eb399 100644 } struct sigaction handle_signal_action = {}; -@@ -794,6 +822,8 @@ int main(int argc, char **argv) +@@ -796,6 +824,8 @@ int main(int argc, char **argv) g_DesiredExternalOrientation = force_external_orientation( optarg ); } else if (strcmp(opt_name, "force-panel-type") == 0) { g_ForcedScreenType = force_panel_type( optarg ); @@ -576,21 +575,21 @@ index ebd018a..4e09e3b 100644 enum class GamescopeUpscaleFilter : uint32_t { -- -2.46.0 +2.46.2 -From 5125582bc6fdfc651ca5ccb58cb71d956e2c3676 Mon Sep 17 00:00:00 2001 +From db836efe685a72571f2df1ad2ce0f00055220206 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Sat, 18 May 2024 08:44:38 -0500 -Subject: [PATCH 07/21] Add rotation gamescope_control command +Subject: [PATCH 07/23] Add rotation gamescope_control command --- protocol/gamescope-control.xml | 18 ++++++++++++ src/Backends/DRMBackend.cpp | 24 ++++++++++++++-- - src/gamescope_shared.h | 18 ++++++++++++ + src/gamescope_shared.h | 10 +++++++ src/main.cpp | 1 + src/wlserver.cpp | 50 ++++++++++++++++++++++++++++++++++ - 5 files changed, 109 insertions(+), 2 deletions(-) + 5 files changed, 101 insertions(+), 2 deletions(-) diff --git a/protocol/gamescope-control.xml b/protocol/gamescope-control.xml index 012c48c..eab8a84 100644 @@ -621,10 +620,10 @@ index 012c48c..eab8a84 100644 diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp -index e3512a1..f05c2e8 100644 +index 8fffcb7..47b8323 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp -@@ -2028,7 +2028,9 @@ namespace gamescope +@@ -2023,7 +2023,9 @@ namespace gamescope void CDRMConnector::UpdateEffectiveOrientation( const drmModeModeInfo *pMode ) { @@ -635,7 +634,7 @@ index e3512a1..f05c2e8 100644 { m_ChosenOrientation = g_DesiredInternalOrientation; } -@@ -2960,8 +2962,26 @@ bool drm_update_color_mgmt(struct drm_t *drm) +@@ -2959,8 +2961,26 @@ bool drm_update_color_mgmt(struct drm_t *drm) return true; } @@ -664,21 +663,13 @@ index e3512a1..f05c2e8 100644 { drm->pending.mode_id = 0; diff --git a/src/gamescope_shared.h b/src/gamescope_shared.h -index d1b7a6e..cffa576 100644 +index feffdc1..6e6b7db 100644 --- a/src/gamescope_shared.h +++ b/src/gamescope_shared.h -@@ -65,6 +65,24 @@ enum GamescopePanelOrientation +@@ -56,6 +56,16 @@ enum GamescopePanelOrientation GAMESCOPE_PANEL_ORIENTATION_AUTO, }; -+struct GamescopeTimelinePoint -+{ -+ struct wlr_drm_syncobj_timeline *pTimeline = nullptr; -+ uint64_t ulPoint = 0; -+ -+ void Release(); -+}; -+ +enum GamescopePanelExternalOrientation +{ + GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_0, // normal @@ -693,10 +684,10 @@ index d1b7a6e..cffa576 100644 // composite priorities working in libliftoff + also // use the proper libliftoff composite plane system. diff --git a/src/main.cpp b/src/main.cpp -index 18eb399..675020f 100644 +index a227936..36421bb 100644 --- a/src/main.cpp +++ b/src/main.cpp -@@ -397,6 +397,7 @@ static gamescope::GamescopeScreenType force_panel_type(const char *str) +@@ -399,6 +399,7 @@ static gamescope::GamescopeScreenType force_panel_type(const char *str) if (strcmp(str, "internal") == 0) { return gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL; } else if (strcmp(str, "external") == 0) { @@ -705,10 +696,10 @@ index 18eb399..675020f 100644 } else { fprintf( stderr, "gamescope: invalid value for --force-panel-type\n" ); diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index 26b953a..c37dbc1 100644 +index ceeef24..e386765 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp -@@ -1042,6 +1042,55 @@ static void gamescope_control_take_screenshot( struct wl_client *client, struct +@@ -1043,6 +1043,55 @@ static void gamescope_control_take_screenshot( struct wl_client *client, struct } ); } @@ -764,7 +755,7 @@ index 26b953a..c37dbc1 100644 static void gamescope_control_handle_destroy( struct wl_client *client, struct wl_resource *resource ) { wl_resource_destroy( resource ); -@@ -1051,6 +1100,7 @@ static const struct gamescope_control_interface gamescope_control_impl = { +@@ -1052,6 +1101,7 @@ static const struct gamescope_control_interface gamescope_control_impl = { .destroy = gamescope_control_handle_destroy, .set_app_target_refresh_cycle = gamescope_control_set_app_target_refresh_cycle, .take_screenshot = gamescope_control_take_screenshot, @@ -773,20 +764,19 @@ index 26b953a..c37dbc1 100644 static uint32_t get_conn_display_info_flags() -- -2.46.0 +2.46.2 -From 304c747d5eab4b62fe38225d04529ff53142e832 Mon Sep 17 00:00:00 2001 +From 7767e9b4d2aa1408a458077424d12b86a6390dbf Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Sat, 18 May 2024 11:54:50 -0500 -Subject: [PATCH 08/21] Fix an issue that caused force-panel to not work +Subject: [PATCH 08/23] Fix an issue that caused force-panel to not work --- protocol/gamescope-control.xml | 1 - src/Backends/DRMBackend.cpp | 3 + - src/gamescope_shared.h | 10 --- src/wlserver.cpp | 145 ++++++++++++++++++++------------- - 4 files changed, 90 insertions(+), 69 deletions(-) + 3 files changed, 90 insertions(+), 59 deletions(-) diff --git a/protocol/gamescope-control.xml b/protocol/gamescope-control.xml index eab8a84..7f5578b 100644 @@ -801,10 +791,10 @@ index eab8a84..7f5578b 100644 diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp -index f05c2e8..663b1e2 100644 +index 47b8323..35ffa73 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp -@@ -318,6 +318,9 @@ namespace gamescope +@@ -309,6 +309,9 @@ namespace gamescope GamescopeScreenType GetScreenType() const override { @@ -814,32 +804,11 @@ index f05c2e8..663b1e2 100644 if ( m_pConnector->connector_type == DRM_MODE_CONNECTOR_eDP || m_pConnector->connector_type == DRM_MODE_CONNECTOR_LVDS || m_pConnector->connector_type == DRM_MODE_CONNECTOR_DSI ) -diff --git a/src/gamescope_shared.h b/src/gamescope_shared.h -index cffa576..a11f598 100644 ---- a/src/gamescope_shared.h -+++ b/src/gamescope_shared.h -@@ -73,16 +73,6 @@ struct GamescopeTimelinePoint - void Release(); - }; - --enum GamescopePanelExternalOrientation --{ -- GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_0, // normal -- GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_270, // right -- GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_90, // left -- GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_180, // upside down -- -- GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_AUTO, --}; -- - // Disable partial composition for now until we get - // composite priorities working in libliftoff + also - // use the proper libliftoff composite plane system. diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index c37dbc1..ff534ad 100644 +index e386765..a3af652 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp -@@ -82,6 +82,8 @@ extern gamescope::ConVar cv_drm_debug_disable_explicit_sync; +@@ -83,6 +83,8 @@ extern gamescope::ConVar cv_drm_debug_disable_explicit_sync; //#define GAMESCOPE_SWAPCHAIN_DEBUG gamescope::ConVar cv_touch_gestures( "enable_touch_gestures", false, "Enable/Disable the usage of touch gestures" ); @@ -848,7 +817,7 @@ index c37dbc1..ff534ad 100644 struct wlserver_t wlserver = { .touch_down_ids = {} -@@ -1048,43 +1050,43 @@ static void gamescope_control_rotate_display( struct wl_client *client, struct w +@@ -1049,43 +1051,43 @@ static void gamescope_control_rotate_display( struct wl_client *client, struct w if (target_type == GAMESCOPE_CONTROL_DISPLAY_TARGET_TYPE_INTERNAL ) { switch (orientation) { @@ -924,7 +893,7 @@ index c37dbc1..ff534ad 100644 } } //drm_set_orientation(&g_DRM, isRotated); -@@ -2512,34 +2514,61 @@ const std::shared_ptr& wlserver_surface_swapchai +@@ -2523,34 +2525,61 @@ const std::shared_ptr& wlserver_surface_swapchai /* Handle the orientation of the touch inputs */ static void apply_touchscreen_orientation(double *x, double *y ) { @@ -1013,23 +982,23 @@ index c37dbc1..ff534ad 100644 void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool bAlwaysWarpCursor ) -- -2.46.0 +2.46.2 -From 3efb4df00c1e88219a3ff7c47af99b7217d1fe95 Mon Sep 17 00:00:00 2001 +From a7e3eafdc7fa8976466cac64c6a354f938deca44 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Sat, 18 May 2024 13:50:57 -0500 -Subject: [PATCH 09/21] Fix an arithmetic error +Subject: [PATCH 09/23] Fix an arithmetic error --- src/Backends/DRMBackend.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp -index 663b1e2..eafb2f9 100644 +index 35ffa73..07f0383 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp -@@ -2031,9 +2031,9 @@ namespace gamescope +@@ -2026,9 +2026,9 @@ namespace gamescope void CDRMConnector::UpdateEffectiveOrientation( const drmModeModeInfo *pMode ) { @@ -1043,23 +1012,23 @@ index 663b1e2..eafb2f9 100644 m_ChosenOrientation = g_DesiredInternalOrientation; } -- -2.46.0 +2.46.2 -From dd53e4d18b122cae5383d77fc3f6e79084d8993f Mon Sep 17 00:00:00 2001 +From 4988c24ed337f2782c9bf14239a4471b474c42b0 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Sat, 18 May 2024 19:04:48 -0500 -Subject: [PATCH 10/21] Rework the touch gestures to be more smooth +Subject: [PATCH 10/23] Rework the touch gestures to be more smooth --- src/wlserver.cpp | 89 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 20 deletions(-) diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index ff534ad..593a074 100644 +index a3af652..a240871 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp -@@ -80,6 +80,8 @@ using namespace std::literals; +@@ -81,6 +81,8 @@ using namespace std::literals; extern gamescope::ConVar cv_drm_debug_disable_explicit_sync; @@ -1068,7 +1037,7 @@ index ff534ad..593a074 100644 //#define GAMESCOPE_SWAPCHAIN_DEBUG gamescope::ConVar cv_touch_gestures( "enable_touch_gestures", false, "Enable/Disable the usage of touch gestures" ); extern GamescopePanelOrientation g_DesiredInternalOrientation; -@@ -362,6 +364,39 @@ void wlserver_open_steam_menu( bool qam ) +@@ -363,6 +365,39 @@ void wlserver_open_steam_menu( bool qam ) XTestFakeKeyEvent(server->get_xdisplay(), XKeysymToKeycode( server->get_xdisplay(), XK_Control_L ), False, CurrentTime); } @@ -1108,7 +1077,7 @@ index ff534ad..593a074 100644 static void wlserver_handle_pointer_button(struct wl_listener *listener, void *data) { struct wlserver_pointer *pointer = wl_container_of( listener, pointer, button ); -@@ -2607,32 +2642,46 @@ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool +@@ -2618,32 +2653,46 @@ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool if ( bAlwaysWarpCursor ) wlserver_mousewarp( tx, ty, time, false ); @@ -1176,25 +1145,25 @@ index ff534ad..593a074 100644 else if ( eMode == gamescope::TouchClickModes::Disabled ) { -- -2.46.0 +2.46.2 -From 70d4ea8937e43752e1adb32ebbcdd3d1a0bcf23c Mon Sep 17 00:00:00 2001 +From de33de84f4cc272d1d2532b9cbb870ac69f9f4c9 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Sun, 19 May 2024 08:55:28 -0500 -Subject: [PATCH 11/21] Fix a typo for --bypass-steam-resolution +Subject: [PATCH 11/23] Fix a typo for --bypass-steam-resolution --- src/steamcompmgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp -index 952a5f8..6fceb1d 100644 +index 2e0e297..44a086d 100644 --- a/src/steamcompmgr.cpp +++ b/src/steamcompmgr.cpp -@@ -7379,7 +7379,7 @@ steamcompmgr_main(int argc, char **argv) +@@ -7454,7 +7454,7 @@ steamcompmgr_main(int argc, char **argv) bForceWindowsFullscreen = true; - } else if (strcmp(opt_name, "hdr-enabled") == 0) { + } else if (strcmp(opt_name, "hdr-enabled") == 0 || strcmp(opt_name, "hdr-enable") == 0) { cv_hdr_enabled = true; - } else if (strcmp(opt_name, "bypass_steam_resolution") == 0) { + } else if (strcmp(opt_name, "bypass-steam-resolution") == 0) { @@ -1202,13 +1171,13 @@ index 952a5f8..6fceb1d 100644 } else if (strcmp(opt_name, "hdr-debug-force-support") == 0) { g_bForceHDRSupportDebug = true; -- -2.46.0 +2.46.2 -From be8e56d7f3bf251f75da24aa8a99d2e91aa60812 Mon Sep 17 00:00:00 2001 +From b674368352abaadb7c447070d5a6ba7c1c342f81 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Sun, 19 May 2024 11:48:52 -0500 -Subject: [PATCH 12/21] Handle gesture cases better to prevent unexpected +Subject: [PATCH 12/23] Handle gesture cases better to prevent unexpected behavior --- @@ -1216,10 +1185,10 @@ Subject: [PATCH 12/21] Handle gesture cases better to prevent unexpected 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index 593a074..833140a 100644 +index a240871..3837c84 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp -@@ -80,7 +80,8 @@ using namespace std::literals; +@@ -81,7 +81,8 @@ using namespace std::literals; extern gamescope::ConVar cv_drm_debug_disable_explicit_sync; @@ -1229,7 +1198,7 @@ index 593a074..833140a 100644 bool pending_osk = false; //#define GAMESCOPE_SWAPCHAIN_DEBUG gamescope::ConVar cv_touch_gestures( "enable_touch_gestures", false, "Enable/Disable the usage of touch gestures" ); -@@ -2606,6 +2607,16 @@ static void apply_touchscreen_orientation(double *x, double *y ) +@@ -2617,6 +2618,16 @@ static void apply_touchscreen_orientation(double *x, double *y ) *y = ty; } @@ -1246,7 +1215,7 @@ index 593a074..833140a 100644 void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool bAlwaysWarpCursor ) { assert( wlserver_is_lock_held() ); -@@ -2644,43 +2655,55 @@ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool +@@ -2655,43 +2666,55 @@ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool if ( cv_touch_gestures ) { @@ -1322,13 +1291,13 @@ index 593a074..833140a 100644 } else if ( eMode == gamescope::TouchClickModes::Disabled ) -- -2.46.0 +2.46.2 -From b31ab55d57f0a8b746d4d0fa7939f6473bcad9a4 Mon Sep 17 00:00:00 2001 +From c672cac17d538df286efaee9f29d289a71e13383 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Sun, 19 May 2024 18:14:23 -0500 -Subject: [PATCH 13/21] Add references to drm_set_orientation() and g_drm in +Subject: [PATCH 13/23] Add references to drm_set_orientation() and g_drm in wlserver for rotation gamescope-control --- @@ -1337,10 +1306,10 @@ Subject: [PATCH 13/21] Add references to drm_set_orientation() and g_drm in 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index 833140a..eb3936a 100644 +index 3837c84..13ea8b5 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp -@@ -1125,8 +1125,9 @@ static void gamescope_control_rotate_display( struct wl_client *client, struct w +@@ -1126,8 +1126,9 @@ static void gamescope_control_rotate_display( struct wl_client *client, struct w wl_log.errorf("Invalid target orientation selected"); } } @@ -1367,13 +1336,13 @@ index 3304c18..0754ee5 100644 void wlserver_destroy_xwayland_server(gamescope_xwayland_server_t *server); -- -2.46.0 +2.46.2 -From 8df476a6f7d41157e847ee7c3346c796e674d9fe Mon Sep 17 00:00:00 2001 +From b7b08665aaf344cd9930069e52931335daafaddb Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Mon, 20 May 2024 07:02:52 -0500 -Subject: [PATCH 14/21] Fix an issue where forced panel type orientations +Subject: [PATCH 14/23] Fix an issue where forced panel type orientations weren't being applied --- @@ -1381,10 +1350,10 @@ Subject: [PATCH 14/21] Fix an issue where forced panel type orientations 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp -index eafb2f9..1ea1221 100644 +index 07f0383..8200619 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp -@@ -2031,20 +2031,19 @@ namespace gamescope +@@ -2026,20 +2026,19 @@ namespace gamescope void CDRMConnector::UpdateEffectiveOrientation( const drmModeModeInfo *pMode ) { @@ -1411,7 +1380,7 @@ index eafb2f9..1ea1221 100644 switch ( this->GetProperties().panel_orientation->GetCurrentValue() ) { case DRM_MODE_PANEL_ORIENTATION_NORMAL: -@@ -2066,6 +2065,7 @@ namespace gamescope +@@ -2061,6 +2060,7 @@ namespace gamescope if ( this->GetScreenType() == gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL && pMode ) { @@ -1419,7 +1388,7 @@ index eafb2f9..1ea1221 100644 // Auto-detect portait mode for internal displays m_ChosenOrientation = pMode->hdisplay < pMode->vdisplay ? GAMESCOPE_PANEL_ORIENTATION_270 -@@ -2073,6 +2073,7 @@ namespace gamescope +@@ -2068,6 +2068,7 @@ namespace gamescope } else { @@ -1428,23 +1397,23 @@ index eafb2f9..1ea1221 100644 } } -- -2.46.0 +2.46.2 -From 5d7781dd8ca41f4d865aa336b4e925beeec9349e Mon Sep 17 00:00:00 2001 +From a98358aafc43480b3373030ef6d39c5342df5394 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Mon, 20 May 2024 07:25:29 -0500 -Subject: [PATCH 15/21] add missing curly bracket... +Subject: [PATCH 15/23] add missing curly bracket... --- src/Backends/DRMBackend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp -index 1ea1221..8d86df0 100644 +index 8200619..10b9b92 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp -@@ -2033,7 +2033,7 @@ namespace gamescope +@@ -2028,7 +2028,7 @@ namespace gamescope { if ((this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO) || (this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO && g_bExternalForced)) { @@ -1454,13 +1423,13 @@ index 1ea1221..8d86df0 100644 } else if (this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO) { drm_log.infof("We are rotating the orientation of an external display"); -- -2.46.0 +2.46.2 -From 0282352468bb6b99e75eb1c24cb3ed555886fff5 Mon Sep 17 00:00:00 2001 +From 28fa8b1b2b61beb37e60149f4eeac2b12eeb5d59 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Mon, 20 May 2024 10:17:55 -0500 -Subject: [PATCH 16/21] Fix case where real externals were rotated with faked +Subject: [PATCH 16/23] Fix case where real externals were rotated with faked external panels --- @@ -1469,10 +1438,10 @@ Subject: [PATCH 16/21] Fix case where real externals were rotated with faked 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp -index 8d86df0..0008505 100644 +index 10b9b92..848c71f 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp -@@ -318,13 +318,20 @@ namespace gamescope +@@ -309,13 +309,20 @@ namespace gamescope GamescopeScreenType GetScreenType() const override { @@ -1497,7 +1466,7 @@ index 8d86df0..0008505 100644 return GAMESCOPE_SCREEN_TYPE_EXTERNAL; } -@@ -2031,11 +2038,11 @@ namespace gamescope +@@ -2026,11 +2033,11 @@ namespace gamescope void CDRMConnector::UpdateEffectiveOrientation( const drmModeModeInfo *pMode ) { @@ -1513,10 +1482,10 @@ index 8d86df0..0008505 100644 m_ChosenOrientation = g_DesiredExternalOrientation; } diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index eb3936a..896ec04 100644 +index 13ea8b5..8b9201c 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp -@@ -2555,29 +2555,57 @@ static void apply_touchscreen_orientation(double *x, double *y ) +@@ -2566,29 +2566,57 @@ static void apply_touchscreen_orientation(double *x, double *y ) double ty = 0; // Use internal screen always for orientation purposes. @@ -1597,13 +1566,13 @@ index eb3936a..896ec04 100644 else if (g_ForcedScreenType == gamescope::GAMESCOPE_SCREEN_TYPE_AUTO) { -- -2.46.0 +2.46.2 -From 276c1220de3542467b6d8e2218dfa1f2ccfc5b79 Mon Sep 17 00:00:00 2001 +From 686be5e1e03f708525755f344fabc24b1e81f3fe Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Mon, 20 May 2024 16:30:47 -0500 -Subject: [PATCH 17/21] Add verbose panel logs and attempt to address all +Subject: [PATCH 17/23] Add verbose panel logs and attempt to address all orientation issues --- @@ -1613,10 +1582,10 @@ Subject: [PATCH 17/21] Add verbose panel logs and attempt to address all 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp -index 0008505..bd5ffec 100644 +index 848c71f..e1b1d48 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp -@@ -56,6 +56,7 @@ static constexpr bool k_bUseCursorPlane = false; +@@ -58,6 +58,7 @@ static constexpr bool k_bUseCursorPlane = false; extern int g_nPreferredOutputWidth; extern int g_nPreferredOutputHeight; @@ -1624,7 +1593,7 @@ index 0008505..bd5ffec 100644 gamescope::ConVar cv_drm_single_plane_optimizations( "drm_single_plane_optimizations", true, "Whether or not to enable optimizations for single plane usage." ); -@@ -324,6 +325,7 @@ namespace gamescope +@@ -315,6 +316,7 @@ namespace gamescope { if ( g_bExternalForced ) { @@ -1632,7 +1601,7 @@ index 0008505..bd5ffec 100644 return g_ForcedScreenType; } else -@@ -332,7 +334,7 @@ namespace gamescope +@@ -323,7 +325,7 @@ namespace gamescope } } @@ -1641,7 +1610,7 @@ index 0008505..bd5ffec 100644 return GAMESCOPE_SCREEN_TYPE_EXTERNAL; } -@@ -2038,7 +2040,19 @@ namespace gamescope +@@ -2033,7 +2035,19 @@ namespace gamescope void CDRMConnector::UpdateEffectiveOrientation( const drmModeModeInfo *pMode ) { @@ -1663,10 +1632,10 @@ index 0008505..bd5ffec 100644 m_ChosenOrientation = g_DesiredInternalOrientation; } diff --git a/src/wlserver.cpp b/src/wlserver.cpp -index 896ec04..e5bb2e2 100644 +index 8b9201c..7adf7db 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp -@@ -2559,26 +2559,29 @@ static void apply_touchscreen_orientation(double *x, double *y ) +@@ -2570,26 +2570,29 @@ static void apply_touchscreen_orientation(double *x, double *y ) { if ( g_ForcedScreenType == gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL ) { @@ -1728,23 +1697,23 @@ index 0754ee5..bdf3b0b 100644 void wlserver_destroy_xwayland_server(gamescope_xwayland_server_t *server); -- -2.46.0 +2.46.2 -From 11664b820a9065b597d8655e53ade8dd9a29c4bc Mon Sep 17 00:00:00 2001 +From 0ca7930d0463e87733aeeebed7c4585c712b27e5 Mon Sep 17 00:00:00 2001 From: Bouke Sybren Haarsma Date: Tue, 28 May 2024 21:56:47 +0200 -Subject: [PATCH 18/21] add closing bracket +Subject: [PATCH 18/23] add closing bracket --- src/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.cpp b/src/main.cpp -index 675020f..315b718 100644 +index 36421bb..83fc011 100644 --- a/src/main.cpp +++ b/src/main.cpp -@@ -465,6 +465,7 @@ static enum gamescope::GamescopeBackend parse_backend_name(const char *str) +@@ -467,6 +467,7 @@ static enum gamescope::GamescopeBackend parse_backend_name(const char *str) fprintf( stderr, "gamescope: invalid value for --backend\n" ); exit(1); } @@ -1753,13 +1722,13 @@ index 675020f..315b718 100644 std::vector g_customRefreshRates; // eg: 60,60,90,110-120 -- -2.46.0 +2.46.2 -From 1e5c439eb0b1e809a3ec6414e8d0536db22c9601 Mon Sep 17 00:00:00 2001 +From 14a226e40efba864cd2b01b258f7cc4e3aedc322 Mon Sep 17 00:00:00 2001 From: Bouke Sybren Haarsma Date: Wed, 3 Jan 2024 17:03:04 +0100 -Subject: [PATCH 19/21] remove hacky texture +Subject: [PATCH 19/23] remove hacky texture This will use more hardware planes, causing some devices to composite yeilding lower framerates --- @@ -1767,10 +1736,10 @@ This will use more hardware planes, causing some devices to composite yeilding l 1 file changed, 17 insertions(+), 45 deletions(-) diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp -index 6fceb1d..4dbbdaf 100644 +index 44a086d..8b288ab 100644 --- a/src/steamcompmgr.cpp +++ b/src/steamcompmgr.cpp -@@ -1620,7 +1620,7 @@ bool MouseCursor::getTexture() +@@ -1623,7 +1623,7 @@ bool MouseCursor::getTexture() { pixels[i * image->width + j] = image->pixels[i * image->width + j]; } @@ -1779,7 +1748,7 @@ index 6fceb1d..4dbbdaf 100644 std::vector resizeBuffer( nDesiredWidth * nDesiredHeight ); stbir_resize_uint8_srgb( (unsigned char *)pixels.data(), image->width, image->height, 0, (unsigned char *)resizeBuffer.data(), nDesiredWidth, nDesiredHeight, 0, -@@ -2306,7 +2306,7 @@ paint_all(bool async) +@@ -2318,7 +2318,7 @@ paint_all(bool async) } } } @@ -1788,7 +1757,7 @@ index 6fceb1d..4dbbdaf 100644 int nOldLayerCount = frameInfo.layerCount; uint32_t flags = 0; -@@ -2314,7 +2314,7 @@ paint_all(bool async) +@@ -2326,7 +2326,7 @@ paint_all(bool async) flags |= PaintWindowFlag::BasePlane; paint_window(w, w, &frameInfo, global_focus.cursor, flags); update_touch_scaling( &frameInfo ); @@ -1797,7 +1766,7 @@ index 6fceb1d..4dbbdaf 100644 // paint UI unless it's fully hidden, which it communicates to us through opacity=0 // we paint it to extract scaling coefficients above, then remove the layer if one was added if ( w->opacity == TRANSLUCENT && bHasVideoUnderlay && nOldLayerCount < frameInfo.layerCount ) -@@ -2327,7 +2327,7 @@ paint_all(bool async) +@@ -2339,7 +2339,7 @@ paint_all(bool async) float opacityScale = g_bPendingFade ? 0.0f : ((currentTime - fadeOutStartTime) / (float)g_FadeOutDuration); @@ -1806,7 +1775,7 @@ index 6fceb1d..4dbbdaf 100644 paint_cached_base_layer(g_HeldCommits[HELD_COMMIT_FADE], g_CachedPlanes[HELD_COMMIT_FADE], &frameInfo, 1.0f - opacityScale, false); paint_window(w, w, &frameInfo, global_focus.cursor, PaintWindowFlag::BasePlane | PaintWindowFlag::FadeTarget | PaintWindowFlag::DrawBorders, opacityScale, override); } -@@ -2401,34 +2401,6 @@ paint_all(bool async) +@@ -2413,34 +2413,6 @@ paint_all(bool async) if ( overlay == global_focus.inputFocusWindow ) update_touch_scaling( &frameInfo ); } @@ -1841,7 +1810,7 @@ index 6fceb1d..4dbbdaf 100644 if (notification) { -@@ -3014,7 +2986,7 @@ win_maybe_a_dropdown( steamcompmgr_win_t *w ) +@@ -3045,7 +3017,7 @@ win_maybe_a_dropdown( steamcompmgr_win_t *w ) // // TODO: Come back to me for original Age of Empires HD launcher. // Does that use it? It wants blending! @@ -1850,7 +1819,7 @@ index 6fceb1d..4dbbdaf 100644 // Only do this if we have CONTROLPARENT right now. Some other apps, such as the // Street Fighter V (310950) Splash Screen also use LAYERED and TOOLWINDOW, and we don't // want that to be overlayed. -@@ -3029,12 +3001,12 @@ win_maybe_a_dropdown( steamcompmgr_win_t *w ) +@@ -3060,12 +3032,12 @@ win_maybe_a_dropdown( steamcompmgr_win_t *w ) // Josh: // The logic here is as follows. The window will be treated as a dropdown if: @@ -1865,7 +1834,7 @@ index 6fceb1d..4dbbdaf 100644 // - If the window has transient for, disregard it, as it is trying to redirecting us elsewhere // ie. a settings menu dialog popup or something. // - If the window has both skip taskbar and pager, treat it as a dialog. -@@ -3126,7 +3098,7 @@ static bool is_good_override_candidate( steamcompmgr_win_t *override, steamcompm +@@ -3157,7 +3129,7 @@ static bool is_good_override_candidate( steamcompmgr_win_t *override, steamcompm return false; return override != focus && override->GetGeometry().nX >= 0 && override->GetGeometry().nY >= 0; @@ -1874,7 +1843,7 @@ index 6fceb1d..4dbbdaf 100644 static bool pick_primary_focus_and_override(focus_t *out, Window focusControlWindow, const std::vector& vecPossibleFocusWindows, bool globalFocus, const std::vector& ctxFocusControlAppIDs) -@@ -3267,7 +3239,7 @@ found:; +@@ -3298,7 +3270,7 @@ found:; if ( focus ) { @@ -1883,7 +1852,7 @@ index 6fceb1d..4dbbdaf 100644 out->focusWindow = focus; else focus->outdatedInteractiveFocus = true; -@@ -3310,9 +3282,9 @@ found:; +@@ -3341,9 +3313,9 @@ found:; override_focus = fake_override; goto found2; } @@ -1895,7 +1864,7 @@ index 6fceb1d..4dbbdaf 100644 found2:; resolveTransientOverrides( true ); } -@@ -4574,7 +4546,7 @@ finish_destroy_win(xwayland_ctx_t *ctx, Window id, bool gone) +@@ -4605,7 +4577,7 @@ finish_destroy_win(xwayland_ctx_t *ctx, Window id, bool gone) { if (gone) finish_unmap_win (ctx, w); @@ -1904,7 +1873,7 @@ index 6fceb1d..4dbbdaf 100644 { std::unique_lock lock( ctx->list_mutex ); *prev = w->xwayland().next; -@@ -4631,7 +4603,7 @@ destroy_win(xwayland_ctx_t *ctx, Window id, bool gone, bool fade) +@@ -4662,7 +4634,7 @@ destroy_win(xwayland_ctx_t *ctx, Window id, bool gone, bool fade) global_focus.overrideWindow = nullptr; if (x11_win(global_focus.fadeWindow) == id && gone) global_focus.fadeWindow = nullptr; @@ -1913,7 +1882,7 @@ index 6fceb1d..4dbbdaf 100644 MakeFocusDirty(); finish_destroy_win(ctx, id, gone); -@@ -5243,7 +5215,7 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev) +@@ -5286,7 +5258,7 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev) { get_win_type(ctx, w); MakeFocusDirty(); @@ -1922,7 +1891,7 @@ index 6fceb1d..4dbbdaf 100644 } if (ev->atom == ctx->atoms.sizeHintsAtom) { -@@ -6153,7 +6125,7 @@ void handle_done_commits_xdg( bool vblank, uint64_t vblank_idx ) +@@ -6196,7 +6168,7 @@ void handle_done_commits_xdg( bool vblank, uint64_t vblank_idx ) commits_before_their_time.push_back( entry ); continue; } @@ -1931,7 +1900,7 @@ index 6fceb1d..4dbbdaf 100644 if (!entry.earliestPresentTime) { entry.earliestPresentTime = next_refresh_time; -@@ -7143,7 +7115,7 @@ void update_mode_atoms(xwayland_ctx_t *root_ctx, bool* needs_flush = nullptr) +@@ -7218,7 +7190,7 @@ void update_mode_atoms(xwayland_ctx_t *root_ctx, bool* needs_flush = nullptr) } XChangeProperty(root_ctx->dpy, root_ctx->root, root_ctx->atoms.gamescopeDisplayModeListExternal, XA_STRING, 8, PropModeReplace, (unsigned char *)modes, strlen(modes) + 1 ); @@ -1940,7 +1909,7 @@ index 6fceb1d..4dbbdaf 100644 uint32_t one = 1; XChangeProperty(root_ctx->dpy, root_ctx->root, root_ctx->atoms.gamescopeDisplayIsExternal, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&one, 1 ); -@@ -7975,7 +7947,7 @@ void steamcompmgr_send_frame_done_to_focus_window() +@@ -8065,7 +8037,7 @@ void steamcompmgr_send_frame_done_to_focus_window() { wlserver_lock(); wlserver_send_frame_done( global_focus.focusWindow->xwayland().surface.main_surface , &now ); @@ -1950,61 +1919,177 @@ index 6fceb1d..4dbbdaf 100644 } -- -2.46.0 +2.46.2 -From 672fd75c5ac7bb1226c418270fa134ad6fe07b30 Mon Sep 17 00:00:00 2001 -From: Kyle Gospodnetich -Date: Tue, 2 Jul 2024 14:12:47 -0700 -Subject: [PATCH 20/21] Only change refresh rates on internal displays +From e2f4c39992e2fa55f03225019fe244f08f49b287 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?= + +Date: Tue, 9 Jul 2024 18:29:16 -0300 +Subject: [PATCH 20/23] disable explicit sync to avoid graphical artifacts --- src/Backends/DRMBackend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp -index bd5ffec..03b9b4c 100644 +index e1b1d48..ae5c767 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp -@@ -2162,7 +2162,7 @@ namespace gamescope - ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Jupiter"sv ) || - ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Galileo"sv ); +@@ -70,7 +70,7 @@ gamescope::ConVar cv_drm_debug_disable_blend_tf( "drm_debug_disable_blend_ + gamescope::ConVar cv_drm_debug_disable_ctm( "drm_debug_disable_ctm", false, "CTM chicken bit. (Forces CTM off, does not affect other logic)" ); + gamescope::ConVar cv_drm_debug_disable_color_encoding( "drm_debug_disable_color_encoding", false, "YUV Color Encoding chicken bit. (Forces COLOR_ENCODING to DEFAULT, does not affect other logic)" ); + gamescope::ConVar cv_drm_debug_disable_color_range( "drm_debug_disable_color_range", false, "YUV Color Range chicken bit. (Forces COLOR_RANGE to DEFAULT, does not affect other logic)" ); +-gamescope::ConVar cv_drm_debug_disable_explicit_sync( "drm_debug_disable_explicit_sync", false, "Force disable explicit sync on the DRM backend." ); ++gamescope::ConVar cv_drm_debug_disable_explicit_sync( "drm_debug_disable_explicit_sync", true, "Force disable explicit sync on the DRM backend." ); + gamescope::ConVar cv_drm_debug_disable_in_fence_fd( "drm_debug_disable_in_fence_fd", false, "Force disable IN_FENCE_FD being set to avoid over-synchronization on the DRM backend." ); -- if ( g_customRefreshRates.size() > 0 ) { -+ if ( g_customRefreshRates.size() > 0 && GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL ) { - m_Mutable.ValidDynamicRefreshRates = std::span(g_customRefreshRates); - return; - } + namespace gamescope -- -2.46.0 +2.46.2 -From 0cada655064b2bb2c0b5540f4c249a3c6a1254ed Mon Sep 17 00:00:00 2001 +From 9c77c12061530ff1403ed213c60f060791deb863 Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich -Date: Tue, 2 Jul 2024 15:14:23 -0700 -Subject: [PATCH 21/21] Also check g_bExternalForced +Date: Tue, 2 Jul 2024 14:12:47 -0700 +Subject: [PATCH 21/23] Only change refresh rates on internal displays --- - src/Backends/DRMBackend.cpp | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) + src/Backends/DRMBackend.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp -index 03b9b4c..24e81b1 100644 +index ae5c767..1fc35e5 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp -@@ -2162,9 +2162,9 @@ namespace gamescope - ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Jupiter"sv ) || - ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Galileo"sv ); +@@ -2251,7 +2251,7 @@ namespace gamescope -- if ( g_customRefreshRates.size() > 0 && GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL ) { -- m_Mutable.ValidDynamicRefreshRates = std::span(g_customRefreshRates); -- return; -+ if ( g_customRefreshRates.size() > 0 && ( GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL || g_bExternalForced ) ) { -+ m_Mutable.ValidDynamicRefreshRates = std::span(g_customRefreshRates); -+ return; - } - if ( bSteamDeckDisplay ) - { + bHasKnownHDRInfo = true; + } +- } else if ( g_customRefreshRates.size() > 0 ) { ++ } else if ( g_customRefreshRates.size() > 0 && GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL ) { + m_Mutable.ValidDynamicRefreshRates = g_customRefreshRates; + return; + } -- -2.46.0 +2.46.2 + + +From f67acb1e222ac04d08acc4480d071a871f188553 Mon Sep 17 00:00:00 2001 +From: Kyle Gospodnetich +Date: Tue, 2 Jul 2024 15:14:23 -0700 +Subject: [PATCH 22/23] Also check g_bExternalForced + +--- + src/Backends/DRMBackend.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp +index 1fc35e5..6048a2d 100644 +--- a/src/Backends/DRMBackend.cpp ++++ b/src/Backends/DRMBackend.cpp +@@ -2251,7 +2251,7 @@ namespace gamescope + + bHasKnownHDRInfo = true; + } +- } else if ( g_customRefreshRates.size() > 0 && GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL ) { ++ } else if ( g_customRefreshRates.size() > 0 && ( GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL || g_bExternalForced ) ) { + m_Mutable.ValidDynamicRefreshRates = g_customRefreshRates; + return; + } +-- +2.46.2 + + +From 3e9510adf6d246a29fcb0fe5df11bcf1b4299f72 Mon Sep 17 00:00:00 2001 +From: Alesh Slovak +Date: Thu, 26 Sep 2024 07:13:24 -0400 +Subject: [PATCH 23/23] Revert "steamcompmgr: Move outdatedInteractiveFocus to + window" + +This reverts commit 299bc3410dcfd46da5e3c988354b60ed3a356900. +--- + src/steamcompmgr.cpp | 39 +++++++++++++++++++++++-------------- + src/steamcompmgr_shared.hpp | 1 - + 2 files changed, 24 insertions(+), 16 deletions(-) + +diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp +index 8b288ab..dcb2c71 100644 +--- a/src/steamcompmgr.cpp ++++ b/src/steamcompmgr.cpp +@@ -3273,7 +3273,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. +@@ -6025,28 +6025,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 ) + { +diff --git a/src/steamcompmgr_shared.hpp b/src/steamcompmgr_shared.hpp +index 095694e..e41fad9 100644 +--- a/src/steamcompmgr_shared.hpp ++++ b/src/steamcompmgr_shared.hpp +@@ -125,7 +125,6 @@ struct steamcompmgr_win_t { + unsigned int requestedHeight = 0; + bool is_dialog = false; + bool maybe_a_dropdown = false; +- bool outdatedInteractiveFocus = false; + + bool hasHwndStyle = false; + uint32_t hwndStyle = 0; +-- +2.46.2 diff --git a/spec_files/gamescope/gamescope.spec b/spec_files/gamescope/gamescope.spec index e523b35c..d70780a4 100644 --- a/spec_files/gamescope/gamescope.spec +++ b/spec_files/gamescope/gamescope.spec @@ -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 @@ -131,6 +130,7 @@ cd gamescope %{_bindir}/gamescopectl %{_bindir}/gamescopestream %{_bindir}/gamescopereaper +%{_datadir}/gamescope/* %files libs %{_libdir}/libVkLayer_FROG_gamescope_wsi_*.so diff --git a/spec_files/gamescope/revert-299bc34.patch b/spec_files/gamescope/revert-299bc34.patch deleted file mode 100644 index 891a001a..00000000 --- a/spec_files/gamescope/revert-299bc34.patch +++ /dev/null @@ -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 ) - { From aedc63282f28c260ba3dda4c9263f87f40746ba1 Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Tue, 8 Oct 2024 10:39:17 -0700 Subject: [PATCH 2/3] chore: Restore 32-bit vkcapture --- Containerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Containerfile b/Containerfile index be771dfb..d4ce360d 100644 --- a/Containerfile +++ b/Containerfile @@ -522,9 +522,10 @@ RUN --mount=type=cache,dst=/var/cache/rpm-ostree \ vkBasalt.i686 \ mangohud.x86_64 \ mangohud.i686 \ - obs-vkcapture.x86_64 \ libobs_vkcapture.x86_64 \ - libobs_glcapture.x86_64 && \ + libobs_glcapture.x86_64 \ + libobs_vkcapture.i686 \ + libobs_glcapture.i686 && \ ln -s wine32 /usr/bin/wine && \ ln -s wine32-preloader /usr/bin/wine-preloader && \ ln -s wineserver64 /usr/bin/wineserver && \ From caf157d6a54c76279cad7f21bc69495cec4dab08 Mon Sep 17 00:00:00 2001 From: Kyle Gospodnetich Date: Tue, 8 Oct 2024 11:44:22 -0700 Subject: [PATCH 3/3] chore: Fix protontricks flatpak path for installer --- installer/gnome_flatpaks/flatpaks | 2 +- installer/kde_flatpaks/flatpaks | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/installer/gnome_flatpaks/flatpaks b/installer/gnome_flatpaks/flatpaks index 41cc5b33..711b5b6b 100644 --- a/installer/gnome_flatpaks/flatpaks +++ b/installer/gnome_flatpaks/flatpaks @@ -1,6 +1,6 @@ app/org.mozilla.firefox/x86_64/stable app/com.mattjakeman.ExtensionManager/x86_64/stable -app/com.github.Matoking.protontricks/stable +app/com.github.Matoking.protontricks/x86_64/stable app/io.github.fastrizwaan.WineZGUI/x86_64/stable app/io.github.dvlv.boxbuddyrs/x86_64/stable app/it.mijorus.gearlever/x86_64/stable diff --git a/installer/kde_flatpaks/flatpaks b/installer/kde_flatpaks/flatpaks index abb01541..f76db38b 100644 --- a/installer/kde_flatpaks/flatpaks +++ b/installer/kde_flatpaks/flatpaks @@ -8,7 +8,7 @@ app/io.github.fastrizwaan.WineZGUI/x86_64/stable app/io.github.dvlv.boxbuddyrs/x86_64/stable app/it.mijorus.gearlever/x86_64/stable app/com.github.tchx84.Flatseal/x86_64/stable -app/com.github.Matoking.protontricks/stable +app/com.github.Matoking.protontricks/x86_64/stable app/io.github.flattool.Warehouse/x86_64/stable app/net.davidotek.pupgui2/x86_64/stable runtime/org.freedesktop.Platform.VulkanLayer.MangoHud/x86_64/23.08