diff mbox

drm/i915: Call drm_handle_vblank() after processing pending pageflips

Message ID 1348831536-22546-1-git-send-email-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson Sept. 28, 2012, 11:25 a.m. UTC
When we process a pageflip completion, we append an event to the vblank
queue. That queue is processed by drm_handle_vblank() and so by calling
drm_handle_vblank() prior to processing the pageflips, we incur an extra
frame of latency in reporting the flip event.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_irq.c |   22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

Comments

Rodrigo Vivi Sept. 29, 2012, 12:57 a.m. UTC | #1
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com>

On Fri, Sep 28, 2012 at 8:25 AM, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> When we process a pageflip completion, we append an event to the vblank
> queue. That queue is processed by drm_handle_vblank() and so by calling
> drm_handle_vblank() prior to processing the pageflips, we incur an extra
> frame of latency in reporting the flip event.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/i915_irq.c |   22 ++++++++++------------
>  1 file changed, 10 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 6361276..e18e56b 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -564,13 +564,12 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
>                 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
>
>                 for_each_pipe(pipe) {
> -                       if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
> -                               drm_handle_vblank(dev, pipe);
> -
>                         if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) {
>                                 intel_prepare_page_flip(dev, pipe);
>                                 intel_finish_page_flip(dev, pipe);
>                         }
> +                       if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
> +                               drm_handle_vblank(dev, pipe);
>                 }
>
>                 /* Consume port.  Then clear IIR or we'll miss events */
> @@ -2220,22 +2219,22 @@ static irqreturn_t i8xx_irq_handler(DRM_IRQ_ARGS)
>                 if (iir & I915_USER_INTERRUPT)
>                         notify_ring(dev, &dev_priv->ring[RCS]);
>
> -               if (pipe_stats[0] & PIPE_VBLANK_INTERRUPT_STATUS &&
> -                   drm_handle_vblank(dev, 0)) {
> +               if (pipe_stats[0] & PIPE_VBLANK_INTERRUPT_STATUS) {
>                         if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) {
>                                 intel_prepare_page_flip(dev, 0);
>                                 intel_finish_page_flip(dev, 0);
>                                 flip_mask &= ~I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT;
>                         }
> +                       drm_handle_vblank(dev, 0);
>                 }
>
> -               if (pipe_stats[1] & PIPE_VBLANK_INTERRUPT_STATUS &&
> -                   drm_handle_vblank(dev, 1)) {
> +               if (pipe_stats[1] & PIPE_VBLANK_INTERRUPT_STATUS) {
>                         if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) {
>                                 intel_prepare_page_flip(dev, 1);
>                                 intel_finish_page_flip(dev, 1);
>                                 flip_mask &= ~I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
>                         }
> +                       drm_handle_vblank(dev, 1);
>                 }
>
>                 iir = new_iir;
> @@ -2418,13 +2417,13 @@ static irqreturn_t i915_irq_handler(DRM_IRQ_ARGS)
>                         int plane = pipe;
>                         if (IS_MOBILE(dev))
>                                 plane = !plane;
> -                       if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
> -                           drm_handle_vblank(dev, pipe)) {
> +                       if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) {
>                                 if (iir & flip[plane]) {
>                                         intel_prepare_page_flip(dev, plane);
>                                         intel_finish_page_flip(dev, pipe);
>                                         flip_mask &= ~flip[plane];
>                                 }
> +                               drm_handle_vblank(dev, pipe);
>                         }
>
>                         if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
> @@ -2662,17 +2661,16 @@ static irqreturn_t i965_irq_handler(DRM_IRQ_ARGS)
>                         intel_prepare_page_flip(dev, 1);
>
>                 for_each_pipe(pipe) {
> -                       if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
> -                           drm_handle_vblank(dev, pipe)) {
> +                       if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) {
>                                 i915_pageflip_stall_check(dev, pipe);
>                                 intel_finish_page_flip(dev, pipe);
> +                               drm_handle_vblank(dev, pipe);
>                         }
>
>                         if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
>                                 blc_event = true;
>                 }
>
> -
>                 if (blc_event || (iir & I915_ASLE_INTERRUPT))
>                         intel_opregion_asle_intr(dev);
>
> --
> 1.7.10.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 6361276..e18e56b 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -564,13 +564,12 @@  static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
 		spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 
 		for_each_pipe(pipe) {
-			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
-				drm_handle_vblank(dev, pipe);
-
 			if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) {
 				intel_prepare_page_flip(dev, pipe);
 				intel_finish_page_flip(dev, pipe);
 			}
+			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
+				drm_handle_vblank(dev, pipe);
 		}
 
 		/* Consume port.  Then clear IIR or we'll miss events */
@@ -2220,22 +2219,22 @@  static irqreturn_t i8xx_irq_handler(DRM_IRQ_ARGS)
 		if (iir & I915_USER_INTERRUPT)
 			notify_ring(dev, &dev_priv->ring[RCS]);
 
-		if (pipe_stats[0] & PIPE_VBLANK_INTERRUPT_STATUS &&
-		    drm_handle_vblank(dev, 0)) {
+		if (pipe_stats[0] & PIPE_VBLANK_INTERRUPT_STATUS) {
 			if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) {
 				intel_prepare_page_flip(dev, 0);
 				intel_finish_page_flip(dev, 0);
 				flip_mask &= ~I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT;
 			}
+			drm_handle_vblank(dev, 0);
 		}
 
-		if (pipe_stats[1] & PIPE_VBLANK_INTERRUPT_STATUS &&
-		    drm_handle_vblank(dev, 1)) {
+		if (pipe_stats[1] & PIPE_VBLANK_INTERRUPT_STATUS) {
 			if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) {
 				intel_prepare_page_flip(dev, 1);
 				intel_finish_page_flip(dev, 1);
 				flip_mask &= ~I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
 			}
+			drm_handle_vblank(dev, 1);
 		}
 
 		iir = new_iir;
@@ -2418,13 +2417,13 @@  static irqreturn_t i915_irq_handler(DRM_IRQ_ARGS)
 			int plane = pipe;
 			if (IS_MOBILE(dev))
 				plane = !plane;
-			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
-			    drm_handle_vblank(dev, pipe)) {
+			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) {
 				if (iir & flip[plane]) {
 					intel_prepare_page_flip(dev, plane);
 					intel_finish_page_flip(dev, pipe);
 					flip_mask &= ~flip[plane];
 				}
+				drm_handle_vblank(dev, pipe);
 			}
 
 			if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
@@ -2662,17 +2661,16 @@  static irqreturn_t i965_irq_handler(DRM_IRQ_ARGS)
 			intel_prepare_page_flip(dev, 1);
 
 		for_each_pipe(pipe) {
-			if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
-			    drm_handle_vblank(dev, pipe)) {
+			if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) {
 				i915_pageflip_stall_check(dev, pipe);
 				intel_finish_page_flip(dev, pipe);
+				drm_handle_vblank(dev, pipe);
 			}
 
 			if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
 				blc_event = true;
 		}
 
-
 		if (blc_event || (iir & I915_ASLE_INTERRUPT))
 			intel_opregion_asle_intr(dev);