Re: [PATCH v14 40/41] compositor-drm: Support plane IN_FORMATS

2018-07-10 Thread Pekka Paalanen
On Tue, 10 Jul 2018 08:41:46 +0100
Daniel Stone  wrote:

> Hi Pekka,
> 
> On Mon, 29 Jan 2018 at 15:01, Pekka Paalanen  wrote:
> > On Wed, 20 Dec 2017 12:26:57 + Daniel Stone  
> > wrote:  
> > > @@ -212,6 +212,9 @@ if test x$enable_drm_compositor = xyes; then
> > >PKG_CHECK_MODULES(DRM_COMPOSITOR_ATOMIC, [libdrm >= 2.4.78],
> > >   [AC_DEFINE([HAVE_DRM_ATOMIC], 1, [libdrm supports 
> > > atomic API])],
> > >   [AC_MSG_WARN([libdrm does not support atomic 
> > > modesetting, will omit that capability])])
> > > +  PKG_CHECK_MODULES(DRM_COMPOSITOR_FORMATS_BLOB, [libdrm >= 2.4.83],
> > > + [AC_DEFINE([HAVE_DRM_FORMATS_BLOB], 1, [libdrm supports 
> > > modifier advertisement])],
> > > + [AC_MSG_WARN([libdrm does not support modifier 
> > > advertisement])])
> > >PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM, [gbm >= 17.2],
> > >   [AC_DEFINE([HAVE_GBM_FD_IMPORT], 1, [gbm supports 
> > > import with modifiers])],
> > >   [AC_MSG_WARN([GBM does not support dmabuf import, will 
> > > omit that capability])])  
> >
> > Hi,
> >
> > I wonder, we are getting more and more of these "libdrm has ..."
> > feature checks. How about merging some to produce fewer build types?
> > Just a general idea, not specifically for this patch.  
> 
> Assuming enough distros support the new bits, I'd be open to having
> two levels of libdrm support: ancient or supports-everything.
> Annoyingly the gbm check is separate, but I suppose we could connect,
> e.g., both of libdrm >= 2.4.83 + gbm >= 17.2 to modifiers, rather than
> having modifiers half-supported when only one of them is sufficiently
> new.

That sounds reasonable to me.

Now that we've heard of the weak functions trick, I'd be happy to
remove some autoconf checks for library functions and replace them with
runtime weak function checks that would also be reported in the log.
Maybe that can cut the number of #ifdefs and checks.

Let's keep these ideas for follow-up. They would help the Meson
migration as well, having less dependency checks to cross-check.


> > > + unsigned i, j;
> > > + drmModePropertyBlobRes *blob;
> > > + struct drm_format_modifier_blob *fmt_mod_blob;
> > > + uint32_t *blob_formats;
> > > + struct drm_format_modifier *blob_modifiers;
> > > +
> > > + blob = drmModeGetPropertyBlob(plane->backend->drm.fd, blob_id);
> > > + if (!blob)
> > > + return false;
> > > +
> > > + fmt_mod_blob = blob->data;  
> >
> > Should we not check that fmt_mod_blob.version == 1?  
> 
> No. Future versions can add new bits to the end of the blob, but they
> can't break compatibility - doing so would require a new property
> name. Usually DRM uses size to do this, but as we have two
> variable-length arrays whose size can't be trivially determined by the
> client, we use version to indicate any possible future extensions to
> the structure, and the offset fields to point to the VLAs.
> 
> The current version is 1; I guess we could check for version 0 and
> bail out if we see it, but no kernel has ever had it and it seems a
> bit pathological. Future versions will still be parseable as the
> original, so those are fine.

Understood.


Thanks,
pq


pgp_1lW0E5AnD.pgp
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH v14 40/41] compositor-drm: Support plane IN_FORMATS

2018-07-10 Thread Daniel Stone
Hi Pekka,

On Mon, 29 Jan 2018 at 15:01, Pekka Paalanen  wrote:
> On Wed, 20 Dec 2017 12:26:57 + Daniel Stone  wrote:
> > @@ -212,6 +212,9 @@ if test x$enable_drm_compositor = xyes; then
> >PKG_CHECK_MODULES(DRM_COMPOSITOR_ATOMIC, [libdrm >= 2.4.78],
> >   [AC_DEFINE([HAVE_DRM_ATOMIC], 1, [libdrm supports atomic 
> > API])],
> >   [AC_MSG_WARN([libdrm does not support atomic modesetting, 
> > will omit that capability])])
> > +  PKG_CHECK_MODULES(DRM_COMPOSITOR_FORMATS_BLOB, [libdrm >= 2.4.83],
> > + [AC_DEFINE([HAVE_DRM_FORMATS_BLOB], 1, [libdrm supports 
> > modifier advertisement])],
> > + [AC_MSG_WARN([libdrm does not support modifier 
> > advertisement])])
> >PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM, [gbm >= 17.2],
> >   [AC_DEFINE([HAVE_GBM_FD_IMPORT], 1, [gbm supports import 
> > with modifiers])],
> >   [AC_MSG_WARN([GBM does not support dmabuf import, will 
> > omit that capability])])
>
> Hi,
>
> I wonder, we are getting more and more of these "libdrm has ..."
> feature checks. How about merging some to produce fewer build types?
> Just a general idea, not specifically for this patch.

Assuming enough distros support the new bits, I'd be open to having
two levels of libdrm support: ancient or supports-everything.
Annoyingly the gbm check is separate, but I suppose we could connect,
e.g., both of libdrm >= 2.4.83 + gbm >= 17.2 to modifiers, rather than
having modifiers half-supported when only one of them is sufficiently
new.

> > +#ifdef HAVE_DRM_FORMATS_BLOB
> > +static inline uint32_t *
> > +formats_ptr(struct drm_format_modifier_blob *blob)
> > +{
> > + return (uint32_t *)(((char *)blob) + blob->formats_offset);
> > +}
> > +
> > +static inline struct drm_format_modifier *
> > +modifiers_ptr(struct drm_format_modifier_blob *blob)
> > +{
> > + return (struct drm_format_modifier *)(((char *)blob) + 
> > blob->modifiers_offset);
> > +}
>
> These two functions are unlikely to be used anywhere else than
> populate_format_modifiers(), so they might as well be in the same #ifdef
> block. If even functions at all. A long line.

Both done.

> > @@ -3635,6 +3667,61 @@ init_pixman(struct drm_backend *b)
> >   return pixman_renderer_init(b->compositor);
> >  }
> >
> > +/**
> > + * Populates the formats array, and the modifiers of each format for a 
> > drm_plane.
> > + */
> > +#ifdef HAVE_DRM_FORMATS_BLOB
> > +static bool
> > +populate_format_modifiers(struct drm_plane *plane, const drmModePlane 
> > *kplane,
> > +   uint32_t blob_id)
>
> I think this should be:
>
> static int
> drm_plane_populate_format_modifiers(...
>
> I believe we tend to use int for success/failure returns, where
> negative is a failure. Boolean return values are more used for
> functions that return a truth value, like drm_device_is_kms().

Both done.

> > + unsigned i, j;
> > + drmModePropertyBlobRes *blob;
> > + struct drm_format_modifier_blob *fmt_mod_blob;
> > + uint32_t *blob_formats;
> > + struct drm_format_modifier *blob_modifiers;
> > +
> > + blob = drmModeGetPropertyBlob(plane->backend->drm.fd, blob_id);
> > + if (!blob)
> > + return false;
> > +
> > + fmt_mod_blob = blob->data;
>
> Should we not check that fmt_mod_blob.version == 1?

No. Future versions can add new bits to the end of the blob, but they
can't break compatibility - doing so would require a new property
name. Usually DRM uses size to do this, but as we have two
variable-length arrays whose size can't be trivially determined by the
client, we use version to indicate any possible future extensions to
the structure, and the offset fields to point to the VLAs.

The current version is 1; I guess we could check for version 0 and
bail out if we see it, but no kernel has ever had it and it seems a
bit pathological. Future versions will still be parseable as the
original, so those are fine.

> > + blob_formats = formats_ptr(fmt_mod_blob);
> > + blob_modifiers = modifiers_ptr(fmt_mod_blob);
> > +
> > + assert(plane->count_formats == fmt_mod_blob->count_formats);
> > +
> > + for (i = 0; i < fmt_mod_blob->count_formats; i++) {
> > + uint32_t count_modifiers = 0;
> > + uint64_t *modifiers = NULL;
> > +
> > + for (j = 0; j < fmt_mod_blob->count_modifiers; j++) {
> > + struct drm_format_modifier *mod = &blob_modifiers[j];
> > +
> > + if ((i < mod->offset) || (i > mod->offset + 63))
> > + continue;
> > + if (!(mod->formats & (1 << (i - mod->offset
> > + continue;
> > +
> > + modifiers = realloc(modifiers, (count_modifiers + 1) 
> > * sizeof(modifiers[0]));
>
> Split line, please.

Done.

> > + if (!modifiers) {
>
> Realloc is a bit inconvenient in that if it fails, the original
> allocation 

Re: [PATCH v14 40/41] compositor-drm: Support plane IN_FORMATS

2018-01-29 Thread Pekka Paalanen
On Wed, 20 Dec 2017 12:26:57 +
Daniel Stone  wrote:

> From: Sergi Granell 
> 
> The per-plane IN_FORMATS property adds information about format
> modifiers; we can use these to both feed GBM with the set of modifiers
> we want to use for rendering, and also as an early-out test when we're
> trying to see if a FB will go on a particular plane.
> 
> Signed-off-by: Sergi Granell 
> Reviewed-by: Daniel Stone 
> Signed-off-by: Daniel Stone 
> ---
>  configure.ac   |   3 ++
>  libweston/compositor-drm.c | 128 
> +
>  2 files changed, 122 insertions(+), 9 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 8d0d6582a..bc6fefc1e 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -212,6 +212,9 @@ if test x$enable_drm_compositor = xyes; then
>PKG_CHECK_MODULES(DRM_COMPOSITOR_ATOMIC, [libdrm >= 2.4.78],
>   [AC_DEFINE([HAVE_DRM_ATOMIC], 1, [libdrm supports atomic 
> API])],
>   [AC_MSG_WARN([libdrm does not support atomic modesetting, 
> will omit that capability])])
> +  PKG_CHECK_MODULES(DRM_COMPOSITOR_FORMATS_BLOB, [libdrm >= 2.4.83],
> + [AC_DEFINE([HAVE_DRM_FORMATS_BLOB], 1, [libdrm supports 
> modifier advertisement])],
> + [AC_MSG_WARN([libdrm does not support modifier 
> advertisement])])
>PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM, [gbm >= 17.2],
>   [AC_DEFINE([HAVE_GBM_FD_IMPORT], 1, [gbm supports import 
> with modifiers])],
>   [AC_MSG_WARN([GBM does not support dmabuf import, will omit 
> that capability])])

Hi,

I wonder, we are getting more and more of these "libdrm has ..."
feature checks. How about merging some to produce fewer build types?
Just a general idea, not specifically for this patch.

> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index cb1c23b03..ba2217fc0 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -83,6 +83,20 @@
>  #define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
>  #endif
>  
> +#ifdef HAVE_DRM_FORMATS_BLOB
> +static inline uint32_t *
> +formats_ptr(struct drm_format_modifier_blob *blob)
> +{
> + return (uint32_t *)(((char *)blob) + blob->formats_offset);
> +}
> +
> +static inline struct drm_format_modifier *
> +modifiers_ptr(struct drm_format_modifier_blob *blob)
> +{
> + return (struct drm_format_modifier *)(((char *)blob) + 
> blob->modifiers_offset);
> +}

These two functions are unlikely to be used anywhere else than
populate_format_modifiers(), so they might as well be in the same #ifdef
block. If even functions at all. A long line.

> +#endif
> +
>  /**
>   * Represents the values of an enum-type KMS property
>   */
> @@ -127,6 +141,7 @@ enum wdrm_plane_property {
>   WDRM_PLANE_CRTC_H,
>   WDRM_PLANE_FB_ID,
>   WDRM_PLANE_CRTC_ID,
> + WDRM_PLANE_IN_FORMATS,
>   WDRM_PLANE__COUNT
>  };
>  
> @@ -168,6 +183,7 @@ static const struct drm_property_info plane_props[] = {
>   [WDRM_PLANE_CRTC_H] = { .name = "CRTC_H", },
>   [WDRM_PLANE_FB_ID] = { .name = "FB_ID", },
>   [WDRM_PLANE_CRTC_ID] = { .name = "CRTC_ID", },
> + [WDRM_PLANE_IN_FORMATS] = { .name = "IN_FORMATS" },
>  };
>  
>  /**
> @@ -403,7 +419,11 @@ struct drm_plane {
>  
>   struct wl_list link;
>  
> - uint32_t formats[];
> + struct {
> + uint32_t format;
> + uint32_t count_modifiers;
> + uint64_t *modifiers;
> + } formats[];
>  };
>  
>  struct drm_output {
> @@ -2879,7 +2899,19 @@ drm_output_prepare_overlay_view(struct 
> drm_output_state *output_state,
>  
>   /* Check whether the format is supported */
>   for (i = 0; i < p->count_formats; i++) {
> - if (p->formats[i] == fb->format->format)
> + unsigned int j;
> +
> + if (p->formats[i].format != fb->format->format)
> + continue;
> +
> + if (fb->modifier == DRM_FORMAT_MOD_INVALID)
> + break;
> +
> + for (j = 0; j < p->formats[i].count_modifiers; j++) {
> + if (p->formats[i].modifiers[j] == fb->modifier)
> + break;
> + }
> + if (j != p->formats[i].count_modifiers)
>   break;
>   }
>   if (i == p->count_formats)
> @@ -3635,6 +3667,61 @@ init_pixman(struct drm_backend *b)
>   return pixman_renderer_init(b->compositor);
>  }
>  
> +/**
> + * Populates the formats array, and the modifiers of each format for a 
> drm_plane.
> + */
> +#ifdef HAVE_DRM_FORMATS_BLOB
> +static bool
> +populate_format_modifiers(struct drm_plane *plane, const drmModePlane 
> *kplane,
> +   uint32_t blob_id)

I think this should be:

static int
drm_plane_populate_format_modifiers(...

I believe we tend to use int 

[PATCH v14 40/41] compositor-drm: Support plane IN_FORMATS

2017-12-20 Thread Daniel Stone
From: Sergi Granell 

The per-plane IN_FORMATS property adds information about format
modifiers; we can use these to both feed GBM with the set of modifiers
we want to use for rendering, and also as an early-out test when we're
trying to see if a FB will go on a particular plane.

Signed-off-by: Sergi Granell 
Reviewed-by: Daniel Stone 
Signed-off-by: Daniel Stone 
---
 configure.ac   |   3 ++
 libweston/compositor-drm.c | 128 +
 2 files changed, 122 insertions(+), 9 deletions(-)

diff --git a/configure.ac b/configure.ac
index 8d0d6582a..bc6fefc1e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -212,6 +212,9 @@ if test x$enable_drm_compositor = xyes; then
   PKG_CHECK_MODULES(DRM_COMPOSITOR_ATOMIC, [libdrm >= 2.4.78],
[AC_DEFINE([HAVE_DRM_ATOMIC], 1, [libdrm supports atomic 
API])],
[AC_MSG_WARN([libdrm does not support atomic modesetting, 
will omit that capability])])
+  PKG_CHECK_MODULES(DRM_COMPOSITOR_FORMATS_BLOB, [libdrm >= 2.4.83],
+   [AC_DEFINE([HAVE_DRM_FORMATS_BLOB], 1, [libdrm supports 
modifier advertisement])],
+   [AC_MSG_WARN([libdrm does not support modifier 
advertisement])])
   PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM, [gbm >= 17.2],
[AC_DEFINE([HAVE_GBM_FD_IMPORT], 1, [gbm supports import 
with modifiers])],
[AC_MSG_WARN([GBM does not support dmabuf import, will omit 
that capability])])
diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index cb1c23b03..ba2217fc0 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -83,6 +83,20 @@
 #define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
 #endif
 
+#ifdef HAVE_DRM_FORMATS_BLOB
+static inline uint32_t *
+formats_ptr(struct drm_format_modifier_blob *blob)
+{
+   return (uint32_t *)(((char *)blob) + blob->formats_offset);
+}
+
+static inline struct drm_format_modifier *
+modifiers_ptr(struct drm_format_modifier_blob *blob)
+{
+   return (struct drm_format_modifier *)(((char *)blob) + 
blob->modifiers_offset);
+}
+#endif
+
 /**
  * Represents the values of an enum-type KMS property
  */
@@ -127,6 +141,7 @@ enum wdrm_plane_property {
WDRM_PLANE_CRTC_H,
WDRM_PLANE_FB_ID,
WDRM_PLANE_CRTC_ID,
+   WDRM_PLANE_IN_FORMATS,
WDRM_PLANE__COUNT
 };
 
@@ -168,6 +183,7 @@ static const struct drm_property_info plane_props[] = {
[WDRM_PLANE_CRTC_H] = { .name = "CRTC_H", },
[WDRM_PLANE_FB_ID] = { .name = "FB_ID", },
[WDRM_PLANE_CRTC_ID] = { .name = "CRTC_ID", },
+   [WDRM_PLANE_IN_FORMATS] = { .name = "IN_FORMATS" },
 };
 
 /**
@@ -403,7 +419,11 @@ struct drm_plane {
 
struct wl_list link;
 
-   uint32_t formats[];
+   struct {
+   uint32_t format;
+   uint32_t count_modifiers;
+   uint64_t *modifiers;
+   } formats[];
 };
 
 struct drm_output {
@@ -2879,7 +2899,19 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
 
/* Check whether the format is supported */
for (i = 0; i < p->count_formats; i++) {
-   if (p->formats[i] == fb->format->format)
+   unsigned int j;
+
+   if (p->formats[i].format != fb->format->format)
+   continue;
+
+   if (fb->modifier == DRM_FORMAT_MOD_INVALID)
+   break;
+
+   for (j = 0; j < p->formats[i].count_modifiers; j++) {
+   if (p->formats[i].modifiers[j] == fb->modifier)
+   break;
+   }
+   if (j != p->formats[i].count_modifiers)
break;
}
if (i == p->count_formats)
@@ -3635,6 +3667,61 @@ init_pixman(struct drm_backend *b)
return pixman_renderer_init(b->compositor);
 }
 
+/**
+ * Populates the formats array, and the modifiers of each format for a 
drm_plane.
+ */
+#ifdef HAVE_DRM_FORMATS_BLOB
+static bool
+populate_format_modifiers(struct drm_plane *plane, const drmModePlane *kplane,
+ uint32_t blob_id)
+{
+   unsigned i, j;
+   drmModePropertyBlobRes *blob;
+   struct drm_format_modifier_blob *fmt_mod_blob;
+   uint32_t *blob_formats;
+   struct drm_format_modifier *blob_modifiers;
+
+   blob = drmModeGetPropertyBlob(plane->backend->drm.fd, blob_id);
+   if (!blob)
+   return false;
+
+   fmt_mod_blob = blob->data;
+   blob_formats = formats_ptr(fmt_mod_blob);
+   blob_modifiers = modifiers_ptr(fmt_mod_blob);
+
+   assert(plane->count_formats == fmt_mod_blob->count_formats);
+
+   for (i = 0; i < fmt_mod_blob->count_formats; i++) {
+   uint32_t count_modifiers = 0;
+   uint64_t *modifiers = NULL;
+
+   for (