egl/dri2: Create EGLImages with dmabuf modifiers
Allow creating EGLImages with dmabuf format modifiers when target is EGL_LINUX_DMA_BUF_EXT for EGL_EXT_image_dma_buf_import_modifiers. v2: - clear modifier assembling and error label name (Eric Engestrom) v3: - remove goto jumps within switch-case (Emil Velikov) - treat zero as valid modifier (Daniel Stone) - ensure same modifier across all dmabuf planes (Emil Velikov) v4: - allow modifiers to add extra planes (Louis-Francis Ratté-Boulianne) v5: - fix error checking, some cleanups (Jason Ekstrand) - pass single copy of the modifier to createImageFromDmaBufs2 Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Signed-off-by: Varad Gautam <varad.gautam@collabora.com> Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com> Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
This commit is contained in:
committed by
Eric Engestrom
parent
c5929634a0
commit
6f10e7c37a
@@ -87,6 +87,10 @@
|
|||||||
#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2') /* [31:0] R:G 16:16 little endian */
|
#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2') /* [31:0] R:G 16:16 little endian */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DRM_FORMAT_MOD_INVALID
|
||||||
|
#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dri_set_background_context(void *loaderPrivate)
|
dri_set_background_context(void *loaderPrivate)
|
||||||
{
|
{
|
||||||
@@ -1987,6 +1991,37 @@ dri2_check_dma_buf_attribs(const _EGLImageAttribs *attrs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If <target> is EGL_LINUX_DMA_BUF_EXT, both or neither of the following
|
||||||
|
* attribute values may be given.
|
||||||
|
*
|
||||||
|
* This is referring to EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT and
|
||||||
|
* EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, and the same for other planes.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < DMA_BUF_MAX_PLANES; ++i) {
|
||||||
|
if (attrs->DMABufPlaneModifiersLo[i].IsPresent !=
|
||||||
|
attrs->DMABufPlaneModifiersHi[i].IsPresent) {
|
||||||
|
_eglError(EGL_BAD_PARAMETER, "modifier attribute lo or hi missing");
|
||||||
|
return EGL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Although the EGL_EXT_image_dma_buf_import_modifiers spec doesn't
|
||||||
|
* mandate it, we only accept the same modifier across all planes. */
|
||||||
|
for (i = 1; i < DMA_BUF_MAX_PLANES; ++i) {
|
||||||
|
if (attrs->DMABufPlaneFds[i].IsPresent) {
|
||||||
|
if ((attrs->DMABufPlaneModifiersLo[0].IsPresent !=
|
||||||
|
attrs->DMABufPlaneModifiersLo[i].IsPresent) ||
|
||||||
|
(attrs->DMABufPlaneModifiersLo[0].Value !=
|
||||||
|
attrs->DMABufPlaneModifiersLo[i].Value) ||
|
||||||
|
(attrs->DMABufPlaneModifiersHi[0].Value !=
|
||||||
|
attrs->DMABufPlaneModifiersHi[i].Value)) {
|
||||||
|
_eglError(EGL_BAD_PARAMETER, "modifier attributes not equal");
|
||||||
|
return EGL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return EGL_TRUE;
|
return EGL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2095,7 +2130,25 @@ dri2_check_dma_buf_format(const _EGLImageAttribs *attrs)
|
|||||||
for (i = plane_n; i < DMA_BUF_MAX_PLANES; ++i) {
|
for (i = plane_n; i < DMA_BUF_MAX_PLANES; ++i) {
|
||||||
if (attrs->DMABufPlaneFds[i].IsPresent ||
|
if (attrs->DMABufPlaneFds[i].IsPresent ||
|
||||||
attrs->DMABufPlaneOffsets[i].IsPresent ||
|
attrs->DMABufPlaneOffsets[i].IsPresent ||
|
||||||
attrs->DMABufPlanePitches[i].IsPresent) {
|
attrs->DMABufPlanePitches[i].IsPresent ||
|
||||||
|
attrs->DMABufPlaneModifiersLo[i].IsPresent ||
|
||||||
|
attrs->DMABufPlaneModifiersHi[i].IsPresent) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The modifiers extension spec says:
|
||||||
|
*
|
||||||
|
* "Modifiers may modify any attribute of a buffer import, including
|
||||||
|
* but not limited to adding extra planes to a format which
|
||||||
|
* otherwise does not have those planes. As an example, a modifier
|
||||||
|
* may add a plane for an external compression buffer to a
|
||||||
|
* single-plane format. The exact meaning and effect of any
|
||||||
|
* modifier is canonically defined by drm_fourcc.h, not as part of
|
||||||
|
* this extension."
|
||||||
|
*/
|
||||||
|
if (attrs->DMABufPlaneModifiersLo[i].IsPresent &&
|
||||||
|
attrs->DMABufPlaneModifiersHi[i].IsPresent)
|
||||||
|
continue;
|
||||||
|
|
||||||
_eglError(EGL_BAD_ATTRIBUTE, "too many plane attributes");
|
_eglError(EGL_BAD_ATTRIBUTE, "too many plane attributes");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2128,6 +2181,8 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
|
|||||||
int fds[DMA_BUF_MAX_PLANES];
|
int fds[DMA_BUF_MAX_PLANES];
|
||||||
int pitches[DMA_BUF_MAX_PLANES];
|
int pitches[DMA_BUF_MAX_PLANES];
|
||||||
int offsets[DMA_BUF_MAX_PLANES];
|
int offsets[DMA_BUF_MAX_PLANES];
|
||||||
|
uint64_t modifier;
|
||||||
|
bool has_modifier = false;
|
||||||
unsigned error;
|
unsigned error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2160,16 +2215,47 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
|
|||||||
offsets[i] = attrs.DMABufPlaneOffsets[i].Value;
|
offsets[i] = attrs.DMABufPlaneOffsets[i].Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
dri_image =
|
/* dri2_check_dma_buf_attribs ensures that the modifier, if available,
|
||||||
dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
|
* will be present in attrs.DMABufPlaneModifiersLo[0] and
|
||||||
attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
|
* attrs.DMABufPlaneModifiersHi[0] */
|
||||||
fds, num_fds, pitches, offsets,
|
if (attrs.DMABufPlaneModifiersLo[0].IsPresent) {
|
||||||
attrs.DMABufYuvColorSpaceHint.Value,
|
modifier =
|
||||||
attrs.DMABufSampleRangeHint.Value,
|
((uint64_t) attrs.DMABufPlaneModifiersHi[0].Value << 32) |
|
||||||
attrs.DMABufChromaHorizontalSiting.Value,
|
attrs.DMABufPlaneModifiersLo[0].Value;
|
||||||
attrs.DMABufChromaVerticalSiting.Value,
|
has_modifier = true;
|
||||||
&error,
|
} else {
|
||||||
NULL);
|
modifier = DRM_FORMAT_MOD_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_modifier) {
|
||||||
|
if (dri2_dpy->image->base.version < 15 ||
|
||||||
|
dri2_dpy->image->createImageFromDmaBufs2 == NULL) {
|
||||||
|
_eglError(EGL_BAD_MATCH, "unsupported dma_buf format modifier");
|
||||||
|
return EGL_NO_IMAGE_KHR;
|
||||||
|
}
|
||||||
|
dri_image =
|
||||||
|
dri2_dpy->image->createImageFromDmaBufs2(dri2_dpy->dri_screen,
|
||||||
|
attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
|
||||||
|
modifier, fds, num_fds, pitches, offsets,
|
||||||
|
attrs.DMABufYuvColorSpaceHint.Value,
|
||||||
|
attrs.DMABufSampleRangeHint.Value,
|
||||||
|
attrs.DMABufChromaHorizontalSiting.Value,
|
||||||
|
attrs.DMABufChromaVerticalSiting.Value,
|
||||||
|
&error,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dri_image =
|
||||||
|
dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
|
||||||
|
attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
|
||||||
|
fds, num_fds, pitches, offsets,
|
||||||
|
attrs.DMABufYuvColorSpaceHint.Value,
|
||||||
|
attrs.DMABufSampleRangeHint.Value,
|
||||||
|
attrs.DMABufChromaHorizontalSiting.Value,
|
||||||
|
attrs.DMABufChromaVerticalSiting.Value,
|
||||||
|
&error,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
dri2_create_image_khr_texture_error(error);
|
dri2_create_image_khr_texture_error(error);
|
||||||
|
|
||||||
if (!dri_image)
|
if (!dri_image)
|
||||||
|
|||||||
@@ -106,6 +106,18 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
|
|||||||
attrs->DMABufPlanePitches[0].Value = val;
|
attrs->DMABufPlanePitches[0].Value = val;
|
||||||
attrs->DMABufPlanePitches[0].IsPresent = EGL_TRUE;
|
attrs->DMABufPlanePitches[0].IsPresent = EGL_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT:
|
||||||
|
if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
|
||||||
|
err = EGL_BAD_PARAMETER;
|
||||||
|
attrs->DMABufPlaneModifiersLo[0].Value = val;
|
||||||
|
attrs->DMABufPlaneModifiersLo[0].IsPresent = EGL_TRUE;
|
||||||
|
break;
|
||||||
|
case EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT:
|
||||||
|
if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
|
||||||
|
err = EGL_BAD_PARAMETER;
|
||||||
|
attrs->DMABufPlaneModifiersHi[0].Value = val;
|
||||||
|
attrs->DMABufPlaneModifiersHi[0].IsPresent = EGL_TRUE;
|
||||||
|
break;
|
||||||
case EGL_DMA_BUF_PLANE1_FD_EXT:
|
case EGL_DMA_BUF_PLANE1_FD_EXT:
|
||||||
attrs->DMABufPlaneFds[1].Value = val;
|
attrs->DMABufPlaneFds[1].Value = val;
|
||||||
attrs->DMABufPlaneFds[1].IsPresent = EGL_TRUE;
|
attrs->DMABufPlaneFds[1].IsPresent = EGL_TRUE;
|
||||||
@@ -118,6 +130,18 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
|
|||||||
attrs->DMABufPlanePitches[1].Value = val;
|
attrs->DMABufPlanePitches[1].Value = val;
|
||||||
attrs->DMABufPlanePitches[1].IsPresent = EGL_TRUE;
|
attrs->DMABufPlanePitches[1].IsPresent = EGL_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT:
|
||||||
|
if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
|
||||||
|
err = EGL_BAD_PARAMETER;
|
||||||
|
attrs->DMABufPlaneModifiersLo[1].Value = val;
|
||||||
|
attrs->DMABufPlaneModifiersLo[1].IsPresent = EGL_TRUE;
|
||||||
|
break;
|
||||||
|
case EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT:
|
||||||
|
if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
|
||||||
|
err = EGL_BAD_PARAMETER;
|
||||||
|
attrs->DMABufPlaneModifiersHi[1].Value = val;
|
||||||
|
attrs->DMABufPlaneModifiersHi[1].IsPresent = EGL_TRUE;
|
||||||
|
break;
|
||||||
case EGL_DMA_BUF_PLANE2_FD_EXT:
|
case EGL_DMA_BUF_PLANE2_FD_EXT:
|
||||||
attrs->DMABufPlaneFds[2].Value = val;
|
attrs->DMABufPlaneFds[2].Value = val;
|
||||||
attrs->DMABufPlaneFds[2].IsPresent = EGL_TRUE;
|
attrs->DMABufPlaneFds[2].IsPresent = EGL_TRUE;
|
||||||
@@ -130,6 +154,18 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
|
|||||||
attrs->DMABufPlanePitches[2].Value = val;
|
attrs->DMABufPlanePitches[2].Value = val;
|
||||||
attrs->DMABufPlanePitches[2].IsPresent = EGL_TRUE;
|
attrs->DMABufPlanePitches[2].IsPresent = EGL_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT:
|
||||||
|
if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
|
||||||
|
err = EGL_BAD_PARAMETER;
|
||||||
|
attrs->DMABufPlaneModifiersLo[2].Value = val;
|
||||||
|
attrs->DMABufPlaneModifiersLo[2].IsPresent = EGL_TRUE;
|
||||||
|
break;
|
||||||
|
case EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT:
|
||||||
|
if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
|
||||||
|
err = EGL_BAD_PARAMETER;
|
||||||
|
attrs->DMABufPlaneModifiersHi[2].Value = val;
|
||||||
|
attrs->DMABufPlaneModifiersHi[2].IsPresent = EGL_TRUE;
|
||||||
|
break;
|
||||||
case EGL_DMA_BUF_PLANE3_FD_EXT:
|
case EGL_DMA_BUF_PLANE3_FD_EXT:
|
||||||
if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
|
if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
|
||||||
err = EGL_BAD_PARAMETER;
|
err = EGL_BAD_PARAMETER;
|
||||||
@@ -148,6 +184,18 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
|
|||||||
attrs->DMABufPlanePitches[3].Value = val;
|
attrs->DMABufPlanePitches[3].Value = val;
|
||||||
attrs->DMABufPlanePitches[3].IsPresent = EGL_TRUE;
|
attrs->DMABufPlanePitches[3].IsPresent = EGL_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT:
|
||||||
|
if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
|
||||||
|
err = EGL_BAD_PARAMETER;
|
||||||
|
attrs->DMABufPlaneModifiersLo[3].Value = val;
|
||||||
|
attrs->DMABufPlaneModifiersLo[3].IsPresent = EGL_TRUE;
|
||||||
|
break;
|
||||||
|
case EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT:
|
||||||
|
if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
|
||||||
|
err = EGL_BAD_PARAMETER;
|
||||||
|
attrs->DMABufPlaneModifiersHi[3].Value = val;
|
||||||
|
attrs->DMABufPlaneModifiersHi[3].IsPresent = EGL_TRUE;
|
||||||
|
break;
|
||||||
case EGL_YUV_COLOR_SPACE_HINT_EXT:
|
case EGL_YUV_COLOR_SPACE_HINT_EXT:
|
||||||
if (val != EGL_ITU_REC601_EXT && val != EGL_ITU_REC709_EXT &&
|
if (val != EGL_ITU_REC601_EXT && val != EGL_ITU_REC709_EXT &&
|
||||||
val != EGL_ITU_REC2020_EXT) {
|
val != EGL_ITU_REC2020_EXT) {
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ struct _egl_image_attribs
|
|||||||
struct _egl_image_attrib_int DMABufPlaneFds[DMA_BUF_MAX_PLANES];
|
struct _egl_image_attrib_int DMABufPlaneFds[DMA_BUF_MAX_PLANES];
|
||||||
struct _egl_image_attrib_int DMABufPlaneOffsets[DMA_BUF_MAX_PLANES];
|
struct _egl_image_attrib_int DMABufPlaneOffsets[DMA_BUF_MAX_PLANES];
|
||||||
struct _egl_image_attrib_int DMABufPlanePitches[DMA_BUF_MAX_PLANES];
|
struct _egl_image_attrib_int DMABufPlanePitches[DMA_BUF_MAX_PLANES];
|
||||||
|
struct _egl_image_attrib_int DMABufPlaneModifiersLo[DMA_BUF_MAX_PLANES];
|
||||||
|
struct _egl_image_attrib_int DMABufPlaneModifiersHi[DMA_BUF_MAX_PLANES];
|
||||||
struct _egl_image_attrib_int DMABufYuvColorSpaceHint;
|
struct _egl_image_attrib_int DMABufYuvColorSpaceHint;
|
||||||
struct _egl_image_attrib_int DMABufSampleRangeHint;
|
struct _egl_image_attrib_int DMABufSampleRangeHint;
|
||||||
struct _egl_image_attrib_int DMABufChromaHorizontalSiting;
|
struct _egl_image_attrib_int DMABufChromaHorizontalSiting;
|
||||||
|
|||||||
Reference in New Issue
Block a user