From d1210d6dc0d353f8c7c567cdab1361faf24813e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Wed, 30 Aug 2023 21:34:58 +0200 Subject: [PATCH] vaallocator: use VADRMPRIMESurfaceDescriptor to create surfaces To import DMAbufs we used VASurfaceAttribExternalBuffers which works, but it's not specific for DRM PRIME 2, since it lacks of many metadata. This patch replaces VASurfaceAttribExternalBuffers with VADRMPRIMESurfaceDescriptor in va_create_surfaces(). Still, this patch assumes linear modifier only. The hack for RGB surfaces in I965 driver was pushed down into va_create_surfaces() to avoid handling both structures. Part-of: --- .../gst-libs/gst/va/gstvaallocator.c | 83 ++++++++++++------- .../gst-libs/gst/va/vasurfaceimage.c | 42 ++++++++-- .../gst-libs/gst/va/vasurfaceimage.h | 2 +- 3 files changed, 89 insertions(+), 38 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/va/gstvaallocator.c b/subprojects/gst-plugins-bad/gst-libs/gst/va/gstvaallocator.c index 372a5bb5cc..ec6642f9a2 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/va/gstvaallocator.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/va/gstvaallocator.c @@ -545,7 +545,6 @@ _va_create_surface_and_export_to_dmabuf (GstVaDisplay * display, { VADRMPRIMESurfaceDescriptor desc = { 0, }; guint32 i, fourcc, rt_format, export_flags; - VASurfaceAttribExternalBuffers *extbuf = NULL, ext_buf; GstVideoFormat format; VASurfaceID surface; guint64 prev_modifier = DRM_FORMAT_MOD_INVALID; @@ -559,24 +558,9 @@ _va_create_surface_and_export_to_dmabuf (GstVaDisplay * display, if (fourcc == 0 || rt_format == 0) return FALSE; - /* HACK(victor): disable tiling for i965 driver for RGB formats */ - if (GST_VA_DISPLAY_IS_IMPLEMENTATION (display, INTEL_I965) - && GST_VIDEO_INFO_IS_RGB (info)) { - /* *INDENT-OFF* */ - ext_buf = (VASurfaceAttribExternalBuffers) { - .width = GST_VIDEO_INFO_WIDTH (info), - .height = GST_VIDEO_INFO_HEIGHT (info), - .num_planes = GST_VIDEO_INFO_N_PLANES (info), - .pixel_format = fourcc, - }; - /* *INDENT-ON* */ - - extbuf = &ext_buf; - } - if (!va_create_surfaces (display, rt_format, fourcc, GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info), - usage_hint, modifiers, num_modifiers, extbuf, &surface, 1)) + usage_hint, modifiers, num_modifiers, NULL, &surface, 1)) return FALSE; /* workaround for missing layered dmabuf formats in i965 */ @@ -1044,6 +1028,26 @@ gst_va_dmabuf_allocator_get_format (GstAllocator * allocator, return TRUE; } +static gboolean +_is_fd_repeated (uintptr_t fds[GST_VIDEO_MAX_PLANES], guint cur, guint * prev) +{ + guint i; + + g_assert (cur <= GST_VIDEO_MAX_PLANES); + + if (cur == 0) + return FALSE; + + for (i = 0; i < cur; i++) { + if (fds[i] == fds[cur]) { + if (prev) + *prev = i; + return TRUE; + } + } + return FALSE; +} + /** * gst_va_dmabuf_memories_setup: * @display: a #GstVaDisplay @@ -1073,18 +1077,16 @@ gst_va_dmabuf_memories_setup (GstVaDisplay * display, GstVideoInfo * info, GstVideoFormat format; GstVaBufferSurface *buf; /* *INDENT-OFF* */ - VASurfaceAttribExternalBuffers ext_buf = { + VADRMPRIMESurfaceDescriptor desc = { .width = GST_VIDEO_INFO_WIDTH (info), .height = GST_VIDEO_INFO_HEIGHT (info), - .data_size = GST_VIDEO_INFO_SIZE (info), - .num_planes = GST_VIDEO_INFO_N_PLANES (info), - .buffers = fds, - .num_buffers = GST_VIDEO_INFO_N_PLANES (info), + /* GStreamer can only describe one PRIME layer */ + .num_layers = 1, }; /* *INDENT-ON* */ VASurfaceID surface; guint32 fourcc, rt_format; - guint i, n_planes; + guint i, j, prev, n_planes; gboolean ret; g_return_val_if_fail (GST_IS_VA_DISPLAY (display), FALSE); @@ -1103,21 +1105,38 @@ gst_va_dmabuf_memories_setup (GstVaDisplay * display, GstVideoInfo * info, if (fourcc == 0) return FALSE; - ext_buf.pixel_format = fourcc; + desc.fourcc = fourcc; + desc.layers[0].num_planes = n_planes; + /* FIXME: use GstVideoInfoDmaDrm */ + desc.layers[0].drm_format = gst_va_drm_fourcc_from_video_format (format); - for (i = 0; i < n_planes; i++) { - ext_buf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (info, i); - ext_buf.offsets[i] = offset[i]; + for (i = j = 0; i < n_planes; i++) { + desc.layers[0].pitch[i] = GST_VIDEO_INFO_PLANE_STRIDE (info, i); + desc.layers[0].offset[i] = offset[i]; + + if (_is_fd_repeated (fds, i, &prev)) { + desc.layers[0].object_index[i] = prev; + continue; + } + + desc.objects[j].fd = fds[i]; + desc.objects[j].size = _get_fd_size (fds[i]); + /* FIXME: use GstVideoInfoDmaDrm */ + desc.objects[j].drm_format_modifier = DRM_FORMAT_MOD_LINEAR; + + desc.layers[0].object_index[i] = j; + j++; } - ret = va_create_surfaces (display, rt_format, ext_buf.pixel_format, - ext_buf.width, ext_buf.height, usage_hint, NULL, 0, &ext_buf, &surface, - 1); + desc.num_objects = j; + + ret = va_create_surfaces (display, rt_format, fourcc, desc.width, desc.height, + usage_hint, NULL, 0, &desc, &surface, 1); if (!ret) return FALSE; - GST_LOG_OBJECT (display, "Created surface %#x [%dx%d]", surface, - ext_buf.width, ext_buf.height); + GST_LOG_OBJECT (display, "Created surface %#x [%dx%d]", surface, desc.width, + desc.height); buf = gst_va_buffer_surface_new (surface); buf->display = gst_object_ref (display); diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/va/vasurfaceimage.c b/subprojects/gst-plugins-bad/gst-libs/gst/va/vasurfaceimage.c index 4155ab3987..a15c90a8a1 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/va/vasurfaceimage.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/va/vasurfaceimage.c @@ -48,10 +48,25 @@ va_destroy_surfaces (GstVaDisplay * display, VASurfaceID * surfaces, return TRUE; } +static gboolean +_rt_format_is_rgb (guint rt_format) +{ + switch (rt_format) { + case VA_RT_FORMAT_RGB16: + case VA_RT_FORMAT_RGB32: + case VA_RT_FORMAT_RGB32_10: + return TRUE; + default: + break; + } + + return FALSE; +} + gboolean va_create_surfaces (GstVaDisplay * display, guint rt_format, guint fourcc, guint width, guint height, gint usage_hint, guint64 * modifiers, - guint num_modifiers, VASurfaceAttribExternalBuffers * ext_buf, + guint num_modifiers, VADRMPRIMESurfaceDescriptor * desc, VASurfaceID * surfaces, guint num_surfaces) { VADisplay dpy = gst_va_display_get_va_dpy (display); @@ -67,8 +82,8 @@ va_create_surfaces (GstVaDisplay * display, guint rt_format, guint fourcc, .type = VASurfaceAttribMemoryType, .flags = VA_SURFACE_ATTRIB_SETTABLE, .value.type = VAGenericValueTypeInteger, - .value.value.i = (ext_buf && ext_buf->num_buffers > 0) - ? VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME + .value.value.i = (desc && desc->num_objects > 0) + ? VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 : VA_SURFACE_ATTRIB_MEM_TYPE_VA, }, }; @@ -76,6 +91,12 @@ va_create_surfaces (GstVaDisplay * display, guint rt_format, guint fourcc, .num_modifiers = num_modifiers, .modifiers = modifiers, }; + VASurfaceAttribExternalBuffers extbuf = { + .width = width, + .height = height, + .num_planes = 1, + .pixel_format = fourcc, + }; /* *INDENT-ON* */ VAStatus status; guint num_attrs = 2; @@ -95,15 +116,26 @@ va_create_surfaces (GstVaDisplay * display, guint rt_format, guint fourcc, /* *INDENT-ON* */ } - if (ext_buf) { + if (desc && desc->num_objects > 0) { /* *INDENT-OFF* */ attrs[num_attrs++] = (VASurfaceAttrib) { .type = VASurfaceAttribExternalBufferDescriptor, .flags = VA_SURFACE_ATTRIB_SETTABLE, .value.type = VAGenericValueTypePointer, - .value.value.p = ext_buf, + .value.value.p = desc, }; /* *INDENT-ON* */ + } else if (GST_VA_DISPLAY_IS_IMPLEMENTATION (display, INTEL_I965) + && _rt_format_is_rgb (rt_format)) { + /* HACK(victor): disable tiling for i965 driver for RGB formats */ + /* *INDENT-OFF* */ + attrs[num_attrs++] = (VASurfaceAttrib) { + .type = VASurfaceAttribExternalBufferDescriptor, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypePointer, + .value.value.p = &extbuf, + }; + /* *INDENT-ON* */ } if (num_modifiers > 0 && modifiers) { diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/va/vasurfaceimage.h b/subprojects/gst-plugins-bad/gst-libs/gst/va/vasurfaceimage.h index c3e2bf8fcf..f75566a759 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/va/vasurfaceimage.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/va/vasurfaceimage.h @@ -34,7 +34,7 @@ gboolean va_create_surfaces (GstVaDisplay * displa gint usage_hint, guint64 * modifiers, guint num_modifiers, - VASurfaceAttribExternalBuffers * ext_buf, + VADRMPRIMESurfaceDescriptor * desc, VASurfaceID * surfaces, guint num_surfaces); gboolean va_destroy_surfaces (GstVaDisplay * display,