Skip to content

Commit

Permalink
rendervulkan: Attempt at fixing modifierless devices having issues
Browse files Browse the repository at this point in the history
  • Loading branch information
misyltoad committed Sep 16, 2024
1 parent 7a27374 commit 0110109
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 70 deletions.
34 changes: 16 additions & 18 deletions src/Backends/WaylandBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,8 +577,6 @@ namespace gamescope
void SetFullscreen( bool bFullscreen ); // Thread safe, can be called from the input thread.
void UpdateFullscreenState();

bool SupportsFormat( uint32_t uDRMFormat ) const;

bool HostCompositorIsCurrentlyVRR() const { return m_bHostCompositorIsCurrentlyVRR; }
void SetHostCompositorIsCurrentlyVRR( bool bActive ) { m_bHostCompositorIsCurrentlyVRR = bActive; }

Expand Down Expand Up @@ -672,8 +670,8 @@ namespace gamescope
zwp_locked_pointer_v1 *m_pLockedPointer = nullptr;
zwp_relative_pointer_v1 *m_pRelativePointer = nullptr;

bool m_bCanUseModifiers = false;
std::unordered_map<uint32_t, std::vector<uint64_t>> m_FormatModifiers;
std::unordered_set<uint32_t> m_ModifierlessFormats;
std::unordered_map<uint32_t, wl_buffer *> m_ImportedFbs;

uint32_t m_uPointerEnterSerial = 0;
Expand Down Expand Up @@ -1770,13 +1768,10 @@ namespace gamescope
if ( !cv_wayland_use_modifiers )
return false;

return !m_FormatModifiers.empty();
return m_bCanUseModifiers;
}
std::span<const uint64_t> CWaylandBackend::GetSupportedModifiers( uint32_t uDrmFormat ) const
{
if ( !UsesModifiers() )
return std::span<const uint64_t>{};

auto iter = m_FormatModifiers.find( uDrmFormat );
if ( iter == m_FormatModifiers.end() )
return std::span<const uint64_t>{};
Expand Down Expand Up @@ -2069,13 +2064,6 @@ namespace gamescope
}
}

bool CWaylandBackend::SupportsFormat( uint32_t uDRMFormat ) const
{
return UsesModifiers()
? m_FormatModifiers.contains( uDRMFormat )
: m_ModifierlessFormats.contains( uDRMFormat );
}

/////////////////////
// Wayland Callbacks
/////////////////////
Expand Down Expand Up @@ -2169,11 +2157,21 @@ namespace gamescope
void CWaylandBackend::Wayland_Modifier( zwp_linux_dmabuf_v1 *pDmabuf, uint32_t uFormat, uint32_t uModifierHi, uint32_t uModifierLo )
{
uint64_t ulModifier = ( uint64_t( uModifierHi ) << 32 ) | uModifierLo;
//xdg_log.infof( "Modifier: %s (0x%" PRIX32 ") %lx", drmGetFormatName( uFormat ), uFormat, ulModifier );

#if 0
const char *pszExtraModifierName = "";
if ( ulModifier == DRM_FORMAT_MOD_INVALID )
pszExtraModifierName = " (Invalid)";
if ( ulModifier == DRM_FORMAT_MOD_LINEAR )
pszExtraModifierName = " (Invalid)";

xdg_log.infof( "Modifier: %s (0x%" PRIX32 ") %lx%s", drmGetFormatName( uFormat ), uFormat, ulModifier, pszExtraModifierName );
#endif

if ( ulModifier != DRM_FORMAT_MOD_INVALID )
m_FormatModifiers[uFormat].emplace_back( ulModifier );
else
m_ModifierlessFormats.emplace( uFormat );
m_bCanUseModifiers = true;

m_FormatModifiers[uFormat].emplace_back( ulModifier );
}

// Output
Expand Down
6 changes: 6 additions & 0 deletions src/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "Timeline.h"
#include "convar.h"
#include "rc.h"
#include "drm_include.h"
#include "Utils/Algorithm.h"

#include <cassert>
#include <span>
Expand Down Expand Up @@ -203,6 +205,10 @@ namespace gamescope

virtual bool UsesModifiers() const = 0;
virtual std::span<const uint64_t> GetSupportedModifiers( uint32_t uDrmFormat ) const = 0;
inline bool SupportsFormat( uint32_t uDrmFormat ) const
{
return Algorithm::Contains( this->GetSupportedModifiers( uDrmFormat ), DRM_FORMAT_MOD_INVALID );
}

virtual IBackendConnector *GetCurrentConnector() = 0;
virtual IBackendConnector *GetConnector( GamescopeScreenType eScreenType ) = 0;
Expand Down
95 changes: 43 additions & 52 deletions src/rendervulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <thread>
#include <dlfcn.h>
#include "vulkan_include.h"
#include "Utils/Algorithm.h"

#if defined(__linux__)
#include <sys/sysmacros.h>
Expand Down Expand Up @@ -122,12 +123,6 @@ VulkanOutput_t g_output;
uint32_t g_uCompositeDebug = 0u;
gamescope::ConVar<uint32_t> cv_composite_debug{ "composite_debug", 0, "Debug composition flags" };

template <typename T>
static bool Contains( const std::span<const T> x, T value )
{
return std::ranges::any_of( x, std::bind_front(std::equal_to{}, value) );
}

static std::map< VkFormat, std::map< uint64_t, VkDrmFormatModifierPropertiesEXT > > DRMModifierProps = {};
static struct wlr_drm_format_set sampledShmFormats = {};
static struct wlr_drm_format_set sampledDRMFormats = {};
Expand Down Expand Up @@ -2064,7 +2059,7 @@ bool CVulkanTexture::BInit( uint32_t width, uint32_t height, uint32_t depth, uin
assert( drmFormat == pDMA->format );
}

if ( g_device.supportsModifiers() && pDMA && pDMA->modifier != DRM_FORMAT_MOD_INVALID )
if ( GetBackend()->UsesModifiers() && g_device.supportsModifiers() && pDMA && pDMA->modifier != DRM_FORMAT_MOD_INVALID )
{
VkExternalImageFormatProperties externalImageProperties = {
.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
Expand Down Expand Up @@ -2754,66 +2749,62 @@ bool vulkan_init_format(VkFormat format, uint32_t drmFormat)

wlr_drm_format_set_add( &sampledShmFormats, drmFormat, DRM_FORMAT_MOD_LINEAR );

if ( !g_device.supportsModifiers() )
if ( g_device.supportsModifiers() )
{
if ( GetBackend()->UsesModifiers() )
{
if ( !Contains<uint64_t>( GetBackend()->GetSupportedModifiers( drmFormat ), DRM_FORMAT_MOD_INVALID ) )
return false;
}

wlr_drm_format_set_add( &sampledDRMFormats, drmFormat, DRM_FORMAT_MOD_INVALID );
return false;
}

// Then, collect the list of modifiers supported for sampled usage
VkDrmFormatModifierPropertiesListEXT modifierPropList = {
.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
};
VkFormatProperties2 formatProps = {
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
.pNext = &modifierPropList,
};

g_device.vk.GetPhysicalDeviceFormatProperties2( g_device.physDev(), format, &formatProps );
// Then, collect the list of modifiers supported for sampled usage
VkDrmFormatModifierPropertiesListEXT modifierPropList = {
.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
};
VkFormatProperties2 formatProps = {
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
.pNext = &modifierPropList,
};

if ( modifierPropList.drmFormatModifierCount == 0 )
{
vk_errorf( res, "vkGetPhysicalDeviceFormatProperties2 returned zero modifiers for DRM format 0x%" PRIX32, drmFormat );
return false;
}
g_device.vk.GetPhysicalDeviceFormatProperties2( g_device.physDev(), format, &formatProps );

std::vector<VkDrmFormatModifierPropertiesEXT> modifierProps(modifierPropList.drmFormatModifierCount);
modifierPropList.pDrmFormatModifierProperties = modifierProps.data();
g_device.vk.GetPhysicalDeviceFormatProperties2( g_device.physDev(), format, &formatProps );
if ( modifierPropList.drmFormatModifierCount == 0 )
{
vk_errorf( res, "vkGetPhysicalDeviceFormatProperties2 returned zero modifiers for DRM format 0x%" PRIX32, drmFormat );
return false;
}

std::map< uint64_t, VkDrmFormatModifierPropertiesEXT > map = {};
std::vector<VkDrmFormatModifierPropertiesEXT> modifierProps(modifierPropList.drmFormatModifierCount);
modifierPropList.pDrmFormatModifierProperties = modifierProps.data();
g_device.vk.GetPhysicalDeviceFormatProperties2( g_device.physDev(), format, &formatProps );

for ( size_t j = 0; j < modifierProps.size(); j++ )
{
map[ modifierProps[j].drmFormatModifier ] = modifierProps[j];
std::map< uint64_t, VkDrmFormatModifierPropertiesEXT > map = {};

uint64_t modifier = modifierProps[j].drmFormatModifier;
for ( size_t j = 0; j < modifierProps.size(); j++ )
{
map[ modifierProps[j].drmFormatModifier ] = modifierProps[j];

if ( !is_image_format_modifier_supported( format, drmFormat, modifier ) )
continue;
uint64_t modifier = modifierProps[j].drmFormatModifier;

if ( ( modifierProps[j].drmFormatModifierTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT ) == 0 )
{
if ( !is_image_format_modifier_supported( format, drmFormat, modifier ) )
continue;
}

if ( GetBackend()->UsesModifiers() )
{
if ( !Contains<uint64_t>( GetBackend()->GetSupportedModifiers( drmFormat ), modifier ) )
if ( ( modifierProps[j].drmFormatModifierTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT ) == 0 )
{
continue;
}

if ( !gamescope::Algorithm::Contains( GetBackend()->GetSupportedModifiers( drmFormat ), modifier ) )
continue;

wlr_drm_format_set_add( &sampledDRMFormats, drmFormat, modifier );
}

wlr_drm_format_set_add( &sampledDRMFormats, drmFormat, modifier );
DRMModifierProps[ format ] = map;
return true;
}
else
{
if ( !GetBackend()->SupportsFormat( drmFormat ) )
return false;

DRMModifierProps[ format ] = map;
return true;
wlr_drm_format_set_add( &sampledDRMFormats, drmFormat, DRM_FORMAT_MOD_INVALID );
return false;
}
}

bool vulkan_init_formats()
Expand Down

0 comments on commit 0110109

Please sign in to comment.