diff --git a/src/virgl_egl_context.c b/src/virgl_egl_context.c index 8aa587b..2310464 100644 --- a/src/virgl_egl_context.c +++ b/src/virgl_egl_context.c @@ -36,22 +36,45 @@ #include #include #include + +#include "util/u_memory.h" + #include "virglrenderer.h" #include "virgl_egl.h" #include "virgl_hw.h" #include "virgl_gbm.h" +#include "vrend_util.h" + +#define EGL_KHR_SURFACELESS_CONTEXT BIT(0) +#define EGL_KHR_CREATE_CONTEXT BIT(1) +#define EGL_MESA_DRM_IMAGE BIT(2) +#define EGL_MESA_IMAGE_DMA_BUF_EXPORT BIT(3) +#define EGL_MESA_DMA_BUF_IMAGE_IMPORT BIT(4) +#define EGL_KHR_GL_COLORSPACE BIT(5) +#define EGL_EXT_IMAGE_DMA_BUF_IMPORT BIT(6) +#define EGL_EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS BIT(7) +#define EGL_KHR_FENCE_SYNC BIT(8) + +static const struct { + uint32_t bit; + const char *string; +} extensions_list[] = { + { EGL_KHR_SURFACELESS_CONTEXT, "EGL_KHR_surfaceless_context" }, + { EGL_KHR_CREATE_CONTEXT, "EGL_KHR_create_context" }, + { EGL_MESA_DRM_IMAGE, "EGL_MESA_drm_image" }, + { EGL_MESA_IMAGE_DMA_BUF_EXPORT, "EGL_MESA_image_dma_buf_export" }, + { EGL_KHR_GL_COLORSPACE, "EGL_KHR_gl_colorspace" }, + { EGL_EXT_IMAGE_DMA_BUF_IMPORT, "EGL_EXT_image_dma_buf_import" }, + { EGL_EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS, "EGL_EXT_image_dma_buf_import_modifiers" }, + { EGL_KHR_FENCE_SYNC, "EGL_KHR_fence_sync"} +}; struct virgl_egl { struct virgl_gbm *gbm; EGLDisplay egl_display; EGLConfig egl_conf; EGLContext egl_ctx; - bool have_mesa_drm_image; - bool have_mesa_dma_buf_img_export; - bool have_khr_gl_colorspace; - bool have_ext_image_dma_buf_import; - bool have_ext_image_dma_buf_import_modifiers; - bool have_khr_fence_sync; + uint32_t extension_bits; bool need_fence_and_wait_external; }; @@ -84,6 +107,21 @@ static bool virgl_egl_has_extension_in_string(const char *haystack, const char * return false; } +static int virgl_egl_init_extensions(struct virgl_egl *egl, const char *extensions) +{ + for (uint32_t i = 0; i < ARRAY_SIZE(extensions_list); i++) { + if (virgl_egl_has_extension_in_string(extensions, extensions_list[i].string)) + egl->extension_bits |= extensions_list[i].bit; + } + + if (!has_bits(egl->extension_bits, EGL_KHR_SURFACELESS_CONTEXT | EGL_KHR_CREATE_CONTEXT)) { + vrend_printf( "Missing EGL_KHR_surfaceless_context or EGL_KHR_create_context\n"); + return -1; + } + + return 0; +} + struct virgl_egl *virgl_egl_init(struct virgl_gbm *gbm, bool surfaceless, bool gles) { static EGLint conf_att[] = { @@ -102,7 +140,7 @@ struct virgl_egl *virgl_egl_init(struct virgl_gbm *gbm, bool surfaceless, bool g EGLBoolean success; EGLenum api; EGLint major, minor, num_configs; - const char *extension_list; + const char *extensions; struct virgl_egl *egl; egl = calloc(1, sizeof(struct virgl_egl)); @@ -167,45 +205,18 @@ struct virgl_egl *virgl_egl_init(struct virgl_gbm *gbm, bool surfaceless, bool g if (!success) goto fail; - extension_list = eglQueryString(egl->egl_display, EGL_EXTENSIONS); + extensions = eglQueryString(egl->egl_display, EGL_EXTENSIONS); #ifdef VIRGL_EGL_DEBUG vrend_printf( "EGL major/minor: %d.%d\n", major, minor); 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", extension_list); + vrend_printf( "EGL extensions: %s\n", extensions); #endif - /* require surfaceless context */ - if (!virgl_egl_has_extension_in_string(extension_list, "EGL_KHR_surfaceless_context")) { - vrend_printf( "failed to find support for surfaceless context\n"); - goto fail; - } - if (!virgl_egl_has_extension_in_string(extension_list, "EGL_KHR_create_context")) { - vrend_printf( "failed to find EGL_KHR_create_context extensions\n"); + if (virgl_egl_init_extensions(egl, extensions)) goto fail; - } - - egl->have_mesa_drm_image = false; - egl->have_mesa_dma_buf_img_export = false; - if (virgl_egl_has_extension_in_string(extension_list, "EGL_MESA_drm_image")) - egl->have_mesa_drm_image = true; - - if (virgl_egl_has_extension_in_string(extension_list, "EGL_MESA_image_dma_buf_export")) - egl->have_mesa_dma_buf_img_export = true; - - if (virgl_egl_has_extension_in_string(extension_list, "EGL_EXT_image_dma_buf_import")) - egl->have_ext_image_dma_buf_import = true; - - if (virgl_egl_has_extension_in_string(extension_list, "EGL_EXT_image_dma_buf_import_modifiers")) - egl->have_ext_image_dma_buf_import_modifiers = true; - - egl->have_khr_gl_colorspace = - virgl_egl_has_extension_in_string(extension_list, "EGL_KHR_gl_colorspace"); - - egl->have_khr_fence_sync = - virgl_egl_has_extension_in_string(extension_list, "EGL_KHR_fence_sync"); // ARM Mali platforms need explicit synchronization prior to mapping. if (!strcmp(eglQueryString(egl->egl_display, EGL_VENDOR), "ARM")) @@ -290,7 +301,7 @@ int virgl_egl_get_fourcc_for_texture(struct virgl_egl *egl, uint32_t tex_id, uin EGLImageKHR image; EGLBoolean success; - if (!egl->have_mesa_dma_buf_img_export) { + if (!has_bit(egl->extension_bits, EGL_MESA_IMAGE_DMA_BUF_EXPORT)) { ret = 0; goto fallback; } @@ -324,7 +335,7 @@ int virgl_egl_get_fd_for_texture2(struct virgl_egl *egl, uint32_t tex_id, int *f (EGLClientBuffer)(unsigned long)tex_id, NULL); if (!image) return EINVAL; - if (!egl->have_mesa_dma_buf_img_export) + if (!has_bit(egl->extension_bits, EGL_MESA_IMAGE_DMA_BUF_EXPORT)) goto out_destroy; if (!eglExportDMABUFImageMESA(egl->egl_display, image, fd, @@ -352,12 +363,12 @@ int virgl_egl_get_fd_for_texture(struct virgl_egl *egl, uint32_t tex_id, int *fd return EINVAL; ret = EINVAL; - if (egl->have_mesa_dma_buf_img_export) { + if (has_bit(egl->extension_bits, EGL_MESA_IMAGE_DMA_BUF_EXPORT)) { success = eglExportDMABUFImageMESA(egl->egl_display, image, fd, &stride, &offset); if (!success) goto out_destroy; - } else if (egl->have_mesa_drm_image) { + } else if (has_bit(egl->extension_bits, EGL_MESA_DRM_IMAGE)) { EGLint handle; success = eglExportDRMImageMESA(egl->egl_display, image, NULL, &handle, &stride); @@ -383,7 +394,7 @@ int virgl_egl_get_fd_for_texture(struct virgl_egl *egl, uint32_t tex_id, int *fd bool virgl_has_egl_khr_gl_colorspace(struct virgl_egl *egl) { - return egl->have_khr_gl_colorspace; + return has_bit(egl->extension_bits, EGL_KHR_GL_COLORSPACE); } void *virgl_egl_image_from_dmabuf(struct virgl_egl *egl, struct gbm_bo *bo) @@ -424,7 +435,7 @@ void *virgl_egl_image_from_dmabuf(struct virgl_egl *egl, struct gbm_bo *bo) khr_image_attrs[attrs_index++] = gbm_bo_get_offset(bo, plane); khr_image_attrs[attrs_index++] = EGL_DMA_BUF_PLANE0_PITCH_EXT + plane * 3; khr_image_attrs[attrs_index++] = gbm_bo_get_stride_for_plane(bo, plane); - if (egl->have_ext_image_dma_buf_import_modifiers) { + if (has_bit(egl->extension_bits, EGL_EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS)) { const uint64_t modifier = gbm_bo_get_modifier(bo); khr_image_attrs[attrs_index++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT + plane * 2; @@ -478,7 +489,7 @@ void *virgl_egl_aux_plane_image_from_dmabuf(struct virgl_egl *egl, struct gbm_bo gbm_bo_get_stride_for_plane(bo, plane), }; - if (egl->have_ext_image_dma_buf_import_modifiers) { + if (has_bit(egl->extension_bits, EGL_EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS)) { const uint64_t modifier = gbm_bo_get_modifier(bo); khr_image_attrs[12] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; khr_image_attrs[13] = modifier & 0xfffffffful; @@ -512,7 +523,7 @@ void virgl_egl_fence_and_wait_external(struct virgl_egl *egl) EGL_NONE}; EGLSyncKHR fence; - if (!egl || !egl->have_khr_fence_sync) { + if (!egl || !has_bit(egl->extension_bits, EGL_KHR_FENCE_SYNC)) { return; }