Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91e9f352 authored by Deepak Rawat's avatar Deepak Rawat Committed by Thomas Hellstrom
Browse files

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: default avatarDeepak Rawat <drawat@vmware.com>
Reviewed-by: default avatarSinclair Yeh <syeh@vmware.com>
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
parent 78230c46
Loading
Loading
Loading
Loading
+19 −12
Original line number Diff line number Diff line
@@ -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,11 +2329,17 @@ 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 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++) {
		struct vmw_display_unit *unit = units[k];
+12 −5
Original line number Diff line number Diff line
@@ -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);
+14 −5
Original line number Diff line number Diff line
@@ -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) *
+11 −4
Original line number Diff line number Diff line
@@ -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 @@ 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
@@ -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;