[vlc-devel] [PATCH 2/2] vaapi: add support for DRM modifiers

Steve Lhomme robux4 at ycbcr.xyz
Thu Jan 20 07:47:29 UTC 2022


Hi,

On 2022-01-20 2:13, Lin, Shuicheng wrote:
> Hi,
> In order to fix the same issue in 3.0.x branch, I cherry-pick the 2 patches from master to 3.0.x.
> I confirm issue could be fixed in 3.0.x branch with the patch.
> I have done the "Check List" [0] for the patches.
> Anything else should I do in order to get the patch merged to the 3.0.x branch?
> Thanks.
> 
> [0]: https://wiki.videolan.org/Sending_Patches_VLC/#Check_List

The wiki is outdated.
You should send patches via Merge Requests on our gitlab:
https://code.videolan.org/videolan/vlc/

You can create an account, fork the VLC repo, create a branch based on 
the 3.0.x branch, add your 2 patches, upload to Gitlab and then create a 
Merge Request targeting 3.0.x.

> Best Regards
> Shuicheng
> 
> -----Original Message-----
> From: Lin, Shuicheng <shuicheng.lin at intel.com>
> Sent: Wednesday, January 19, 2022 12:25 AM
> To: vlc-devel at videolan.org
> Cc: Landwerlin, Lionel G <lionel.g.landwerlin at intel.com>; Thomas Guillem <thomas at gllm.fr>; Lin, Shuicheng <shuicheng.lin at intel.com>
> Subject: [PATCH 2/2] vaapi: add support for DRM modifiers
> 
> From: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
> 
> DRM modifiers communicate a description of the data layout in the buffers exported/imported through various API.
> 
> On Intel HW this exports tiling information as well as potential compression.
> 
> Signed-off-by: Thomas Guillem <thomas at gllm.fr> (cherry picked from commit 3633417edb6330c335c7d3602e255534979c05e7)
> Signed-off-by: Shuicheng Lin <shuicheng.lin at intel.com>
> ---
>   modules/hw/vaapi/vlc_vaapi.c                  | 15 +++
>   modules/hw/vaapi/vlc_vaapi.h                  | 10 ++
>   modules/video_output/opengl/converter_vaapi.c | 92 +++++++++++++++++--
>   3 files changed, 109 insertions(+), 8 deletions(-)
> 
> diff --git a/modules/hw/vaapi/vlc_vaapi.c b/modules/hw/vaapi/vlc_vaapi.c index 6af4932dd5..cb6e1a1f07 100644
> --- a/modules/hw/vaapi/vlc_vaapi.c
> +++ b/modules/hw/vaapi/vlc_vaapi.c
> @@ -733,3 +733,18 @@ vlc_vaapi_PicGetDisplay(picture_t *pic)
>   
>       return ((struct vaapi_pic_ctx *)pic->context)->picref->p_sys->instance->va_dpy;
>   }
> +
> +#if VA_CHECK_VERSION(1, 1, 0)
> +int
> +vlc_vaapi_ExportSurfaceHandle(vlc_object_t *o,
> +                              VADisplay dpy,
> +                              VASurfaceID surface,
> +                              uint32_t mem_type,
> +                              uint32_t flags,
> +                              void *descriptor) {
> +    VA_CALL(o, vaExportSurfaceHandle, dpy, surface, mem_type, flags, descriptor);
> +    return VLC_SUCCESS;
> +error: return VLC_EGENERIC;
> +}
> +#endif
> diff --git a/modules/hw/vaapi/vlc_vaapi.h b/modules/hw/vaapi/vlc_vaapi.h index 98737c6929..c02f76a1a6 100644
> --- a/modules/hw/vaapi/vlc_vaapi.h
> +++ b/modules/hw/vaapi/vlc_vaapi.h
> @@ -228,4 +228,14 @@ vlc_vaapi_IsChromaOpaque(int i_vlc_chroma)
>           || i_vlc_chroma == VLC_CODEC_VAAPI_420_10BPP;  }
>   
> +#if VA_CHECK_VERSION(1, 1, 0)
> +int
> +vlc_vaapi_ExportSurfaceHandle(vlc_object_t *o,
> +                              VADisplay dpy,
> +                              VASurfaceID surface,
> +                              uint32_t mem_type,
> +                              uint32_t flags,
> +                              void *descriptor); #endif
> +
>   #endif /* VLC_VAAPI_H */
> diff --git a/modules/video_output/opengl/converter_vaapi.c b/modules/video_output/opengl/converter_vaapi.c
> index 8b2d2acbfc..cd842f711c 100644
> --- a/modules/video_output/opengl/converter_vaapi.c
> +++ b/modules/video_output/opengl/converter_vaapi.c
> @@ -47,6 +47,14 @@
>   # include <fcntl.h>
>   #endif
>   
> +#define DRM_FORMAT_MOD_VENDOR_NONE    0
> +#define DRM_FORMAT_RESERVED           ((1ULL << 56) - 1)
> +
> +#define fourcc_mod_code(vendor, val) \
> +        ((((EGLuint64KHR)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) |
> +((val) & 0x00ffffffffffffffULL))
> +
> +#define DRM_FORMAT_MOD_INVALID  fourcc_mod_code(NONE,
> +DRM_FORMAT_RESERVED)
> +
>   struct priv
>   {
>       struct vlc_vaapi_instance *vainst;
> @@ -58,16 +66,23 @@ struct priv
>       EGLint drm_fourccs[3];
>   
>       struct {
> -        picture_t *  pic;
> -        VAImage      va_image;
> -        VABufferInfo va_buffer_info;
> -        void *       egl_images[3];
> +        picture_t *                 pic;
> +#if VA_CHECK_VERSION(1, 1, 0)
> +        /* VADRMPRIMESurfaceDescriptor carries modifier information
> +         * (GPU tiling, compression, etc...) */
> +        VADRMPRIMESurfaceDescriptor va_surface_descriptor; #else
> +        VABufferInfo                va_buffer_info;
> +#endif
> +        VAImage                     va_image;
> +        void *                      egl_images[3];
>       } last;
>   };
>   
>   static EGLImageKHR
>   vaegl_image_create(const opengl_tex_converter_t *tc, EGLint w, EGLint h,
> -                   EGLint fourcc, EGLint fd, EGLint offset, EGLint pitch)
> +                   EGLint fourcc, EGLint fd, EGLint offset, EGLint pitch,
> +                   EGLuint64KHR modifier)
>   {
>       EGLint attribs[] = {
>           EGL_WIDTH, w,
> @@ -76,6 +91,8 @@ vaegl_image_create(const opengl_tex_converter_t *tc, EGLint w, EGLint h,
>           EGL_DMA_BUF_PLANE0_FD_EXT, fd,
>           EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
>           EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch,
> +        EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, modifier & 0xffffffff,
> +        EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, modifier >> 32,
>           EGL_NONE
>       };
>   
> @@ -97,7 +114,12 @@ vaegl_release_last_pic(const opengl_tex_converter_t *tc, struct priv *priv)
>       for (unsigned i = 0; i < priv->last.va_image.num_planes; ++i)
>           vaegl_image_destroy(tc, priv->last.egl_images[i]);
>   
> +#if VA_CHECK_VERSION(1, 1, 0)
> +    for (unsigned i = 0; i < priv->last.va_surface_descriptor.num_objects; ++i)
> +        close(priv->last.va_surface_descriptor.objects[i].fd);
> +#else
>       vlc_vaapi_ReleaseBufferHandle(o, priv->vadpy, priv->last.va_image.buf);
> +#endif
>   
>       vlc_vaapi_DestroyImage(o, priv->vadpy, priv->last.va_image.image_id);
>   
> @@ -161,14 +183,20 @@ tc_vaegl_update(const opengl_tex_converter_t *tc, GLuint *textures,
>       struct priv *priv = tc->priv;
>       vlc_object_t *o = VLC_OBJECT(tc->gl);
>       VAImage va_image;
> +#if VA_CHECK_VERSION(1, 1, 0)
> +    VADRMPRIMESurfaceDescriptor va_surface_descriptor; #else
>       VABufferInfo va_buffer_info;
> +#endif
>       EGLImageKHR egl_images[3] = { };
>       bool release_image = false, release_buffer_info = false;
>   
>       if (pic == priv->last.pic)
>       {
>           va_image = priv->last.va_image;
> -        va_buffer_info = priv->last.va_buffer_info;
> +#if VA_CHECK_VERSION(1, 1, 0)
> +        va_surface_descriptor = priv->last.va_surface_descriptor;
> +#endif
>           for (unsigned i = 0; i < priv->last.va_image.num_planes; ++i)
>               egl_images[i] = priv->last.egl_images[i];
>       }
> @@ -181,21 +209,55 @@ tc_vaegl_update(const opengl_tex_converter_t *tc, GLuint *textures,
>   
>           assert(va_image.format.fourcc == priv->fourcc);
>   
> +#if VA_CHECK_VERSION(1, 1, 0)
> +        if (vlc_vaapi_ExportSurfaceHandle(o, priv->vadpy, vlc_vaapi_PicGetSurface(pic),
> +                                          VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, 0,
> +                                          &va_surface_descriptor))
> +            goto error;
> +#else
>           va_buffer_info = (VABufferInfo) {
>               .mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME
>           };
>           if (vlc_vaapi_AcquireBufferHandle(o, priv->vadpy, va_image.buf,
>                                             &va_buffer_info))
>               goto error;
> +#endif
>           release_buffer_info = true;
>       }
>   
> +#if VA_CHECK_VERSION(1, 1, 0)
> +    for (unsigned i = 0; i < va_surface_descriptor.num_layers; ++i)
> +    {
> +        unsigned obj_idx =
> +va_surface_descriptor.layers[i].object_index[0];
> +
> +        /* Since we don't ask for composite object through
> +         * vaExportSurfaceHandle, we shouldn't get any multiplane
> +         * layer. */
> +        if (va_surface_descriptor.layers[i].num_planes > 1)
> +          goto error;
> +
> +        egl_images[i] =
> +            vaegl_image_create(tc, tex_width[i], tex_height[i],
> +                               priv->drm_fourccs[i],
> +                               va_surface_descriptor.objects[obj_idx].fd,
> +                               va_surface_descriptor.layers[i].offset[0],
> +                               va_surface_descriptor.layers[i].pitch[0],
> +                               va_surface_descriptor.objects[obj_idx].drm_format_modifier);
> +        if (egl_images[i] == NULL)
> +            goto error;
> +
> +        tc->vt->BindTexture(tc->tex_target, textures[i]);
> +
> +        priv->glEGLImageTargetTexture2DOES(tc->tex_target, egl_images[i]);
> +    }
> +#else
>       for (unsigned i = 0; i < va_image.num_planes; ++i)
>       {
>           egl_images[i] =
>               vaegl_image_create(tc, tex_width[i], tex_height[i],
>                                  priv->drm_fourccs[i], va_buffer_info.handle,
> -                               va_image.offsets[i], va_image.pitches[i]);
> +                               va_image.offsets[i], va_image.pitches[i],
> +                               DRM_FORMAT_MOD_INVALID);
>           if (egl_images[i] == NULL)
>               goto error;
>   
> @@ -203,6 +265,7 @@ tc_vaegl_update(const opengl_tex_converter_t *tc, GLuint *textures,
>   
>           priv->glEGLImageTargetTexture2DOES(tc->tex_target, egl_images[i]);
>       }
> +#endif
>   
>       if (pic != priv->last.pic)
>       {
> @@ -210,7 +273,12 @@ tc_vaegl_update(const opengl_tex_converter_t *tc, GLuint *textures,
>               vaegl_release_last_pic(tc, priv);
>           priv->last.pic = picture_Hold(pic);
>           priv->last.va_image = va_image;
> +#if VA_CHECK_VERSION(1, 1, 0)
> +        priv->last.va_surface_descriptor = va_surface_descriptor; #else
>           priv->last.va_buffer_info = va_buffer_info;
> +#endif
> +
>           for (unsigned i = 0; i < va_image.num_planes; ++i)
>               priv->last.egl_images[i] = egl_images[i];
>       }
> @@ -221,7 +289,14 @@ error:
>       if (release_image)
>       {
>           if (release_buffer_info)
> +        {
> +#if VA_CHECK_VERSION(1, 1, 0)
> +            for (unsigned i = 0; i < va_surface_descriptor.num_objects; ++i)
> +                close(va_surface_descriptor.objects[i].fd);
> +#else
>               vlc_vaapi_ReleaseBufferHandle(o, priv->vadpy, va_image.buf);
> +#endif
> +        }
>   
>           for (unsigned i = 0; i < 3 && egl_images[i] != NULL; ++i)
>               vaegl_image_destroy(tc, egl_images[i]); @@ -267,7 +342,8 @@ tc_vaegl_get_pool(const opengl_tex_converter_t *tc, unsigned requested_count)
>           EGLint h = (va_image.height * tc->texs[i].h.num) / tc->texs[i].h.den;
>           EGLImageKHR egl_image =
>               vaegl_image_create(tc, w, h, priv->drm_fourccs[i], va_buffer_info.handle,
> -                               va_image.offsets[i], va_image.pitches[i]);
> +                               va_image.offsets[i], va_image.pitches[i],
> +                               DRM_FORMAT_MOD_INVALID);
>           if (egl_image == NULL)
>           {
>               msg_Warn(o, "Can't create Image KHR: kernel too old ?");
> --
> 2.25.1
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list