From: Daniel Vetter <daniel@ffwll.ch>
To: ville.syrjala@linux.intel.com
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 12:03:08 +0200 [thread overview]
Message-ID: <20160810100308.GW6232@phenom.ffwll.local> (raw)
In-Reply-To: <1470821001-25272-12-git-send-email-ville.syrjala@linux.intel.com>
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().
> +
> + /*
> * 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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2016-08-10 10:03 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 [this message]
2016-08-10 11:26 ` Ville Syrjälä
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=20160810100308.GW6232@phenom.ffwll.local \
--to=daniel@ffwll.ch \
--cc=intel-gfx@lists.freedesktop.org \
--cc=ville.syrjala@linux.intel.com \
/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