egl: overhaul the fourcc retrieval function

We really need a new mesa interface that works properly for all this.
macos/master
Dave Airlie 10 years ago
parent 58ef21b0b8
commit 5783d84b30
  1. 1
      src/virgl_egl.h
  2. 52
      src/virgl_egl_context.c
  3. 6
      src/virglrenderer.c
  4. 2
      src/virglrenderer.h
  5. 2
      tests/test_virgl_init.c

@ -35,6 +35,7 @@ void virgl_egl_destroy_context(struct virgl_egl *ve, virgl_renderer_gl_context v
int virgl_egl_make_context_current(struct virgl_egl *ve, virgl_renderer_gl_context virglctx); int virgl_egl_make_context_current(struct virgl_egl *ve, virgl_renderer_gl_context virglctx);
virgl_renderer_gl_context virgl_egl_get_current_context(struct virgl_egl *ve); virgl_renderer_gl_context virgl_egl_get_current_context(struct virgl_egl *ve);
int virgl_egl_get_fourcc_for_texture(struct virgl_egl *ve, uint32_t tex_id, uint32_t format, int *fourcc);
int virgl_egl_get_fd_for_texture(struct virgl_egl *ve, uint32_t tex_id, int *fd); int virgl_egl_get_fd_for_texture(struct virgl_egl *ve, uint32_t tex_id, int *fd);
uint32_t virgl_egl_get_gbm_format(uint32_t format); uint32_t virgl_egl_get_gbm_format(uint32_t format);
#endif #endif

@ -258,17 +258,54 @@ virgl_renderer_gl_context virgl_egl_get_current_context(struct virgl_egl *ve)
return (virgl_renderer_gl_context)eglctx; return (virgl_renderer_gl_context)eglctx;
} }
int virgl_egl_get_fd_for_texture(struct virgl_egl *ve, uint32_t tex_id, int *fd) int virgl_egl_get_fourcc_for_texture(struct virgl_egl *ve, uint32_t tex_id, uint32_t format, int *fourcc)
{ {
int ret;
#ifndef EGL_MESA_image_dma_buf_export
ret = 0;
goto fallback;
#else
EGLImageKHR image; EGLImageKHR image;
EGLint stride; EGLint stride;
EGLBoolean b; EGLBoolean b;
if (!ve->have_mesa_dma_buf_img_export)
goto fallback;
image = eglCreateImageKHR(ve->egl_display, eglGetCurrentContext(), EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(unsigned long)tex_id, NULL); image = eglCreateImageKHR(ve->egl_display, eglGetCurrentContext(), EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(unsigned long)tex_id, NULL);
if (!image) if (!image)
return EINVAL; return EINVAL;
ret = EINVAL;
b = eglExportDMABUFImageQueryMESA(ve->egl_display, image, fourcc, NULL);
if (!b)
goto out_destroy;
ret = 0;
out_destroy:
eglDestroyImageKHR(ve->egl_display, image);
return ret;
#endif
fallback:
*fourcc = virgl_egl_get_gbm_format(format);
return ret;
}
int virgl_egl_get_fd_for_texture(struct virgl_egl *ve, uint32_t tex_id, int *fd)
{
EGLImageKHR image;
EGLint stride;
EGLBoolean b;
int ret;
image = eglCreateImageKHR(ve->egl_display, eglGetCurrentContext(), EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(unsigned long)tex_id, NULL);
if (!image)
return EINVAL;
ret = EINVAL;
if (ve->have_mesa_dma_buf_img_export) { if (ve->have_mesa_dma_buf_img_export) {
#ifdef EGL_MESA_image_dma_buf_export #ifdef EGL_MESA_image_dma_buf_export
b = eglExportDMABUFImageMESA(ve->egl_display, b = eglExportDMABUFImageMESA(ve->egl_display,
@ -276,7 +313,7 @@ int virgl_egl_get_fd_for_texture(struct virgl_egl *ve, uint32_t tex_id, int *fd)
fd, fd,
&stride); &stride);
#else #else
return EINVAL; goto out_destroy;
#endif #endif
} else { } else {
#ifdef EGL_MESA_drm_image #ifdef EGL_MESA_drm_image
@ -288,18 +325,21 @@ int virgl_egl_get_fd_for_texture(struct virgl_egl *ve, uint32_t tex_id, int *fd)
&stride); &stride);
if (!b) if (!b)
return EINVAL; goto out_destroy;
fprintf(stderr,"image exported %d %d\n", handle, stride); fprintf(stderr,"image exported %d %d\n", handle, stride);
r = drmPrimeHandleToFD(ve->fd, handle, DRM_CLOEXEC, fd); r = drmPrimeHandleToFD(ve->fd, handle, DRM_CLOEXEC, fd);
if (r < 0) if (r < 0)
return EINVAL; goto out_destroy;
#else #else
return EINVAL; goto out_destroy;
#endif #endif
} }
return 0; ret = 0;
out_destroy:
eglDestroyImageKHR(ve->egl_display, image);
return ret;
} }
uint32_t virgl_egl_get_gbm_format(uint32_t format) uint32_t virgl_egl_get_gbm_format(uint32_t format)

@ -42,6 +42,8 @@
#include "virglrenderer.h" #include "virglrenderer.h"
#include "virgl_egl.h" #include "virgl_egl.h"
struct virgl_egl *egl_info;
/* new API - just wrap internal API for now */ /* new API - just wrap internal API for now */
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)
@ -161,7 +163,7 @@ int virgl_renderer_resource_get_info(int res_handle,
int ret; int ret;
ret = vrend_renderer_resource_get_info(res_handle, (struct vrend_renderer_resource_info *)info); ret = vrend_renderer_resource_get_info(res_handle, (struct vrend_renderer_resource_info *)info);
if (ret == 0) if (ret == 0)
info->gbm_format = virgl_egl_get_gbm_format(info->virgl_format); return virgl_egl_get_fourcc_for_texture(egl_info, info->tex_id, info->virgl_format, &info->drm_fourcc);
return ret; return ret;
} }
@ -182,7 +184,7 @@ static struct virgl_renderer_callbacks *rcbs;
static void *dev_cookie; static void *dev_cookie;
static int use_egl_context; static int use_egl_context;
struct virgl_egl *egl_info;
static struct vrend_if_cbs virgl_cbs; static struct vrend_if_cbs virgl_cbs;
void vrend_transfer_write_return(void *data, uint32_t bytes, uint64_t offset, void vrend_transfer_write_return(void *data, uint32_t bytes, uint64_t offset,

@ -141,7 +141,7 @@ struct virgl_renderer_resource_info {
uint32_t flags; uint32_t flags;
uint32_t tex_id; uint32_t tex_id;
uint32_t stride; uint32_t stride;
uint32_t gbm_format; int drm_fourcc;
}; };
VIRGL_EXPORT int virgl_renderer_resource_get_info(int res_handle, VIRGL_EXPORT int virgl_renderer_resource_get_info(int res_handle,

@ -328,7 +328,7 @@ START_TEST(virgl_test_get_resource_info)
ret = virgl_renderer_resource_get_info(res.handle, &info); ret = virgl_renderer_resource_get_info(res.handle, &info);
ck_assert_int_eq(ret, 0); ck_assert_int_eq(ret, 0);
ck_assert_int_eq(info.gbm_format, GBM_FORMAT_XRGB8888); ck_assert_int_eq(info.drm_fourcc, GBM_FORMAT_XRGB8888);
ck_assert_int_eq(info.virgl_format, res.format); ck_assert_int_eq(info.virgl_format, res.format);
ck_assert_int_eq(res.width, info.width); ck_assert_int_eq(res.width, info.width);
ck_assert_int_eq(res.height, info.height); ck_assert_int_eq(res.height, info.height);

Loading…
Cancel
Save