aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2016-02-12 02:32:08 -0500
committerThomas Hellstrom <thellstrom@vmware.com>2016-03-14 09:56:23 -0400
commit897b818077f3c11eda82ead57fd173c7f12f9796 (patch)
tree49ac863e409c6cab3e555e7829a726e6041fd3bc
parentfea7dd547b038bfed6728641dc35703ab29a16d3 (diff)
drm/vmwgfx: Fix screen object page flips for large framebuffers
For page flips the framebuffer may be much larger than the crtc scanout area and may be attached to multiple crtcs. When flipping a crtc, make sure we dirty only that crtc's area of the framebuffer. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Sinclair Yeh <syeh@vmware.com>
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c5
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h1
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c18
3 files changed, 14 insertions, 10 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index b221a8c40282..29bec974464c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -663,9 +663,8 @@ static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer,
663 break; 663 break;
664 case vmw_du_screen_object: 664 case vmw_du_screen_object:
665 ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, &vfbd->base, 665 ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, &vfbd->base,
666 clips, num_clips, increment, 666 clips, NULL, num_clips,
667 true, 667 increment, true, NULL);
668 NULL);
669 break; 668 break;
670 case vmw_du_legacy: 669 case vmw_du_legacy:
671 ret = vmw_kms_ldu_do_dmabuf_dirty(dev_priv, &vfbd->base, 0, 0, 670 ret = vmw_kms_ldu_do_dmabuf_dirty(dev_priv, &vfbd->base, 0, 0,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index edd81503516d..d41928c12a42 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -287,6 +287,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
287int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv, 287int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
288 struct vmw_framebuffer *framebuffer, 288 struct vmw_framebuffer *framebuffer,
289 struct drm_clip_rect *clips, 289 struct drm_clip_rect *clips,
290 struct drm_vmw_rect *vclips,
290 unsigned num_clips, int increment, 291 unsigned num_clips, int increment,
291 bool interruptible, 292 bool interruptible,
292 struct vmw_fence_obj **out_fence); 293 struct vmw_fence_obj **out_fence);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index cbc1fbaa3d8e..c0de3b8d4e5d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -470,7 +470,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
470 struct drm_framebuffer *old_fb = crtc->primary->fb; 470 struct drm_framebuffer *old_fb = crtc->primary->fb;
471 struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); 471 struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb);
472 struct vmw_fence_obj *fence = NULL; 472 struct vmw_fence_obj *fence = NULL;
473 struct drm_clip_rect clips; 473 struct drm_vmw_rect vclips;
474 int ret; 474 int ret;
475 475
476 /* require ScreenObject support for page flipping */ 476 /* require ScreenObject support for page flipping */
@@ -483,17 +483,18 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
483 crtc->primary->fb = fb; 483 crtc->primary->fb = fb;
484 484
485 /* do a full screen dirty update */ 485 /* do a full screen dirty update */
486 clips.x1 = clips.y1 = 0; 486 vclips.x = crtc->x;
487 clips.x2 = fb->width; 487 vclips.y = crtc->y;
488 clips.y2 = fb->height; 488 vclips.w = crtc->mode.hdisplay;
489 vclips.h = crtc->mode.vdisplay;
489 490
490 if (vfb->dmabuf) 491 if (vfb->dmabuf)
491 ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, vfb, 492 ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, vfb,
492 &clips, 1, 1, 493 NULL, &vclips, 1, 1,
493 true, &fence); 494 true, &fence);
494 else 495 else
495 ret = vmw_kms_sou_do_surface_dirty(dev_priv, vfb, 496 ret = vmw_kms_sou_do_surface_dirty(dev_priv, vfb,
496 &clips, NULL, NULL, 497 NULL, &vclips, NULL,
497 0, 0, 1, 1, &fence); 498 0, 0, 1, 1, &fence);
498 499
499 500
@@ -919,6 +920,8 @@ static void vmw_sou_dmabuf_clip(struct vmw_kms_dirty *dirty)
919 * @dev_priv: Pointer to the device private structure. 920 * @dev_priv: Pointer to the device private structure.
920 * @framebuffer: Pointer to the dma-buffer backed framebuffer. 921 * @framebuffer: Pointer to the dma-buffer backed framebuffer.
921 * @clips: Array of clip rects. 922 * @clips: Array of clip rects.
923 * @vclips: Alternate array of clip rects. Either @clips or @vclips must
924 * be NULL.
922 * @num_clips: Number of clip rects in @clips. 925 * @num_clips: Number of clip rects in @clips.
923 * @increment: Increment to use when looping over @clips. 926 * @increment: Increment to use when looping over @clips.
924 * @interruptible: Whether to perform waits interruptible if possible. 927 * @interruptible: Whether to perform waits interruptible if possible.
@@ -932,6 +935,7 @@ static void vmw_sou_dmabuf_clip(struct vmw_kms_dirty *dirty)
932int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv, 935int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
933 struct vmw_framebuffer *framebuffer, 936 struct vmw_framebuffer *framebuffer,
934 struct drm_clip_rect *clips, 937 struct drm_clip_rect *clips,
938 struct drm_vmw_rect *vclips,
935 unsigned num_clips, int increment, 939 unsigned num_clips, int increment,
936 bool interruptible, 940 bool interruptible,
937 struct vmw_fence_obj **out_fence) 941 struct vmw_fence_obj **out_fence)
@@ -955,7 +959,7 @@ int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
955 dirty.clip = vmw_sou_dmabuf_clip; 959 dirty.clip = vmw_sou_dmabuf_clip;
956 dirty.fifo_reserve_size = sizeof(struct vmw_kms_sou_dmabuf_blit) * 960 dirty.fifo_reserve_size = sizeof(struct vmw_kms_sou_dmabuf_blit) *
957 num_clips; 961 num_clips;
958 ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, NULL, 962 ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips,
959 0, 0, num_clips, increment, &dirty); 963 0, 0, num_clips, increment, &dirty);
960 vmw_kms_helper_buffer_finish(dev_priv, NULL, buf, out_fence, NULL); 964 vmw_kms_helper_buffer_finish(dev_priv, NULL, buf, out_fence, NULL);
961 965