public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Daniel Vetter <daniel@ffwll.ch>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v2 11/12] drm/i915: Deal with NV12 CbCr plane AUX surface on SKL+
Date: Wed, 10 Aug 2016 14:26:14 +0300	[thread overview]
Message-ID: <20160810112614.GM4329@intel.com> (raw)
In-Reply-To: <20160810100308.GW6232@phenom.ffwll.local>

On Wed, Aug 10, 2016 at 12:03:08PM +0200, Daniel Vetter wrote:
> On Wed, Aug 10, 2016 at 12:23:20PM +0300, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > With NV12 we have two color planes to deal with so we must compute the
> > surface and x/y offsets for the second plane as well.
> > 
> > What makes this a bit nasty is that the hardware expects the surface
> > offset to be specified as a distance from the main surface offset.
> > What's worse, the distance must be non-negative (no neat wraparound or
> > anything). So we must make sure that the main surface offset is always
> > less or equal to the AUX surface offset. We do that by computing the AUX
> > offset first and the main surface offset second. If the main surface
> > offset ends up being above the AUX offset, we just push it down as far
> > as is required while still maintaining the required alignment etc.
> > 
> > Fortunately the AUX offset only reuqires 4K alignment, so we don't need
> > to do any of the backwards searching for an acceptable offset that we
> > must do for the main surface. And X tiled + NV12 isn't a supported
> > combination anyway.
> > 
> > Note that this just computes aux surface offsets, we do not yet program
> > them into the actual hardware registers, and hence we can't yet expose
> > NV12.
> > 
> > v2: Rebase due to drm_plane_state src/dst rects
> >     s/TODO.../something else/ in the commit message/ (Daniel)
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 62 ++++++++++++++++++++++++++++++++++--
> >  drivers/gpu/drm/i915/intel_drv.h     |  4 +++
> >  2 files changed, 64 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index b719c07599fd..f8487bcdb271 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2463,8 +2463,14 @@ u32 intel_compute_tile_offset(int *x, int *y,
> >  	const struct drm_i915_private *dev_priv = to_i915(state->base.plane->dev);
> >  	const struct drm_framebuffer *fb = state->base.fb;
> >  	unsigned int rotation = state->base.rotation;
> > -	u32 alignment = intel_surf_alignment(dev_priv, fb->modifier[plane]);
> >  	int pitch = intel_fb_pitch(fb, plane, rotation);
> > +	u32 alignment;
> > +
> > +	/* AUX_DIST needs only 4K alignment */
> > +	if (fb->pixel_format == DRM_FORMAT_NV12 && plane == 1)
> > +		alignment = 4096;
> > +	else
> > +		alignment = intel_surf_alignment(dev_priv, fb->modifier[plane]);
> >  
> >  	return _intel_compute_tile_offset(dev_priv, x, y, fb, plane, pitch,
> >  					  rotation, alignment);
> > @@ -2895,7 +2901,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
> >  	int h = drm_rect_height(&plane_state->base.src) >> 16;
> >  	int max_width = skl_max_plane_width(fb, 0, rotation);
> >  	int max_height = 4096;
> > -	u32 alignment, offset;
> > +	u32 alignment, offset, aux_offset = plane_state->aux.offset;
> >  
> >  	if (w > max_width || h > max_height) {
> >  		DRM_DEBUG_KMS("requested Y/RGB source size %dx%d too big (limit %dx%d)\n",
> > @@ -2909,6 +2915,15 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
> >  	alignment = intel_surf_alignment(dev_priv, fb->modifier[0]);
> >  
> >  	/*
> > +	 * AUX surface offset is specified as the distance from the
> > +	 * main surface offset, and it must be non-negative. Make
> > +	 * sure that is what we will get.
> > +	 */
> > +	if (offset > aux_offset)
> > +		offset = intel_adjust_tile_offset(&x, &y, plane_state, 0,
> > +						  offset, aux_offset & ~(alignment - 1));
> 
> Note to self: Need to make sure that multiplanar fbs all reference the
> same underlying bo. But that code isn't yet added to
> intel_framebuffer_init().

Yep. It would be a lot more work to support different handles for the
planes, so I figure we shouldn't bother. Frankly I don't understand
why the hw doesn't just take two independent offsets, since it would
require exactly the same number of bits in the registers anyway. But
yeah, we have the hw we have, so we must live with it.

> 
> > +
> > +	/*
> >  	 * When using an X-tiled surface, the plane blows up
> >  	 * if the x offset + width exceed the stride.
> >  	 *
> > @@ -2935,6 +2950,35 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
> >  	return 0;
> >  }
> >  
> > +static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
> > +{
> > +	const struct drm_framebuffer *fb = plane_state->base.fb;
> > +	unsigned int rotation = plane_state->base.rotation;
> > +	int max_width = skl_max_plane_width(fb, 1, rotation);
> > +	int max_height = 4096;
> > +	int x = plane_state->base.src.x1 >> 17;
> > +	int y = plane_state->base.src.y1 >> 17;
> > +	int w = drm_rect_width(&plane_state->base.src) >> 17;
> > +	int h = drm_rect_height(&plane_state->base.src) >> 17;
> > +	u32 offset;
> > +
> > +	intel_add_fb_offsets(&x, &y, plane_state, 1);
> > +	offset = intel_compute_tile_offset(&x, &y, plane_state, 1);
> > +
> > +	/* FIXME not quite sure how/if these apply to the chroma plane */
> > +	if (w > max_width || h > max_height) {
> > +		DRM_DEBUG_KMS("CbCr source size %dx%d too big (limit %dx%d)\n",
> > +			      w, h, max_width, max_height);
> > +		return -EINVAL;
> > +	}
> 
> We also need to check pitch of the 2nd plane, but I guess that's done at
> fb_init time, not at atomic_check time. Looks all reasonable as-is.
> 
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> 
> > +
> > +	plane_state->aux.offset = offset;
> > +	plane_state->aux.x = x;
> > +	plane_state->aux.y = y;
> > +
> > +	return 0;
> > +}
> > +
> >  int skl_check_plane_surface(struct intel_plane_state *plane_state)
> >  {
> >  	const struct drm_framebuffer *fb = plane_state->base.fb;
> > @@ -2946,6 +2990,20 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
> >  		drm_rect_rotate(&plane_state->base.src,
> >  				fb->width, fb->height, BIT(DRM_ROTATE_270));
> >  
> > +	/*
> > +	 * Handle the AUX surface first since
> > +	 * the main surface setup depends on it.
> > +	 */
> > +	if (fb->pixel_format == DRM_FORMAT_NV12) {
> > +		ret = skl_check_nv12_aux_surface(plane_state);
> > +		if (ret)
> > +			return ret;
> > +	} else {
> > +		plane_state->aux.offset = ~0xfff;
> > +		plane_state->aux.x = 0;
> > +		plane_state->aux.y = 0;
> > +	}
> > +
> >  	ret = skl_check_main_surface(plane_state);
> >  	if (ret)
> >  		return ret;
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 2fde13833fcb..df8e7514c08c 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -354,6 +354,10 @@ struct intel_plane_state {
> >  		u32 offset;
> >  		int x, y;
> >  	} main;
> > +	struct {
> > +		u32 offset;
> > +		int x, y;
> > +	} aux;
> >  
> >  	/*
> >  	 * scaler_id
> > -- 
> > 2.7.4
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2016-08-10 11:26 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-10  9:23 [PATCH v5 00/12] drm/i915: Handle fb->offsets[] and rewrite fb rotation handling to be more generic (v5) ville.syrjala
2016-08-10  9:23 ` [PATCH v6 01/12] drm/i915: Rewrite fb rotation GTT handling ville.syrjala
2016-08-10  9:49   ` Daniel Vetter
2016-08-10  9:23 ` [PATCH v3 02/12] drm/i915: Don't pass pitch to intel_compute_page_offset() ville.syrjala
2016-08-10  9:23 ` [PATCH v2 03/12] drm/i915: Move SKL hw stride calculation into a helper ville.syrjala
2016-08-10  9:23 ` [PATCH 04/12] drm/i915: Pass around plane_state instead of fb+rotation ville.syrjala
2016-08-10  9:23 ` [PATCH v4 05/12] drm/i915: Use fb modifiers for display tiling decisions ville.syrjala
2016-08-10  9:23 ` [PATCH v3 06/12] drm/i915: Adjust obj tiling vs. fb modifier rules ville.syrjala
2016-08-10  9:43   ` Daniel Vetter
2016-08-10  9:23 ` [PATCH v2 07/12] drm/i915: Limit fb x offset due to fences ville.syrjala
2016-08-10  9:23 ` [PATCH 08/12] drm/i915: Allow calling intel_adjust_tile_offset() multiple times ville.syrjala
2016-08-10  9:46   ` Chris Wilson
2016-08-10  9:48   ` Daniel Vetter
2016-08-10 11:17     ` Ville Syrjälä
2016-08-10  9:23 ` [PATCH 09/12] drm/i915: Make intel_adjust_tile_offset() work for linear buffers ville.syrjala
2016-08-10  9:23 ` [PATCH v2 10/12] drm/i915: Compute display surface offset in the plane check hook for SKL+ ville.syrjala
2016-08-10  9:23 ` [PATCH v2 11/12] drm/i915: Deal with NV12 CbCr plane AUX surface on SKL+ ville.syrjala
2016-08-10 10:03   ` Daniel Vetter
2016-08-10 11:26     ` Ville Syrjälä [this message]
2016-08-10  9:23 ` [PATCH v2 12/12] drm/i915: Make sure fb offset is (macro)pixel aligned ville.syrjala
2016-08-10 10:04   ` Daniel Vetter
2016-08-10 11:02     ` Ville Syrjälä
2016-08-10 11:33       ` Ville Syrjälä
2016-08-11 16:37         ` Ville Syrjälä
2016-08-10 11:46 ` ✗ Ro.CI.BAT: failure for drm/i915: Handle fb->offsets[] and rewrite fb rotation handling to be more generic (v5) Patchwork
2016-08-10 12:40   ` Ville Syrjälä

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=20160810112614.GM4329@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=daniel@ffwll.ch \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox