From patchwork Fri Feb 19 09:14:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 8358501 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 3F21F9F372 for ; Fri, 19 Feb 2016 09:15:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 84B7320416 for ; Fri, 19 Feb 2016 09:15:22 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id ADFB720411 for ; Fri, 19 Feb 2016 09:15:21 +0000 (UTC) Received: from localhost ([::1]:50177 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aWh9k-00064N-Sw for patchwork-qemu-devel@patchwork.kernel.org; Fri, 19 Feb 2016 04:15:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47215) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aWh9S-0005zq-HO for qemu-devel@nongnu.org; Fri, 19 Feb 2016 04:15:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aWh9N-0003BL-JE for qemu-devel@nongnu.org; Fri, 19 Feb 2016 04:15:02 -0500 Received: from mx1.redhat.com ([209.132.183.28]:53490) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aWh9N-0003B1-BG for qemu-devel@nongnu.org; Fri, 19 Feb 2016 04:14:57 -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 EBD328E6EB; Fri, 19 Feb 2016 09:14:56 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-116-34.ams2.redhat.com [10.36.116.34]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u1J9Et3H008895; Fri, 19 Feb 2016 04:14:56 -0500 Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 06AE080C28; Fri, 19 Feb 2016 10:14:55 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Fri, 19 Feb 2016 10:14:40 +0100 Message-Id: <1455873289-349-4-git-send-email-kraxel@redhat.com> In-Reply-To: <1455873289-349-1-git-send-email-kraxel@redhat.com> References: <1455873289-349-1-git-send-email-kraxel@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: spice-devel@lists.freedesktop.org, =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Gerd Hoffmann Subject: [Qemu-devel] [PATCH v2 03/12] egl-helpers: add functions for render nodes and dma-buf passing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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é 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 @@ #include #include +#include extern EGLDisplay *qemu_egl_display; extern EGLConfig qemu_egl_config; +#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 *fourcc); + +#endif + EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win); 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 +#include "config-host.h" #include "ui/egl-helpers.h" EGLDisplay *qemu_egl_display; @@ -20,6 +22,133 @@ static int egl_debug; /* ---------------------------------------------------------------------- */ +#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 = opendir("/dev/dri"); + if (!dir) { + return -1; + } + + fd = -1; + while ((e = readdir(dir))) { + if (e->d_type != DT_CHR) { + continue; + } + + if (strncmp(e->d_name, "renderD", 7)) { + continue; + } + + r = asprintf(&p, "/dev/dri/%s", e->d_name); + if (r < 0) { + return -1; + } + + r = open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK); + if (r < 0) { + free(p); + continue; + } + fd = r; + free(p); + break; + } + + closedir(dir); + if (fd < 0) { + return -1; + } + return fd; +} + +int egl_rendernode_init(void) +{ + qemu_egl_rn_fd = -1; + + qemu_egl_rn_fd = qemu_egl_rendernode_open(); + if (qemu_egl_rn_fd == -1) { + fprintf(stderr, "egl: no drm render node available\n"); + goto err; + } + + qemu_egl_rn_gbm_dev = 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 supported\n"); + goto err; + } + + qemu_egl_rn_ctx = 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 != -1) { + close(qemu_egl_rn_fd); + } + + return -1; +} + +int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc) +{ + EGLImageKHR image; + EGLint num_planes, fd; + + image = 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 != 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;