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

Commit ef86cfee authored by Thomas Hellstrom's avatar Thomas Hellstrom
Browse files

drm/vmwgfx: Use the cpu blit utility for framebuffer to screen target blits



This blit was previously performed using two large vmaps, one of which
was teared down and remapped on each blit. Use the more resource-
conserving TTM cpu blit instead.

The blit is used in boundary-box computing mode which makes it possible
to minimize the bounding box used in host operations.

Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarBrian Paul <brianp@vmware.com>
parent 79273e1b
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -185,6 +185,22 @@ static const struct ttm_place evictable_placement_flags[] = {
	}
};

static const struct ttm_place nonfixed_placement_flags[] = {
	{
		.fpfn = 0,
		.lpfn = 0,
		.flags = TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED
	}, {
		.fpfn = 0,
		.lpfn = 0,
		.flags = VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED
	}, {
		.fpfn = 0,
		.lpfn = 0,
		.flags = VMW_PL_FLAG_MOB | TTM_PL_FLAG_CACHED
	}
};

struct ttm_placement vmw_evictable_placement = {
	.num_placement = 4,
	.placement = evictable_placement_flags,
@@ -213,6 +229,13 @@ struct ttm_placement vmw_mob_ne_placement = {
	.busy_placement = &mob_ne_placement_flags
};

struct ttm_placement vmw_nonfixed_placement = {
	.num_placement = 3,
	.placement = nonfixed_placement_flags,
	.num_busy_placement = 1,
	.busy_placement = &sys_placement_flags
};

struct vmw_ttm_tt {
	struct ttm_dma_tt dma_ttm;
	struct vmw_private *dev_priv;
+1 −0
Original line number Diff line number Diff line
@@ -767,6 +767,7 @@ extern struct ttm_placement vmw_evictable_placement;
extern struct ttm_placement vmw_srf_placement;
extern struct ttm_placement vmw_mob_placement;
extern struct ttm_placement vmw_mob_ne_placement;
extern struct ttm_placement vmw_nonfixed_placement;
extern struct ttm_bo_driver vmw_bo_driver;
extern int vmw_dma_quiescent(struct drm_device *dev);
extern int vmw_bo_map_dma(struct ttm_buffer_object *bo);
+32 −18
Original line number Diff line number Diff line
@@ -682,9 +682,6 @@ vmw_du_plane_duplicate_state(struct drm_plane *plane)
		return NULL;

	vps->pinned = 0;

	/* Mapping is managed by prepare_fb/cleanup_fb */
	memset(&vps->host_map, 0, sizeof(vps->host_map));
	vps->cpp = 0;

	/* Each ref counted resource needs to be acquired again */
@@ -746,11 +743,6 @@ vmw_du_plane_destroy_state(struct drm_plane *plane,


	/* Should have been freed by cleanup_fb */
	if (vps->host_map.virtual) {
		DRM_ERROR("Host mapping not freed\n");
		ttm_bo_kunmap(&vps->host_map);
	}

	if (vps->surf)
		vmw_surface_unreference(&vps->surf);

@@ -1129,12 +1121,14 @@ static const struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = {
};

/**
 * Pin the dmabuffer to the start of vram.
 * Pin the dmabuffer in a location suitable for access by the
 * display system.
 */
static int vmw_framebuffer_pin(struct vmw_framebuffer *vfb)
{
	struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
	struct vmw_dma_buffer *buf;
	struct ttm_placement *placement;
	int ret;

	buf = vfb->dmabuf ?  vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
@@ -1151,12 +1145,24 @@ static int vmw_framebuffer_pin(struct vmw_framebuffer *vfb)
		break;
	case vmw_du_screen_object:
	case vmw_du_screen_target:
		if (vfb->dmabuf)
			return vmw_dmabuf_pin_in_vram_or_gmr(dev_priv, buf,
							     false);
		if (vfb->dmabuf) {
			if (dev_priv->capabilities & SVGA_CAP_3D) {
				/*
				 * Use surface DMA to get content to
				 * sreen target surface.
				 */
				placement = &vmw_vram_gmr_placement;
			} else {
				/* Use CPU blit. */
				placement = &vmw_sys_placement;
			}
		} else {
			/* Use surface / image update */
			placement = &vmw_mob_placement;
		}

		return vmw_dmabuf_pin_in_placement(dev_priv, buf,
						   &vmw_mob_placement, false);
		return vmw_dmabuf_pin_in_placement(dev_priv, buf, placement,
						   false);
	default:
		return -EINVAL;
	}
@@ -2419,12 +2425,19 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
int vmw_kms_helper_buffer_prepare(struct vmw_private *dev_priv,
				  struct vmw_dma_buffer *buf,
				  bool interruptible,
				  bool validate_as_mob)
				  bool validate_as_mob,
				  bool for_cpu_blit)
{
	struct ttm_operation_ctx ctx = {
		.interruptible = interruptible,
		.no_wait_gpu = false};
	struct ttm_buffer_object *bo = &buf->base;
	int ret;

	ttm_bo_reserve(bo, false, false, NULL);
	if (for_cpu_blit)
		ret = ttm_bo_validate(bo, &vmw_nonfixed_placement, &ctx);
	else
		ret = vmw_validate_single_buffer(dev_priv, bo, interruptible,
						 validate_as_mob);
	if (ret)
@@ -2538,7 +2551,8 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
	if (res->backup) {
		ret = vmw_kms_helper_buffer_prepare(res->dev_priv, res->backup,
						    interruptible,
						    res->dev_priv->has_mob);
						    res->dev_priv->has_mob,
						    false);
		if (ret)
			goto out_unreserve;
	}
+2 −2
Original line number Diff line number Diff line
@@ -177,7 +177,6 @@ struct vmw_plane_state {
	int pinned;

	/* For CPU Blit */
	struct ttm_bo_kmap_obj host_map;
	unsigned int cpp;
};

@@ -289,7 +288,8 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
int vmw_kms_helper_buffer_prepare(struct vmw_private *dev_priv,
				  struct vmw_dma_buffer *buf,
				  bool interruptible,
				  bool validate_as_mob);
				  bool validate_as_mob,
				  bool for_cpu_blit);
void vmw_kms_helper_buffer_revert(struct vmw_dma_buffer *buf);
void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
				  struct drm_file *file_priv,
+3 −2
Original line number Diff line number Diff line
@@ -1032,7 +1032,7 @@ int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
	int ret;

	ret = vmw_kms_helper_buffer_prepare(dev_priv, buf, interruptible,
					    false);
					    false, false);
	if (ret)
		return ret;

@@ -1130,7 +1130,8 @@ int vmw_kms_sou_readback(struct vmw_private *dev_priv,
	struct vmw_kms_dirty dirty;
	int ret;

	ret = vmw_kms_helper_buffer_prepare(dev_priv, buf, true, false);
	ret = vmw_kms_helper_buffer_prepare(dev_priv, buf, true, false,
					    false);
	if (ret)
		return ret;

Loading