[PATCH v1 5/6] drm/i915: Do not do fb src adjustments for NV12
Vidya Srinivas
vidya.srinivas at intel.com
Wed Apr 11 09:09:29 UTC 2018
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);
+
+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)
--
2.7.4
More information about the Intel-gfx-trybot
mailing list