Skip to content

Commit

Permalink
Server: Add DRI3 extension
Browse files Browse the repository at this point in the history
  • Loading branch information
dcommander committed Feb 27, 2024
1 parent d28daaa commit 162b4ae
Show file tree
Hide file tree
Showing 19 changed files with 1,963 additions and 5 deletions.
5 changes: 5 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ variables are always on. A new CMake variable (`TVNC_INTELZLIB`) can be used
on x86 platforms to disable the in-tree SIMD-accelerated Intel zlib
implementation and build against the system-supplied zlib implementation.

2. The TurboVNC Server now supports the DRI3 X extension when using open source
GPU drivers. This enables GPU acceleration in a TurboVNC session without
VirtualGL, although the performance will be better with VirtualGL. Refer to
the description of the `-drinode` option in the Xvnc man page for more details.


3.1.1
=====
Expand Down
3 changes: 3 additions & 0 deletions cmakescripts/BuildPackages.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ if(TVNC_BUILDSERVER)
set(DEBDEPENDS "libpam0g, ${DEBDEPENDS}")
endif()
set(DEBDEPENDS "${DEBDEPENDS}, dbus-x11, xauth, x11-xkb-utils, xkb-data, libxdmcp6, libxfont2, libpixman-1-0, libgl1-mesa-glx")
if(TVNC_DRI3)
set(DEBDEPENDS "${DEBDEPENDS}, libgbm1")
endif()
if(TVNC_BUILDWEBSERVER)
set(DEBDEPENDS "${DEBDEPENDS}, python3")
endif()
Expand Down
7 changes: 7 additions & 0 deletions unix/Xvnc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ include_directories(${ZLIB_INCLUDE_DIRS})
configure_file(include/tvnc_version.h.in
programs/Xserver/include/tvnc_version.h)

option(TVNC_DRI3
"Include DRI3 extension in Xvnc (enables GPU acceleration when using open source drivers)"
ON)
boolean_number(TVNC_DRI3)
boolean_number(TVNC_DRI3 PARENT_SCOPE)
report_option(TVNC_DRI3 "DRI3 extension")

set(OpenGL_GL_PREFERENCE LEGACY)
include(FindOpenGL)

Expand Down
10 changes: 10 additions & 0 deletions unix/Xvnc/programs/Xserver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ if(TVNC_NVCONTROL)
add_definitions(-DNVCONTROL)
endif()
add_definitions(-DGLXEXT)
if(TVNC_DRI3)
pkg_check_modules(DRM REQUIRED libdrm IMPORTED_TARGET)
add_definitions(-DDRI3)
endif()

add_definitions(-DHAVE_DIX_CONFIG_H -DCLIENTIDS -DHAS_SHM -DHAVE_XSHMFENCE)

Expand Down Expand Up @@ -125,6 +129,9 @@ add_subdirectory(Xi)
add_subdirectory(composite)
add_subdirectory(damageext)
add_subdirectory(dix)
if(TVNC_DRI3)
add_subdirectory(dri3)
endif()
add_subdirectory(fb)
add_subdirectory(glx)
add_subdirectory(mi)
Expand Down Expand Up @@ -156,6 +163,9 @@ set(EXTRA_LIB "")
if(TVNC_NVCONTROL)
set(EXTRA_LIB ${EXTRA_LIB} XNVCtrl)
endif()
if(TVNC_DRI3)
set(EXTRA_LIB ${EXTRA_LIB} dri3 xshmfence ${DRM_LIBS} gbm)
endif()
if(HAVE_MONOTONIC_CLOCK)
set(EXTRA_LIB ${EXTRA_LIB} rt)
endif()
Expand Down
11 changes: 9 additions & 2 deletions unix/Xvnc/programs/Xserver/Xvnc.man.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.\" ** The above line should force tbl to be a preprocessor **
.\" Man page for Xvnc
.\"
.\" Copyright (C) 2010, 2012, 2014-2022 D. R. Commander
.\" Copyright (C) 2010, 2012, 2014-2023 D. R. Commander
.\" Copyright (C) 2021 Steffen Kieß
.\" Copyright (C) 2010 University Corporation for Atmospheric Research
.\" Copyright (C) 2005-2008 Sun Microsystems, Inc.
Expand All @@ -14,7 +14,7 @@
.\" License as specified in the file LICENCE.TXT that comes with the
.\" TurboVNC distribution.
.\"
.TH Xvnc 1 "March 2021" "" "TurboVNC"
.TH Xvnc 1 "August 2023" "" "TurboVNC"
.SH NAME
Xvnc \- the TurboVNC X server
.SH SYNOPSIS
Expand Down Expand Up @@ -252,6 +252,13 @@ connects and requests that the client-side devices be cloned, it is too late.
.TP
\fBTURBOVNC DISPLAY OPTIONS\fR

.TP
\fB-drinode\fR \fIrender-node\fR
Enable the DRI3 X extension, which provides GPU acceleration for OpenGL and
other rendering APIs when using open source GPU drivers. \fIrender-node\fR is
the path of the DRM render node for the GPU that you wish to use (for example,
\fB/dev/dri/renderD128\fR).

.TP
\fB\-geometry\fR \fIwidth\fRx\fIheight\fR
Set width and height of the virtual X display (single-screen.)
Expand Down
10 changes: 10 additions & 0 deletions unix/Xvnc/programs/Xserver/damageext/damageext.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/*
* Copyright © 2002 Keith Packard
* Copyright 2013 Red Hat, Inc.
* Copyright © 2023 Kasm
* Copyright © 2024 D. R. Commander
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
Expand Down Expand Up @@ -30,6 +32,10 @@
#include "protocol-versions.h"
#include "extinit.h"

#if defined(DRI3) && defined(TURBOVNC)
extern void xvnc_sync_dri3_textures(void);
#endif

#ifdef PANORAMIX
#include "panoramiX.h"
#include "panoramiXsrv.h"
Expand Down Expand Up @@ -97,6 +103,10 @@ DamageExtNotify(DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes)

damageGetGeometry(pDrawable, &x, &y, &w, &h);

#if defined(DRI3) && defined(TURBOVNC)
xvnc_dri3_sync_pixmaps_to_bos();
#endif

UpdateCurrentTimeIf();
ev = (xDamageNotifyEvent) {
.type = DamageEventBase + XDamageNotify,
Expand Down
10 changes: 10 additions & 0 deletions unix/Xvnc/programs/Xserver/dri3/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
include_directories(../miext/sync ../randr ../render)

add_definitions(-DHAVE_XORG_CONFIG_H)

add_library(dri3 STATIC
dri3.c
dri3_request.c
dri3_screen.c)

target_link_libraries(dri3 PkgConfig::DRM)
120 changes: 120 additions & 0 deletions unix/Xvnc/programs/Xserver/dri3/dri3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright © 2013 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/

#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif

#include "dri3_priv.h"

#include <drm_fourcc.h>

static int dri3_request;
DevPrivateKeyRec dri3_screen_private_key;

static int dri3_screen_generation;

static Bool
dri3_close_screen(ScreenPtr screen)
{
dri3_screen_priv_ptr screen_priv = dri3_screen_priv(screen);

unwrap(screen_priv, screen, CloseScreen);

free(screen_priv);
return (*screen->CloseScreen) (screen);
}

Bool
dri3_screen_init(ScreenPtr screen, const dri3_screen_info_rec *info)
{
dri3_screen_generation = serverGeneration;

if (!dixRegisterPrivateKey(&dri3_screen_private_key, PRIVATE_SCREEN, 0))
return FALSE;

if (!dri3_screen_priv(screen)) {
dri3_screen_priv_ptr screen_priv = calloc(1, sizeof (dri3_screen_priv_rec));
if (!screen_priv)
return FALSE;

wrap(screen_priv, screen, CloseScreen, dri3_close_screen);

screen_priv->info = info;

dixSetPrivate(&screen->devPrivates, &dri3_screen_private_key, screen_priv);
}

return TRUE;
}

void
dri3_extension_init(void)
{
ExtensionEntry *extension;
int i;

/* If no screens support DRI3, there's no point offering the
* extension at all
*/
if (dri3_screen_generation != serverGeneration)
return;

#ifdef PANORAMIX
if (!noPanoramiXExtension)
return;
#endif

extension = AddExtension(DRI3_NAME, DRI3NumberEvents, DRI3NumberErrors,
proc_dri3_dispatch, sproc_dri3_dispatch,
NULL, StandardMinorOpcode);
if (!extension)
goto bail;

dri3_request = extension->base;

for (i = 0; i < screenInfo.numScreens; i++) {
if (!dri3_screen_init(screenInfo.screens[i], NULL))
goto bail;
}
return;

bail:
FatalError("Cannot initialize DRI3 extension");
}

uint32_t
drm_format_for_depth(uint32_t depth, uint32_t bpp)
{
switch (bpp) {
case 16:
return DRM_FORMAT_RGB565;
case 24:
return DRM_FORMAT_XRGB8888;
case 30:
return DRM_FORMAT_XRGB2101010;
case 32:
return DRM_FORMAT_ARGB8888;
default:
return 0;
}
}
117 changes: 117 additions & 0 deletions unix/Xvnc/programs/Xserver/dri3/dri3.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright © 2013 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/

#ifndef _DRI3_H_
#define _DRI3_H_

#ifdef DRI3

#include <X11/extensions/dri3proto.h>
#include <randrstr.h>

#define DRI3_SCREEN_INFO_VERSION 2

typedef int (*dri3_open_proc)(ScreenPtr screen,
RRProviderPtr provider,
int *fd);

typedef int (*dri3_open_client_proc)(ClientPtr client,
ScreenPtr screen,
RRProviderPtr provider,
int *fd);

typedef PixmapPtr (*dri3_pixmap_from_fd_proc) (ScreenPtr screen,
int fd,
CARD16 width,
CARD16 height,
CARD16 stride,
CARD8 depth,
CARD8 bpp);

typedef PixmapPtr (*dri3_pixmap_from_fds_proc) (ScreenPtr screen,
CARD8 num_fds,
const int *fds,
CARD16 width,
CARD16 height,
const CARD32 *strides,
const CARD32 *offsets,
CARD8 depth,
CARD8 bpp,
CARD64 modifier);

typedef int (*dri3_fd_from_pixmap_proc) (ScreenPtr screen,
PixmapPtr pixmap,
CARD16 *stride,
CARD32 *size);

typedef int (*dri3_fds_from_pixmap_proc) (ScreenPtr screen,
PixmapPtr pixmap,
int *fds,
uint32_t *strides,
uint32_t *offsets,
uint64_t *modifier);

typedef int (*dri3_get_formats_proc) (ScreenPtr screen,
CARD32 *num_formats,
CARD32 **formats);

typedef int (*dri3_get_modifiers_proc) (ScreenPtr screen,
uint32_t format,
uint32_t *num_modifiers,
uint64_t **modifiers);

typedef int (*dri3_get_drawable_modifiers_proc) (DrawablePtr draw,
uint32_t format,
uint32_t *num_modifiers,
uint64_t **modifiers);

typedef struct dri3_screen_info {
uint32_t version;

dri3_open_proc open;
dri3_pixmap_from_fd_proc pixmap_from_fd;
dri3_fd_from_pixmap_proc fd_from_pixmap;

/* Version 1 */
dri3_open_client_proc open_client;

/* Version 2 */
dri3_pixmap_from_fds_proc pixmap_from_fds;
dri3_fds_from_pixmap_proc fds_from_pixmap;
dri3_get_formats_proc get_formats;
dri3_get_modifiers_proc get_modifiers;
dri3_get_drawable_modifiers_proc get_drawable_modifiers;

} dri3_screen_info_rec, *dri3_screen_info_ptr;

extern _X_EXPORT Bool
dri3_screen_init(ScreenPtr screen, const dri3_screen_info_rec *info);

extern _X_EXPORT int
dri3_send_open_reply(ClientPtr client, int fd);

extern _X_EXPORT uint32_t
drm_format_for_depth(uint32_t depth, uint32_t bpp);

#endif

#endif /* _DRI3_H_ */
Loading

0 comments on commit 162b4ae

Please sign in to comment.