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 <davidriley@chromium.org>
Reviewed-by: Dave Airlie <airlied@redhat.com>
macos/master
David Riley 6 years ago committed by Dave Airlie
parent 6cf9b5ece6
commit 77a42bc8f0
  1. 11
      src/virglrenderer.c
  2. 1
      src/virglrenderer.h
  3. 19
      src/vrend_renderer.c
  4. 2
      src/vrend_renderer.h

@ -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) 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) void virgl_renderer_resource_unref(uint32_t res_handle)

@ -104,6 +104,7 @@ struct virgl_renderer_resource_create_args {
/* new API */ /* 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_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 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); VIRGL_EXPORT int virgl_renderer_context_create(uint32_t handle, uint32_t nlen, const char *name);

@ -4790,7 +4790,8 @@ vrend_renderer_resource_copy_args(struct vrend_renderer_resource_create_args *ar
gr->base.array_size = args->array_size; 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; uint level;
GLenum internalformat, glformat, gltype; GLenum internalformat, glformat, gltype;
@ -4832,7 +4833,15 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr)
return EINVAL; 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 (vrend_state.use_gles) {
if (gr->target == GL_TEXTURE_2D_MULTISAMPLE) { if (gr->target == GL_TEXTURE_2D_MULTISAMPLE) {
glTexStorage2DMultisample(gr->target, pr->nr_samples, glTexStorage2DMultisample(gr->target, pr->nr_samples,
@ -4919,7 +4928,7 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr)
return 0; 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; struct vrend_resource *gr;
int ret; int ret;
@ -4980,7 +4989,7 @@ int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *a
} }
vrend_create_buffer(gr, args->width); vrend_create_buffer(gr, args->width);
} else { } else {
int r = vrend_renderer_resource_allocate_texture(gr); int r = vrend_renderer_resource_allocate_texture(gr, image_oes);
if (r) if (r)
return 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; args.array_size = src_res->base.array_size;
intermediate_copy = (struct vrend_resource *)CALLOC_STRUCT(vrend_texture); intermediate_copy = (struct vrend_resource *)CALLOC_STRUCT(vrend_texture);
vrend_renderer_resource_copy_args(&args, intermediate_copy); 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); glGenFramebuffers(1, &intermediate_fbo);
} else { } else {

@ -164,7 +164,7 @@ struct vrend_renderer_resource_create_args {
uint32_t flags; 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); void vrend_renderer_resource_unref(uint32_t handle);

Loading…
Cancel
Save