On Sun, Aug 21, 2016 at 02:15:33PM +0100, Chris Wilson wrote:
> The generic atomic helper likes to skip a prepare_plane_fb() if it
> decides that the plane->fb is unchanged. This is wrong for us for a
> couple of reasons:
> 
>  - if the pipe is reconfigured (i.e. a size change) but the framebuffer
>    is untouched, we still have to flush any rendering prior to the
>    reconfiguration to prevent wait-for-scanline GPU hangs
> 
>  - if the framebuffer is rotated, it remains the same but has a
>    different view and a different address.
> 
> Finally, even if the framebuffer is unchanged the flip/modeset should be
> ordered with respect to rendering to the frontbuffer.
> 
> Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

Won't this again break the hacks we have to make the cursor happy?

And maybe we should have this in the core helpers even, with a
drm_plane_state->fb_changed.
-Daniel

> ---
>  drivers/gpu/drm/i915/intel_atomic_plane.c |  2 --
>  drivers/gpu/drm/i915/intel_display.c      | 60 
> ++++++++++++++++++++++++-------
>  drivers/gpu/drm/i915/intel_drv.h          |  4 ---
>  3 files changed, 47 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c 
> b/drivers/gpu/drm/i915/intel_atomic_plane.c
> index b41bf380f2ab..76a5bbbaaa98 100644
> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> @@ -190,8 +190,6 @@ static void intel_plane_atomic_update(struct drm_plane 
> *plane,
>  }
>  
>  const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
> -     .prepare_fb = intel_prepare_plane_fb,
> -     .cleanup_fb = intel_cleanup_plane_fb,
>       .atomic_check = intel_plane_atomic_check,
>       .atomic_update = intel_plane_atomic_update,
>  };
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index c4096204e5a3..9c769b5c91b8 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13938,7 +13938,7 @@ static int intel_atomic_check(struct drm_device *dev,
>   *
>   * Returns 0 on success, negative error code on failure.
>   */
> -int
> +static int
>  intel_prepare_plane_fb(struct drm_plane *plane,
>                      struct drm_plane_state *new_state)
>  {
> @@ -14024,7 +14024,7 @@ intel_prepare_plane_fb(struct drm_plane *plane,
>   *
>   * Must be called with struct_mutex held.
>   */
> -void
> +static void
>  intel_cleanup_plane_fb(struct drm_plane *plane,
>                      struct drm_plane_state *old_state)
>  {
> @@ -14043,6 +14043,49 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
>               intel_unpin_fb_obj(old_state->fb, old_state->rotation);
>  }
>  
> +static int intel_atomic_commit_prepare_planes(struct drm_atomic_state *state)
> +{
> +     struct drm_plane *plane;
> +     struct drm_plane_state *plane_state;
> +     int i, j, ret;
> +
> +     ret = mutex_lock_interruptible(&state->dev->struct_mutex);
> +     if (ret)
> +             return ret;
> +
> +     for_each_plane_in_state(state, plane, plane_state, i) {
> +             ret = intel_prepare_plane_fb(plane, plane_state);
> +             if (ret)
> +                     break;
> +     }
> +
> +     if (ret) {
> +             for_each_plane_in_state(state, plane, plane_state, j) {
> +                     if (j >= i)
> +                             break;
> +
> +                     intel_cleanup_plane_fb(plane, plane_state);
> +             }
> +     }
> +
> +     mutex_unlock(&state->dev->struct_mutex);
> +
> +     return ret;
> +}
> +
> +static void intel_atomic_commit_cleanup_planes(struct drm_atomic_state 
> *state)
> +{
> +     struct drm_plane *plane;
> +     struct drm_plane_state *plane_state;
> +     int i;
> +
> +     mutex_lock(&state->dev->struct_mutex);
> +
> +     for_each_plane_in_state(state, plane, plane_state, i)
> +             intel_cleanup_plane_fb(plane, plane_state);
> +
> +     mutex_unlock(&state->dev->struct_mutex);
> +}
>  
>  static int intel_atomic_prepare_commit(struct drm_device *dev,
>                                      struct drm_atomic_state *state,
> @@ -14065,14 +14108,7 @@ static int intel_atomic_prepare_commit(struct 
> drm_device *dev,
>                       flush_workqueue(dev_priv->wq);
>       }
>  
> -     ret = mutex_lock_interruptible(&dev->struct_mutex);
> -     if (ret)
> -             return ret;
> -
> -     ret = drm_atomic_helper_prepare_planes(dev, state);
> -     mutex_unlock(&dev->struct_mutex);
> -
> -     return ret;
> +     return intel_atomic_commit_prepare_planes(state);
>  }
>  
>  u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
> @@ -14301,9 +14337,7 @@ static void intel_atomic_commit_tail(struct 
> drm_atomic_state *state)
>       if (intel_state->modeset)
>               intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
>  
> -     mutex_lock(&dev->struct_mutex);
> -     drm_atomic_helper_cleanup_planes(dev, state);
> -     mutex_unlock(&dev->struct_mutex);
> +     intel_atomic_commit_cleanup_planes(state);
>  
>       drm_atomic_helper_commit_cleanup_done(state);
>  
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index acb42d66fb08..3416796e5343 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1249,10 +1249,6 @@ __intel_framebuffer_create(struct drm_device *dev,
>  void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe);
>  void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int 
> pipe);
>  void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe);
> -int intel_prepare_plane_fb(struct drm_plane *plane,
> -                        struct drm_plane_state *new_state);
> -void intel_cleanup_plane_fb(struct drm_plane *plane,
> -                         struct drm_plane_state *old_state);
>  int intel_plane_atomic_get_property(struct drm_plane *plane,
>                                   const struct drm_plane_state *state,
>                                   struct drm_property *property,
> -- 
> 2.9.3
> 

-- 
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

Reply via email to