]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
drm/vmwgfx: Avoid iterating over display unit if crtc is available
authorDeepak Rawat <drawat@vmware.com>
Tue, 16 Jan 2018 07:24:17 +0000 (08:24 +0100)
committerThomas Hellstrom <thellstrom@vmware.com>
Thu, 22 Mar 2018 09:55:28 +0000 (10:55 +0100)
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>
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c

index 34ecc27fc30a234a5b277996bc3a0272bbc20815..53392d64ca03184bec78c1700c549b7233d1129e 100644 (file)
@@ -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++) {
index cd9da2dd79af1a062d4aaa3d6b6ded468bd4207e..42b0f1589d3f4d03dce26573f3a74e3a5367f8f7 100644 (file)
@@ -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);
index 63a4cd794b73a12821ea8adbfb72e997367c5193..a17f6c70fc38cd8410ee7356142cb5afc2eb40d3 100644 (file)
@@ -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) *
index b68d74888ab1100be82f8a2a9fdc3234a4e04293..c22bf80d4ddde7b659dab782b214641ba32ca067 100644 (file)
@@ -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;