From fe3dbc6ba617af8cc42e0d855186cc49847fb030 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 16 Nov 2023 00:09:59 +0000 Subject: [PATCH] steamcompmgr: Add horrible disgusting hacky blank texture to replace overlay when disabled This is a TEMPORARY HACK we will definitely get rid of eventually. Use a transparent overlay image of the screen's size for the Steam Overlay when not present to workaround garbage AMDGPU state tracking which causes full plane + LUT updates every time stuff is enabled/disabled. --- src/rendervulkan.cpp | 29 +++++++++++++++++++++++++++++ src/rendervulkan.hpp | 3 +++ src/steamcompmgr.cpp | 35 ++++++++++++++++++++++++++++------- 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/rendervulkan.cpp b/src/rendervulkan.cpp index ca767adbd8..e3b4130de6 100644 --- a/src/rendervulkan.cpp +++ b/src/rendervulkan.cpp @@ -2726,6 +2726,32 @@ void vulkan_update_luts(const std::shared_ptr& lut1d, const std: g_device.waitIdle(); // TODO: Sync this better } +std::shared_ptr vulkan_get_hacky_blank_texture() +{ + return g_output.temporaryHackyBlankImage; +} + +std::shared_ptr vulkan_create_debug_blank_texture() +{ + CVulkanTexture::createFlags flags; + flags.bFlippable = !BIsNested(); + flags.bSampled = true; + flags.bTransferDst = true; + + auto texture = std::make_shared(); + assert( texture->BInit( g_nOutputWidth, g_nOutputHeight, 1u, VulkanFormatToDRM( VK_FORMAT_B8G8R8A8_UNORM ), flags ) ); + + void* dst = g_device.uploadBufferData( g_nOutputWidth * g_nOutputHeight * 4 ); + memset( dst, 0x0, g_nOutputWidth * g_nOutputHeight * 4 ); + + auto cmdBuffer = g_device.commandBuffer(); + cmdBuffer->copyBufferToImage(g_device.uploadBuffer(), 0, 0, texture); + g_device.submit(std::move(cmdBuffer)); + g_device.waitIdle(); + + return texture; +} + #if HAVE_OPENVR std::shared_ptr vulkan_create_debug_white_texture() { @@ -2951,6 +2977,9 @@ static bool vulkan_make_output_images( VulkanOutput_t *pOutput ) return false; } + // Oh no. + pOutput->temporaryHackyBlankImage = vulkan_create_debug_blank_texture(); + if ( pOutput->outputFormatOverlay != VK_FORMAT_UNDEFINED && !kDisablePartialComposition ) { VkFormat partialFormat = pOutput->outputFormatOverlay; diff --git a/src/rendervulkan.hpp b/src/rendervulkan.hpp index 6ebc305bed..8cd9d89dbe 100644 --- a/src/rendervulkan.hpp +++ b/src/rendervulkan.hpp @@ -391,6 +391,8 @@ std::shared_ptr vulkan_create_1d_lut(uint32_t size); std::shared_ptr vulkan_create_3d_lut(uint32_t width, uint32_t height, uint32_t depth); void vulkan_update_luts(const std::shared_ptr& lut1d, const std::shared_ptr& lut3d, void* lut1d_data, void* lut3d_data); +std::shared_ptr vulkan_get_hacky_blank_texture(); + bool vulkan_screenshot( const struct FrameInfo_t *frameInfo, std::shared_ptr pScreenshotTexture ); struct wlr_renderer *vulkan_renderer_create( void ); @@ -485,6 +487,7 @@ struct VulkanOutput_t uint32_t nOutImage; // swapchain index in nested mode, or ping/pong between two RTs std::vector> outputImages; std::vector> outputImagesPartialOverlay; + std::shared_ptr temporaryHackyBlankImage; VkFormat outputFormat = VK_FORMAT_UNDEFINED; VkFormat outputFormatOverlay = VK_FORMAT_UNDEFINED; diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp index b1c2647c90..617ab7ef7c 100644 --- a/src/steamcompmgr.cpp +++ b/src/steamcompmgr.cpp @@ -2533,15 +2533,36 @@ paint_all(bool async) } } - if (overlay) + if (overlay && overlay->opacity) { - if (overlay->opacity) - { - paint_window(overlay, overlay, &frameInfo, global_focus.cursor, PaintWindowFlag::DrawBorders); + paint_window(overlay, overlay, &frameInfo, global_focus.cursor, PaintWindowFlag::DrawBorders); - if ( overlay == global_focus.inputFocusWindow ) - update_touch_scaling( &frameInfo ); - } + if ( overlay == global_focus.inputFocusWindow ) + update_touch_scaling( &frameInfo ); + } + else + { + // HACK! HACK HACK HACK + // To avoid stutter when toggling the overlay on + int curLayer = frameInfo.layerCount++; + + FrameInfo_t::Layer_t *layer = &frameInfo.layers[ curLayer ]; + + layer->scale.x = 1.0f; + layer->scale.y = 1.0f; + layer->offset.x = 0.0f; + layer->offset.y = 0.0f; + layer->opacity = 1.0f; // BLAH + layer->zpos = g_zposOverlay; + layer->applyColorMgmt = g_ColorMgmt.pending.enabled; + + layer->colorspace = GAMESCOPE_APP_TEXTURE_COLORSPACE_LINEAR; + layer->ctm = nullptr; + layer->tex = vulkan_get_hacky_blank_texture(); + layer->fbid = layer->tex->fbid(); + + layer->filter = GamescopeUpscaleFilter::NEAREST; + layer->blackBorder = true; } if (notification)