[xserver] glamor_egl: For DRI3 use render nodes if possible

Submitted by Stanislav Lanci on March 18, 2019, 3:50 p.m.

Details

Message ID 20190318155055.6903-1-pixo@polepetko.eu
State New
Headers show
Series "glamor_egl: For DRI3 use render nodes if possible" ( rev: 1 ) in X.org

Not browsing as part of any series.

Commit Message

Stanislav Lanci March 18, 2019, 3:50 p.m.
Using render nodes for DRI3 will allow hardware acceleration
of OpenGL application while running on DRM leased resources.

Fixes: https://gitlab.freedesktop.org/xorg/xserver/issues/664

Signed-off-by: Stanislav Lanci <pixo@polepetko.eu>
---
 glamor/glamor_egl.c | 43 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 39 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 69844d4e2..0e8359599 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -62,6 +62,7 @@  struct glamor_egl_screen_private {
     CloseScreenProcPtr saved_close_screen;
     DestroyPixmapProcPtr saved_destroy_pixmap;
     xf86FreeScreenProc *saved_free_screen;
+    char *render_node;
 };
 
 int xf86GlamorEGLPrivateIndex = -1;
@@ -762,10 +763,7 @@  glamor_egl_close_screen(ScreenPtr screen)
 
 #ifdef DRI3
 static int
-glamor_dri3_open_client(ClientPtr client,
-                        ScreenPtr screen,
-                        RRProviderPtr provider,
-                        int *fdp)
+glamor_dri3_open_master_node(ScreenPtr screen, int *fdp)
 {
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     struct glamor_egl_screen_private *glamor_egl =
@@ -811,6 +809,41 @@  glamor_dri3_open_client(ClientPtr client,
     return Success;
 }
 
+static int glamor_dri3_open_render_node(ScreenPtr screen, int *fdp)
+{
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
+    int fd;
+
+    fd = open(glamor_egl->render_node, O_RDWR | O_CLOEXEC);
+    if (fd < 0)
+        return BadAlloc;
+
+    *fdp = fd;
+    return Success;
+}
+
+static int
+glamor_dri3_open_client(ClientPtr client,
+                        ScreenPtr screen,
+                        RRProviderPtr provider,
+                        int *fdp)
+{
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
+    int ret = BadAlloc;
+
+    if (glamor_egl->render_node)
+        ret = glamor_dri3_open_render_node(screen, fdp);
+
+    if (ret != Success)
+        ret = glamor_dri3_open_master_node(screen, fdp);
+
+    return ret;
+}
+
 static const dri3_screen_info_rec glamor_dri3_info = {
     .version = 2,
     .open_client = glamor_dri3_open_client,
@@ -884,6 +917,7 @@  static void glamor_egl_cleanup(struct glamor_egl_screen_private *glamor_egl)
     if (glamor_egl->gbm)
         gbm_device_destroy(glamor_egl->gbm);
     free(glamor_egl->device_path);
+    free(glamor_egl->render_node);
     free(glamor_egl);
 }
 
@@ -916,6 +950,7 @@  glamor_egl_init(ScrnInfoPtr scrn, int fd)
 
     scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl;
     glamor_egl->fd = fd;
+    glamor_egl->render_node = drmGetRenderDeviceNameFromFd(glamor_egl->fd);
     glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
     if (glamor_egl->gbm == NULL) {
         ErrorF("couldn't get display device\n");