On Fri, 11 Dec 2020, Simon Ser <contact@xxxxxxxxxxx> wrote: > User-space expects to be able to pick a primary plane for each CRTC > exposed by the driver. Make sure this assumption holds in > drm_mode_config_validate. > > Use the legacy drm_crtc.primary field to check this, because it's > simpler and we require drivers to set it anyways. Accumulate a set of > primary planes which are already used for a CRTC in a bitmask. Error out > if a primary plane is re-used. > > Signed-off-by: Simon Ser <contact@xxxxxxxxxxx> > Cc: Daniel Vetter <daniel@xxxxxxxx> > Cc: Pekka Paalanen <ppaalanen@xxxxxxxxx> > --- > drivers/gpu/drm/drm_mode_config.c | 21 +++++++++++++++++++++ > drivers/gpu/drm/drm_plane.c | 6 ++++++ > 2 files changed, 27 insertions(+) > > diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c > index fbe680035129..f143f56f0820 100644 > --- a/drivers/gpu/drm/drm_mode_config.c > +++ b/drivers/gpu/drm/drm_mode_config.c > @@ -626,6 +626,9 @@ void drm_mode_config_validate(struct drm_device *dev) > { > struct drm_encoder *encoder; > struct drm_crtc *crtc; > + struct drm_plane *plane; > + __u64 primary_with_crtc = 0, cursor_with_crtc = 0; Why __u64 and not u64? > + unsigned num_primary = 0; I think the preference is to spell out the full type instead of using just "unsigned". BR, Jani. > > if (!drm_core_check_feature(dev, DRIVER_MODESET)) > return; > @@ -647,12 +650,30 @@ void drm_mode_config_validate(struct drm_device *dev) > "Bogus primary plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n", > crtc->primary->base.id, crtc->primary->name, > crtc->base.id, crtc->name); > + WARN(primary_with_crtc & BIT(crtc->primary->index), > + "Primary plane [PLANE:%d:%s] used for two CRTCs", > + crtc->primary->base.id, crtc->primary->name); > + primary_with_crtc |= BIT(crtc->primary->index); > } > if (crtc->cursor) { > WARN(!(crtc->cursor->possible_crtcs & BIT(crtc->index)), > "Bogus cursor plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n", > crtc->cursor->base.id, crtc->cursor->name, > crtc->base.id, crtc->name); > + WARN(cursor_with_crtc & BIT(crtc->cursor->index), > + "Primary plane [PLANE:%d:%s] used for two CRTCs", > + crtc->cursor->base.id, crtc->cursor->name); > + cursor_with_crtc |= BIT(crtc->cursor->index); > } > } > + > + drm_for_each_plane(plane, dev) { > + if (plane->type == DRM_PLANE_TYPE_PRIMARY) { > + num_primary++; > + } > + } > + > + WARN(num_primary != dev->mode_config.num_crtc, > + "Must have as many primary planes as there are CRTCs, but have %u primary planes and %u CRTCs", > + num_primary, dev->mode_config.num_crtc); > } > diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c > index 49b0a8b9ac02..a1f4510efa83 100644 > --- a/drivers/gpu/drm/drm_plane.c > +++ b/drivers/gpu/drm/drm_plane.c > @@ -54,6 +54,12 @@ > * enum drm_plane_type). A plane can be compatible with multiple CRTCs, see > * &drm_plane.possible_crtcs. > * > + * Each CRTC must have a unique primary plane userspace can attach to enable > + * the CRTC. In other words, userspace must be able to attach a different > + * primary plane to each CRTC at the same time. Primary planes can still be > + * compatible with multiple CRTCs. There must be exactly as many primary planes > + * as there are CRTCs. > + * > * Legacy uAPI doesn't expose the primary and cursor planes directly. DRM core > * relies on the driver to set the primary and optionally the cursor plane used > * for legacy IOCTLs. This is done by calling drm_crtc_init_with_planes(). All -- Jani Nikula, Intel Open Source Graphics Center _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel