lima: fix buffer import with offset
authorQiang Yu <yuq825@gmail.com>
Sat, 28 Mar 2020 06:09:22 +0000 (14:09 +0800)
committerMarge Bot <eric+marge@anholt.net>
Tue, 31 Mar 2020 01:40:29 +0000 (01:40 +0000)
With EGL_EXT_image_dma_buf_import, user can import dma_buf
with offset.

This is also used by AOSP GLConsumer::updateTexImage
with HAL_PIXEL_FORMAT_YV12 buffer which store YUV planes in
the same buffer with offset. Render sample from it using
GL_OES_EGL_image_external. This should fix some video
display problem when using MediaCodec soft decoding which
generates HAL_PIXEL_FORMAT_YV12 buffer and render it on
screen.

Test program:
https://github.com/yuq/gfx/tree/master/yuv2rgb/dma-buf

Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4362>

src/gallium/drivers/lima/lima_resource.c

index bd3549db44866e297c8e7d14268672e3751ecf91..fb416652e53b23ababb61ea8ee188b65ca34f98a 100644 (file)
@@ -291,10 +291,20 @@ lima_resource_from_handle(struct pipe_screen *pscreen,
         const struct pipe_resource *templat,
         struct winsys_handle *handle, unsigned usage)
 {
-   struct lima_resource *res;
-   struct lima_screen *screen = lima_screen(pscreen);
+   if (templat->bind & (PIPE_BIND_SAMPLER_VIEW |
+                        PIPE_BIND_RENDER_TARGET |
+                        PIPE_BIND_DEPTH_STENCIL)) {
+      /* sampler hardware need offset alignment 64, while render hardware
+       * need offset alignment 8, but due to render target may be reloaded
+       * which uses the sampler, set alignment requrement to 64 for all
+       */
+      if (handle->offset & 0x3f) {
+         debug_error("import buffer offset not properly aligned\n");
+         return NULL;
+      }
+   }
 
-   res = CALLOC_STRUCT(lima_resource);
+   struct lima_resource *res = CALLOC_STRUCT(lima_resource);
    if (!res)
       return NULL;
 
@@ -302,9 +312,10 @@ lima_resource_from_handle(struct pipe_screen *pscreen,
    *pres = *templat;
    pres->screen = pscreen;
    pipe_reference_init(&pres->reference, 1);
-   res->levels[0].offset = 0;
+   res->levels[0].offset = handle->offset;
    res->levels[0].stride = handle->stride;
 
+   struct lima_screen *screen = lima_screen(pscreen);
    res->bo = lima_bo_import(screen, handle);
    if (!res->bo) {
       FREE(res);