From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Fritz Koenig <frkoenig@google.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH] drm/i915 : clip yuv primary planes to hw constraints
Date: Wed, 30 May 2018 19:58:34 +0300 [thread overview]
Message-ID: <20180530165834.GR23723@intel.com> (raw)
In-Reply-To: <20180525192740.41927-1-frkoenig@google.com>
On Fri, May 25, 2018 at 12:27:40PM -0700, Fritz Koenig wrote:
> YUV planes need to be multiples of 2 to scan out. This was
> handled correctly for planes other than the primary in the
> intel_check_sprite_plane, where the code fixes up the plane
> and makes it compliant. Move this code into a location that
> allows the primary check to access it as well.
intel_check_sprite_plane() is not something we should be spreading.
It's doing way too many platform specific things. I think where I
want to go instead is per-platform plane .check() functions instead.
To that end I think you should just add the relevant checks to eg.
skl_check_plane_surface() for now.
We especially don't want to be moving large chunks of code from
intel_sprite.c to intel_display.c. I'm actually trying to do the
exact opposite and move all the plane code into intel_sprite.c
(or maybe even introduce a new file for the skl+ plane code
entirely).
> Signed-off-by: Fritz Koenig <frkoenig@google.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 170 +++++++++++++++++++++++++++
> drivers/gpu/drm/i915/intel_drv.h | 2 +
> drivers/gpu/drm/i915/intel_sprite.c | 154 +-----------------------
> 3 files changed, 175 insertions(+), 151 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5f03af455047..e1eb0fb988a6 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -12856,6 +12856,170 @@ skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state
> return max_scale;
> }
>
> +int
> +intel_clip_src_rect(struct intel_plane *plane,
> + struct intel_crtc_state *crtc_state,
> + struct intel_plane_state *state)
> +{
> + struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> + struct drm_framebuffer *fb = state->base.fb;
> + 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->base.src;
> + struct drm_rect *dst = &state->base.dst;
> + struct drm_rect clip = {};
> + int hscale, vscale;
> + int max_scale, min_scale;
> + bool can_scale;
> +
> + *src = drm_plane_state_src(&state->base);
> + *dst = drm_plane_state_dest(&state->base);
> +
> + /* setup can_scale, min_scale, max_scale */
> + if (INTEL_GEN(dev_priv) >= 9) {
> + /* use scaler when colorkey is not required */
> + if (!state->ckey.flags) {
> + can_scale = 1;
> + min_scale = 1;
> + max_scale = skl_max_scale(crtc, crtc_state);
> + } else {
> + can_scale = 0;
> + min_scale = DRM_PLANE_HELPER_NO_SCALING;
> + max_scale = DRM_PLANE_HELPER_NO_SCALING;
> + }
> + } else {
> + can_scale = plane->can_scale;
> + max_scale = plane->max_downscale << 16;
> + min_scale = plane->can_scale ? 1 : (1 << 16);
> + }
> +
> + /*
> + * FIXME the following code does a bunch of fuzzy adjustments to the
> + * coordinates and sizes. We probably need some way to decide whether
> + * more strict checking should be done instead.
> + */
> + drm_rect_rotate(src, fb->width << 16, fb->height << 16,
> + state->base.rotation);
> +
> + 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);
> + BUG_ON(vscale < 0);
> +
> + if (crtc_state->base.enable)
> + drm_mode_get_hv_timing(&crtc_state->base.mode,
> + &clip.x2, &clip.y2);
> +
> + state->base.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);
> +
> + if (state->base.visible) {
> + /* check again in case clipping clamped the results */
> + 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: ", src, true);
> + drm_rect_debug_print("dst: ", dst, false);
> +
> + return hscale;
> + }
> +
> + 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: ", src, true);
> + drm_rect_debug_print("dst: ", 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_rotate_inv(src, fb->width << 16, fb->height << 16,
> + state->base.rotation);
> +
> + /* sanity check to make sure the src viewport wasn't enlarged */
> + WARN_ON(src->x1 < (int) state->base.src_x ||
> + src->y1 < (int) state->base.src_y ||
> + src->x2 > (int) state->base.src_x + state->base.src_w ||
> + src->y2 > (int) state->base.src_y + state->base.src_h);
> +
> + /*
> + * Hardware doesn't handle subpixel coordinates.
> + * Adjust to (macro)pixel boundary, but be careful not to
> + * 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;
> +
> + if (intel_format_is_yuv(fb->format->format)) {
> + src_x &= ~1;
> + src_w &= ~1;
> +
> + /*
> + * Must keep src and dst the
> + * same if we can't scale.
> + */
> + if (!can_scale)
> + crtc_w &= ~1;
> +
> + if (crtc_w == 0)
> + state->base.visible = false;
> + }
> + }
> +
> + /* Check size restrictions when scaling */
> + if (state->base.visible && (src_w != crtc_w || src_h != crtc_h)) {
> + unsigned int width_bytes;
> + int cpp = fb->format->cpp[0];
> +
> + WARN_ON(!can_scale);
> +
> + /* FIXME interlacing min height is 6 */
> +
> + if (crtc_w < 3 || crtc_h < 3)
> + state->base.visible = false;
> +
> + if (src_w < 3 || src_h < 3)
> + state->base.visible = false;
> +
> + width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
> +
> + if (INTEL_GEN(dev_priv) < 9 && (src_w > 2048 || src_h > 2048 ||
> + width_bytes > 4096 || fb->pitches[0] > 4096)) {
> + DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
> + return -EINVAL;
> + }
> + }
> +
> + if (state->base.visible) {
> + src->x1 = src_x << 16;
> + src->x2 = (src_x + src_w) << 16;
> + src->y1 = src_y << 16;
> + src->y2 = (src_y + src_h) << 16;
> + }
> +
> + 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_check_primary_plane(struct intel_plane *plane,
> struct intel_crtc_state *crtc_state,
> @@ -12887,6 +13051,12 @@ intel_check_primary_plane(struct intel_plane *plane,
> if (!state->base.fb)
> return 0;
>
> + if (intel_format_is_yuv(state->base.fb->format->format)) {
> + ret = intel_clip_src_rect(plane, crtc_state, state);
> + if (ret)
> + return ret;
> + }
> +
> if (INTEL_GEN(dev_priv) >= 9) {
> ret = skl_check_plane_surface(crtc_state, state);
> if (ret)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index a80fbad9be0f..43847927a927 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1591,6 +1591,8 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
>
> int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
> int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
> +int intel_clip_src_rect(struct intel_plane *plane,
> + struct intel_crtc_state *crtc_state, struct intel_plane_state *state);
>
> static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
> {
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index dbdcf85032df..892d3247ed69 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -935,21 +935,9 @@ intel_check_sprite_plane(struct intel_plane *plane,
> struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> struct drm_framebuffer *fb = state->base.fb;
> - 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->base.src;
> - struct drm_rect *dst = &state->base.dst;
> - struct drm_rect clip = {};
> int max_stride = INTEL_GEN(dev_priv) >= 9 ? 32768 : 16384;
> - int hscale, vscale;
> - int max_scale, min_scale;
> - bool can_scale;
> int ret;
>
> - *src = drm_plane_state_src(&state->base);
> - *dst = drm_plane_state_dest(&state->base);
> -
> if (!fb) {
> state->base.visible = false;
> return 0;
> @@ -967,145 +955,9 @@ intel_check_sprite_plane(struct intel_plane *plane,
> return -EINVAL;
> }
>
> - /* setup can_scale, min_scale, max_scale */
> - if (INTEL_GEN(dev_priv) >= 9) {
> - /* use scaler when colorkey is not required */
> - if (!state->ckey.flags) {
> - can_scale = 1;
> - min_scale = 1;
> - max_scale = skl_max_scale(crtc, crtc_state);
> - } else {
> - can_scale = 0;
> - min_scale = DRM_PLANE_HELPER_NO_SCALING;
> - max_scale = DRM_PLANE_HELPER_NO_SCALING;
> - }
> - } else {
> - can_scale = plane->can_scale;
> - max_scale = plane->max_downscale << 16;
> - min_scale = plane->can_scale ? 1 : (1 << 16);
> - }
> -
> - /*
> - * FIXME the following code does a bunch of fuzzy adjustments to the
> - * coordinates and sizes. We probably need some way to decide whether
> - * more strict checking should be done instead.
> - */
> - drm_rect_rotate(src, fb->width << 16, fb->height << 16,
> - state->base.rotation);
> -
> - 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);
> - BUG_ON(vscale < 0);
> -
> - if (crtc_state->base.enable)
> - drm_mode_get_hv_timing(&crtc_state->base.mode,
> - &clip.x2, &clip.y2);
> -
> - state->base.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);
> -
> - if (state->base.visible) {
> - /* check again in case clipping clamped the results */
> - 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: ", src, true);
> - drm_rect_debug_print("dst: ", dst, false);
> -
> - return hscale;
> - }
> -
> - 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: ", src, true);
> - drm_rect_debug_print("dst: ", 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_rotate_inv(src, fb->width << 16, fb->height << 16,
> - state->base.rotation);
> -
> - /* sanity check to make sure the src viewport wasn't enlarged */
> - WARN_ON(src->x1 < (int) state->base.src_x ||
> - src->y1 < (int) state->base.src_y ||
> - src->x2 > (int) state->base.src_x + state->base.src_w ||
> - src->y2 > (int) state->base.src_y + state->base.src_h);
> -
> - /*
> - * Hardware doesn't handle subpixel coordinates.
> - * Adjust to (macro)pixel boundary, but be careful not to
> - * 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;
> -
> - if (intel_format_is_yuv(fb->format->format)) {
> - src_x &= ~1;
> - src_w &= ~1;
> -
> - /*
> - * Must keep src and dst the
> - * same if we can't scale.
> - */
> - if (!can_scale)
> - crtc_w &= ~1;
> -
> - if (crtc_w == 0)
> - state->base.visible = false;
> - }
> - }
> -
> - /* Check size restrictions when scaling */
> - if (state->base.visible && (src_w != crtc_w || src_h != crtc_h)) {
> - unsigned int width_bytes;
> - int cpp = fb->format->cpp[0];
> -
> - WARN_ON(!can_scale);
> -
> - /* FIXME interlacing min height is 6 */
> -
> - if (crtc_w < 3 || crtc_h < 3)
> - state->base.visible = false;
> -
> - if (src_w < 3 || src_h < 3)
> - state->base.visible = false;
> -
> - width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
> -
> - if (INTEL_GEN(dev_priv) < 9 && (src_w > 2048 || src_h > 2048 ||
> - width_bytes > 4096 || fb->pitches[0] > 4096)) {
> - DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
> - return -EINVAL;
> - }
> - }
> -
> - if (state->base.visible) {
> - src->x1 = src_x << 16;
> - src->x2 = (src_x + src_w) << 16;
> - src->y1 = src_y << 16;
> - src->y2 = (src_y + src_h) << 16;
> - }
> -
> - dst->x1 = crtc_x;
> - dst->x2 = crtc_x + crtc_w;
> - dst->y1 = crtc_y;
> - dst->y2 = crtc_y + crtc_h;
> + ret = intel_clip_src_rect(plane, crtc_state, state);
> + if (ret)
> + return ret;
>
> if (INTEL_GEN(dev_priv) >= 9) {
> ret = skl_check_plane_surface(crtc_state, state);
> --
> 2.17.0.921.gf22659ad46-goog
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2018-05-30 16:58 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-25 19:27 [PATCH] drm/i915 : clip yuv primary planes to hw constraints Fritz Koenig
2018-05-25 20:09 ` ✗ Fi.CI.BAT: failure for drm/i915 : clip yuv primary planes to hw constraints (rev2) Patchwork
2018-05-30 16:58 ` Ville Syrjälä [this message]
-- strict thread matches above, loose matches on Subject: below --
2018-05-25 18:00 [PATCH] drm/i915 : clip yuv primary planes to hw constraints Fritz Koenig
2018-05-25 18:12 ` Ville Syrjälä
2018-05-25 20:48 ` Fritz Koenig
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=20180530165834.GR23723@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=frkoenig@google.com \
--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.