Message ID | 1455787610-31787-3-git-send-email-kraxel@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi On Thu, Feb 18, 2016 at 10:26 AM, Gerd Hoffmann <kraxel@redhat.com> wrote: > 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 <kraxel@redhat.com> > --- > 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 <epoxy/gl.h> > #include <epoxy/egl.h> > +#include <gbm.h> > > 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 <glob.h> > +#include <dirent.h> > > +#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; > -- > 1.8.3.1 > Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
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 <epoxy/gl.h> #include <epoxy/egl.h> +#include <gbm.h> 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 <glob.h> +#include <dirent.h> +#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;
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 <kraxel@redhat.com> --- include/ui/egl-helpers.h | 13 +++++ ui/egl-helpers.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+)