From: Deepak Rawat <dra...@vmware.com>

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 <dra...@vmware.com>
Reviewed-by: Sinclair Yeh <s...@vmware.com>
Reviewed-by: Thomas Hellstrom <thellst...@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c  | 31 +++++++++++++++++++------------
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h  | 17 ++++++++++++-----
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 19 ++++++++++++++-----
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 15 +++++++++++----
 4 files changed, 56 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index a2a93d7..cc98e01 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -900,11 +900,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);
@@ -940,11 +940,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");
@@ -1102,12 +1103,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,
@@ -1593,7 +1594,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);
 }
 
 
@@ -1612,7 +1613,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,
@@ -2340,10 +2341,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++) {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index ff9c838..70a7be2 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -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);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index bc5f602..21f4019 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -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) *
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index 90b5437..b2f7db6 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -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;
@@ -793,6 +793,7 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty 
*dirty)
  * @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
@@ -809,7 +810,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;
@@ -843,6 +845,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,
@@ -954,6 +958,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.
@@ -966,7 +971,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);
@@ -991,6 +997,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;
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to