From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60377) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aYDtE-0006zK-Hd for qemu-devel@nongnu.org; Tue, 23 Feb 2016 09:24:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aYDt7-0001TX-KX for qemu-devel@nongnu.org; Tue, 23 Feb 2016 09:24:36 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51285) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aYDt7-0001TS-Cj for qemu-devel@nongnu.org; Tue, 23 Feb 2016 09:24:29 -0500 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 1179372658 for ; Tue, 23 Feb 2016 14:24:29 +0000 (UTC) From: Gerd Hoffmann Date: Tue, 23 Feb 2016 15:24:17 +0100 Message-Id: <1456237462-3687-4-git-send-email-kraxel@redhat.com> In-Reply-To: <1456237462-3687-1-git-send-email-kraxel@redhat.com> References: <1456237462-3687-1-git-send-email-kraxel@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PULL 3/8] egl-helpers: add functions for render nodes and dma-buf passing List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann Adds helpers to open a drm render node and create a opengl context for it. Also add a helper to export a texture as dma-buf. Signed-off-by: Gerd Hoffmann Reviewed-by: Marc-Andr=C3=A9 Lureau --- include/ui/egl-helpers.h | 13 +++++ ui/egl-helpers.c | 129 +++++++++++++++++++++++++++++++++++++++++= ++++++ 2 files changed, 142 insertions(+) diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h index 8c84398..03fcf4b 100644 --- a/include/ui/egl-helpers.h +++ b/include/ui/egl-helpers.h @@ -3,10 +3,23 @@ =20 #include #include +#include =20 extern EGLDisplay *qemu_egl_display; extern EGLConfig qemu_egl_config; =20 +#ifdef CONFIG_OPENGL_DMABUF + +extern int qemu_egl_rn_fd; +extern struct gbm_device *qemu_egl_rn_gbm_dev; +extern EGLContext qemu_egl_rn_ctx; + +int qemu_egl_rendernode_open(void); +int egl_rendernode_init(void); +int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *four= cc); + +#endif + EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win); =20 int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug); diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c index 4c83834..54be44c 100644 --- a/ui/egl-helpers.c +++ b/ui/egl-helpers.c @@ -1,6 +1,8 @@ #include "qemu/osdep.h" #include +#include =20 +#include "config-host.h" #include "ui/egl-helpers.h" =20 EGLDisplay *qemu_egl_display; @@ -20,6 +22,133 @@ static int egl_debug; =20 /* ---------------------------------------------------------------------= - */ =20 +#ifdef CONFIG_OPENGL_DMABUF + +int qemu_egl_rn_fd; +struct gbm_device *qemu_egl_rn_gbm_dev; +EGLContext qemu_egl_rn_ctx; + +int qemu_egl_rendernode_open(void) +{ + DIR *dir; + struct dirent *e; + int r, fd; + char *p; + + dir =3D opendir("/dev/dri"); + if (!dir) { + return -1; + } + + fd =3D -1; + while ((e =3D readdir(dir))) { + if (e->d_type !=3D DT_CHR) { + continue; + } + + if (strncmp(e->d_name, "renderD", 7)) { + continue; + } + + r =3D asprintf(&p, "/dev/dri/%s", e->d_name); + if (r < 0) { + return -1; + } + + r =3D open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK); + if (r < 0) { + free(p); + continue; + } + fd =3D r; + free(p); + break; + } + + closedir(dir); + if (fd < 0) { + return -1; + } + return fd; +} + +int egl_rendernode_init(void) +{ + qemu_egl_rn_fd =3D -1; + + qemu_egl_rn_fd =3D qemu_egl_rendernode_open(); + if (qemu_egl_rn_fd =3D=3D -1) { + fprintf(stderr, "egl: no drm render node available\n"); + goto err; + } + + qemu_egl_rn_gbm_dev =3D gbm_create_device(qemu_egl_rn_fd); + if (!qemu_egl_rn_gbm_dev) { + fprintf(stderr, "egl: gbm_create_device failed\n"); + goto err; + } + + qemu_egl_init_dpy((EGLNativeDisplayType)qemu_egl_rn_gbm_dev, false, = false); + + if (!epoxy_has_egl_extension(qemu_egl_display, + "EGL_KHR_surfaceless_context")) { + fprintf(stderr, "egl: EGL_KHR_surfaceless_context not supported\= n"); + goto err; + } + if (!epoxy_has_egl_extension(qemu_egl_display, + "EGL_MESA_image_dma_buf_export")) { + fprintf(stderr, "egl: EGL_MESA_image_dma_buf_export not supporte= d\n"); + goto err; + } + + qemu_egl_rn_ctx =3D qemu_egl_init_ctx(); + if (!qemu_egl_rn_ctx) { + fprintf(stderr, "egl: egl_init_ctx failed\n"); + goto err; + } + + return 0; + +err: + if (qemu_egl_rn_gbm_dev) { + gbm_device_destroy(qemu_egl_rn_gbm_dev); + } + if (qemu_egl_rn_fd !=3D -1) { + close(qemu_egl_rn_fd); + } + + return -1; +} + +int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *four= cc) +{ + EGLImageKHR image; + EGLint num_planes, fd; + + image =3D eglCreateImageKHR(qemu_egl_display, eglGetCurrentContext()= , + EGL_GL_TEXTURE_2D_KHR, + (EGLClientBuffer)(unsigned long)tex_id, + NULL); + if (!image) { + return -1; + } + + eglExportDMABUFImageQueryMESA(qemu_egl_display, image, fourcc, + &num_planes, NULL); + if (num_planes !=3D 1) { + eglDestroyImageKHR(qemu_egl_display, image); + return -1; + } + eglExportDMABUFImageMESA(qemu_egl_display, image, &fd, stride, NULL)= ; + eglDestroyImageKHR(qemu_egl_display, image); + + return fd; +} + +#endif /* CONFIG_OPENGL_DMABUF */ + +/* ---------------------------------------------------------------------= - */ + EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win) { EGLSurface esurface; --=20 1.8.3.1