All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jani Nikula <jani.nikula@linux.intel.com>
To: Gustavo Padovan <gustavo@padovan.org>, intel-gfx@lists.freedesktop.org
Cc: Gustavo Padovan <gustavo.padovan@collabora.co.uk>,
	dri-devel@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH -v4 2/4] drm/i915: split intel_update_plane into	check() and commit()
Date: Thu, 11 Sep 2014 19:42:50 +0300	[thread overview]
Message-ID: <871trikt11.fsf@intel.com> (raw)
In-Reply-To: <1409947489-2667-3-git-send-email-gustavo@padovan.org>

On Fri, 05 Sep 2014, Gustavo Padovan <gustavo@padovan.org> wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>
> Due to the upcoming atomic modesetting feature we need to separate
> some update functions into a check step that can fail and a commit
> step that should, ideally, never fail.
>
> This commit splits intel_update_plane() and its commit part can still
> fail due to the fb pinning procedure.

This patch regresses our tests:
https://bugs.freedesktop.org/show_bug.cgi?id=83747

BR,
Jani.


>
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> ---
>  drivers/gpu/drm/i915/intel_sprite.c | 233 ++++++++++++++++++++++--------------
>  1 file changed, 141 insertions(+), 92 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 07a74ef..a4306cf 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -845,57 +845,24 @@ static bool colorkey_enabled(struct intel_plane *intel_plane)
>  }
>  
>  static int
> -intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
> -		   struct drm_framebuffer *fb, int crtc_x, int crtc_y,
> -		   unsigned int crtc_w, unsigned int crtc_h,
> -		   uint32_t src_x, uint32_t src_y,
> -		   uint32_t src_w, uint32_t src_h)
> +intel_check_sprite_plane(struct drm_plane *plane,
> +			 struct intel_plane_state *state)
>  {
> -	struct drm_device *dev = plane->dev;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc);
>  	struct intel_plane *intel_plane = to_intel_plane(plane);
> -	enum pipe pipe = intel_crtc->pipe;
> +	struct drm_framebuffer *fb = state->fb;
>  	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
>  	struct drm_i915_gem_object *obj = intel_fb->obj;
> -	struct drm_i915_gem_object *old_obj = intel_plane->obj;
> -	int ret;
> -	bool primary_enabled;
> -	bool visible;
> +	int crtc_x, crtc_y;
> +	unsigned int crtc_w, crtc_h;
> +	uint32_t src_x, src_y, src_w, src_h;
> +	struct drm_rect *src = &state->src;
> +	struct drm_rect *dst = &state->dst;
> +	struct drm_rect *orig_src = &state->orig_src;
> +	const struct drm_rect *clip = &state->clip;
>  	int hscale, vscale;
>  	int max_scale, min_scale;
>  	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
> -	struct drm_rect src = {
> -		/* sample coordinates in 16.16 fixed point */
> -		.x1 = src_x,
> -		.x2 = src_x + src_w,
> -		.y1 = src_y,
> -		.y2 = src_y + src_h,
> -	};
> -	struct drm_rect dst = {
> -		/* integer pixels */
> -		.x1 = crtc_x,
> -		.x2 = crtc_x + crtc_w,
> -		.y1 = crtc_y,
> -		.y2 = crtc_y + crtc_h,
> -	};
> -	const struct drm_rect clip = {
> -		.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
> -		.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
> -	};
> -	const struct {
> -		int crtc_x, crtc_y;
> -		unsigned int crtc_w, crtc_h;
> -		uint32_t src_x, src_y, src_w, src_h;
> -	} orig = {
> -		.crtc_x = crtc_x,
> -		.crtc_y = crtc_y,
> -		.crtc_w = crtc_w,
> -		.crtc_h = crtc_h,
> -		.src_x = src_x,
> -		.src_y = src_y,
> -		.src_w = src_w,
> -		.src_h = src_h,
> -	};
>  
>  	/* Don't modify another pipe's plane */
>  	if (intel_plane->pipe != intel_crtc->pipe) {
> @@ -927,55 +894,55 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
>  	max_scale = intel_plane->max_downscale << 16;
>  	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
>  
> -	drm_rect_rotate(&src, fb->width << 16, fb->height << 16,
> +	drm_rect_rotate(src, fb->width << 16, fb->height << 16,
>  			intel_plane->rotation);
>  
> -	hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale);
> +	hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
>  	BUG_ON(hscale < 0);
>  
> -	vscale = drm_rect_calc_vscale_relaxed(&src, &dst, min_scale, max_scale);
> +	vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
>  	BUG_ON(vscale < 0);
>  
> -	visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale);
> +	state->visible =  drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
>  
> -	crtc_x = dst.x1;
> -	crtc_y = dst.y1;
> -	crtc_w = drm_rect_width(&dst);
> -	crtc_h = drm_rect_height(&dst);
> +	crtc_x = dst->x1;
> +	crtc_y = dst->y1;
> +	crtc_w = drm_rect_width(dst);
> +	crtc_h = drm_rect_height(dst);
>  
> -	if (visible) {
> +	if (state->visible) {
>  		/* check again in case clipping clamped the results */
> -		hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale);
> +		hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
>  		if (hscale < 0) {
>  			DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
> -			drm_rect_debug_print(&src, true);
> -			drm_rect_debug_print(&dst, false);
> +			drm_rect_debug_print(src, true);
> +			drm_rect_debug_print(dst, false);
>  
>  			return hscale;
>  		}
>  
> -		vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale);
> +		vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
>  		if (vscale < 0) {
>  			DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
> -			drm_rect_debug_print(&src, true);
> -			drm_rect_debug_print(&dst, false);
> +			drm_rect_debug_print(src, true);
> +			drm_rect_debug_print(dst, false);
>  
>  			return vscale;
>  		}
>  
>  		/* 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));
> +		drm_rect_adjust_size(src,
> +				     drm_rect_width(dst) * hscale - drm_rect_width(src),
> +				     drm_rect_height(dst) * vscale - drm_rect_height(src));
>  
> -		drm_rect_rotate_inv(&src, fb->width << 16, fb->height << 16,
> +		drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
>  				    intel_plane->rotation);
>  
>  		/* sanity check to make sure the src viewport wasn't enlarged */
> -		WARN_ON(src.x1 < (int) src_x ||
> -			src.y1 < (int) src_y ||
> -			src.x2 > (int) (src_x + src_w) ||
> -			src.y2 > (int) (src_y + src_h));
> +		WARN_ON(src->x1 < (int) orig_src->x1 ||
> +			src->y1 < (int) orig_src->y1 ||
> +			src->x2 > (int) orig_src->x2 ||
> +			src->y2 > (int) orig_src->y2);
>  
>  		/*
>  		 * Hardware doesn't handle subpixel coordinates.
> @@ -983,10 +950,10 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
>  		 * increase the source viewport size, because that could
>  		 * push the downscaling factor out of bounds.
>  		 */
> -		src_x = src.x1 >> 16;
> -		src_w = drm_rect_width(&src) >> 16;
> -		src_y = src.y1 >> 16;
> -		src_h = drm_rect_height(&src) >> 16;
> +		src_x = src->x1 >> 16;
> +		src_w = drm_rect_width(src) >> 16;
> +		src_y = src->y1 >> 16;
> +		src_h = drm_rect_height(src) >> 16;
>  
>  		if (format_is_yuv(fb->pixel_format)) {
>  			src_x &= ~1;
> @@ -1000,12 +967,12 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
>  				crtc_w &= ~1;
>  
>  			if (crtc_w == 0)
> -				visible = false;
> +				state->visible = false;
>  		}
>  	}
>  
>  	/* Check size restrictions when scaling */
> -	if (visible && (src_w != crtc_w || src_h != crtc_h)) {
> +	if (state->visible && (src_w != crtc_w || src_h != crtc_h)) {
>  		unsigned int width_bytes;
>  
>  		WARN_ON(!intel_plane->can_scale);
> @@ -1013,12 +980,13 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
>  		/* FIXME interlacing min height is 6 */
>  
>  		if (crtc_w < 3 || crtc_h < 3)
> -			visible = false;
> +			state->visible = false;
>  
>  		if (src_w < 3 || src_h < 3)
> -			visible = false;
> +			state->visible = false;
>  
> -		width_bytes = ((src_x * pixel_size) & 63) + src_w * pixel_size;
> +		width_bytes = ((src_x * pixel_size) & 63) +
> +					src_w * pixel_size;
>  
>  		if (src_w > 2048 || src_h > 2048 ||
>  		    width_bytes > 4096 || fb->pitches[0] > 4096) {
> @@ -1027,17 +995,48 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
>  		}
>  	}
>  
> -	dst.x1 = crtc_x;
> -	dst.x2 = crtc_x + crtc_w;
> -	dst.y1 = crtc_y;
> -	dst.y2 = crtc_y + crtc_h;
> +	if (state->visible) {
> +		src->x1 = src_x;
> +		src->x2 = src_x + src_w;
> +		src->y1 = src_y;
> +		src->y2 = src_y + src_h;
> +	}
> +
> +	dst->x1 = crtc_x;
> +	dst->x2 = crtc_x + crtc_w;
> +	dst->y1 = crtc_y;
> +	dst->y2 = crtc_y + crtc_h;
> +
> +	return 0;
> +}
> +
> +static int
> +intel_commit_sprite_plane(struct drm_plane *plane,
> +			  struct intel_plane_state *state)
> +{
> +	struct drm_device *dev = plane->dev;
> +	struct drm_crtc *crtc = state->crtc;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_plane *intel_plane = to_intel_plane(plane);
> +	enum pipe pipe = intel_crtc->pipe;
> +	struct drm_framebuffer *fb = state->fb;
> +	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
> +	struct drm_i915_gem_object *obj = intel_fb->obj;
> +	struct drm_i915_gem_object *old_obj = intel_plane->obj;
> +	int crtc_x, crtc_y;
> +	unsigned int crtc_w, crtc_h;
> +	uint32_t src_x, src_y, src_w, src_h;
> +	struct drm_rect *dst = &state->dst;
> +	const struct drm_rect *clip = &state->clip;
> +	bool primary_enabled;
> +	int ret;
>  
>  	/*
>  	 * If the sprite is completely covering the primary plane,
>  	 * we can disable the primary and save power.
>  	 */
> -	primary_enabled = !drm_rect_equals(&dst, &clip) || colorkey_enabled(intel_plane);
> -	WARN_ON(!primary_enabled && !visible && intel_crtc->active);
> +	primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane);
> +	WARN_ON(!primary_enabled && !state->visible && intel_crtc->active);
>  
>  	mutex_lock(&dev->struct_mutex);
>  
> @@ -1055,14 +1054,14 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
>  	if (ret)
>  		return ret;
>  
> -	intel_plane->crtc_x = orig.crtc_x;
> -	intel_plane->crtc_y = orig.crtc_y;
> -	intel_plane->crtc_w = orig.crtc_w;
> -	intel_plane->crtc_h = orig.crtc_h;
> -	intel_plane->src_x = orig.src_x;
> -	intel_plane->src_y = orig.src_y;
> -	intel_plane->src_w = orig.src_w;
> -	intel_plane->src_h = orig.src_h;
> +	intel_plane->crtc_x = state->orig_dst.x1;
> +	intel_plane->crtc_y = state->orig_dst.y1;
> +	intel_plane->crtc_w = drm_rect_width(&state->orig_dst);
> +	intel_plane->crtc_h = drm_rect_height(&state->orig_dst);
> +	intel_plane->src_x = state->orig_src.x1;
> +	intel_plane->src_y = state->orig_src.y1;
> +	intel_plane->src_w = drm_rect_width(&state->orig_src);
> +	intel_plane->src_h = drm_rect_height(&state->orig_src);
>  	intel_plane->obj = obj;
>  
>  	if (intel_crtc->active) {
> @@ -1076,12 +1075,22 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
>  		if (primary_was_enabled && !primary_enabled)
>  			intel_pre_disable_primary(crtc);
>  
> -		if (visible)
> +		if (state->visible) {
> +			crtc_x = state->dst.x1;
> +			crtc_y = state->dst.x2;
> +			crtc_w = drm_rect_width(&state->dst);
> +			crtc_h = drm_rect_height(&state->dst);
> +			src_x = state->src.x1;
> +			src_y = state->src.y1;
> +			src_w = drm_rect_width(&state->src);
> +			src_h = drm_rect_height(&state->src);
>  			intel_plane->update_plane(plane, crtc, fb, obj,
>  						  crtc_x, crtc_y, crtc_w, crtc_h,
>  						  src_x, src_y, src_w, src_h);
> -		else
> +		} else {
>  			intel_plane->disable_plane(plane, crtc);
> +		}
> +
>  
>  		intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe));
>  
> @@ -1109,6 +1118,46 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
>  }
>  
>  static int
> +intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
> +		   struct drm_framebuffer *fb, int crtc_x, int crtc_y,
> +		   unsigned int crtc_w, unsigned int crtc_h,
> +		   uint32_t src_x, uint32_t src_y,
> +		   uint32_t src_w, uint32_t src_h)
> +{
> +	struct intel_plane_state state;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	int ret;
> +
> +	state.crtc = crtc;
> +	state.fb = fb;
> +
> +	/* sample coordinates in 16.16 fixed point */
> +	state.src.x1 = src_x;
> +	state.src.x2 = src_x + src_w;
> +	state.src.y1 = src_y;
> +	state.src.y2 = src_y + src_h;
> +
> +	/* integer pixels */
> +	state.dst.x1 = crtc_x;
> +	state.dst.x2 = crtc_x + crtc_w;
> +	state.dst.y1 = crtc_y;
> +	state.dst.y2 = crtc_y + crtc_h;
> +
> +	state.clip.x1 = 0;
> +	state.clip.y1 = 0;
> +	state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0;
> +	state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0;
> +	state.orig_src = state.src;
> +	state.orig_dst = state.dst;
> +
> +	ret = intel_check_sprite_plane(plane, &state);
> +	if (ret)
> +		return ret;
> +
> +	return intel_commit_sprite_plane(plane, &state);
> +}
> +
> +static int
>  intel_disable_plane(struct drm_plane *plane)
>  {
>  	struct drm_device *dev = plane->dev;
> -- 
> 1.9.3
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center

  reply	other threads:[~2014-09-11 16:42 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-05 20:04 [PATCH -v4 0/4] split plane's updates functions into check() and commit() Gustavo Padovan
2014-09-05 20:04 ` [PATCH -v4 1/4] drm/i915: create struct intel_plane_state Gustavo Padovan
2014-09-05 20:04 ` [PATCH -v4 2/4] drm/i915: split intel_update_plane into check() and commit() Gustavo Padovan
2014-09-11 16:42   ` Jani Nikula [this message]
2014-09-11 20:42     ` [PATCH] drm/i915: Fix regression in the sprite plane update split Gustavo Padovan
2014-09-12  7:12       ` Jani Nikula
2014-09-12  8:27         ` Daniel Vetter
2014-09-05 20:04 ` [PATCH -v4 3/4] drm/i915: split intel_cursor_plane_update() into check() and commit() Gustavo Padovan
2014-09-05 20:22   ` [PATCH -v5 " Gustavo Padovan
2014-09-05 20:04 ` [PATCH -v4 4/4] drm/i915: split intel_primary_plane_setplane() " Gustavo Padovan
2014-09-08 13:53 ` [Intel-gfx] [PATCH -v4 0/4] split plane's updates functions " Ville Syrjälä
2014-09-08 13:59 ` Ville Syrjälä
2014-09-08 16:32   ` [Intel-gfx] " Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=871trikt11.fsf@intel.com \
    --to=jani.nikula@linux.intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gustavo.padovan@collabora.co.uk \
    --cc=gustavo@padovan.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.