[PATCH v1 5/6] drm/i915: Do not do fb src adjustments for NV12

Srinivas, Vidya vidya.srinivas at intel.com
Thu Apr 12 02:40:51 UTC 2018



> -----Original Message-----
> From: Maarten Lankhorst [mailto:maarten.lankhorst at linux.intel.com]
> Sent: Wednesday, April 11, 2018 4:08 PM
> To: Srinivas, Vidya <vidya.srinivas at intel.com>; intel-gfx-
> trybot at lists.freedesktop.org
> Cc: Kamath, Sunil <sunil.kamath at intel.com>; Saarinen, Jani
> <jani.saarinen at intel.com>
> Subject: Re: [PATCH v1 5/6] drm/i915: Do not do fb src adjustments for
> NV12
> 
> Op 11-04-18 om 11:09 schreef Vidya Srinivas:
> > We skip src trunction/adjustments for
> > NV12 case and handle the sizes directly.
> > Without this, pipe fifo underruns are seen on APL/KBL.
> >
> > Credits-to: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> > Signed-off-by: Vidya Srinivas <vidya.srinivas at intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 88
> > ++++++++++++++++++++++++++++++++++--
> >  drivers/gpu/drm/i915/intel_sprite.c  | 10 +++-
> >  2 files changed, 92 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index ebb3f8e..e4cf7a6 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -12951,6 +12951,86 @@ skl_max_scale(struct intel_crtc *intel_crtc,
> > }
> >
> >  static int
> > +intel_primary_plane_state(struct drm_plane_state *plane_state,
> > +			  const struct drm_crtc_state *crtc_state,
> > +			  int min_scale, int max_scale,
> > +			  bool can_position, bool can_update_disabled) {
> > +	struct drm_framebuffer *fb = plane_state->fb;
> > +	struct drm_rect *src = &plane_state->src;
> > +	struct drm_rect *dst = &plane_state->dst;
> > +	unsigned int rotation = plane_state->rotation;
> > +	struct drm_rect clip = {};
> > +	int hscale, vscale;
> > +
> > +	WARN_ON(plane_state->crtc && plane_state->crtc != crtc_state-
> >crtc);
> > +
> > +	*src = drm_plane_state_src(plane_state);
> > +	*dst = drm_plane_state_dest(plane_state);
> > +
> > +	if (!fb) {
> > +		plane_state->visible = false;
> > +		return 0;
> > +	}
> > +
> > +	/* crtc should only be NULL when disabling (i.e., !fb) */
> > +	if (WARN_ON(!plane_state->crtc)) {
> > +		plane_state->visible = false;
> > +		return 0;
> > +	}
> > +
> > +	if (!crtc_state->enable && !can_update_disabled) {
> > +		DRM_DEBUG_KMS("Cannot update plane of a disabled
> CRTC.\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
> > +
> > +	/* Check scaling */
> > +	hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
> > +	vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
> > +	if (hscale < 0 || vscale < 0) {
> > +		DRM_DEBUG_KMS("Invalid scaling of plane\n");
> > +		drm_rect_debug_print("src: ", &plane_state->src, true);
> > +		drm_rect_debug_print("dst: ", &plane_state->dst, false);
> > +		return -ERANGE;
> > +	}
> > +
> > +	if (crtc_state->enable)
> > +		drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2,
> &clip.y2);
> > +
> > +	if (fb->format->format == DRM_FORMAT_NV12) {
> > +		plane_state->visible = true;
> > +		goto skip_clip;
> > +	}
> > +
> > +	plane_state->visible =
> > +		drm_rect_clip_scaled(src, dst, &clip, hscale, vscale);
> The real problem is that it needs to be a multiple of 4. I think the clipping
> here is harmless, we should just adjust intel_check_sprite_plane for >= SKL.
> This will make it so we don't have to duplicate its checks.
> 
> For NV12 we still want to call clip_rect_scaled, but then adjust all
> coordinates by dividing by 4 on before the check, and multiplying with 4
> after?

Thank you. Will try that today.

Regards
Vidya
> 
> ~Maarten
> 
> > +skip_clip:
> > +	drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
> > +rotation);
> > +
> > +	if (!plane_state->visible)
> > +		/*
> > +		 * Plane isn't visible; some drivers can handle this
> > +		 * so we just return success here.  Drivers that can't
> > +		 * (including those that use the primary plane helper's
> > +		 * update function) will return an error from their
> > +		 * update_plane handler.
> > +		 */
> > +		return 0;
> > +
> > +	if (!can_position && !drm_rect_equals(dst, &clip)) {
> > +		DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
> > +		drm_rect_debug_print("dst: ", dst, false);
> > +		drm_rect_debug_print("clip: ", &clip, false);
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> >  intel_check_primary_plane(struct intel_plane *plane,
> >  			  struct intel_crtc_state *crtc_state,
> >  			  struct intel_plane_state *state) @@ -12975,10
> +13055,10 @@
> > intel_check_primary_plane(struct intel_plane *plane,
> >  		can_position = true;
> >  	}
> >
> > -	ret = drm_atomic_helper_check_plane_state(&state->base,
> > -						  &crtc_state->base,
> > -						  min_scale, max_scale,
> > -						  can_position, true);
> > +	ret = intel_primary_plane_state(&state->base,
> > +					&crtc_state->base,
> > +					min_scale, max_scale,
> > +					can_position, true);
> 
> >  	if (ret)
> >  		return ret;
> >
> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> > b/drivers/gpu/drm/i915/intel_sprite.c
> > index d5dad44..1e47b97 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -1035,11 +1035,14 @@ intel_check_sprite_plane(struct intel_plane
> *plane,
> >  			return vscale;
> >  		}
> >
> > +		if (state->base.fb && fb->format->format ==
> DRM_FORMAT_NV12)
> > +			goto skip_adjust;
> > +
> >  		/* Make the source viewport size an exact multiple of the
> scaling factors. */
> >  		drm_rect_adjust_size(src,
> >  				     drm_rect_width(dst) * hscale -
> drm_rect_width(src),
> >  				     drm_rect_height(dst) * vscale -
> drm_rect_height(src));
> > -
> > +skip_adjust:
> >  		drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
> >  				    state->base.rotation);
> >
> > @@ -1100,6 +1103,9 @@ intel_check_sprite_plane(struct intel_plane
> *plane,
> >  		}
> >  	}
> >
> > +	if (state->base.fb && fb->format->format == DRM_FORMAT_NV12)
> > +		goto out;
> > +
> >  	if (state->base.visible) {
> >  		src->x1 = src_x << 16;
> >  		src->x2 = (src_x + src_w) << 16;
> > @@ -1111,7 +1117,7 @@ intel_check_sprite_plane(struct intel_plane
> *plane,
> >  	dst->x2 = crtc_x + crtc_w;
> >  	dst->y1 = crtc_y;
> >  	dst->y2 = crtc_y + crtc_h;
> > -
> > +out:
> >  	if (INTEL_GEN(dev_priv) >= 9) {
> >  		ret = skl_check_plane_surface(crtc_state, state);
> >  		if (ret)
> 



More information about the Intel-gfx-trybot mailing list