From: Matthew Schwartz Subject: Lazily allocate shared Vulkan output images Origin: upstream, commit e383171ff1c0f7b5b37f05f2bb67f7c5282b087f Backport the upstream lazy-allocation change to Gamescope 3.16.20. Native Wayland presentation normally sends the game's DMA-BUF directly to the host compositor, so allocating six output-sized Vulkan images at startup and after every host-window configure is unnecessary. Allocate those images only if a frame actually needs full Vulkan composition. --- a/src/rendervulkan.cpp +++ b/src/rendervulkan.cpp @@ -3345,6 +3345,31 @@ static bool vulkan_make_output_images( VulkanOutput_t *pOutput ) return true; } +// Without a swapchain the shared images are ours to make, so they wait for their first use. +static bool vulkan_defer_output_images() +{ + return !GetBackend()->UsesVulkanSwapchain(); +} + +static bool vulkan_ensure_output_images() +{ + if ( !vulkan_defer_output_images() ) + return true; + + VulkanOutput_t *pOutput = &g_output; + if ( !pOutput->outputImages.empty() && pOutput->outputImages[0] ) + return true; + + vk_log.debugf( "Making the shared output images on first use" ); + if ( vulkan_make_output_images( pOutput ) ) + return true; + + // A half-made set would pass the check above, so the next use tries again from nothing. + pOutput->outputImages.clear(); + pOutput->outputImagesPartialOverlay.clear(); + return false; +} + bool vulkan_remake_output_images() { VulkanOutput_t *pOutput = &g_output; @@ -3355,6 +3380,14 @@ bool vulkan_remake_output_images() for (auto& pScreenshotImage : pOutput->pScreenshotImages) pScreenshotImage = nullptr; + if ( vulkan_defer_output_images() ) + { + pOutput->outputImages.clear(); + pOutput->outputImagesPartialOverlay.clear(); + pOutput->temporaryHackyBlankImage = vulkan_create_debug_blank_texture(); + return true; + } + bool bRet = vulkan_make_output_images( pOutput ); assert( bRet ); return bRet; @@ -3433,7 +3466,9 @@ bool vulkan_make_output() return false; } - if ( !vulkan_make_output_images( pOutput ) ) + if ( vulkan_defer_output_images() ) + pOutput->temporaryHackyBlankImage = vulkan_create_debug_blank_texture(); + else if ( !vulkan_make_output_images( pOutput ) ) return false; } @@ -3980,6 +4015,9 @@ std::optional vulkan_composite( struct FrameInfo_t *frameInfo, gamesco g_reshadeManager.clear(); } + if ( !pOutputOverride && !vulkan_ensure_output_images() ) + return std::nullopt; + gamescope::Rc compositeImage; if ( pOutputOverride ) compositeImage = pOutputOverride;