Re: [PATCH 2/2] vaapi: add support for DRM modifiers

"Lin, Shuicheng" <[email protected]>
Newsgroups gmane.comp.video.videolan.vlc.devel
Message-ID <DM4PR11MB54564D34E2D43D279D7EC0BCEA5A9@DM4PR11MB5456.namprd11.prod.outlook.com>
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

Best Regards
Shuicheng

-----Original Message-----
From: Lin, Shuicheng <[email protected]> 
Sent: Wednesday, January 19, 2022 12:25 AM
To: [email protected]
Cc: Landwerlin, Lionel G <[email protected]>; Thomas Guillem <[email protected]>; Lin, Shuicheng <[email protected]>
Subject: [PATCH 2/2] vaapi: add support for DRM modifiers

From: Lionel Landwerlin <[email protected]>

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 <[email protected]> (cherry picked from commit 3633417edb6330c335c7d3602e255534979c05e7)
Signed-off-by: Shuicheng Lin <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.