diff options
author | Christian Gmeiner <christian.gmeiner@gmail.com> | 2018-03-23 16:00:50 +0100 |
---|---|---|
committer | Christian Gmeiner <christian.gmeiner@gmail.com> | 2018-04-03 21:40:41 +0200 |
commit | 98f31bfaf61f2cfb01ff747ae91f2b3bc7564ce6 (patch) | |
tree | 094cfc924c6afb8695d4328c0a38f21cf77ae555 | |
parent | 4f7cec00b6e2ccf8ee3b8575b77303e65c1acea9 (diff) | |
download | kmscube-98f31bfaf61f2cfb01ff747ae91f2b3bc7564ce6.tar.gz |
cube-tex: make use of modifiers
Fixes rendering issues with mode rgba on etnaviv. I have applied
the same change for nv12 variants but they are not supported on
etnaviv.
v1 -> v2:
- check if EGL_EXT_image_dma_buf_import_modifiers is supported
- use weak function trick for gbm_bo_get_modifier(..)
v2 -> v3:
- check if modifier != DRM_FORMAT_MOD_INVALID
Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
-rw-r--r-- | common.c | 3 | ||||
-rw-r--r-- | common.h | 19 | ||||
-rw-r--r-- | cube-tex.c | 96 |
3 files changed, 106 insertions, 12 deletions
@@ -216,6 +216,9 @@ int init_egl(struct egl *egl, const struct gbm *gbm) get_proc_dpy(EGL_KHR_fence_sync, eglClientWaitSyncKHR); get_proc_dpy(EGL_ANDROID_native_fence_sync, eglDupNativeFenceFDANDROID); + egl->modifiers_supported = has_ext(egl_exts_dpy, + "EGL_EXT_image_dma_buf_import_modifiers"); + printf("Using display %p with EGL version %d.%d\n", egl->display, major, minor); @@ -31,6 +31,7 @@ #include <gbm.h> #include <drm_fourcc.h> +#include <stdbool.h> #ifndef DRM_FORMAT_MOD_LINEAR #define DRM_FORMAT_MOD_LINEAR 0 @@ -59,6 +60,22 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, #define WEAK __attribute__((weak)) +/* Define tokens from EGL_EXT_image_dma_buf_import_modifiers */ +#ifndef EGL_EXT_image_dma_buf_import_modifiers +#define EGL_EXT_image_dma_buf_import_modifiers 1 +#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440 +#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441 +#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442 +#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 +#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 +#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445 +#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446 +#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447 +#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448 +#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449 +#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A +#endif + struct gbm { struct gbm_device *dev; struct gbm_surface *surface; @@ -85,6 +102,8 @@ struct egl { PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR; PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID; + bool modifiers_supported; + void (*draw)(unsigned i); }; @@ -29,6 +29,7 @@ #include "common.h" #include "esUtil.h" +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) struct { struct egl egl; @@ -213,7 +214,10 @@ static const char *fragment_shader_source_2img = static const uint32_t texw = 512, texh = 512; -static int get_fd_rgba(uint32_t *pstride) +WEAK uint64_t +gbm_bo_get_modifier(struct gbm_bo *bo); + +static int get_fd_rgba(uint32_t *pstride, uint64_t *modifier) { struct gbm_bo *bo; void *map_data = NULL; @@ -235,6 +239,11 @@ static int get_fd_rgba(uint32_t *pstride) fd = gbm_bo_get_fd(bo); + if (gbm_bo_get_modifier) + *modifier = gbm_bo_get_modifier(bo); + else + *modifier = DRM_FORMAT_MOD_LINEAR; + /* we have the fd now, no longer need the bo: */ gbm_bo_destroy(bo); @@ -243,7 +252,7 @@ static int get_fd_rgba(uint32_t *pstride) return fd; } -static int get_fd_y(uint32_t *pstride) +static int get_fd_y(uint32_t *pstride, uint64_t *modifier) { struct gbm_bo *bo; void *map_data = NULL; @@ -265,6 +274,11 @@ static int get_fd_y(uint32_t *pstride) fd = gbm_bo_get_fd(bo); + if (gbm_bo_get_modifier) + *modifier = gbm_bo_get_modifier(bo); + else + *modifier = DRM_FORMAT_MOD_LINEAR; + /* we have the fd now, no longer need the bo: */ gbm_bo_destroy(bo); @@ -273,7 +287,7 @@ static int get_fd_y(uint32_t *pstride) return fd; } -static int get_fd_uv(uint32_t *pstride) +static int get_fd_uv(uint32_t *pstride, uint64_t *modifier) { struct gbm_bo *bo; void *map_data = NULL; @@ -295,6 +309,11 @@ static int get_fd_uv(uint32_t *pstride) fd = gbm_bo_get_fd(bo); + if (gbm_bo_get_modifier) + *modifier = gbm_bo_get_modifier(bo); + else + *modifier = DRM_FORMAT_MOD_LINEAR; + /* we have the fd now, no longer need the bo: */ gbm_bo_destroy(bo); @@ -306,16 +325,28 @@ static int get_fd_uv(uint32_t *pstride) static int init_tex_rgba(void) { uint32_t stride; - int fd = get_fd_rgba(&stride); - const EGLint attr[] = { + uint64_t modifier; + int fd = get_fd_rgba(&stride, &modifier); + EGLint attr[] = { EGL_WIDTH, texw, EGL_HEIGHT, texh, EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ABGR8888, EGL_DMA_BUF_PLANE0_FD_EXT, fd, EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, stride, + EGL_NONE, EGL_NONE, /* modifier lo */ + EGL_NONE, EGL_NONE, /* modifier hi */ EGL_NONE }; + + if (egl->modifiers_supported && + modifier != DRM_FORMAT_MOD_INVALID) { + unsigned size = ARRAY_SIZE(attr); + attr[size - 5] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; + attr[size - 4] = modifier & 0xFFFFFFFF; + attr[size - 3] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT; + attr[size - 2] = modifier >> 32; + } EGLImage img; glGenTextures(1, gl.tex); @@ -339,26 +370,48 @@ static int init_tex_rgba(void) static int init_tex_nv12_2img(void) { uint32_t stride_y, stride_uv; - int fd_y = get_fd_y(&stride_y); - int fd_uv = get_fd_uv(&stride_uv); - const EGLint attr_y[] = { + uint64_t modifier_y, modifier_uv; + int fd_y = get_fd_y(&stride_y, &modifier_y); + int fd_uv = get_fd_uv(&stride_uv, &modifier_uv); + EGLint attr_y[] = { EGL_WIDTH, texw, EGL_HEIGHT, texh, EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_R8, EGL_DMA_BUF_PLANE0_FD_EXT, fd_y, EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, stride_y, + EGL_NONE, EGL_NONE, /* modifier lo */ + EGL_NONE, EGL_NONE, /* modifier hi */ EGL_NONE }; - const EGLint attr_uv[] = { + EGLint attr_uv[] = { EGL_WIDTH, texw/2, EGL_HEIGHT, texh/2, EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_GR88, EGL_DMA_BUF_PLANE0_FD_EXT, fd_uv, EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, stride_uv, + EGL_NONE, EGL_NONE, /* modifier lo */ + EGL_NONE, EGL_NONE, /* modifier hi */ EGL_NONE }; + + if (egl->modifiers_supported && + modifier_y != DRM_FORMAT_MOD_INVALID && + modifier_uv != DRM_FORMAT_MOD_INVALID) { + unsigned size = ARRAY_SIZE(attr_y); + attr_y[size - 5] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; + attr_y[size - 4] = modifier_y & 0xFFFFFFFF; + attr_y[size - 3] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT; + attr_y[size - 2] = modifier_y >> 32; + + size = ARRAY_SIZE(attr_uv); + attr_uv[size - 5] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; + attr_uv[size - 4] = modifier_uv & 0xFFFFFFFF; + attr_uv[size - 3] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT; + attr_uv[size - 2] = modifier_uv >> 32; + } + EGLImage img_y, img_uv; glGenTextures(2, gl.tex); @@ -397,9 +450,10 @@ static int init_tex_nv12_2img(void) static int init_tex_nv12_1img(void) { uint32_t stride_y, stride_uv; - int fd_y = get_fd_y(&stride_y); - int fd_uv = get_fd_uv(&stride_uv); - const EGLint attr[] = { + uint64_t modifier_y, modifier_uv; + int fd_y = get_fd_y(&stride_y, &modifier_y); + int fd_uv = get_fd_uv(&stride_uv, &modifier_uv); + EGLint attr[] = { EGL_WIDTH, texw, EGL_HEIGHT, texh, EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_NV12, @@ -409,10 +463,28 @@ static int init_tex_nv12_1img(void) EGL_DMA_BUF_PLANE1_FD_EXT, fd_uv, EGL_DMA_BUF_PLANE1_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE1_PITCH_EXT, stride_uv, + EGL_NONE, EGL_NONE, /* modifier lo */ + EGL_NONE, EGL_NONE, /* modifier hi */ + EGL_NONE, EGL_NONE, /* modifier lo */ + EGL_NONE, EGL_NONE, /* modifier hi */ EGL_NONE }; EGLImage img; + if (egl->modifiers_supported && + modifier_y != DRM_FORMAT_MOD_INVALID && + modifier_uv != DRM_FORMAT_MOD_INVALID) { + unsigned size = ARRAY_SIZE(attr); + attr[size - 9] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; + attr[size - 8] = modifier_y & 0xFFFFFFFF; + attr[size - 7] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT; + attr[size - 6] = modifier_y >> 32; + attr[size - 5] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT; + attr[size - 4] = modifier_uv & 0xFFFFFFFF; + attr[size - 3] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT; + attr[size - 2] = modifier_uv >> 32; + } + glGenTextures(1, gl.tex); img = egl->eglCreateImageKHR(egl->display, EGL_NO_CONTEXT, |