drm/vmwgfx: Avoid iterating over display unit if crtc is available
In case of page flip there is no need to iterate over all display unit in the function "vmw_kms_helper_dirty". If crtc is available then dirty commands is performed on that crtc only. Signed-off-by: Deepak Rawat <drawat@vmware.com> Reviewed-by: Sinclair Yeh <syeh@vmware.com> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
This commit is contained in:
parent
78230c46ec
commit
91e9f352cd
|
@ -888,11 +888,11 @@ static int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
|
|||
if (dev_priv->active_display_unit == vmw_du_screen_object)
|
||||
ret = vmw_kms_sou_do_surface_dirty(dev_priv, &vfbs->base,
|
||||
clips, NULL, NULL, 0, 0,
|
||||
num_clips, inc, NULL);
|
||||
num_clips, inc, NULL, NULL);
|
||||
else
|
||||
ret = vmw_kms_stdu_surface_dirty(dev_priv, &vfbs->base,
|
||||
clips, NULL, NULL, 0, 0,
|
||||
num_clips, inc, NULL);
|
||||
num_clips, inc, NULL, NULL);
|
||||
|
||||
vmw_fifo_flush(dev_priv, false);
|
||||
ttm_read_unlock(&dev_priv->reservation_sem);
|
||||
|
@ -928,11 +928,12 @@ int vmw_kms_readback(struct vmw_private *dev_priv,
|
|||
switch (dev_priv->active_display_unit) {
|
||||
case vmw_du_screen_object:
|
||||
return vmw_kms_sou_readback(dev_priv, file_priv, vfb,
|
||||
user_fence_rep, vclips, num_clips);
|
||||
user_fence_rep, vclips, num_clips,
|
||||
NULL);
|
||||
case vmw_du_screen_target:
|
||||
return vmw_kms_stdu_dma(dev_priv, file_priv, vfb,
|
||||
user_fence_rep, NULL, vclips, num_clips,
|
||||
1, false, true);
|
||||
1, false, true, NULL);
|
||||
default:
|
||||
WARN_ONCE(true,
|
||||
"Readback called with invalid display system.\n");
|
||||
|
@ -1090,12 +1091,12 @@ static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer,
|
|||
case vmw_du_screen_target:
|
||||
ret = vmw_kms_stdu_dma(dev_priv, NULL, &vfbd->base, NULL,
|
||||
clips, NULL, num_clips, increment,
|
||||
true, true);
|
||||
true, true, NULL);
|
||||
break;
|
||||
case vmw_du_screen_object:
|
||||
ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, &vfbd->base,
|
||||
clips, NULL, num_clips,
|
||||
increment, true, NULL);
|
||||
increment, true, NULL, NULL);
|
||||
break;
|
||||
case vmw_du_legacy:
|
||||
ret = vmw_kms_ldu_do_dmabuf_dirty(dev_priv, &vfbd->base, 0, 0,
|
||||
|
@ -1581,7 +1582,7 @@ static int vmw_kms_generic_present(struct vmw_private *dev_priv,
|
|||
{
|
||||
return vmw_kms_sou_do_surface_dirty(dev_priv, vfb, NULL, clips,
|
||||
&surface->res, destX, destY,
|
||||
num_clips, 1, NULL);
|
||||
num_clips, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1600,7 +1601,7 @@ int vmw_kms_present(struct vmw_private *dev_priv,
|
|||
case vmw_du_screen_target:
|
||||
ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, clips,
|
||||
&surface->res, destX, destY,
|
||||
num_clips, 1, NULL);
|
||||
num_clips, 1, NULL, NULL);
|
||||
break;
|
||||
case vmw_du_screen_object:
|
||||
ret = vmw_kms_generic_present(dev_priv, file_priv, vfb, surface,
|
||||
|
@ -2328,10 +2329,16 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
|
|||
|
||||
dirty->dev_priv = dev_priv;
|
||||
|
||||
list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
|
||||
if (crtc->primary->fb != &framebuffer->base)
|
||||
continue;
|
||||
units[num_units++] = vmw_crtc_to_du(crtc);
|
||||
/* If crtc is passed, no need to iterate over other display units */
|
||||
if (dirty->crtc) {
|
||||
units[num_units++] = vmw_crtc_to_du(dirty->crtc);
|
||||
} else {
|
||||
list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list,
|
||||
head) {
|
||||
if (crtc->primary->fb != &framebuffer->base)
|
||||
continue;
|
||||
units[num_units++] = vmw_crtc_to_du(crtc);
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; k < num_units; k++) {
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
* @unit: The current display unit. Set up by the helper before a call to @clip.
|
||||
* @cmd: The allocated fifo space. Set up by the helper before the first @clip
|
||||
* call.
|
||||
* @crtc: The crtc for which to build dirty commands.
|
||||
* @num_hits: Number of clip rect commands for this display unit.
|
||||
* Cleared by the helper before the first @clip call. Updated by the @clip
|
||||
* callback.
|
||||
|
@ -71,6 +72,7 @@ struct vmw_kms_dirty {
|
|||
struct vmw_private *dev_priv;
|
||||
struct vmw_display_unit *unit;
|
||||
void *cmd;
|
||||
struct drm_crtc *crtc;
|
||||
u32 num_hits;
|
||||
s32 fb_x;
|
||||
s32 fb_y;
|
||||
|
@ -398,20 +400,23 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
|
|||
s32 dest_x,
|
||||
s32 dest_y,
|
||||
unsigned num_clips, int inc,
|
||||
struct vmw_fence_obj **out_fence);
|
||||
struct vmw_fence_obj **out_fence,
|
||||
struct drm_crtc *crtc);
|
||||
int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
|
||||
struct vmw_framebuffer *framebuffer,
|
||||
struct drm_clip_rect *clips,
|
||||
struct drm_vmw_rect *vclips,
|
||||
unsigned num_clips, int increment,
|
||||
bool interruptible,
|
||||
struct vmw_fence_obj **out_fence);
|
||||
struct vmw_fence_obj **out_fence,
|
||||
struct drm_crtc *crtc);
|
||||
int vmw_kms_sou_readback(struct vmw_private *dev_priv,
|
||||
struct drm_file *file_priv,
|
||||
struct vmw_framebuffer *vfb,
|
||||
struct drm_vmw_fence_rep __user *user_fence_rep,
|
||||
struct drm_vmw_rect *vclips,
|
||||
uint32_t num_clips);
|
||||
uint32_t num_clips,
|
||||
struct drm_crtc *crtc);
|
||||
|
||||
/*
|
||||
* Screen Target Display Unit functions - vmwgfx_stdu.c
|
||||
|
@ -425,7 +430,8 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
|
|||
s32 dest_x,
|
||||
s32 dest_y,
|
||||
unsigned num_clips, int inc,
|
||||
struct vmw_fence_obj **out_fence);
|
||||
struct vmw_fence_obj **out_fence,
|
||||
struct drm_crtc *crtc);
|
||||
int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
|
||||
struct drm_file *file_priv,
|
||||
struct vmw_framebuffer *vfb,
|
||||
|
@ -435,7 +441,8 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
|
|||
uint32_t num_clips,
|
||||
int increment,
|
||||
bool to_surface,
|
||||
bool interruptible);
|
||||
bool interruptible,
|
||||
struct drm_crtc *crtc);
|
||||
|
||||
int vmw_kms_set_config(struct drm_mode_set *set,
|
||||
struct drm_modeset_acquire_ctx *ctx);
|
||||
|
|
|
@ -341,11 +341,11 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
|
|||
if (vfb->dmabuf)
|
||||
ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, vfb,
|
||||
NULL, &vclips, 1, 1,
|
||||
true, &fence);
|
||||
true, &fence, crtc);
|
||||
else
|
||||
ret = vmw_kms_sou_do_surface_dirty(dev_priv, vfb,
|
||||
NULL, &vclips, NULL,
|
||||
0, 0, 1, 1, &fence);
|
||||
0, 0, 1, 1, &fence, crtc);
|
||||
|
||||
|
||||
if (ret != 0)
|
||||
|
@ -892,6 +892,7 @@ static void vmw_sou_surface_clip(struct vmw_kms_dirty *dirty)
|
|||
* @out_fence: If non-NULL, will return a ref-counted pointer to a
|
||||
* struct vmw_fence_obj. The returned fence pointer may be NULL in which
|
||||
* case the device has already synchronized.
|
||||
* @crtc: If crtc is passed, perform surface dirty on that crtc only.
|
||||
*
|
||||
* Returns 0 on success, negative error code on failure. -ERESTARTSYS if
|
||||
* interrupted.
|
||||
|
@ -904,7 +905,8 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
|
|||
s32 dest_x,
|
||||
s32 dest_y,
|
||||
unsigned num_clips, int inc,
|
||||
struct vmw_fence_obj **out_fence)
|
||||
struct vmw_fence_obj **out_fence,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
struct vmw_framebuffer_surface *vfbs =
|
||||
container_of(framebuffer, typeof(*vfbs), base);
|
||||
|
@ -923,6 +925,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
|
|||
sdirty.base.dev_priv = dev_priv;
|
||||
sdirty.base.fifo_reserve_size = sizeof(struct vmw_kms_sou_dirty_cmd) +
|
||||
sizeof(SVGASignedRect) * num_clips;
|
||||
sdirty.base.crtc = crtc;
|
||||
|
||||
sdirty.sid = srf->id;
|
||||
sdirty.left = sdirty.top = S32_MAX;
|
||||
|
@ -994,6 +997,7 @@ static void vmw_sou_dmabuf_clip(struct vmw_kms_dirty *dirty)
|
|||
* @out_fence: If non-NULL, will return a ref-counted pointer to a
|
||||
* struct vmw_fence_obj. The returned fence pointer may be NULL in which
|
||||
* case the device has already synchronized.
|
||||
* @crtc: If crtc is passed, perform dmabuf dirty on that crtc only.
|
||||
*
|
||||
* Returns 0 on success, negative error code on failure. -ERESTARTSYS if
|
||||
* interrupted.
|
||||
|
@ -1004,7 +1008,8 @@ int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
|
|||
struct drm_vmw_rect *vclips,
|
||||
unsigned num_clips, int increment,
|
||||
bool interruptible,
|
||||
struct vmw_fence_obj **out_fence)
|
||||
struct vmw_fence_obj **out_fence,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
struct vmw_dma_buffer *buf =
|
||||
container_of(framebuffer, struct vmw_framebuffer_dmabuf,
|
||||
|
@ -1021,6 +1026,7 @@ int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
|
|||
if (unlikely(ret != 0))
|
||||
goto out_revert;
|
||||
|
||||
dirty.crtc = crtc;
|
||||
dirty.fifo_commit = vmw_sou_dmabuf_fifo_commit;
|
||||
dirty.clip = vmw_sou_dmabuf_clip;
|
||||
dirty.fifo_reserve_size = sizeof(struct vmw_kms_sou_dmabuf_blit) *
|
||||
|
@ -1092,6 +1098,7 @@ static void vmw_sou_readback_clip(struct vmw_kms_dirty *dirty)
|
|||
* Must be set to non-NULL if @file_priv is non-NULL.
|
||||
* @vclips: Array of clip rects.
|
||||
* @num_clips: Number of clip rects in @vclips.
|
||||
* @crtc: If crtc is passed, readback on that crtc only.
|
||||
*
|
||||
* Returns 0 on success, negative error code on failure. -ERESTARTSYS if
|
||||
* interrupted.
|
||||
|
@ -1101,7 +1108,8 @@ int vmw_kms_sou_readback(struct vmw_private *dev_priv,
|
|||
struct vmw_framebuffer *vfb,
|
||||
struct drm_vmw_fence_rep __user *user_fence_rep,
|
||||
struct drm_vmw_rect *vclips,
|
||||
uint32_t num_clips)
|
||||
uint32_t num_clips,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
struct vmw_dma_buffer *buf =
|
||||
container_of(vfb, struct vmw_framebuffer_dmabuf, base)->buffer;
|
||||
|
@ -1116,6 +1124,7 @@ int vmw_kms_sou_readback(struct vmw_private *dev_priv,
|
|||
if (unlikely(ret != 0))
|
||||
goto out_revert;
|
||||
|
||||
dirty.crtc = crtc;
|
||||
dirty.fifo_commit = vmw_sou_readback_fifo_commit;
|
||||
dirty.clip = vmw_sou_readback_clip;
|
||||
dirty.fifo_reserve_size = sizeof(struct vmw_kms_sou_readback_blit) *
|
||||
|
|
|
@ -530,10 +530,10 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc,
|
|||
|
||||
if (vfb->dmabuf)
|
||||
ret = vmw_kms_stdu_dma(dev_priv, NULL, vfb, NULL, NULL, &vclips,
|
||||
1, 1, true, false);
|
||||
1, 1, true, false, crtc);
|
||||
else
|
||||
ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, &vclips,
|
||||
NULL, 0, 0, 1, 1, NULL);
|
||||
NULL, 0, 0, 1, 1, NULL, crtc);
|
||||
if (ret) {
|
||||
DRM_ERROR("Page flip update error %d.\n", ret);
|
||||
return ret;
|
||||
|
@ -802,6 +802,7 @@ out_cleanup:
|
|||
* @to_surface: Whether to DMA to the screen target system as opposed to
|
||||
* from the screen target system.
|
||||
* @interruptible: Whether to perform waits interruptible if possible.
|
||||
* @crtc: If crtc is passed, perform stdu dma on that crtc only.
|
||||
*
|
||||
* If DMA-ing till the screen target system, the function will also notify
|
||||
* the screen target system that a bounding box of the cliprects has been
|
||||
|
@ -818,7 +819,8 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
|
|||
uint32_t num_clips,
|
||||
int increment,
|
||||
bool to_surface,
|
||||
bool interruptible)
|
||||
bool interruptible,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
struct vmw_dma_buffer *buf =
|
||||
container_of(vfb, struct vmw_framebuffer_dmabuf, base)->buffer;
|
||||
|
@ -852,6 +854,8 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
|
|||
ddirty.base.fifo_reserve_size = 0;
|
||||
}
|
||||
|
||||
ddirty.base.crtc = crtc;
|
||||
|
||||
ret = vmw_kms_helper_dirty(dev_priv, vfb, clips, vclips,
|
||||
0, 0, num_clips, increment, &ddirty.base);
|
||||
vmw_kms_helper_buffer_finish(dev_priv, file_priv, buf, NULL,
|
||||
|
@ -963,6 +967,7 @@ static void vmw_kms_stdu_surface_fifo_commit(struct vmw_kms_dirty *dirty)
|
|||
* @out_fence: If non-NULL, will return a ref-counted pointer to a
|
||||
* struct vmw_fence_obj. The returned fence pointer may be NULL in which
|
||||
* case the device has already synchronized.
|
||||
* @crtc: If crtc is passed, perform surface dirty on that crtc only.
|
||||
*
|
||||
* Returns 0 on success, negative error code on failure. -ERESTARTSYS if
|
||||
* interrupted.
|
||||
|
@ -975,7 +980,8 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
|
|||
s32 dest_x,
|
||||
s32 dest_y,
|
||||
unsigned num_clips, int inc,
|
||||
struct vmw_fence_obj **out_fence)
|
||||
struct vmw_fence_obj **out_fence,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
struct vmw_framebuffer_surface *vfbs =
|
||||
container_of(framebuffer, typeof(*vfbs), base);
|
||||
|
@ -1000,6 +1006,7 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
|
|||
sdirty.base.fifo_reserve_size = sizeof(struct vmw_stdu_surface_copy) +
|
||||
sizeof(SVGA3dCopyBox) * num_clips +
|
||||
sizeof(struct vmw_stdu_update);
|
||||
sdirty.base.crtc = crtc;
|
||||
sdirty.sid = srf->id;
|
||||
sdirty.left = sdirty.top = S32_MAX;
|
||||
sdirty.right = sdirty.bottom = S32_MIN;
|
||||
|
|
Loading…
Reference in New Issue