Commit 897b8180 authored by Thomas Hellstrom's avatar Thomas Hellstrom

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: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarSinclair Yeh <syeh@vmware.com>
parent fea7dd54
...@@ -663,9 +663,8 @@ static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, ...@@ -663,9 +663,8 @@ static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer,
break; break;
case vmw_du_screen_object: case vmw_du_screen_object:
ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, &vfbd->base, ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, &vfbd->base,
clips, num_clips, increment, clips, NULL, num_clips,
true, increment, true, NULL);
NULL);
break; break;
case vmw_du_legacy: case vmw_du_legacy:
ret = vmw_kms_ldu_do_dmabuf_dirty(dev_priv, &vfbd->base, 0, 0, ret = vmw_kms_ldu_do_dmabuf_dirty(dev_priv, &vfbd->base, 0, 0,
......
...@@ -287,6 +287,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv, ...@@ -287,6 +287,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv, int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
struct vmw_framebuffer *framebuffer, struct vmw_framebuffer *framebuffer,
struct drm_clip_rect *clips, struct drm_clip_rect *clips,
struct drm_vmw_rect *vclips,
unsigned num_clips, int increment, unsigned num_clips, int increment,
bool interruptible, bool interruptible,
struct vmw_fence_obj **out_fence); struct vmw_fence_obj **out_fence);
......
...@@ -470,7 +470,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, ...@@ -470,7 +470,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *old_fb = crtc->primary->fb; struct drm_framebuffer *old_fb = crtc->primary->fb;
struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb);
struct vmw_fence_obj *fence = NULL; struct vmw_fence_obj *fence = NULL;
struct drm_clip_rect clips; struct drm_vmw_rect vclips;
int ret; int ret;
/* require ScreenObject support for page flipping */ /* require ScreenObject support for page flipping */
...@@ -483,17 +483,18 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, ...@@ -483,17 +483,18 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
crtc->primary->fb = fb; crtc->primary->fb = fb;
/* do a full screen dirty update */ /* do a full screen dirty update */
clips.x1 = clips.y1 = 0; vclips.x = crtc->x;
clips.x2 = fb->width; vclips.y = crtc->y;
clips.y2 = fb->height; vclips.w = crtc->mode.hdisplay;
vclips.h = crtc->mode.vdisplay;
if (vfb->dmabuf) if (vfb->dmabuf)
ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, vfb, ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, vfb,
&clips, 1, 1, NULL, &vclips, 1, 1,
true, &fence); true, &fence);
else else
ret = vmw_kms_sou_do_surface_dirty(dev_priv, vfb, ret = vmw_kms_sou_do_surface_dirty(dev_priv, vfb,
&clips, NULL, NULL, NULL, &vclips, NULL,
0, 0, 1, 1, &fence); 0, 0, 1, 1, &fence);
...@@ -919,6 +920,8 @@ static void vmw_sou_dmabuf_clip(struct vmw_kms_dirty *dirty) ...@@ -919,6 +920,8 @@ static void vmw_sou_dmabuf_clip(struct vmw_kms_dirty *dirty)
* @dev_priv: Pointer to the device private structure. * @dev_priv: Pointer to the device private structure.
* @framebuffer: Pointer to the dma-buffer backed framebuffer. * @framebuffer: Pointer to the dma-buffer backed framebuffer.
* @clips: Array of clip rects. * @clips: Array of clip rects.
* @vclips: Alternate array of clip rects. Either @clips or @vclips must
* be NULL.
* @num_clips: Number of clip rects in @clips. * @num_clips: Number of clip rects in @clips.
* @increment: Increment to use when looping over @clips. * @increment: Increment to use when looping over @clips.
* @interruptible: Whether to perform waits interruptible if possible. * @interruptible: Whether to perform waits interruptible if possible.
...@@ -932,6 +935,7 @@ static void vmw_sou_dmabuf_clip(struct vmw_kms_dirty *dirty) ...@@ -932,6 +935,7 @@ static void vmw_sou_dmabuf_clip(struct vmw_kms_dirty *dirty)
int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv, int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
struct vmw_framebuffer *framebuffer, struct vmw_framebuffer *framebuffer,
struct drm_clip_rect *clips, struct drm_clip_rect *clips,
struct drm_vmw_rect *vclips,
unsigned num_clips, int increment, unsigned num_clips, int increment,
bool interruptible, bool interruptible,
struct vmw_fence_obj **out_fence) struct vmw_fence_obj **out_fence)
...@@ -955,7 +959,7 @@ int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv, ...@@ -955,7 +959,7 @@ int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
dirty.clip = vmw_sou_dmabuf_clip; dirty.clip = vmw_sou_dmabuf_clip;
dirty.fifo_reserve_size = sizeof(struct vmw_kms_sou_dmabuf_blit) * dirty.fifo_reserve_size = sizeof(struct vmw_kms_sou_dmabuf_blit) *
num_clips; num_clips;
ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, NULL, ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips,
0, 0, num_clips, increment, &dirty); 0, 0, num_clips, increment, &dirty);
vmw_kms_helper_buffer_finish(dev_priv, NULL, buf, out_fence, NULL); vmw_kms_helper_buffer_finish(dev_priv, NULL, buf, out_fence, NULL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment