vrend: clean up virgl_egl_image_from_*

Make virgl_egl_image_from_dmabuf a generic helper.  Add
virgl_egl_image_from_gbm_bo and virgl_egl_aux_plane_image_from_gbm_bo
that use the helper.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Gert Wollny <gert.wollny@collabora.com>
macos/master
Chia-I Wu 4 years ago
parent 03dd77537a
commit 1f36f00ad6
  1. 4
      src/vrend_renderer.c
  2. 176
      src/vrend_winsys_egl.c
  3. 14
      src/vrend_winsys_egl.h

@ -6740,7 +6740,7 @@ static void vrend_resource_gbm_init(struct vrend_resource *gr, uint32_t format)
if (!virgl_gbm_gpu_import_required(gr->base.bind))
return;
gr->egl_image = virgl_egl_image_from_dmabuf(egl, bo);
gr->egl_image = virgl_egl_image_from_gbm_bo(egl, bo);
if (!gr->egl_image) {
gr->gbm_bo = NULL;
gbm_bo_destroy(bo);
@ -6952,7 +6952,7 @@ static int vrend_resource_alloc_texture(struct vrend_resource *gr,
!vrend_format_can_texture_view(gr->base.format)) {
for (int i = 0; i < gbm_bo_get_plane_count(gr->gbm_bo); i++) {
gr->aux_plane_egl_image[i] =
virgl_egl_aux_plane_image_from_dmabuf(egl, gr->gbm_bo, i);
virgl_egl_aux_plane_image_from_gbm_bo(egl, gr->gbm_bo, i);
}
}
#endif

@ -39,6 +39,7 @@
#include "util/u_memory.h"
#include "virglrenderer.h"
#include "vrend_winsys.h"
#include "vrend_winsys_egl.h"
#include "virgl_hw.h"
#include "vrend_winsys_gbm.h"
@ -405,121 +406,148 @@ bool virgl_has_egl_khr_gl_colorspace(struct virgl_egl *egl)
return has_bit(egl->extension_bits, EGL_KHR_GL_COLORSPACE);
}
void *virgl_egl_image_from_dmabuf(struct virgl_egl *egl,
uint32_t width,
uint32_t height,
uint32_t drm_format,
uint64_t drm_modifier,
uint32_t plane_count,
const int *plane_fds,
const uint32_t *plane_strides,
const uint32_t *plane_offsets)
{
EGLint attrs[6 + VIRGL_GBM_MAX_PLANES * 10 + 1];
uint32_t count;
assert(VIRGL_GBM_MAX_PLANES <= 4);
assert(plane_count && plane_count <= VIRGL_GBM_MAX_PLANES);
count = 0;
attrs[count++] = EGL_WIDTH;
attrs[count++] = width;
attrs[count++] = EGL_HEIGHT;
attrs[count++] = height;
attrs[count++] = EGL_LINUX_DRM_FOURCC_EXT;
attrs[count++] = drm_format;
for (uint32_t i = 0; i < plane_count; i++) {
if (i < 3) {
attrs[count++] = EGL_DMA_BUF_PLANE0_FD_EXT + i * 3;
attrs[count++] = plane_fds[i];
attrs[count++] = EGL_DMA_BUF_PLANE0_PITCH_EXT + i * 3;
attrs[count++] = plane_strides[i];
attrs[count++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT + i * 3;
attrs[count++] = plane_offsets[i];
}
if (has_bit(egl->extension_bits, EGL_EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS)) {
if (i == 3) {
attrs[count++] = EGL_DMA_BUF_PLANE3_FD_EXT;
attrs[count++] = plane_fds[i];
attrs[count++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
attrs[count++] = plane_strides[i];
attrs[count++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
attrs[count++] = plane_offsets[i];
}
if (drm_modifier != DRM_FORMAT_MOD_INVALID) {
attrs[count++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT + i * 2;
attrs[count++] = (uint32_t)drm_modifier;
attrs[count++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT + i * 2;
attrs[count++] = (uint32_t)(drm_modifier >> 32);
}
}
}
attrs[count++] = EGL_NONE;
assert(count <= ARRAY_SIZE(attrs));
return (void *)eglCreateImageKHR(egl->egl_display,
EGL_NO_CONTEXT,
EGL_LINUX_DMA_BUF_EXT,
(EGLClientBuffer)NULL,
attrs);
}
void virgl_egl_image_destroy(struct virgl_egl *egl, void *image)
{
eglDestroyImageKHR(egl->egl_display, image);
}
#ifdef ENABLE_MINIGBM_ALLOCATION
void *virgl_egl_image_from_dmabuf(struct virgl_egl *egl, struct gbm_bo *bo)
void *virgl_egl_image_from_gbm_bo(struct virgl_egl *egl, struct gbm_bo *bo)
{
int ret;
EGLImageKHR image;
void *image = NULL;
int fds[VIRGL_GBM_MAX_PLANES] = {-1, -1, -1, -1};
uint32_t strides[VIRGL_GBM_MAX_PLANES];
uint32_t offsets[VIRGL_GBM_MAX_PLANES];
int num_planes = gbm_bo_get_plane_count(bo);
// When the bo has 3 planes with modifier support, it requires 37 components.
EGLint khr_image_attrs[37] = {
EGL_WIDTH,
gbm_bo_get_width(bo),
EGL_HEIGHT,
gbm_bo_get_height(bo),
EGL_LINUX_DRM_FOURCC_EXT,
(int)gbm_bo_get_format(bo),
EGL_NONE,
};
if (num_planes < 0 || num_planes > VIRGL_GBM_MAX_PLANES)
return (void *)EGL_NO_IMAGE_KHR;
return NULL;
for (int plane = 0; plane < num_planes; plane++) {
uint32_t handle = gbm_bo_get_handle_for_plane(bo, plane).u32;
ret = virgl_gbm_export_fd(egl->gbm->device, handle, &fds[plane]);
if (ret < 0) {
vrend_printf( "failed to export plane handle\n");
image = (void *)EGL_NO_IMAGE_KHR;
goto out_close;
}
}
size_t attrs_index = 6;
for (int plane = 0; plane < num_planes; plane++) {
khr_image_attrs[attrs_index++] = EGL_DMA_BUF_PLANE0_FD_EXT + plane * 3;
khr_image_attrs[attrs_index++] = fds[plane];
khr_image_attrs[attrs_index++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT + plane * 3;
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 (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;
khr_image_attrs[attrs_index++] = modifier & 0xfffffffful;
khr_image_attrs[attrs_index++] =
EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT + plane * 2;
khr_image_attrs[attrs_index++] = modifier >> 32;
}
strides[plane] = gbm_bo_get_stride_for_plane(bo, plane);
offsets[plane] = gbm_bo_get_offset(bo, plane);
}
khr_image_attrs[attrs_index++] = EGL_NONE;
image = eglCreateImageKHR(egl->egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL,
khr_image_attrs);
image = virgl_egl_image_from_dmabuf(egl,
gbm_bo_get_width(bo),
gbm_bo_get_height(bo),
gbm_bo_get_format(bo),
gbm_bo_get_modifier(bo),
num_planes,
fds,
strides,
offsets);
out_close:
for (int plane = 0; plane < num_planes; plane++)
close(fds[plane]);
return (void*)image;
return image;
}
void *virgl_egl_aux_plane_image_from_dmabuf(struct virgl_egl *egl, struct gbm_bo *bo, int plane)
void *virgl_egl_aux_plane_image_from_gbm_bo(struct virgl_egl *egl, struct gbm_bo *bo, int plane)
{
int ret;
EGLImageKHR image = EGL_NO_IMAGE_KHR;
void *image = NULL;
int fd = -1;
int bytes_per_pixel = virgl_gbm_get_plane_bytes_per_pixel(bo, plane);
if (bytes_per_pixel != 1 && bytes_per_pixel != 2)
return (void *)EGL_NO_IMAGE_KHR;
return NULL;
uint32_t handle = gbm_bo_get_handle_for_plane(bo, plane).u32;
ret = drmPrimeHandleToFD(gbm_device_get_fd(egl->gbm->device), handle, DRM_CLOEXEC, &fd);
if (ret < 0) {
vrend_printf("failed to export plane handle %d\n", errno);
return (void *)EGL_NO_IMAGE_KHR;
}
EGLint khr_image_attrs[17] = {
EGL_WIDTH,
virgl_gbm_get_plane_width(bo, plane),
EGL_HEIGHT,
virgl_gbm_get_plane_height(bo, plane),
EGL_LINUX_DRM_FOURCC_EXT,
(int) (bytes_per_pixel == 1 ? GBM_FORMAT_R8 : GBM_FORMAT_GR88),
EGL_DMA_BUF_PLANE0_FD_EXT,
fd,
EGL_DMA_BUF_PLANE0_OFFSET_EXT,
gbm_bo_get_offset(bo, plane),
EGL_DMA_BUF_PLANE0_PITCH_EXT,
gbm_bo_get_stride_for_plane(bo, plane),
};
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;
khr_image_attrs[14] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
khr_image_attrs[15] = modifier >> 32;
khr_image_attrs[16] = EGL_NONE;
} else {
khr_image_attrs[12] = EGL_NONE;
return NULL;
}
image = eglCreateImageKHR(egl->egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, khr_image_attrs);
const uint32_t format = bytes_per_pixel == 1 ? GBM_FORMAT_R8 : GBM_FORMAT_GR88;
const uint32_t stride = gbm_bo_get_stride_for_plane(bo, plane);
const uint32_t offset = gbm_bo_get_offset(bo, plane);
image = virgl_egl_image_from_dmabuf(egl,
virgl_gbm_get_plane_width(bo, plane),
virgl_gbm_get_plane_height(bo, plane),
format,
gbm_bo_get_modifier(bo),
1,
&fd,
&stride,
&offset);
close(fd);
return (void*)image;
}
void virgl_egl_image_destroy(struct virgl_egl *egl, void *image)
{
eglDestroyImageKHR(egl->egl_display, image);
return image;
}
#endif
#endif /* ENABLE_MINIGBM_ALLOCATION */
bool virgl_egl_supports_fences(struct virgl_egl *egl)
{

@ -56,10 +56,20 @@ int virgl_egl_get_fd_for_texture(struct virgl_egl *egl, uint32_t tex_id, int *fd
int virgl_egl_get_fd_for_texture2(struct virgl_egl *egl, uint32_t tex_id, int *fd, int *stride,
int *offset);
void *virgl_egl_image_from_dmabuf(struct virgl_egl *egl, struct gbm_bo *bo);
void *virgl_egl_aux_plane_image_from_dmabuf(struct virgl_egl *egl, struct gbm_bo *bo, int plane);
void *virgl_egl_image_from_dmabuf(struct virgl_egl *egl,
uint32_t width,
uint32_t height,
uint32_t drm_format,
uint64_t drm_modifier,
uint32_t plane_count,
const int *plane_fds,
const uint32_t *plane_strides,
const uint32_t *plane_offsets);
void virgl_egl_image_destroy(struct virgl_egl *egl, void *image);
void *virgl_egl_image_from_gbm_bo(struct virgl_egl *egl, struct gbm_bo *bo);
void *virgl_egl_aux_plane_image_from_gbm_bo(struct virgl_egl *egl, struct gbm_bo *bo, int plane);
bool virgl_egl_supports_fences(struct virgl_egl *egl);
EGLSyncKHR virgl_egl_fence_create(struct virgl_egl *egl);
void virgl_egl_fence_destroy(struct virgl_egl *egl, EGLSyncKHR fence);

Loading…
Cancel
Save