vrend: Add get_egl_display callback

This is required for support of untyped resources on virtio
devices which create their own egl context.

Currently untyped resources support is reported to mesa only in case
virglrenderer creates it's own egl context from scratch. The problem
that this context is not "sharable" with device context and if it's
created vrend uses it instead of context callbacks implemented by device.
Thus such approach is not suitable for devices with it's own egl context.

The only thing that is required for untyped resources support is
initialized eglDisplay handle that is requried for eglCreateImageKHR,
thus add callback for device to share it.

Untyped resources feature support is required for sharing vkr resources
with vrend.

Signed-off-by: Oleksandr.Gabrylchuk <Oleksandr.Gabrylchuk@opensynergy.com>
Signed-off-by: Andrii Pauk <Andrii.Pauk@opensynergy.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
macos/master
Andrii Pauk 3 years ago committed by Chia-I Wu
parent a663e5d20a
commit 06240496bf
  1. 24
      src/virglrenderer.c
  2. 25
      src/virglrenderer.h
  3. 24
      src/vrend_winsys.c
  4. 2
      src/vrend_winsys.h
  5. 28
      src/vrend_winsys_egl.c
  6. 2
      src/vrend_winsys_egl.h

@ -60,6 +60,7 @@ struct global_state {
bool vrend_initialized;
bool vkr_initialized;
bool proxy_initialized;
bool external_winsys_initialized;
};
static struct global_state state;
@ -610,7 +611,7 @@ void virgl_renderer_cleanup(UNUSED void *cookie)
if (state.vrend_initialized)
vrend_renderer_fini();
if (state.winsys_initialized)
if (state.winsys_initialized || state.external_winsys_initialized)
vrend_winsys_cleanup();
memset(&state, 0, sizeof(state));
@ -679,6 +680,27 @@ int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks
state.winsys_initialized = true;
}
if (!state.winsys_initialized && !state.external_winsys_initialized &&
state.cbs && state.cbs->version >= 4 && state.cbs->get_egl_display) {
void *egl_display = NULL;
if (!cbs->create_gl_context || !cbs->destroy_gl_context ||
!cbs->make_current)
goto fail;
egl_display = state.cbs->get_egl_display(cookie);
if (!egl_display)
goto fail;
ret = vrend_winsys_init_external(egl_display);
if (ret)
goto fail;
state.external_winsys_initialized = true;
}
if (!state.vrend_initialized && !(flags & VIRGL_RENDERER_NO_VIRGL)) {
uint32_t renderer_flags = 0;

@ -46,7 +46,7 @@ struct virgl_renderer_gl_ctx_param {
};
#ifdef VIRGL_RENDERER_UNSTABLE_APIS
#define VIRGL_RENDERER_CALLBACKS_VERSION 3
#define VIRGL_RENDERER_CALLBACKS_VERSION 4
#else
#define VIRGL_RENDERER_CALLBACKS_VERSION 2
#endif
@ -55,18 +55,37 @@ struct virgl_renderer_callbacks {
int version;
void (*write_fence)(void *cookie, uint32_t fence);
/* interact with GL implementation */
/*
* The following 3 callbacks allows virglrenderer to
* use winsys from caller, instead of initializing it's own
* winsys (flag VIRGL_RENDERER_USE_EGL or VIRGL_RENDERER_USE_GLX).
*/
/* create a GL/GLES context */
virgl_renderer_gl_context (*create_gl_context)(void *cookie, int scanout_idx, struct virgl_renderer_gl_ctx_param *param);
/* destroy a GL/GLES context */
void (*destroy_gl_context)(void *cookie, virgl_renderer_gl_context ctx);
/* make a context current */
int (*make_current)(void *cookie, int scanout_idx, virgl_renderer_gl_context ctx);
int (*get_drm_fd)(void *cookie); /* v2, used with flags & VIRGL_RENDERER_USE_EGL */
/*
* v2, used with flags & VIRGL_RENDERER_USE_EGL
* Chose the drm fd, that will be used by virglrenderer
* for winsys initialization.
*/
int (*get_drm_fd)(void *cookie);
#ifdef VIRGL_RENDERER_UNSTABLE_APIS
void (*write_context_fence)(void *cookie, uint32_t ctx_id, uint64_t queue_id, void *fence_cookie);
/* version 0: a connected socket of type SOCK_SEQPACKET */
int (*get_server_fd)(void *cookie, uint32_t version);
/*
* Get the EGLDisplay from caller. It requires create_gl_context,
* destroy_gl_context, make_current to be implemented by caller.
*/
void *(*get_egl_display)(void *cookie);
#endif
};

@ -33,7 +33,8 @@
enum {
CONTEXT_NONE,
CONTEXT_EGL,
CONTEXT_GLX
CONTEXT_GLX,
CONTEXT_EGL_EXTERNAL
};
static int use_context = CONTEXT_NONE;
@ -102,6 +103,10 @@ void vrend_winsys_cleanup(void)
virgl_gbm_fini(gbm);
gbm = NULL;
}
} else if (use_context == CONTEXT_EGL_EXTERNAL) {
free(egl);
egl = NULL;
use_context = CONTEXT_NONE;
}
#endif
#ifdef HAVE_EPOXY_GLX_H
@ -113,6 +118,23 @@ void vrend_winsys_cleanup(void)
#endif
}
int vrend_winsys_init_external(void *egl_display)
{
#ifdef HAVE_EPOXY_EGL_H
egl = virgl_egl_init_external(egl_display);
if (!egl)
return -1;
use_context = CONTEXT_EGL_EXTERNAL;
#else
(void)egl_display;
vrend_printf( "EGL is not supported on this platform\n");
return -1;
#endif
return 0;
}
virgl_renderer_gl_context vrend_winsys_create_context(struct virgl_gl_ctx_param *param)
{
#ifdef HAVE_EPOXY_EGL_H

@ -48,6 +48,8 @@ extern struct virgl_gbm *gbm;
int vrend_winsys_init(uint32_t flags, int preferred_fd);
void vrend_winsys_cleanup(void);
int vrend_winsys_init_external(void *egl_display);
virgl_renderer_gl_context vrend_winsys_create_context(struct virgl_gl_ctx_param *param);
void vrend_winsys_destroy_context(virgl_renderer_gl_context ctx);
int vrend_winsys_make_context_current(virgl_renderer_gl_context ctx);

@ -419,6 +419,34 @@ void virgl_egl_destroy(struct virgl_egl *egl)
free(egl);
}
struct virgl_egl *virgl_egl_init_external(EGLDisplay egl_display)
{
const char *extensions;
struct virgl_egl *egl;
egl = calloc(1, sizeof(struct virgl_egl));
if (!egl)
return NULL;
egl->egl_display = egl_display;
extensions = eglQueryString(egl->egl_display, EGL_EXTENSIONS);
#ifdef VIRGL_EGL_DEBUG
vrend_printf( "EGL version: %s\n",
eglQueryString(egl->egl_display, EGL_VERSION));
vrend_printf( "EGL vendor: %s\n",
eglQueryString(egl->egl_display, EGL_VENDOR));
vrend_printf( "EGL extensions: %s\n", extensions);
#endif
if (virgl_egl_init_extensions(egl, extensions)) {
free(egl);
return NULL;
}
return egl;
}
virgl_renderer_gl_context virgl_egl_create_context(struct virgl_egl *egl, struct virgl_gl_ctx_param *vparams)
{
EGLContext egl_ctx;

@ -37,6 +37,8 @@ struct virgl_egl *virgl_egl_init(struct virgl_gbm *gbm, bool surfaceless, bool g
void virgl_egl_destroy(struct virgl_egl *egl);
struct virgl_egl *virgl_egl_init_external(EGLDisplay egl_display);
virgl_renderer_gl_context virgl_egl_create_context(struct virgl_egl *egl,
struct virgl_gl_ctx_param *vparams);

Loading…
Cancel
Save