Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 86 additions & 2 deletions src/Backends/DRMBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ namespace gamescope

struct drm_t {
bool bUseLiftoff;
bool bSplitDisplay = false; // true when render GPU != display GPU (e.g. Pi5 V3D+VC4)

int fd = -1;

Expand Down Expand Up @@ -1229,9 +1230,63 @@ bool init_drm(struct drm_t *drm, int width, int height, int refresh)

if ( !drmIsKMS( drm->fd ) )
{
drm_log.errorf( "'%s' is not a KMS device", drm->device_name );
drm_log.infof( "'%s' is not a KMS device, searching for a separate KMS display device (split render/display architecture)...", drm->device_name );
wlsession_close_kms();
return -1;

bool bFoundKmsDevice = false;
drmDevice **drmDevices = nullptr;
int nDevices = drmGetDevices2( 0, nullptr, 0 );
if ( nDevices > 0 )
{
drmDevices = (drmDevice **)calloc( nDevices, sizeof(drmDevice *) );
nDevices = drmGetDevices2( 0, drmDevices, nDevices );
}
for ( int i = 0; i < nDevices; i++ )
{
drmDevice *pDevice = drmDevices[i];
if ( !( pDevice->available_nodes & ( 1 << DRM_NODE_PRIMARY ) ) )
continue;

const char *pPrimaryNode = pDevice->nodes[DRM_NODE_PRIMARY];

// Skip the Vulkan device's node that we already tried
if ( drm->device_name && strcmp( pPrimaryNode, drm->device_name ) == 0 )
continue;

int fd = open( pPrimaryNode, O_RDWR | O_CLOEXEC );
if ( fd < 0 )
continue;

if ( drmIsKMS( fd ) )
{
close( fd );
free( drm->device_name );
drm->device_name = strdup( pPrimaryNode );
drm_log.infof( "Found separate KMS display device: '%s'", drm->device_name );
drm->fd = wlsession_open_kms( drm->device_name );
if ( drm->fd >= 0 )
{
drm->bSplitDisplay = true;
bFoundKmsDevice = true;
break;
}
}
else
{
close( fd );
}
}
if ( drmDevices )
{
drmFreeDevices( drmDevices, nDevices );
free( drmDevices );
}

if ( !bFoundKmsDevice )
{
drm_log.errorf( "No KMS-capable display device found" );
return false;
}
}

if (drmSetClientCap(drm->fd, DRM_CLIENT_CAP_ATOMIC, 1) != 0) {
Expand Down Expand Up @@ -1338,6 +1393,20 @@ bool init_drm(struct drm_t *drm, int width, int height, int refresh)
// 2. When compositing HDR content as a fallback when we undock, it avoids introducing
// a bunch of horrible banding when going to G2.2 curve.
// It ensures that we can dither that.
if ( drm->bSplitDisplay )
{
drm_log.infof( "Split display mode: preferring 8-bit formats for cross-device compatibility" );
g_nDRMFormat = pick_plane_format(&drm->primary_formats, DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888);
if ( g_nDRMFormat == DRM_FORMAT_INVALID ) {
g_nDRMFormat = pick_plane_format(&drm->primary_formats, DRM_FORMAT_XRGB2101010, DRM_FORMAT_ARGB2101010);
if ( g_nDRMFormat == DRM_FORMAT_INVALID ) {
drm_log.errorf("Primary plane doesn't support any formats >= 8888");
return false;
}
}
}
else
{
g_nDRMFormat = pick_plane_format(&drm->primary_formats, DRM_FORMAT_XRGB2101010, DRM_FORMAT_ARGB2101010);
if ( g_nDRMFormat == DRM_FORMAT_INVALID ) {
g_nDRMFormat = pick_plane_format(&drm->primary_formats, DRM_FORMAT_XBGR2101010, DRM_FORMAT_ABGR2101010);
Expand All @@ -1349,9 +1418,23 @@ bool init_drm(struct drm_t *drm, int width, int height, int refresh)
}
}
}
}

if (have_overlay_planes(drm)) {
// ARGB8888 is the Xformat and AFormat here in this function as we want transparent overlay
if ( drm->bSplitDisplay )
{
g_nDRMFormatOverlay = pick_plane_format(&drm->formats, DRM_FORMAT_ARGB8888, DRM_FORMAT_ARGB8888);
if ( g_nDRMFormatOverlay == DRM_FORMAT_INVALID ) {
g_nDRMFormatOverlay = pick_plane_format(&drm->formats, DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB2101010);
if ( g_nDRMFormatOverlay == DRM_FORMAT_INVALID ) {
drm_log.errorf("Overlay plane doesn't support any formats >= 8888");
return false;
}
}
}
else
{
g_nDRMFormatOverlay = pick_plane_format(&drm->formats, DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB2101010);
if ( g_nDRMFormatOverlay == DRM_FORMAT_INVALID ) {
g_nDRMFormatOverlay = pick_plane_format(&drm->formats, DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR2101010);
Expand All @@ -1363,6 +1446,7 @@ bool init_drm(struct drm_t *drm, int width, int height, int refresh)
}
}
}
}
} else {
switch (g_nDRMFormat) {
case DRM_FORMAT_XRGB2101010:
Expand Down
Loading