From 77a42bc8f0ea408dc87bd77043d9000133aa087b Mon Sep 17 00:00:00 2001 From: David Riley Date: Fri, 8 Jun 2018 12:54:35 -0700 Subject: [PATCH] virglrenderer: Add method to import EGLImageKHRs as resources. Allow resources created externally (eg gbm created buffers as dma bufs) to be used. As an example, crosvm (https://chromium.googlesource.com/chromiumos/platform/crosvm/) will intercept resource creation to use minigbm to allocate buffers that its compositor is able to properly handle since it only supports compositing with buffers allocated via minigbm. This patch allows direct rendering to those buffers without requiring an extra copy. v2: Handle missing extension better. v3: Update commit message with more details on usage. Signed-off-by: David Riley Reviewed-by: Dave Airlie --- src/virglrenderer.c | 11 ++++++++++- src/virglrenderer.h | 1 + src/vrend_renderer.c | 19 ++++++++++++++----- src/vrend_renderer.h | 2 +- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/virglrenderer.c b/src/virglrenderer.c index 562ff83..252355d 100644 --- a/src/virglrenderer.c +++ b/src/virglrenderer.c @@ -60,7 +60,16 @@ static int use_context = CONTEXT_NONE; int virgl_renderer_resource_create(struct virgl_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs) { - return vrend_renderer_resource_create((struct vrend_renderer_resource_create_args *)args, iov, num_iovs); + return vrend_renderer_resource_create((struct vrend_renderer_resource_create_args *)args, iov, num_iovs, NULL); +} + +int virgl_renderer_resource_import_eglimage(struct virgl_renderer_resource_create_args *args, void *image) +{ +#ifdef HAVE_EPOXY_EGL_H + return vrend_renderer_resource_create((struct vrend_renderer_resource_create_args *)args, 0, 0, image); +#else + return EINVAL; +#endif } void virgl_renderer_resource_unref(uint32_t res_handle) diff --git a/src/virglrenderer.h b/src/virglrenderer.h index a095210..4b79d39 100644 --- a/src/virglrenderer.h +++ b/src/virglrenderer.h @@ -104,6 +104,7 @@ struct virgl_renderer_resource_create_args { /* new API */ VIRGL_EXPORT int virgl_renderer_resource_create(struct virgl_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs); +VIRGL_EXPORT int virgl_renderer_resource_import_eglimage(struct virgl_renderer_resource_create_args *args, void *image); VIRGL_EXPORT void virgl_renderer_resource_unref(uint32_t res_handle); VIRGL_EXPORT int virgl_renderer_context_create(uint32_t handle, uint32_t nlen, const char *name); diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 21c44e4..e3325e1 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -4790,7 +4790,8 @@ vrend_renderer_resource_copy_args(struct vrend_renderer_resource_create_args *ar gr->base.array_size = args->array_size; } -static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr) +static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr, + void *image_oes) { uint level; GLenum internalformat, glformat, gltype; @@ -4832,7 +4833,15 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr) return EINVAL; } - if (pr->nr_samples > 1) { + if (image_oes) { + if (epoxy_has_gl_extension("GL_OES_EGL_image_external")) { + glEGLImageTargetTexture2DOES(gr->target, (GLeglImageOES) image_oes); + } else { + fprintf(stderr, "missing GL_OES_EGL_image_external extension\n"); + FREE(gr); + return EINVAL; + } + } else if (pr->nr_samples > 1) { if (vrend_state.use_gles) { if (gr->target == GL_TEXTURE_2D_MULTISAMPLE) { glTexStorage2DMultisample(gr->target, pr->nr_samples, @@ -4919,7 +4928,7 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr) return 0; } -int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs) +int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs, void *image_oes) { struct vrend_resource *gr; int ret; @@ -4980,7 +4989,7 @@ int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *a } vrend_create_buffer(gr, args->width); } else { - int r = vrend_renderer_resource_allocate_texture(gr); + int r = vrend_renderer_resource_allocate_texture(gr, image_oes); if (r) return r; } @@ -6396,7 +6405,7 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx, args.array_size = src_res->base.array_size; intermediate_copy = (struct vrend_resource *)CALLOC_STRUCT(vrend_texture); vrend_renderer_resource_copy_args(&args, intermediate_copy); - vrend_renderer_resource_allocate_texture(intermediate_copy); + vrend_renderer_resource_allocate_texture(intermediate_copy, NULL); glGenFramebuffers(1, &intermediate_fbo); } else { diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h index 40c8ebd..55cb9ad 100644 --- a/src/vrend_renderer.h +++ b/src/vrend_renderer.h @@ -164,7 +164,7 @@ struct vrend_renderer_resource_create_args { uint32_t flags; }; -int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs); +int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs, void *image_eos); void vrend_renderer_resource_unref(uint32_t handle);