opengl: Add low level support for tiled formats

This adds support for tiled format in stride and plane size
code.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2190>
This commit is contained in:
Nicolas Dufresne 2022-04-12 12:24:03 -04:00 committed by GStreamer Marge Bot
parent ab839f3642
commit 4b4d607f4c
3 changed files with 70 additions and 10 deletions

View file

@ -553,6 +553,21 @@ _drm_rgba_fourcc_from_info (const GstVideoInfo * info, int plane,
} }
} }
static gint
get_egl_stride (const GstVideoInfo * info, gint plane)
{
const GstVideoFormatInfo *finfo = info->finfo;
gint stride = info->stride[plane];
guint ws;
if (!GST_VIDEO_FORMAT_INFO_IS_TILED (finfo))
return stride;
gst_video_format_info_get_tile_sizes (finfo, plane, &ws, NULL);
return GST_VIDEO_TILE_X_TILES (stride) << ws;
}
/** /**
* gst_egl_image_from_dmabuf: * gst_egl_image_from_dmabuf:
* @context: a #GstGLContext (must be an EGL context) * @context: a #GstGLContext (must be an EGL context)
@ -601,7 +616,7 @@ gst_egl_image_from_dmabuf (GstGLContext * context,
attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
attribs[atti++] = offset; attribs[atti++] = offset;
attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
attribs[atti++] = GST_VIDEO_INFO_PLANE_STRIDE (in_info, plane); attribs[atti++] = get_egl_stride (in_info, plane);
attribs[atti] = EGL_NONE; attribs[atti] = EGL_NONE;
g_assert (atti == G_N_ELEMENTS (attribs) - 1); g_assert (atti == G_N_ELEMENTS (attribs) - 1);
@ -905,7 +920,7 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context,
attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
attribs[atti++] = offset[0]; attribs[atti++] = offset[0];
attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
attribs[atti++] = in_info->stride[0]; attribs[atti++] = get_egl_stride (in_info, 0);
if (with_modifiers) { if (with_modifiers) {
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff; attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff;
@ -921,7 +936,7 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context,
attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
attribs[atti++] = offset[1]; attribs[atti++] = offset[1];
attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
attribs[atti++] = in_info->stride[1]; attribs[atti++] = get_egl_stride (in_info, 1);
if (with_modifiers) { if (with_modifiers) {
attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff; attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff;
@ -937,7 +952,7 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context,
attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
attribs[atti++] = offset[2]; attribs[atti++] = offset[2];
attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
attribs[atti++] = in_info->stride[2]; attribs[atti++] = get_egl_stride (in_info, 2);
if (with_modifiers) { if (with_modifiers) {
attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT; attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff; attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff;

View file

@ -59,7 +59,7 @@
#define GL_MEM_WIDTH(gl_mem) _get_plane_width (&gl_mem->info, gl_mem->plane) #define GL_MEM_WIDTH(gl_mem) _get_plane_width (&gl_mem->info, gl_mem->plane)
#define GL_MEM_HEIGHT(gl_mem) _get_plane_height (&gl_mem->info, gl_mem->plane) #define GL_MEM_HEIGHT(gl_mem) _get_plane_height (&gl_mem->info, gl_mem->plane)
#define GL_MEM_STRIDE(gl_mem) GST_VIDEO_INFO_PLANE_STRIDE (&gl_mem->info, gl_mem->plane) #define GL_MEM_STRIDE(gl_mem) _get_mem_stride (gl_mem)
static GstAllocator *_gl_memory_allocator; static GstAllocator *_gl_memory_allocator;
@ -122,19 +122,43 @@ _get_plane_width (const GstVideoInfo * info, guint plane)
static inline guint static inline guint
_get_plane_height (const GstVideoInfo * info, guint plane) _get_plane_height (const GstVideoInfo * info, guint plane)
{ {
if (GST_VIDEO_FORMAT_INFO_IS_TILED (info->finfo)) {
guint hs;
gsize stride;
gst_video_format_info_get_tile_sizes (info->finfo, plane, NULL, &hs);
stride = GST_VIDEO_INFO_PLANE_STRIDE (info, plane);
return GST_VIDEO_TILE_Y_TILES (stride) << hs;
}
if (GST_VIDEO_INFO_IS_YUV (info)) { if (GST_VIDEO_INFO_IS_YUV (info)) {
gint comp[GST_VIDEO_MAX_COMPONENTS]; gint comp[GST_VIDEO_MAX_COMPONENTS];
gst_video_format_info_component (info->finfo, plane, comp); gst_video_format_info_component (info->finfo, plane, comp);
return GST_VIDEO_INFO_COMP_HEIGHT (info, comp[0]); return GST_VIDEO_INFO_COMP_HEIGHT (info, comp[0]);
} else {
/* RGB, GRAY */
return GST_VIDEO_INFO_HEIGHT (info);
} }
/* RGB, GRAY */
return GST_VIDEO_INFO_HEIGHT (info);
}
static guint
_get_mem_stride (GstGLMemory * gl_mem)
{
const GstVideoFormatInfo *finfo = gl_mem->info.finfo;
guint stride = GST_VIDEO_INFO_PLANE_STRIDE (&gl_mem->info, gl_mem->plane);
if (!GST_VIDEO_FORMAT_INFO_IS_TILED (finfo))
return stride;
return
GST_VIDEO_TILE_X_TILES (stride) << GST_VIDEO_FORMAT_INFO_TILE_WS (finfo);
} }
static inline void static inline void
_calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context) _calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context)
{ {
GstVideoInfo *info = &gl_mem->info;
guint n_gl_bytes; guint n_gl_bytes;
GstGLFormat tex_format; GstGLFormat tex_format;
guint tex_type; guint tex_type;
@ -142,7 +166,6 @@ _calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context)
gl_mem->tex_scaling[0] = 1.0f; gl_mem->tex_scaling[0] = 1.0f;
gl_mem->tex_scaling[1] = 1.0f; gl_mem->tex_scaling[1] = 1.0f;
gl_mem->unpack_length = 1; gl_mem->unpack_length = 1;
gl_mem->tex_width = GL_MEM_WIDTH (gl_mem);
gst_gl_format_type_from_sized_gl_format (gl_mem->tex_format, &tex_format, gst_gl_format_type_from_sized_gl_format (gl_mem->tex_format, &tex_format,
&tex_type); &tex_type);
@ -152,6 +175,13 @@ _calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context)
return; return;
} }
/* For tiles, we need GL not to clip on the display width, as the would make
* some tile not fully accessible by GLSL. */
if (GST_VIDEO_FORMAT_INFO_IS_TILED (info->finfo))
gl_mem->tex_width = GL_MEM_STRIDE (gl_mem) / n_gl_bytes;
else
gl_mem->tex_width = GL_MEM_WIDTH (gl_mem);
if (USING_OPENGL (context) || USING_GLES3 (context) if (USING_OPENGL (context) || USING_GLES3 (context)
|| USING_OPENGL3 (context)) { || USING_OPENGL3 (context)) {
gl_mem->unpack_length = GL_MEM_STRIDE (gl_mem) / n_gl_bytes; gl_mem->unpack_length = GL_MEM_STRIDE (gl_mem) / n_gl_bytes;

View file

@ -613,6 +613,7 @@ gsize
gst_gl_get_plane_data_size (const GstVideoInfo * info, gst_gl_get_plane_data_size (const GstVideoInfo * info,
const GstVideoAlignment * align, guint plane) const GstVideoAlignment * align, guint plane)
{ {
const GstVideoFormatInfo *finfo = info->finfo;
gint comp[GST_VIDEO_MAX_COMPONENTS]; gint comp[GST_VIDEO_MAX_COMPONENTS];
gint padded_height; gint padded_height;
gsize plane_size; gsize plane_size;
@ -627,7 +628,21 @@ gst_gl_get_plane_data_size (const GstVideoInfo * info,
padded_height = padded_height =
GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, comp[0], padded_height); GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, comp[0], padded_height);
plane_size = GST_VIDEO_INFO_PLANE_STRIDE (info, plane) * padded_height; if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) {
gsize stride;
gint x_tiles, y_tiles;
gint tile_size;
tile_size = gst_video_format_info_get_tile_sizes (finfo, plane, NULL, NULL);
stride = GST_VIDEO_INFO_PLANE_STRIDE (info, plane);
x_tiles = GST_VIDEO_TILE_X_TILES (stride);
y_tiles = GST_VIDEO_TILE_Y_TILES (stride);
plane_size = x_tiles * y_tiles * tile_size;
} else {
plane_size = GST_VIDEO_INFO_PLANE_STRIDE (info, plane) * padded_height;
}
return plane_size; return plane_size;
} }